Skip to content

vscode: merge Architects + Builders trees into a single "Agents" section, architect-rooted when N>1 #1104

Description

@amrmelsayed

Problem

The Codev sidebar currently has two parallel trees that hide a real relationship between them:

  • Architects — flat list of running architect sessions (MAIN, REVIEWER, etc.)
  • Builders — area- or phase-grouped list of in-flight builders

Each builder has a spawnedByArchitect owner (the affinity model that routes gates, blocked-on questions, and afx send architect messages back to the spawner). That ownership is invisible in the UI: nothing on a builder row indicates which architect spawned it, and nothing in the Architects tree indicates what each architect is working on. As more workspaces run multiple specialised architects, "which builder is owned by which architect" becomes increasingly load-bearing for triage.

Proposal

Replace the two trees with one Agents section, rooted at architects when multi-architect, collapsing to today's area-or-phase grouping when single-architect. The architect-rooted variant is a 3-level hierarchy that preserves the existing area/phase grouping below the architect tier rather than displacing it. Architect creation becomes a conversation with the main architect rather than a direct CLI call.

Tree shape

When architectCount > 1:

Agents
├── MAIN
│   ├── TOWER (1 blocked · 1 active)
│   │   ├── #1054 fix afx spawn substring match  blocked on plan-approval [3h]
│   │   └── #1048 cron evaluator ReferenceError
│   └── VSCODE (1 active)
│       └── #1073 codelens keyboard shortcut
├── VSCODE
│   └── (no builders)
└── REVIEWER
    (no builders — passive, never spawns)

When architectCount === 1:

Agents
├── TOWER (1 blocked · 1 active)
│   ├── #1054 fix afx spawn substring match  blocked on plan-approval [3h]
│   └── #1048 cron evaluator ReferenceError
└── VSCODE (1 active)
    └── #1073 codelens keyboard shortcut

Implemented as a count check in the tree's root getChildren(): when architectCount === 1, skip the architect level entirely and root at area-groups. No user toggle, no config — the level that doesn't earn its keep doesn't render.

What survives

  • Existing grouping toggle (group by area vs group by phase) lives at level 2, untouched. Off-axis prefix on builder rows continues to surface the complementary axis.
  • rollupGroupState / worstBuilderState (builder-row.ts:56-107) extend naturally to a second tier: architect-level rollup at level 1, area/phase-level rollup at level 2.
  • Builder file-tree children (BuilderFileTreeItem, BuilderFolderTreeItem) hang off level-3 builder rows exactly as today.
  • Architect rows stay interactive even when childless. A passive architect like REVIEWER renders as a leaf (collapsibleState: None) — right-click → message stays available without pretending to own work it never will.
  • description field on builder rows carries the architect name as a dim badge in the single-architect-collapsed view and in any flat sub-tree where the architect isn't already in the row's ancestry. Conditional render (only when architectCount > 1) so single-architect workspaces stay clean.

What goes away

  • The standalone Architects tree contributes no view of its own. Its registered tree-view id is either removed or repurposed; its content moves to the Agents root level.
  • The existing Builders tree is renamed to Agents and gains the architect-root level adaptively.

Workspace view delineation

The Codev sidebar's Workspace view has its own Architects subsection (workspace.ts:84-92), distinct from the standalone Architects tree this proposal removes. It survives unchanged, reframed by purpose:

  • Workspace > Architects = workspace configuration. "Who is registered in this workspace, open their terminals." Configuration-shaped, read-only-style listing.
  • Agents (new) = active ownership. "Who owns the in-flight work, with their builders nested." Work-shaped, the primary triage surface.

Both views read from the same architect roster (Tower's architects-updated event), so they stay in sync automatically.

Architect creation: conversational, not direct

The Codev: Add Architect action does not call afx workspace add-architect directly anymore. It becomes a request to the main architect, who decides whether to act on it.

The rationale: architect creation is a workspace-orchestration event — it changes the roster, the specialisation matrix, and the conversation routing. Main is the workspace orchestrator (owns backlog triage, release decisions, sibling-architect dispatch); architect creation belongs in main's lane for the same reason cross-cutting work and release decisions do. Letting any developer create an unbriefed architect via direct CLI call leads to architect proliferation, missing briefs, and roster drift in main's state.

New Codev: Add Architect UX:

  1. User invokes the action (Agents title-bar +, Workspace > Architects +, Cmd+K A keybinding, or command palette).
  2. VS Code shows an input box for the architect name. Same validation as today (single source of truth in @cluesmith/codev-core, shipped in v3.2.1).
  3. The extension sends a message to the main architect via afx send architect:main "Please add a <name> architect." (or the equivalent envelope through Tower's command relay — see Implementation notes).
  4. Main receives the request, decides whether the specialisation makes sense (may push back, may ask for scope clarification), runs afx workspace add-architect --name <name> from its own terminal, sends the brief as the new architect's first message, and updates its working memory.
  5. The Workspace view's Architects subsection and the Agents tree both update automatically once Tower broadcasts architects-updated.

What stays available as fallbacks:

  • afx workspace add-architect --name <name> — CLI surface unchanged. Power users who want to bypass main intentionally still can.
  • Main is required to be active. If no main architect is registered or its terminal session is closed, the Add Architect action refuses with a message pointing the user at afx workspace start or the CLI fallback. This is deliberate — the action's contract is "ask main to add", so without main there's nothing to ask.

Optional polish (deferrable, may not ship in v1):

  • Side-effect of the Add Architect action could auto-open main's terminal so the user can follow main's response (or push back / clarify scope) without hunting for it.
  • A second input prompt could collect a scope/brief sentence to include in the message, sparing main a round-trip. Skip for v1 — let main ask if it needs the scope.

Why this shape

Discussed and validated through a design conversation that ruled out:

  • Plain badge on builder rows — minimum-disruption fix, but doesn't surface ownership in the Architects view and forces a per-row visual element competing with the area badge and state suffix.
  • Expand-architect-to-show-its-builders within both trees — logical duplication (same builder in two places), and the Architects tree's primary purpose (message/status) gets buried under secondary builder lists.
  • Group-by-architect as a 3rd grouping option in the Builders tree — cheap and reversible, but doesn't address the underlying parallel-trees problem and leaves the Architects tree without ownership context.
  • Full merge of Architects + Builders + Backlog — the backlog's cardinality (~30+) would dominate the smaller-volume sections; backlog stays in its own tree.
  • Direct CLI architect creation from the sidebar + — fast but bypasses main's awareness; leads to unbriefed architects and roster drift.

The 3-level adaptive design pays its hierarchy cost only when there's value (multiple active spawners), preserves the existing area/phase organising axis, and keeps passive architects (the REVIEWER pattern) honest as leaf rows rather than always-empty parents. The conversational creation model keeps the roster intentional and main's working memory in sync with reality.

Implementation notes

  • Strategy machinery: today's grouping strategies (builders.ts:71-73) operate one level deep. The architect tier is a new outer wrapper that delegates to the existing strategy at level 2. The strategy interface should stay unchanged; the outer wrapper is a separate concern.
  • getChildren() branch: root-level call inspects architectCount. When > 1, returns architect nodes; when === 1, returns the current area/phase group nodes directly (today's behaviour).
  • Architect node collapsibleState: Collapsed when it has builders, None when it doesn't. A passive architect therefore looks like a peer leaf to a collapsed parent — interactive but unmistakably empty.
  • Rollup at the architect tier sums across all area-groups beneath the architect. Same BUILDER_STATE_GLYPH vocabulary, same worst-of severity, same tooltip shape (<b> blocked · <i> waiting · <a> active).
  • Codev: Add Architect command rewrite: today's handler shells out to afx workspace add-architect. New handler resolves the main architect's terminal session (via Tower), prepares the request message, and dispatches it via the existing afx send envelope (or directly through Tower's messaging API to avoid the CLI hop). If main is not registered or its session is closed, the handler shows a modal with the CLI fallback path.
  • Tests: builder-grouping.test.ts, builders-accordion.test.ts, builders-autoreveal.test.ts will need new cases for the multi-architect branch. The single-architect branch should be a regression-test that today's behaviour is preserved bit-for-bit. New tests for the Add Architect handler: main-present → message dispatched; main-absent → modal with CLI fallback; name validation parity with afx workspace add-architect.

Protocol fit

PIR. This is a moderate-scope structural UI change with multiple design decisions baked in (the count-check collapse, the leaf-passive-architect rule, the conversational creation model, the Workspace-view delineation). The plan gate validates the layout decisions before any code is written; the dev gate validates the running tree in the sidebar on both a single-architect and multi-architect workspace, plus the Add Architect → main dispatch flow end-to-end, before the PR is opened.

Open questions

  • Should the Agents section ship with a default-expanded state for architects with >0 builders, or default-collapsed? (Default-collapsed is the lighter-touch starting position; default-expanded matches today's Builders-tree behaviour but adds vertical density in multi-architect workspaces.)
  • Tree-view id migration: rename the existing codev.builders id, or register a new codev.agents id and deprecate codev.builders? Affects external when-clause references and any saved view layout.
  • Add Architect: should the extension auto-open main's terminal after dispatching the request, or stay silent and trust the toast notification? (Auto-open is helpful for follow-up; silent is less intrusive when main is mid-task.)
  • Add Architect: should the input box also collect a scope/brief sentence, or keep it name-only and let main ask? (Name-only ships faster and lets main own the scope conversation; scope-included spares main a round-trip.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/vscodeArea: VS Code extension

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions