diff --git a/CURRENT-STATE.md b/CURRENT-STATE.md index 31116b9a..c145417a 100644 --- a/CURRENT-STATE.md +++ b/CURRENT-STATE.md @@ -12,6 +12,7 @@ ## Recently shipped (post-0.1.0.0) +- **2026-05-01 — PR #158** Session-screen UX impeccable pass + tasklane keyboard flow. Heuristic score 24/40 → 33/40 across five sub-passes (distill, quieter, layout, typeset, polish). Removed duplicate "Suggested checks" chip strip → TaskLane is the single source of truth; added inline `Next steps · N pending` cue on the latest action-bearing AI bubble; consolidated session header to Resolve + Escalate + ⋯ kebab; centered messages column to match composer; dropped all banned decorations (side stripes, gradient surfaces, backdrop blur, accent borderTop) for a single decoration channel per surface; unified 14 text sizes into a 5-step scale. TaskLane keyboard flow: Enter submits + auto-advances, Shift+Enter newline, Esc cancel, focus jumps to Send after the last task. Banner ↔ script-panel are now linked (collapse hides both, any outcome closes both). WhatWeKnow section is collapsible with `sessionStorage` memory + auto-collapse-at-5-facts. Side fix: ParameterizationPreview no longer over-highlights short parameter values (word-boundary check). Two backlog entries logged in `.ai/TODO.md`: ConcludeSessionModal multi-select and `bg-card-hover` Tailwind drift in CommandPalette. - **2026-05-01 — PR #156** Suggested-fix "Awaiting verification" outcome. Engineers can now park a fix in `applied_pending` (waiting on client power-cycle, AD replication, license sync, etc.) instead of forcing a synchronous worked/didn't/partial verdict. PendingBanner with worked / didn't / update reason / dismiss; nudge "Still checking" records pending with a reason; page-level Resolve auto-patches pending → success before the resolution flow opens; page-level Escalate intercepts pending. Migration `c0f3a4b7e91d` (`pending_reason` column + status CHECK constraint). - **2026-04-30 — PR #155** Escalation Mode wedge. Magic-moment handoff-context screen for senior pickup, live SSE escalation arrivals, post-claim time-to-first-action metric (`GET /analytics/flowpilot/escalations`), atomic role-gated claim with conflict resolution, queue self-exclusion, chat ownership extended to claimed sessions. The wedge for the first paying-customer push. diff --git a/.impeccable.md b/PRODUCT.md similarity index 100% rename from .impeccable.md rename to PRODUCT.md diff --git a/frontend/src/components/layout/Sidebar.tsx b/frontend/src/components/layout/Sidebar.tsx index 6dc2b113..f5404ab4 100644 --- a/frontend/src/components/layout/Sidebar.tsx +++ b/frontend/src/components/layout/Sidebar.tsx @@ -2,10 +2,10 @@ import { useCallback, useEffect, useRef, useState, type PointerEvent as ReactPoi import { Link, useLocation } from 'react-router-dom' import type { LucideIcon } from 'lucide-react' import { - LayoutGrid, Clock, AlertTriangle, GitBranch, Code2, Wand2, - ListChecks, Download, BarChart3, + LayoutGrid, Clock, AlertTriangle, GitBranch, + ListChecks, BarChart3, Settings, Pin, PinOff, - History, FileText, Network, Ticket, + FileText, Ticket, BookOpen, } from 'lucide-react' import { cn } from '@/lib/utils' import { useUserPreferencesStore } from '@/store/userPreferencesStore' @@ -31,11 +31,6 @@ interface NavEntry { children?: NavSubItem[] } -interface NavSection { - title: string - items: NavEntry[] -} - /* ── Sidebar component ──────────────────────────────── */ export function Sidebar() { @@ -78,36 +73,40 @@ export function Sidebar() { /* ── Navigation data ──────────────────────────────── */ - /* ── Grouped nav: 5 top-level icons (Sentry-style) ── */ + /* Single source-of-truth IA. Same items, same order, in both rail + * and pinned modes. Pin/unpin is a width/label affordance, not an + * IA switch. A hairline divider separates the two groups; no labels. */ - const railGroups: NavEntry[] = [ + const workItems: NavEntry[] = [ { - href: '/', icon: LayoutGrid, label: 'Home', shortLabel: 'Home', + href: '/', icon: LayoutGrid, label: 'Dashboard', shortLabel: 'Dash', matchPaths: ['/'], }, - { - href: '/sessions', icon: History, label: 'History', shortLabel: 'History', - badge: stats?.active_count || undefined, - matchPaths: ['/sessions', '/escalations', '/pilot'], - children: [ - { href: '/sessions', label: 'Session History', count: stats?.active_count || undefined }, - { href: '/escalations', label: 'Escalations', count: stats?.escalation_count || undefined }, - ], - }, { href: '/tickets', icon: Ticket, label: 'Tickets', shortLabel: 'Tickets', matchPaths: ['/tickets'], }, + { + href: '/sessions', icon: Clock, label: 'Sessions', shortLabel: 'Sessions', + badge: stats?.active_count || undefined, + matchPaths: ['/sessions'], + }, + { + href: '/escalations', icon: AlertTriangle, label: 'Escalations', shortLabel: 'Escal', + badge: stats?.escalation_count || undefined, + matchPaths: ['/escalations'], + }, + ] + + const libraryItems: NavEntry[] = [ { href: '/trees', icon: GitBranch, label: 'Flows', shortLabel: 'Flows', badge: stats?.tree_counts.total || undefined, - matchPaths: ['/trees', '/flows', '/my-trees', '/step-library', '/review-queue', '/network-diagrams'], + matchPaths: ['/trees', '/flows', '/my-trees', '/step-library', '/network-diagrams'], children: [ - { href: '/trees', label: 'Flow Library', count: stats?.tree_counts.total || undefined }, { href: '/trees?type=procedural', label: 'Projects', count: stats?.tree_counts.procedural || undefined }, - { href: '/network-diagrams', label: 'Network Maps' }, { href: '/step-library', label: 'Solutions Library' }, - { href: '/review-queue', label: 'Review Queue' }, + { href: '/network-diagrams', label: 'Network Maps' }, ], }, { @@ -115,60 +114,25 @@ export function Sidebar() { badge: pendingDraftCount || undefined, matchPaths: ['/scripts', '/script-builder'], children: [ - { href: '/scripts', label: 'Script Library', count: pendingDraftCount || undefined }, { href: '/script-builder', label: 'Script Builder' }, ], }, { - href: '/analytics', icon: BarChart3, label: 'Insights', shortLabel: 'Data', + href: '/review-queue', icon: ListChecks, label: 'Review Queue', shortLabel: 'Review', + matchPaths: ['/review-queue'], + }, + { + href: '/analytics', icon: BarChart3, label: 'Analytics', shortLabel: 'Stats', matchPaths: ['/analytics', '/shares'], children: [ - { href: '/analytics', label: 'Analytics' }, { href: '/shares', label: 'Exports' }, ], }, ] - /* Pinned mode still uses the detailed section layout */ - const sections: NavSection[] = [ - { - title: 'RESOLVE', - items: [ - { href: '/', icon: LayoutGrid, label: 'Dashboard', shortLabel: 'Dash' }, - { href: '/sessions', icon: Clock, label: 'Session History', shortLabel: 'History', badge: stats?.active_count || undefined, matchPaths: ['/sessions'] }, - { href: '/tickets', icon: Ticket, label: 'Tickets', shortLabel: 'Tickets', matchPaths: ['/tickets'] }, - { href: '/escalations', icon: AlertTriangle, label: 'Escalations', shortLabel: 'Escal', badge: stats?.escalation_count || undefined }, - ], - }, - { - title: 'KNOWLEDGE', - items: [ - { - href: '/trees', icon: GitBranch, label: 'Flow Library', shortLabel: 'Flows', - badge: stats?.tree_counts.total || undefined, - matchPaths: ['/trees', '/flows', '/my-trees'], - children: [ - { href: '/trees', label: 'Flow Library' }, - { href: '/trees?type=procedural', label: 'Projects', count: stats?.tree_counts.procedural || undefined }, - ], - }, - { href: '/network-diagrams', icon: Network, label: 'Network Maps', shortLabel: 'NetMap', matchPaths: ['/network-diagrams'] }, - { href: '/scripts', icon: Code2, label: 'Scripts', shortLabel: 'Scripts' }, - { href: '/script-builder', icon: Wand2, label: 'Script Builder', shortLabel: 'Builder' }, - { href: '/review-queue', icon: ListChecks, label: 'Review Queue', shortLabel: 'Review' }, - ], - }, - { - title: 'INSIGHTS', - items: [ - { href: '/analytics', icon: BarChart3, label: 'Analytics', shortLabel: 'Stats' }, - { href: '/shares', icon: Download, label: 'Exports', shortLabel: 'Export' }, - ], - }, - ] - const footerItems: NavEntry[] = [ - { href: '/account', icon: Settings, label: 'Account', shortLabel: 'Acct' }, + { href: '/guides', icon: BookOpen, label: 'Guides', shortLabel: 'Guides', matchPaths: ['/guides'] }, + { href: '/account', icon: Settings, label: 'Account', shortLabel: 'Acct', matchPaths: ['/account'] }, ] /* ── Active detection ─────────────────────────────── */ @@ -369,9 +333,9 @@ export function Sidebar() { /* ── Find active flyout group for drawer ── */ + const allRailItems = [...workItems, ...libraryItems, ...footerItems] const activeFlyoutGroup = flyoutIndex && !sidebarPinned - ? railGroups.find((_, i) => `rail-${i}` === flyoutIndex) || - footerItems.find((_, i) => `footer-${i}` === flyoutIndex) + ? allRailItems.find(item => item.href === flyoutIndex) || null : null /* ── Main render ──────────────────────────────────── */ @@ -386,23 +350,20 @@ export function Sidebar() { > {/* Pinned sidebar content */}