You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Requirements drafted by the codev-ide architect (Amr-directed), reviewed and filed by codev:main. Spec and plan are builder-protocol artifacts; this issue is the requirements record.
Naming (re-ruled 2026-08-31 with the owner)
The surface is Tower (container id codev-tower, view id codev.tower). The machine-level supervision surface already has a user-facing name: the web dashboard is "Agent Farm Control Tower" and the daemon is afx tower. Naming the sidebar the same aligns all three surfaces (web, IDE, CLI) under one word for one vantage point. "Fleet" remains the collection noun in copy (the deck's fleet slot, "Fleet RSS", row counts like "3 workspaces need attention"): Tower is the vantage, fleet is what it watches. Guardrail: the Status view already says "Tower: connected", so this view's copy must always read as navigation over workspaces, never as daemon admin. Command ids are functional, not vocabulary-driven: the quick pick is codev.switchWorkspace. (Supersedes the initial "Fleet" ruling; the owner surfaced the dashboard-title consistency argument.)
Placement (owner-ruled at filing, 2026-08-31)
Tower is a separate sidebar: its own activity-bar view container (codev-tower), NOT an eighth section in the existing Codev sidebar (the owner ruled seven sections is already the ceiling there). The split lands on the real semantic boundary: the existing container is workspace-scope, the Tower container is machine-scope. The container's activity-bar icon carries the aggregate needs-attention count as its badge (TreeView.badge), which makes the separate status-bar badge (requirement 7) a should-have rather than a must-have; the spec decides whether both ship. Iconography must make the two Codev icons distinguishable at a glance.
Differentiation from the workspace-scope container (owner discussion, 2026-08-31, Explorer analogy: Explorer is this-project at the top of the built-in stack; Tower is the higher-level view above it):
Icons: same family, one vs many. The Tower icon is the workspace container's motif multiplied into a tiled/stacked form, or a control-tower glyph in the same family, the way Explorer's stacked documents read as "this project's files". Monochrome light/dark pair, rendered and verified at actual 16px (the vscode: Agents view with a 3-way group-by axis (stage / area / architect) + conversational Add Architect #1104 lesson), no brand color.
Badge semantics: only the Tower icon badges, and it badges the cross-workspace attention count. The workspace container stays unbadged so the badge itself signals machine-scope.
Current-workspace marking: the Tower tree explicitly marks this window's workspace row ("current", distinct styling; the spec decides whether it pins first regardless of urgency order).
Titles: "Codev Tower" vs "Codev" for hover/tooltips.
Default position: a marketplace extension cannot claim the top activity-bar slot (VS Code appends extension containers below built-ins; a user's manual drag persists). The Codev IDE fork owns default layout and may ship Tower-above-Explorer out of the box as an IDE default; the extension behaves identically everywhere and users of vanilla VS Code drag it up once if they want the same arrangement.
Problem
VS Code windows, and the extension's entire view set, are bound to the single folder the window has open, while Tower is user-global (one daemon, all workspaces). The only true multi-workspace client today is the Stream Deck plugin; the only cross-workspace path INTO VS Code is the inbound codev.focusWorkspaceWindow command. A user running several codev workspaces has no in-IDE way to see which workspace needs a human, or to jump there.
Requirements
Tower view: a tree view in the dedicated container listing all active Tower workspaces (TowerClient.listWorkspaces()), each row showing the workspace's attention state via the SDK's deriveAttention(OverviewData) / isIdleWaiting (@cluesmith/codev-sdk/builder-helpers, Contextual panel: wire the Attention fallback body from OverviewCache (participating feature of #1049, skeleton fast-follow) #1553), never re-derived locally. Rows expand to the agents needing attention (blocked gate, held mail, PR-ready), reusing the overview fields (blocked, blockedGate, heldCount, prReady, mailboxEscalated, queuedFeedback).
Urgency ordering: workspaces sorted by their AttentionSummary so "needs a human" floats to the top. One shared definition of urgency with all other clients. The comparator over AttentionSummary must be deterministic and documented in the spec (e.g. pending gates before waiting before held-mail counts), since it becomes the de facto cross-client urgency order.
Row labels disambiguate colliding basenames. Two active workspaces on the same machine can share a basename (live case: two codev checkouts under different org directories; see afx send <workspace>:<agent> has no disambiguator when basenames collide — support path-tail matching #1565 for the same collision in afx addressing). Rows must render a disambiguating path tail (cluesmith/codev vs amrmelsayed/codev) whenever basenames collide, and the quick pick must do the same.
Switch action: activating a row opens/focuses that workspace's window, reusing the codev.focusWorkspaceWindow re-validation plus vscode.openFolder { forceNewWindow: true } machinery. The hub stops at the workspace boundary: within-workspace agent-terminal cycling is Cycle agent terminals from keyboard and Stream Deck — next/previous in the Codev sidebar Agents order #1563's lane, and the hub composes with its sidebar-order rule rather than duplicating it.
Activate on demand: the view also lists known-but-inactive workspaces (/api/workspaces returns the full registry with an active flag) in a secondary group. Selecting one activates it (TowerClient.activateWorkspace(path), already in the SDK), waits for confirmation (status/SSE), then opens its window. Notes the spec must resolve:
ConnectionManager.connect() already calls activateWorkspace() idempotently in every window (connection-manager.ts:110-128), so the open-window path converges without explicit pre-activation; keep explicit activation for headless bring-up and for surfacing confirmations BEFORE a window opens.
Activation is Tower's launchInstance(): it registers the workspace, allocates ports, and spawns the main architect PTY, so the workspace comes up live. It also AUTO-ADOPTS a non-codev directory (npx codev adopt --yes, which writes files into the repo). The hub must surface that adopt step for confirmation, never run it silently.
The endpoint is rate-limited (10 activations/min/client).
Deactivation from the row context menu is a should-have (same SDK method family).
If Tower itself is down, the existing codev.autoStartTower path covers it; no new lifecycle code.
Quick pick: a keyboard-first codev.switchWorkspace command presenting the same attention-annotated list as a QuickPick.
Status-bar badge (should-have, see Placement): aggregate cross-workspace needs-attention count; click opens the Tower view or quick pick. The container icon's badge may make this redundant; the spec decides.
Data path: /api/workspaces plus per-workspace /api/overview fan-out, consumed strictly through @cluesmith/codev-sdk (TowerClient) and @cluesmith/codev-types; no raw endpoint coupling. If fan-out proves heavy at high workspace counts, a Tower-side aggregate is a codev-types/Tower addition routed to codev:main pre-gate (explicitly out of scope for v1).
Auth/scope: local key via readLocalKey (@cluesmith/codev-sdk/node, the existing AuthWrapper path); loopback-only. No remote/tunnel reach until the codev-cloud#7-Date/Time Awareness - Metadata Generation Problems #9 threat model lands.
Ship shape: lands in apps/vscode upstream; identical behavior in marketplace and Codev-IDE-bundled builds; zero fork-side code.
Non-goals (v1)
No Tower-side cross-workspace aggregate endpoint (client-side fan-out, as the Stream Deck store already does).
Requirements drafted by the codev-ide architect (Amr-directed), reviewed and filed by codev:main. Spec and plan are builder-protocol artifacts; this issue is the requirements record.
Naming (re-ruled 2026-08-31 with the owner)
The surface is Tower (container id
codev-tower, view idcodev.tower). The machine-level supervision surface already has a user-facing name: the web dashboard is "Agent Farm Control Tower" and the daemon isafx tower. Naming the sidebar the same aligns all three surfaces (web, IDE, CLI) under one word for one vantage point. "Fleet" remains the collection noun in copy (the deck's fleet slot, "Fleet RSS", row counts like "3 workspaces need attention"): Tower is the vantage, fleet is what it watches. Guardrail: the Status view already says "Tower: connected", so this view's copy must always read as navigation over workspaces, never as daemon admin. Command ids are functional, not vocabulary-driven: the quick pick iscodev.switchWorkspace. (Supersedes the initial "Fleet" ruling; the owner surfaced the dashboard-title consistency argument.)Placement (owner-ruled at filing, 2026-08-31)
Tower is a separate sidebar: its own activity-bar view container (
codev-tower), NOT an eighth section in the existing Codev sidebar (the owner ruled seven sections is already the ceiling there). The split lands on the real semantic boundary: the existing container is workspace-scope, the Tower container is machine-scope. The container's activity-bar icon carries the aggregate needs-attention count as its badge (TreeView.badge), which makes the separate status-bar badge (requirement 7) a should-have rather than a must-have; the spec decides whether both ship. Iconography must make the two Codev icons distinguishable at a glance.Differentiation from the workspace-scope container (owner discussion, 2026-08-31, Explorer analogy: Explorer is this-project at the top of the built-in stack; Tower is the higher-level view above it):
Problem
VS Code windows, and the extension's entire view set, are bound to the single folder the window has open, while Tower is user-global (one daemon, all workspaces). The only true multi-workspace client today is the Stream Deck plugin; the only cross-workspace path INTO VS Code is the inbound
codev.focusWorkspaceWindowcommand. A user running several codev workspaces has no in-IDE way to see which workspace needs a human, or to jump there.Requirements
TowerClient.listWorkspaces()), each row showing the workspace's attention state via the SDK'sderiveAttention(OverviewData)/isIdleWaiting(@cluesmith/codev-sdk/builder-helpers, Contextual panel: wire the Attention fallback body from OverviewCache (participating feature of #1049, skeleton fast-follow) #1553), never re-derived locally. Rows expand to the agents needing attention (blocked gate, held mail, PR-ready), reusing the overview fields (blocked,blockedGate,heldCount,prReady,mailboxEscalated,queuedFeedback).codevcheckouts under different org directories; see afx send <workspace>:<agent> has no disambiguator when basenames collide — support path-tail matching #1565 for the same collision in afx addressing). Rows must render a disambiguating path tail (cluesmith/codevvsamrmelsayed/codev) whenever basenames collide, and the quick pick must do the same.codev.focusWorkspaceWindowre-validation plusvscode.openFolder { forceNewWindow: true }machinery. The hub stops at the workspace boundary: within-workspace agent-terminal cycling is Cycle agent terminals from keyboard and Stream Deck — next/previous in the Codev sidebar Agents order #1563's lane, and the hub composes with its sidebar-order rule rather than duplicating it./api/workspacesreturns the full registry with anactiveflag) in a secondary group. Selecting one activates it (TowerClient.activateWorkspace(path), already in the SDK), waits for confirmation (status/SSE), then opens its window. Notes the spec must resolve:ConnectionManager.connect()already callsactivateWorkspace()idempotently in every window (connection-manager.ts:110-128), so the open-window path converges without explicit pre-activation; keep explicit activation for headless bring-up and for surfacing confirmations BEFORE a window opens.launchInstance(): it registers the workspace, allocates ports, and spawns themainarchitect PTY, so the workspace comes up live. It also AUTO-ADOPTS a non-codev directory (npx codev adopt --yes, which writes files into the repo). The hub must surface that adopt step for confirmation, never run it silently.codev.autoStartTowerpath covers it; no new lifecycle code.codev.switchWorkspacecommand presenting the same attention-annotated list as a QuickPick./api/eventsper extension host (the tower: offline gh failures aren't negative-cached (10s hang per request); with per-tab SSE this exhausts Chrome's connection pool and the dashboard becomes unloadable #1211 lesson: per-view EventSources exhausted the browser connection pool), driving refresh of the workspace list and per-workspace overviews; low-frequency poll fallback when SSE is unavailable./api/workspacesplus per-workspace/api/overviewfan-out, consumed strictly through@cluesmith/codev-sdk(TowerClient) and@cluesmith/codev-types; no raw endpoint coupling. If fan-out proves heavy at high workspace counts, a Tower-side aggregate is a codev-types/Tower addition routed to codev:main pre-gate (explicitly out of scope for v1).readLocalKey(@cluesmith/codev-sdk/node, the existing AuthWrapper path); loopback-only. No remote/tunnel reach until the codev-cloud#7-Date/Time Awareness - Metadata Generation Problems #9 threat model lands.apps/vscodeupstream; identical behavior in marketplace and Codev-IDE-bundled builds; zero fork-side code.Non-goals (v1)
POST /api/createexists; a New-Codev-Project flow is its own feature; related contract in vscode: welcome/start-surface polish — Codev entry points, canonical onboarding flow, walkthrough presentation #1537).Links