15 KiB
Gap Card — S01 Home Cockpit
Execution model: in-place incremental refactor of
apps/web+ targeted backend extensions. PRD source of truth: §12.1 (lines 373-410), §15 (data model), §16.1 (API), §20.1 (keep/promote). Mockupscreen_01_home_cockpit.pngis directional — acceptance criteria win over pixels.
1. Screen & purpose
Home Cockpit is the daily executive briefing and launch surface — the first thing the user sees after boot, before opening any workspace. PRD §12.1: "Give the user a useful daily briefing and immediate next actions." Acceptance bar (§12.1): user understands the day in <30 s, continues a workspace in one click, opens Ctrl+K from the keyboard, and captures a note/task/link/file from Home.
This is a new top-level surface in the IA spine (PRD §1: spine item #1). Today there is no Home
Cockpit; the closest things are the per-workspace WorkspaceBriefing (chat home screen) and the
modal LoginBriefing (one-shot catch-up overlay). The mockup shows six regions: greeting + date,
"You were working on" (recent workspaces with Continue), "Overnight" (consolidated / artifacts /
failures counters), "Up next" (events/tasks), "Suggested next actions", "Quick capture", and an
"Active models" tile.
2. Required states (PRD §12.1 + Blueprint p.265/447)
Functional requirements (§12.1):
- Greeting with user name + date/time.
- Active/recent workspaces ranked by recency and priority, each with one-click Continue.
- Overnight summary: memories consolidated, artifacts created, automations completed, failures.
- Upcoming meetings/events/tasks ("Up next").
- Suggested next actions (memory/session/task/schedule-derived).
- Quick capture for note/task/link/file.
- Active models + current mode, only if relevant (do not clutter).
- Ctrl+K hint/access.
States to implement (§12.1 "States" + Blueprint line 447):
Loading · First-run empty · Normal populated · Attention required · Offline/local-only ·
Overnight failure · Permission denied for shared/team data.
3. Current state in repo — disposition: partial (keep-promote + create-new)
PRD §20.1 explicitly: WorkspaceBriefing.tsx → "seed for Home Cockpit widgets" (keep and promote).
There is no HomeCockpit component today — it is a §20.3 "Create" item. So the work is: extract
reusable widget logic from the two existing briefing surfaces, build a new full-screen HomeCockpit,
and wire it to a new cross-workspace aggregation endpoint.
Existing files that feed this screen:
| File | What it does | Reuse role |
|---|---|---|
apps/web/src/components/os/WorkspaceBriefing.tsx (283 LOC) |
Per-workspace "home screen" inside ChatApp when a chat has no messages. Fetches GET /api/workspaces/:id/context; renders greeting, stats bar, pending tasks, recent decisions, "I Remember" memories, recent threads, cross-workspace hints, persona skill chips, suggested prompts, upcoming schedules. Collapse state persisted per-workspace via lib/workspace-briefing-state. |
Keep-promote. Its section components (memory list, pending tasks, decisions, suggested-prompt chips, upcoming schedules) are the widget vocabulary the Cockpit reuses. It is per-workspace, so it can't be the Cockpit as-is. |
apps/web/src/components/os/overlays/LoginBriefing.tsx (363 LOC) |
Modal "I remember…" catch-up shown once after boot. Already does cross-workspace aggregation client-side: getWorkspaces() → per-workspace getWorkspaceContext() (N calls) + searchMemory('…','global') + getMemoryStats(). Builds workspace summaries (memoryCount/sessionCount/lastActive/summary/pendingTasks), ranked memory highlights (lib/briefing-highlights), brag header (lib/login-briefing-brag), time-aware greeting + identity name. Has first-run empty hook (3 demo bubbles). Filters E2E/test workspaces. |
Keep-promote (heaviest reuse). Its data-gathering and ranking is exactly the Cockpit's "You were working on" + greeting + first-run-empty logic — but it does the N+1 fan-out on the client, which §20.4 forbids ("do not duplicate backend state calculation in frontend"). Promote this logic into the new GET /api/home/briefing server route. |
apps/web/src/components/os/apps/DashboardApp.tsx |
Dock app home — Workspaces grid (select/create/open chat), brain-health tier. Currently the thing the home dock key opens. |
Rework/keep. Becomes the workspaces-grid sub-view; Home Cockpit becomes the new default home surface. Not the briefing itself. |
apps/web/src/components/os/apps/CockpitApp.tsx (315 LOC) |
"Cockpit" = system/ops dashboard (health, cost, crons, connectors, weaver, event stats, compliance). Dock id cockpit. Name collision only — this is the ops Command-Center surface, NOT the PRD Home Cockpit. |
Out of scope / do not conflate. Maps to PRD §12.3-ish ops, not §12.1. Flag the naming clash. |
apps/web/src/components/os/cockpit/ComplianceDashboard.tsx |
EU AI Act compliance tiles, hosted inside CockpitApp. |
Not relevant to S01. |
Supporting lib (frontend, reuse as-is):
lib/briefing-highlights.ts (selectBriefingHighlights — importance-then-recency ranking),
lib/login-briefing-brag.ts (computeBragSummary/formatBragLine/timeAgo),
lib/workspace-briefing-state.ts (collapse persistence), lib/persona-display.ts,
lib/skill-recommendations.ts (persona skill chips). Note: lib/suggested-actions.ts is for
chat follow-up chips (regex over the last assistant message) — it is NOT the Home "suggested next
actions" generator; do not reuse it for the Cockpit. Suggested actions for Home come from
buildWorkspaceState().nextActions (backend) aggregated cross-workspace.
Backend builder already present (keep-promote, §20.1): packages/server/src/local/workspace-state.ts
buildWorkspaceState() → typed WorkspaceState (active/openQuestions/pending/blocked/completed/stale/
recentDecisions/nextActions) with freshness classification. This is the per-workspace next-action
engine the Home briefing aggregates over.
4. Frontend work
Create apps/web/src/components/os/apps/HomeCockpitApp.tsx (new top-level surface; register in
Desktop.tsx appConfig + renderAppContent, and make the home dock key open it instead of
DashboardApp — DashboardApp demotes to a "Workspaces" grid reachable from a Cockpit tile/Ctrl+K).
Widget components (extract from the two briefing files so logic is shared, not copy-pasted — CLAUDE.md "many small files"):
home/GreetingHeader.tsx— greeting + name + date/time (promote fromLoginBriefinglines 84-95 +WorkspaceBriefinggreeting). ReusebuildTimeAwareGreetingsemantics from backend; client just renders.home/RecentWorkspacesPanel.tsx— "You were working on": ranked workspace cards w/ Continue button →openChatForWorkspace(id)(viauseWindowManager). PromoteLoginBriefingsummaries list (lines 277-334).home/OvernightPanel.tsx— counters (consolidated / artifacts / automations done / failures); failure rows expandable → Automation Center. New (no current equivalent).home/UpNextPanel.tsx— upcoming events/tasks/schedules. ReuseupcomingSchedules+pendingTasksshapes; aggregate across workspaces.home/SuggestedActionsPanel.tsx— top NnextActionsaggregated frombuildWorkspaceState, each routing to its workspace. Notlib/suggested-actions.ts.home/QuickCapturePanel.tsx— note/task/link/file input →POST /api/quick-capture. New.home/ActiveModelsTile.tsx— promoteModelPilotCard/useProviders; render only when relevant.
Data layer:
- New hook
hooks/useHomeBriefing.ts→adapter.getHomeBriefing()+adapter.getOvernight(), with the §12.1 state machine (loading/empty/populated/attention/offline/overnight-failure/permission-denied). - Extend
lib/adapter.ts(the single sidecar gateway) withgetHomeBriefing(),getOvernight(),quickCapture(payload). Per the frontend inventory, all PRD §16 endpoints get added here. - First-run empty: reuse
LoginBriefing's demo-bubble hook (lines 222-247). - Offline/local-only: reuse
useOfflineStatus; degrade overnight/team tiles, keep local workspaces. - Ctrl+K hint: surface the existing
GlobalSearch(Ctrl+K) — already wired inuseKeyboardShortcuts.
Decision required (Open Q): does LoginBriefing (modal) survive alongside Home Cockpit, or does the
Cockpit absorb it? They overlap ~80%. Recommend: collapse LoginBriefing into the Cockpit's first paint
and retire the modal (avoid two catch-up surfaces).
5. Backend work (PRD §16.1)
| PRD endpoint | Status | Plan |
|---|---|---|
GET /api/home/briefing |
MISSING | NET-NEW route (new routes/home.ts registered in local/index.ts). Server-side aggregation that promotes LoginBriefing's client N+1 fan-out: iterate workspaceManager workspaces → reuse per-workspace logic already in routes/workspaces.ts /context handler (greeting/summary/recentMemories/pendingTasks/upcomingSchedules) + buildWorkspaceState() (workspace-state.ts) for nextActions, ranked by recency/priority. Reuse briefing-highlights ranking server-side. Substrate touched: memory_frames (per-workspace .mind), session JSONL, awareness, cron-store. No new store. Refactor over EXTEND: factor the /context body into a shared builder so /context and /home/briefing don't duplicate SQL. |
POST /api/quick-capture |
PARTIAL | EXTEND routes/memory.ts (or thin new handler delegating to it). Closest existing write is POST /api/memory/frames. Quick-capture = thin wrapper: default to personal mind, stamp source: 'quick-capture', accept `kind ∈ note |
GET /api/home/overnight |
MISSING | NET-NEW route (same routes/home.ts). Aggregate from existing substrates — no new store: cron/automation runs via GET /api/cron/:id/history (notifications.ts) + cron-store; consolidation/artifact counts from events.ts audit events (GET /api/events?since=) and weaver status (/api/weaver/status); failures from cron history error rows + notifications. Returns { consolidated, artifactsCreated, automationsCompleted, failures[] }. The Overnight failure state is driven by failures.length > 0. |
Notes for the implementer:
- Reuse, don't reinvent (§20.4): the per-workspace catch-up math lives in
routes/workspaces.tslines 311-592 andworkspace-state.ts. Extract the shared body before adding the cross-workspace loop. - Privacy gate (CRITICAL — already bit us): cross-workspace content aggregation was previously a
privacy leak.
routes/workspaces.tslines 553-564 showcrossWorkspaceHintsis deliberately DISABLED (returns[]) because the original iterated every workspace MindDB and returned content snippets with no grant check (security review:cowork/Code-Review_MultiMind_April-2026.mdCritical #1).GET /api/home/briefingis the SAME pattern (read every workspace) — but for Home it is the user's own workspaces, so it is legitimate for personal scope. Team/shared workspace rows must respectapprovalGrantStore/ team RBAC (PRD §12.1Permission denied for shared/team datastate). Do not leak team-workspace content the caller can't access. - Tier: Home briefing must work on FREE/TRIAL (it's the daily landing surface). Team-overnight rows are TEAMS-gated; gate the team slice, not the whole endpoint.
No .mind schema migration required. All three endpoints read existing tables (memory_frames,
awareness, audit events) and write only via existing frame/awareness paths. (PRD §15.4 confidence/
provenance fields are a separate, later migration — not needed for S01.)
6. Shared types needed (PRD §15 vs lib/types.ts)
Today lib/types.ts has WorkspaceContext (lines 66-85) — per-workspace, already carries
greeting/recentMemories/pendingTasks/upcomingSchedules/crossWorkspaceHints. Reuse its sub-shapes.
Add new interfaces (in lib/types.ts, mirrored server-side):
HomeBriefing { greeting; date; recentWorkspaces: RecentWorkspaceCard[]; suggestedActions: SuggestedAction[]; upNext: UpNextItem[]; activeModels?; isFirstRun: boolean }RecentWorkspaceCard { id; name; group; summary?; lastActive; pendingCount; continueSessionId? }OvernightSummary { consolidated: number; artifactsCreated: number; automationsCompleted: number; failures: OvernightFailure[] }OvernightFailure { id; label; automationId?; error; at }QuickCaptureInput { kind: 'note'|'task'|'link'|'file'; content; workspaceId? }SuggestedAction { label; workspaceId; sessionId?; kind }
Align kinds with PRD §15.2 (MemoryKind, ArtifactKind) where they overlap. These are net-new vs the
current lib/types.ts (which has no Home/Overnight/QuickCapture types).
7. Dependencies (screens/phases first)
- AppShell / IA (Sprint 1, PRD §21): Home Cockpit is the default landing surface — needs the dock
homekey repointed and the §10 IA buckets settled first. - Command Center (Ctrl+K) (S03): §12.1 acceptance "open Ctrl+K from the keyboard" —
GlobalSearchalready exists, so this is a soft dep (hint only). - Workspace Desktop (S02): "Continue" routes into the per-workspace runtime; needs
openChatForWorkspace(already inuseWindowManager) — soft dep. - Automation Center (S11): overnight failure rows link there; can ship Home with the count + a stub link.
- Belongs to Sprint 2 ("Home and workspace state") per PRD §21 — after shell, alongside the workspace-context/state API extension.
8. Effort: L
Frontend is mostly promotion of two existing briefing surfaces into shared widgets (medium), but the
backend adds two net-new aggregation routes (/home/briefing, /home/overnight) that must (a)
refactor the per-workspace /context body into a shared builder to avoid duplication and (b) re-implement
the cross-workspace aggregation safely behind the grant/RBAC gate that previously caused a privacy
leak. The security-sensitive cross-workspace read is what pushes this from M to L. Not XL — no new data
store, no schema migration, and the ranking/greeting logic already exists.
9. Open questions
- LoginBriefing fate: retire the modal and absorb its catch-up into Home Cockpit's first paint, or keep both? (~80% overlap; two catch-up surfaces is confusing.)
- "Overnight" semantics: time-window = since last app close? since midnight local? last 12 h? Affects
the
since=query for events/cron history. - Cross-workspace personal read: confirm reading the user's own workspaces server-side (for the
briefing) is acceptable now that it's same-user (the prior leak was content snippets without grant
checks). Team/shared rows still gate through
approvalGrantStore/RBAC — confirm the gate boundary. homevscockpitnaming:CockpitAppalready owns "Cockpit" (ops). PRD calls S01 "Home Cockpit". Final dock/app naming to avoid the collision (proposal: S01 =home/"Home"; keep ops ascockpit).- DashboardApp role: does the Workspaces grid live as a Cockpit tab, a Ctrl+K destination, or stay a
separate dock app? (Affects whether
homedock key fully repoints to HomeCockpit.) - Quick-capture
fileflow: does a file capture upload into a default/personal store, or prompt for a target workspace?POST /api/ingestneeds a destination.