feat: FlowPilot migration — Phase 1-9 + Phase 9 bug fixes + QA fixture harness #147

Merged
chihlasm merged 85 commits from feat/flowpilot-migration into main 2026-04-25 06:02:14 +00:00
Showing only changes of commit f92cbefed9 - Show all commits

View File

@@ -0,0 +1,79 @@
/**
* ChatTabStrip — two-tab strip at the top of the chat region:
* [Chat] [Script Builder ●]
*
* Visibility is controlled by the parent (AssistantChatPage) — this
* component renders whenever it's mounted. The parent decides whether
* to mount it based on fix state.
*
* Tab switching uses onChange; the parent toggles display:none on the
* tab contents so state is preserved across switches.
*/
import { cn } from '@/lib/utils'
export type ChatTab = 'chat' | 'script_builder'
export interface ChatTabStripProps {
active: ChatTab
onChange: (tab: ChatTab) => void
/** When true, shows the amber indicator dot on the Script Builder tab. */
scriptBuilderHasProgress?: boolean
}
export function ChatTabStrip({
active, onChange, scriptBuilderHasProgress,
}: ChatTabStripProps) {
return (
<div
role="tablist"
className="flex gap-1 px-4 pt-2 border-b border-default bg-bg-sidebar"
>
<TabButton
label="Chat"
active={active === 'chat'}
onClick={() => onChange('chat')}
/>
<TabButton
label="Script Builder"
active={active === 'script_builder'}
onClick={() => onChange('script_builder')}
indicator={scriptBuilderHasProgress}
/>
</div>
)
}
function TabButton({
label, active, onClick, indicator,
}: {
label: string
active: boolean
onClick: () => void
indicator?: boolean
}) {
return (
<button
role="tab"
aria-selected={active}
onClick={onClick}
className={cn(
'relative px-3 py-[7px] text-[12.5px] font-medium rounded-t-md transition-colors',
'border-b-2 -mb-px',
active
? 'text-heading border-accent bg-bg-page'
: 'text-muted-foreground border-transparent hover:text-primary hover:bg-white/[0.08]',
)}
>
{label}
{indicator && (
<span
role="img"
aria-label="unsaved progress"
className="ml-1.5 inline-block w-1.5 h-1.5 rounded-full bg-warning align-middle"
/>
)}
</button>
)
}
export default ChatTabStrip