DeviceToolbar gets Subnet/VLAN/Site/DMZ grouping section with
drag-drop. PropertiesPanel gets Show Traffic toggle that switches
edges between connection and animated types. DiagramEditor handles
both device and group node drops.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaces hand-rolled node layout with composable React Flow UI
components. Status is now a border effect instead of a dot.
Hover tooltip shows hostname, IP, vendor, role, notes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GroupNode for subnet/VLAN/site grouping with positioned label badge.
AnimatedSvgEdge for traffic flow visualization with animated SVG
shape along edge path. Both registered in type maps.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Selection state now stores IDs and derives objects from live arrays,
so edits in PropertiesPanel inputs reflect immediately.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Creates the React Flow building blocks for the network diagram editor:
device type registry with icon/color mappings, DeviceNode component with
status indicators and connection handles, ConnectionEdge with per-type
styling, and nodeTypes/edgeTypes registration maps.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds all interfaces for network diagrams and device types including
DiagramNode, DiagramEdge, DeviceProperties, NetworkDiagramResponse,
AI generate request/response, import/export shapes, and list item types.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove duplicate Update/Close actions from chat toolbars (FlowPilotPage,
CockpitPage) — session lifecycle actions now live only in headers. Redesign
ViewToggle as a persistent tab bar with bottom-border active indicator and
ARIA attributes. Standardize all action naming: Resolve (emerald), Update
(blue), Close (rose), Pause (muted). Fix IncidentHeader Resolve from orange
to emerald. Delete unused FlowPilotActionBar component (227 lines). Update
ConcludeSessionModal copy to use forward-facing action verbs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Eliminates the dedicated ViewToggle row on CockpitPage by merging
it into IncidentHeader's action group via extraActions prop. Removes
subtitle from ViewToggle component entirely — the icon + label is
self-explanatory. Cleans up showSubtitle prop from all call sites.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The IncidentHeader overflow menu was see-through due to bg-elevated on
bg-card. Switched to bg-card with shadow-xl and fixed-scrim dismiss
pattern matching production FlowPilotSessionPage. Replaced unicode
ellipsis with MoreHorizontal icon + aria-label. Added Update button
(StatusUpdateModal) to IncidentHeader and FlowPilotPage header bar
for feature parity with production.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Reset triageMeta, psaTicketId, steps, and completedSteps when
activeChatId changes (prevents stale triage data from previous session
showing while AI processes the new one)
- Split the activeChatId and activeActions reset effects so triage
only resets on session switch, not on every new action set
- Add loading placeholders to cockpit work zone: spinner + "analyzing"
text in steps panel, "questions will appear here" in right panel
- Add centered "Starting session..." loader to FlowPilot page when
loading with no messages yet (prefill creation period)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Root cause: race condition between setActiveChatId and the persist
effect. When switching from session A to B, setActiveChatId(B) triggers
the persist effect which writes {chatId: B, questions: [A's data]} to
sessionStorage BEFORE the async selectChat clears the task lane. The
sessionStorage fallback then finds chatId === B and restores A's stale
task lane data.
Fix: clear task lane state synchronously in selectChat before the await.
Server-side pending_task_lane restores it if the new session has data.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix return type annotation on unified_chat_service.send_chat_message (6→7 tuple)
- Fix stale closure in CockpitPage handleStepComplete auto-advance logic
- Fix IncidentHeader copy link hardcoding /assistant/ path (now uses current URL)
- Wire psaTicketId from session data through to CockpitPage incident header
- Fix FlowPilotAsks showing only first question — add chevron navigation for all
- Redesign ViewToggle: add icons (MessageSquare/LayoutDashboard) and subtitles
- Move view toggle from chatbar toolbar to standalone row above input on dashboard
- Standardize toggle placement across dashboard, FlowPilot, and Cockpit pages
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend: stop wiping pending_task_lane when AI response has no new
[ACTIONS]/[QUESTIONS] markers — previous task lane state is still
relevant until replaced by new markers.
Frontend (selectChat): don't eagerly clear task lane before server
response arrives; restore from sessionStorage as fallback when
pending_task_lane is null (covers sessions before backend fix).
StepsPanel: show description and command for all steps instead of
hiding behind hover/active-only visibility. Commands render as
inline code blocks.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Always load session data on mount even when urlSessionId matches
activeChatId, fixing empty state after view toggle between /assistant
and /cockpit (tasks/messages not showing until sidebar click)
- Add loadingRef for synchronous guards preventing duplicate sends,
duplicate session creation, and prefill races
- Fix stale evidence_items closure in CockpitPage handlers
- Move setLoading(true) before first await in handlePrefill and
handleResumeNew
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace all inline session management with the shared useAssistantSession
hook. Keep cockpit-specific state (triageMeta, workZonePct, steps, onboarding)
and handlers. Wire onSessionLoadedRef/onTriageUpdateRef callbacks. Add feature
flag redirect for flowpilot_cockpit. Update router and prefetch references.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Recreates the production AssistantChatPage as FlowPilotPage using the
shared useAssistantSession hook. Classic chat interface with ChatMessage
bubbles, TaskLane side panel, rich input with file uploads, and
conclude/status update modals. ViewToggle commented out pending Task 4.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
No external call sites existed. Feature gating now handled by
useFeatureFlag hook backed by the feature_flags system.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Selector-based hook reads from authStore.featureFlags.
Returns false for unknown keys (fail closed).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Loads resolved feature flags from /auth/me/feature-flags alongside
user, account, and subscription data.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
handleSend, sendPrefill, and handleResumeNew all make async API calls
that can return after the user has switched to a different session. Without
a guard, the stale response overwrites the new session's questions/actions
state — causing the previous session's FlowPilot Asks to persist.
Fix: capture the session ID before each await and check currentChatRef
after — discarding the response if the user has since switched. This
matches the existing guard pattern in selectChat (lesson #106).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Stacked zone layout: incident header → work zone → drag handle →
conversation log → compose
- IncidentHeader wired with triageMeta state and field save handlers
- Work zone: StepsPanel (left) + FlowPilotAsks + WhatWeKnow (right)
- Drag-resizable split with localStorage persistence
- Compact conversation log with you:/fp: prefixes
- Triage state populated on session load/resume
- AI triage_update merged into header via mergeTriageUpdate()
- MSP-native language: FlowPilot, New Case, Close Case
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- IncidentHeader: labelled fields with per-field edit popovers
- StepsPanel: ordered step checklist (✓/→/○) with script CTA
- FlowPilotAsks: quick-reply buttons or free-text input
- WhatWeKnow: evidence list with status toggle and inline editing
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>