From 79c8632dbbf15226dda2c5f47371af02d3ee63f3 Mon Sep 17 00:00:00 2001 From: chihlasm Date: Thu, 2 Apr 2026 16:44:07 +0000 Subject: [PATCH] docs: add FlowPilot / Cockpit side-by-side design spec Sub-project 2 design spec covering dual-page routing, view toggle, sidebar navigation, dashboard integration, and shared logic extraction. Co-Authored-By: Claude Opus 4.6 (1M context) --- ...2-flowpilot-cockpit-side-by-side-design.md | 147 ++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 docs/superpowers/specs/2026-04-02-flowpilot-cockpit-side-by-side-design.md diff --git a/docs/superpowers/specs/2026-04-02-flowpilot-cockpit-side-by-side-design.md b/docs/superpowers/specs/2026-04-02-flowpilot-cockpit-side-by-side-design.md new file mode 100644 index 00000000..03a20395 --- /dev/null +++ b/docs/superpowers/specs/2026-04-02-flowpilot-cockpit-side-by-side-design.md @@ -0,0 +1,147 @@ +# FlowPilot / FlowPilot Cockpit Side-by-Side — Design Spec + +**Date:** 2026-04-02 +**Status:** Approved +**Prerequisite:** Sub-project 1 (Feature Flag Frontend Infrastructure) — completed +**Branch:** `feat/cockpit-harness` (PR #124) + +--- + +## Context + +ResolutionFlow's AI chat assistant lives at `/assistant`. On the `feat/cockpit-harness` branch (PR #124), this page was reframed as a triage cockpit with IncidentHeader, StepsPanel, FlowPilotAsks, and WhatWeKnow panels. The production version on `origin/main` retains the classic chat layout with ChatMessage and TaskLane. + +Rather than replacing one with the other, both views will coexist on separate routes so beta users can try both and provide feedback. Long-term, the cockpit becomes a premium feature gated by the `flowpilot_cockpit` feature flag. + +--- + +## Design + +### 1. Pages & Routing + +Two page components, two route groups, one shared session backend. + +| Route | Page Component | Source | Description | +|-------|---------------|--------|-------------| +| `/assistant`, `/assistant/:sessionId` | `FlowPilotPage.tsx` | Production `AssistantChatPage` from `origin/main` + backported improvements | Classic chat layout: sidebar, chat messages, TaskLane side panel | +| `/cockpit`, `/cockpit/:sessionId` | `CockpitPage.tsx` | Current `AssistantChatPage` from `feat/cockpit-harness` | Cockpit layout: IncidentHeader, StepsPanel, FlowPilotAsks, WhatWeKnow, conversation log | + +**Session portability:** Both pages use the same `ai_sessions` backend and `aiSessionsApi` calls. Navigating from `/assistant/abc123` to `/cockpit/abc123` loads the same session — the cockpit renders triage panels on top of the same data. + +**File changes:** +- Rename current `AssistantChatPage.tsx` → `CockpitPage.tsx` +- Create new `FlowPilotPage.tsx` from `origin/main` version of `AssistantChatPage` with improvements cherry-picked (session-switch race condition guard, etc.) +- Update `router.tsx`: add `/cockpit` and `/cockpit/:sessionId` routes pointing to `CockpitPage`, update `/assistant` routes to point to `FlowPilotPage` +- Remove the now-unused `AssistantChatPage.tsx` import from router + +### 2. View Toggle + +A toggle in the page header lets users switch between FlowPilot and FlowPilot Cockpit mid-session. + +- **Location:** Top bar area of both pages, next to existing action buttons (Resolve/Escalate) +- **Visibility:** Only appears when viewing an active session (not on empty/new session state) AND only if the user has the `flowpilot_cockpit` feature flag enabled +- **Visual:** Segmented control / pill toggle — `FlowPilot | Cockpit` — with the active view highlighted +- **Behavior:** Clicking the other segment navigates via `react-router` `navigate()`: e.g., `/assistant/abc123` → `/cockpit/abc123` +- **Performance:** Navigation is instant — no data refetch needed since both pages load the same session by ID from the API on mount +- **Component:** `ViewToggle.tsx` — shared component imported by both pages + +**Edge case:** If the user is on `/cockpit/:sessionId` but loses the `flowpilot_cockpit` feature flag (admin disables it), the cockpit page redirects to `/assistant/:sessionId` via a `useEffect` check. + +### 3. Sidebar Navigation + +New top-level rail icon for FlowPilot, with flyout showing both views. + +- **Rail icon:** `Sparkles` with label "FlowPilot" +- **Position:** Second item in the rail, right after Home — this is the primary workflow entry point +- **Flyout children:** + - "FlowPilot" → `/assistant` + - "FlowPilot Cockpit" → `/cockpit` — only shown if `useFeatureFlag('flowpilot_cockpit')` returns `true` +- **matchPaths:** `['/assistant', '/cockpit']` — both routes highlight this rail icon +- **Pinned sidebar sections:** Add under the existing "RESOLVE" section with the same gating logic + +### 4. Dashboard Integration + +`QuickStartPage` lets the user choose which view new sessions launch into. + +- **Default behavior:** `StartSessionInput` continues to launch to `/assistant` (FlowPilot) +- **Cockpit launch option:** If the user has the `flowpilot_cockpit` flag enabled, show a small toggle or dropdown near the submit button — "Open in: FlowPilot | Cockpit" — that controls whether the new session navigates to `/assistant/:sessionId` or `/cockpit/:sessionId` +- **Preference persistence:** Store the user's last choice in `userPreferencesStore` (persisted to `localStorage`) so it remembers their preferred launch target across sessions +- **Dashboard session cards:** `ActiveFlowPilotSessions` and `RecentFlowPilotSessions` — clicking a session navigates to the user's stored view preference + +### 5. Shared Logic Extraction + +Both pages share significant session management code. Extract into a shared hook to avoid duplication. + +**`useAssistantSession` hook** (new file: `frontend/src/hooks/useAssistantSession.ts`): +- Session CRUD (create, load, select, delete) +- Chat message sending + response handling +- File upload handling (`pendingUploads`, drag-drop) +- Active questions/actions state management +- Branching integration (`useBranching`) +- Session-switch race condition guard (`currentChatRef` pattern) +- Conclude/resolve/escalate flows +- Prefill auto-submit logic + +**`FlowPilotPage.tsx`** — imports `useAssistantSession`, renders the classic chat layout (ChatMessage, TaskLane sidebar panel) + +**`CockpitPage.tsx`** — imports `useAssistantSession`, renders the cockpit layout (IncidentHeader, StepsPanel, FlowPilotAsks, WhatWeKnow, conversation log) plus manages cockpit-specific state (triage metadata, evidence items, drag-resizable split) + +This keeps each page focused on layout/rendering (~200-400 lines each) while the ~600+ lines of shared session logic live in one place. + +### 6. Backend Changes + +Minimal backend work — most infrastructure already exists. + +The triage columns (`client_name`, `asset_name`, `issue_category`, `triage_hypothesis`, `evidence_items`) are already on the `ai_sessions` table. What's needed: + +- **Verify existing endpoints:** Confirm `PATCH /ai-sessions/{id}/triage` and the `triage_update` field in `ChatMessageResponse` are working. If not, implement per the cockpit design spec (`docs/cockpit/2026-04-01-msp-assistant-harness-design.md`) +- **Handoff draft endpoint:** `POST /ai-sessions/{id}/handoff-draft` (streaming) — needed for the cockpit's Conclude modal. Streams a structured JSON object with `root_cause`, `resolution`, `steps_taken`, `recommendations` +- **No new migrations** — triage columns already exist on this branch, `flowpilot_cockpit` flag seeded in migration 072 +- **No changes to the FlowPilot (chat) page's backend** — it uses the same endpoints it always has + +### 7. UI Naming + +- Rename "AI Assistant" → "FlowPilot" throughout the UI (sidebar, page titles, breadcrumbs, dashboard) +- The cockpit view is labelled "FlowPilot Cockpit" +- Internal code: `FlowPilotPage` and `CockpitPage` + +--- + +## Scope Boundary + +**In scope:** +- New `FlowPilotPage.tsx` (from production `AssistantChatPage` + backported improvements) +- Rename current `AssistantChatPage.tsx` to `CockpitPage.tsx` +- Extract shared session logic into `useAssistantSession` hook +- Routes: `/assistant`, `/assistant/:sessionId`, `/cockpit`, `/cockpit/:sessionId` +- `ViewToggle` component in both page headers (gated by feature flag) +- Sidebar rail entry with flyout (cockpit gated by feature flag) +- Dashboard `StartSessionInput` launch preference toggle +- Verify/complete triage backend endpoints (PATCH triage, handoff-draft streaming) +- Rename "AI Assistant" to "FlowPilot" in UI labels + +**Not in scope:** +- Changes to the guided flow session page (`/pilot`) — stays as-is, hidden from sidebar +- New AI model routing or prompt changes +- PSA integration changes +- Real-time flag updates (reload is fine) +- Mobile-specific cockpit layout (responsive basics only) + +--- + +## Files Changed + +| File | Change | +|------|--------| +| `frontend/src/pages/AssistantChatPage.tsx` | Rename to `CockpitPage.tsx` | +| `frontend/src/pages/FlowPilotPage.tsx` | New — classic chat layout from `origin/main` + improvements | +| `frontend/src/pages/CockpitPage.tsx` | Renamed from AssistantChatPage, refactored to use `useAssistantSession` | +| `frontend/src/hooks/useAssistantSession.ts` | New — shared session logic extracted from both pages | +| `frontend/src/components/assistant/ViewToggle.tsx` | New — segmented control for switching views | +| `frontend/src/router.tsx` | Add `/cockpit` routes, update `/assistant` routes to FlowPilotPage | +| `frontend/src/components/layout/Sidebar.tsx` | Add FlowPilot rail entry with cockpit flyout child | +| `frontend/src/pages/QuickStartPage.tsx` | Add launch preference toggle for cockpit | +| `frontend/src/store/userPreferencesStore.ts` | Add `preferredFlowPilotView` preference | +| `backend/app/api/endpoints/ai_sessions.py` | Verify/add PATCH triage endpoint + handoff-draft streaming endpoint | +| `backend/app/schemas/ai_session.py` | Verify/add TriageUpdate, options on QuestionItem | +| `backend/app/services/unified_chat_service.py` | Verify/add triage extraction in chat responses |