Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
fc61087
chore(porch): 791 init pir
amrmelsayed May 30, 2026
2c6dcf2
[PIR #791] Plan draft
amrmelsayed May 31, 2026
85cf509
[PIR #791] Plan revised: tightened recheck design + walkthrough notes
amrmelsayed May 31, 2026
329da84
chore(porch): 791 plan-approval gate-requested
amrmelsayed May 31, 2026
97dfca0
chore(porch): 791 plan-approval gate-approved
amrmelsayed May 31, 2026
a6e9561
chore(porch): 791 implement phase-transition
amrmelsayed May 31, 2026
2b87f21
[PIR #791] Add CLI preflight core + vscode glue
amrmelsayed May 31, 2026
3ec4203
[PIR #791] Wire preflight into activation; guard CLI-dependent commands
amrmelsayed May 31, 2026
f3b08db
[PIR #791] Add Codev CLI status row with inline recheck
amrmelsayed May 31, 2026
b290812
[PIR #791] Add recheck command, status-row menu, Getting Started walk…
amrmelsayed May 31, 2026
a7ee702
[PIR #791] Tests for preflight core + walkthrough contribution
amrmelsayed May 31, 2026
64c2980
[PIR #791] Refactor command guarding into reg()/regCli() registrars
amrmelsayed Jun 1, 2026
eea70d2
[PIR #791] Note Node.js >=20 prerequisite in install walkthrough
amrmelsayed Jun 1, 2026
725e360
[PIR #791] Update builder thread log
amrmelsayed Jun 1, 2026
faf1233
chore(porch): 791 dev-approval gate-requested
amrmelsayed Jun 1, 2026
ccb5bb5
[PIR #791] Complete Verify step on cliReady context; rename walkthrou…
amrmelsayed Jun 1, 2026
1df7ec2
chore(porch): 791 dev-approval gate-approved
amrmelsayed Jun 1, 2026
b6dc7ed
chore(porch): 791 review phase-transition
amrmelsayed Jun 1, 2026
0ffab46
[PIR #791] Review + retrospective; arch + lessons updates
amrmelsayed Jun 1, 2026
8373f60
[PIR #791] Update builder thread log (review phase)
amrmelsayed Jun 1, 2026
af0a18f
chore(porch): 791 record PR #955
amrmelsayed Jun 1, 2026
c7e0d29
chore(porch): 791 review build-complete
amrmelsayed Jun 1, 2026
72d609d
[PIR #791] Record consultation verdicts + pending-recheck decision in…
amrmelsayed Jun 1, 2026
cca8fb0
chore(porch): 791 pr gate-requested
amrmelsayed Jun 1, 2026
5d229fe
chore(porch): 791 pr gate-approved
amrmelsayed Jun 1, 2026
4d6c06a
chore(porch): 791 protocol complete
amrmelsayed Jun 1, 2026
74736d9
chore(porch): 791 PR #955 merged
amrmelsayed Jun 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions codev/plans/791-vscode-startup-preflight-verif.md

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions codev/projects/791-vscode-startup-preflight-verif/status.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
id: '791'
title: vscode-startup-preflight-verif
protocol: pir
phase: verified
plan_phases: []
current_plan_phase: null
gates:
plan-approval:
status: approved
requested_at: '2026-05-31T03:55:40.568Z'
approved_at: '2026-05-31T04:23:36.693Z'
dev-approval:
status: approved
requested_at: '2026-06-01T11:13:08.978Z'
approved_at: '2026-06-01T11:30:02.959Z'
pr:
status: approved
requested_at: '2026-06-01T11:39:34.800Z'
approved_at: '2026-06-01T11:51:04.034Z'
iteration: 1
build_complete: false
history: []
started_at: '2026-05-30T23:16:57.708Z'
updated_at: '2026-06-01T11:53:56.334Z'
pr_history:
- phase: review
pr_number: 955
branch: builder/pir-791
created_at: '2026-06-01T11:35:38.523Z'
merged: true
merged_at: '2026-06-01T11:53:56.334Z'
pr_ready_for_human: false
1 change: 1 addition & 0 deletions codev/resources/arch.md
Original file line number Diff line number Diff line change
Expand Up @@ -1054,6 +1054,7 @@ The VS Code extension (`packages/vscode`) is a thin client over Tower's existing
- **TerminalLocation.Editor**: Terminals open directly in editor area via `ViewColumn.One` (architect) and `ViewColumn.Two` (builders). Uses stable VS Code API, not the undocumented `moveIntoEditor` command.
- **Subpath exports**: `codev-core` uses subpath exports (`./tower-client`, `./escape-buffer`, etc.) to prevent Node builtins from leaking into the dashboard's Vite build.
- **Injectable auth**: `TowerClient` accepts a `getAuthKey` callback. CLI uses `ensureLocalKey()` (creates key if missing). Extension uses `readLocalKey()` + `SecretStorage` (never creates keys).
- **Startup CLI preflight (#791)**: On `activate()` the extension verifies the `codev` CLI is installed and at least its own `package.json` version (`codev --version`, resolved like `resolveAfxPath`, cached per session, 400ms-bounded, fire-and-forget so activation never blocks). Missing → `Get started with Codev` walkthrough; outdated → upgrade notification; either dismissed → CLI-dependent commands no-op with one "run setup" toast. Commands register through two helpers — `reg` (unguarded) and `regCli` (guarded) — so the registrar name *is* the guard policy (no separate list). Preflight also sets the `codev.cliReady` context key, which drives the walkthrough's Verify-step completion. Lives in `src/preflight/` (`preflight-core.ts` pure + unit-tested, `preflight.ts` vscode glue).

## Repository Dual Nature

Expand Down
2 changes: 2 additions & 0 deletions codev/resources/lessons-learned.md
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,8 @@ Generalizable wisdom extracted from review documents, ordered by impact. Updated
- [From 0126] Building the overview endpoint to work in degraded mode (showing builders but empty PR/backlog sections with error messages when `gh` is unavailable) is a good default pattern for features that depend on external services.
- [From 0364] Use `onPointerDown` with `preventDefault()` and `tabIndex={-1}` to prevent focus stealing from terminal widgets -- this pattern translates directly to any floating controls rendered alongside interactive widgets.
- [From 799] VSCode's built-in Git `FileDecorationProvider` matches resources by repository **path**, not by URI scheme, and every extension-provided decoration shares a fixed `weight: 10` — so an extension cannot outrank Git in the decoration color merge. To stop Git from tinting a custom TreeView row's label (e.g. grey "ignored" on gitignored worktree paths), the row's `resourceUri` must use a **synthetic path that resolves into no open repository**; a non-`file` scheme alone is insufficient because Git never checks the scheme. The file-type icon still resolves off the basename at the path tail.
- [From #791] VSCode walkthrough steps without explicit `completionEvents` fall back to `onStepSelected` — they auto-tick the moment the step is *viewed*, which reads as false "done" progress (and the first step auto-selects on open, so it looks pre-completed). For a step with a real success condition, wire `completionEvents` to an observable signal — `onContext:<key>`, `onCommand:<id>`, `onSettingChanged:<id>` — so the checkmark means "achieved", not "seen". Tie completion to *outcome* (`onContext:codev.cliReady`), not to the *attempt* (`onCommand:recheck`), or a failed retry still ticks the step. Pure "read-and-do" steps (run a command in your own terminal) have no observable signal and are fine left on the view-default.
- [From #791] A running VSCode extension does **not** imply a usable system Node/npm: VSCode ships its own bundled Node for the extension host, never exposed on the user's shell `PATH`. Any "run this CLI / `npm install -g`" guidance must state the Node prerequisite explicitly (codev needs ≥20) and resolve CLI binaries from the workspace/`PATH`, not assume the extension's runtime.

## Documentation

Expand Down
70 changes: 70 additions & 0 deletions codev/reviews/791-vscode-startup-preflight-verif.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# PIR Review: VSCode startup preflight — verify codev CLI installed and version ≥ extension

Fixes #791

## Summary

Adds a startup preflight to the VSCode extension that, on `activate()`, verifies the `codev` CLI is installed and at least as new as the extension's own `package.json` version. The result is cached per session and bounded to 400ms (fire-and-forget, so activation never blocks). A missing CLI auto-opens the `Get started with Codev` walkthrough (once per workspace); an outdated CLI shows an upgrade notification (`Update via npm` / `Open Install Docs`); either prompt dismissed leaves Codev commands registered but no-op'ing cleanly with a single `Run Setup` toast. A persistent **Codev CLI** row in the sidebar Status view plus a `Codev: Recheck CLI` command let the user re-verify after fixing. This replaces the prior cryptic failure mode (a missing CLI surfaced only as a Tower-startup error logged to the OutputChannel) with actionable, state-specific guidance.

## Files Changed

- `packages/vscode/src/preflight/preflight-core.ts` (+105 / -0) — new, pure/vscode-free logic
- `packages/vscode/src/preflight/preflight.ts` (+261 / -0) — new, vscode glue
- `packages/vscode/src/extension.ts` (+~90 / -~50) — preflight wiring + `reg()`/`regCli()` registrars
- `packages/vscode/src/views/status.ts` (+42 / -0) — Codev CLI status row
- `packages/vscode/package.json` (+~35 / -~3) — `recheckCli` command, status-row inline menu, walkthrough contribution
- `packages/vscode/walkthroughs/detect.md`, `install.md`, `verify.md` (+61 / -0) — walkthrough step bodies
- `packages/vscode/src/__tests__/preflight-core.test.ts` (+100 / -0) — new unit tests
- `packages/vscode/src/__tests__/contributes-walkthroughs.test.ts` (+61 / -0) — new contribution-invariant tests
- `packages/vscode/src/__tests__/extension-architect-commands.test.ts` (+~6 / -~6) — updated source-sentinels for the `reg`/`regCli` registrar rename
- `codev/resources/arch.md`, `codev/resources/lessons-learned.md` — see sections below

## Commits

- `2b87f216` [PIR #791] Add CLI preflight core + vscode glue
- `3ec42037` [PIR #791] Wire preflight into activation; guard CLI-dependent commands
- `f3b08dbb` [PIR #791] Add Codev CLI status row with inline recheck
- `b2908122` [PIR #791] Add recheck command, status-row menu, Getting Started walkthrough
- `a7ee702d` [PIR #791] Tests for preflight core + walkthrough contribution
- `64c29805` [PIR #791] Refactor command guarding into reg()/regCli() registrars
- `eea70d29` [PIR #791] Note Node.js >=20 prerequisite in install walkthrough
- `ccb5bb5f` [PIR #791] Complete Verify step on cliReady context; rename walkthrough to 'Get started with Codev'

## Test Results

- `pnpm check-types`: ✓ pass
- `pnpm lint`: ✓ pass
- `pnpm test:unit`: ✓ pass (155 tests, ~25 new across the two new suites)
- `node esbuild.js`: ✓ bundles
- porch `build` + `tests` checks: ✓ pass (8.6s / 21.3s)
- Manual verification (human, at `dev-approval` gate): ran the Extension Development Host against the worktree; reviewed the `Get started with Codev` walkthrough (three steps), confirmed the Verify-step completion now keys off `codev.cliReady`, and approved the title/behaviour.

## Architecture Updates

Updated `codev/resources/arch.md` — added a "Startup CLI preflight (#791)" bullet to the VS Code Extension *Key Design Decisions* list, documenting: the on-activate `codev --version` check vs the extension's own version, the fire-and-forget/cached/400ms-bounded probe, the missing/outdated/dismissed UX branches, the `reg`/`regCli` two-registrar guard pattern (registrar name = guard policy, no separate list), the `codev.cliReady` context key, and the `src/preflight/` core+glue split. This is a genuine new architectural behaviour for the extension (a thin client that now verifies the CLI dependency it relies on), so it belongs in arch.md rather than only in this review.

## Lessons Learned Updates

Added two entries to `codev/resources/lessons-learned.md` (UI/UX), both durable for future VSCode work:

1. **Walkthrough step completion semantics** — steps without explicit `completionEvents` fall back to `onStepSelected` (auto-tick on view, which reads as false progress; the first step auto-selects on open). Wire completion to an observable signal (`onContext:`/`onCommand:`/`onSettingChanged:`), and key it on *outcome* (`onContext:codev.cliReady`) not *attempt* (`onCommand:recheck`) so a failed retry doesn't falsely complete the step.
2. **Bundled Node ≠ system Node** — a running extension doesn't imply a usable `node`/`npm` on the user's PATH (VSCode ships its own bundled Node for the extension host). Install/CLI guidance must state the Node prerequisite (codev needs ≥20) and resolve binaries from workspace/PATH.

## Things to Look At During PR Review

- **The guard split** — `regCli` wraps 15 CLI-dependent commands; `reg` registers the other 29 unguarded (recovery/recheck/config-toggles/read-only viewers). Confirm nothing critical is mis-classified. The policy is now the registrar name at each call site (grep `regCli(`), there is no separate list.
- **Optimistic `pending`** — `isCliReady()` treats the not-yet-resolved preflight window (~≤400ms) as ready, so a command fired during startup is never falsely blocked. The trade-off (a command in that window won't be guarded even if the CLI is actually missing) is intentional; the command then falls through its existing not-connected path and the walkthrough/notification still fires once preflight resolves.
- **`Update via npm` auto-runs** the install in an integrated terminal (the button click is the confirmation). The terminal-close re-verify is instance-matched and exit-code-gated; a failed/cancelled install does not silently re-cache — it surfaces an explicit `Recheck` toast.
- **Walkthrough `when`** — intentionally *not* gated; the walkthrough is always listed and VSCode features it once per install (`workbench.welcomePage.walkthroughs.openOnInstall`), which is acceptable. Our explicit once-per-workspace auto-open on the `missing` path is additive.
- **Recheck button scoped to `missing`/`outdated`, not `pending`** (raised by the Codex consultation as a COMMENT — minor plan drift). Deliberate: `pending` is the ≤400ms transient startup-probe state (shown as a spinner) with a preflight *already in flight* — a recheck button there is meaningless and would risk launching a second concurrent `codev --version`. The plan's wording listed `pending` too; this is an intentional narrowing. Verdicts: Gemini APPROVE, Claude APPROVE, Codex COMMENT (no REQUEST_CHANGES). PIR's consultation is single-pass, so this decision is recorded here for the `pr`-gate reviewer rather than re-reviewed by the models.

## How to Test Locally

- **View diff**: VSCode sidebar → right-click builder `pir-791` → **View Diff**
- **Run the extension**: launch the Extension Development Host against this worktree (the realest test for an extension change)
- **What to verify** (maps to the plan's Test Plan):
- **OK path**: current CLI installed → activate → no toast/walkthrough; Status row shows ✓ with the version; activation feels instant.
- **Missing**: shadow `codev` off PATH → `Get started with Codev` walkthrough opens once per workspace; Status row shows ✗ with inline recheck.
- **Outdated**: stub `codev --version` below the extension version → upgrade notification; `Open Install Docs` opens the browser; `Update via npm` runs the install in a terminal.
- **Recheck**: fix the CLI, click the Status-row recheck button (or run `Codev: Recheck CLI`) → row flips to ✓; the walkthrough's Verify step completes via `codev.cliReady`.
- **Dismiss → no-op**: dismiss, invoke a guarded command (e.g. Spawn Builder) → single `Run Setup` toast; an unguarded command (Reconnect) still works.
47 changes: 47 additions & 0 deletions codev/state/pir-791_thread.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# PIR #791 — vscode startup preflight (codev CLI install/version check)

## Plan phase

**Investigation findings:**
- Only existing CLI preflight: `tower-starter.ts:27-30` resolves `afx`, logs to OutputChannel on failure. No version check, no codev check, no UX.
- `codev --version` prints bare `X.Y.Z` (commander `program.version()`, `cli.ts:47`).
- Extension version source-of-truth: `context.extension.packageJSON.version` (currently 3.1.5).
- No `semver` dep in the vscode package → hand-rolled numeric compare.
- No `contributes.walkthroughs` today → must add one + markdown step bodies.
- vitest tests (`src/__tests__/`) cover pure/vscode-free logic + package.json invariants; vscode glue is reviewed via the vscode-test suite / manual. → split testable core into a vscode-free module.

**Design:** `preflight/preflight-core.ts` (pure: parseSemver/compareSemver/parseCliVersion/resolveCodevPath/decidePreflight) + `preflight/preflight.ts` (vscode glue: runPreflight, cache, walkthrough trigger, outdated notification, command guard). Fire-and-forget on activate (400ms timeout, session-cached). `guard()` wrapper applied to CLI-dependent commands only — split enumerated in plan for gate review.

Plan written to `codev/plans/791-vscode-startup-preflight-verif.md`.

**Plan revision (recheck design):** reviewer asked how versions are obtained + whether a recheck concept exists. Versions: extension's own via `context.extension.packageJSON.version` (truth); CLI via `spawn(codev, ['--version'])` (bare X.Y.Z, commander). Recheck consolidated into one command `codev.recheckCli` with 4 entry points: persistent **Status sidebar row** (`codev.status`, renders even when Tower offline, inline recheck button on non-ok states), instance-matched + exit-code-gated terminal-close re-verify after `Update via npm` (falls back to explicit `Recheck` toast on failed install), walkthrough Verify step link, and the `Run Setup` toast. Added `views/status.ts` + package.json command/menu to Files to Change.

Plan approved by human; advanced to implement.

## Implement phase

Implemented per approved plan. 5 logical commits (2b87f216..a7ee702d):
- `src/preflight/preflight-core.ts` — pure: parseSemver/compareSemver/parseCliVersion/resolveCodevPath/decidePreflight.
- `src/preflight/preflight.ts` — glue: 400ms-timeout probe, session cache, walkthrough/notification dispatch, `codev.recheckCli`, instance-matched + exit-code-gated re-verify after `Update via npm`, isCliReady/showSetupRequiredToast.
- `extension.ts` — fire-and-forget runPreflight on activate; `guard()` on 15 CLI-dependent commands (13 wrap + 2 early-return: removeArchitect, referenceIssueInArchitect); registered unguarded codev.recheckCli.
- `views/status.ts` — persistent "Codev CLI" row + inline recheck button (contextValue codev-cli-{missing,outdated}).
- `package.json` — recheckCli command, status-row inline menu, codevGettingStarted walkthrough (3 steps).
- `walkthroughs/{detect,install,verify}.md`.
- Tests: preflight-core.test.ts + contributes-walkthroughs.test.ts.

Gotcha: worktree had no node_modules; ran pnpm install + built codev-types/codev-core before check-types passed (the `@cluesmith/codev-core/*` module-not-found + cascading implicit-any errors were pre-existing infra, not my diff).

Verified: check-types ✓, lint ✓, test:unit 155 ✓, esbuild ✓.

### Reviewer-driven refinements (pre-push)
- Command guarding refactored twice on reviewer steer: inline `guard()` → declarative `CLI_DEPENDENT` Set → finally **two registrars** `reg` (unguarded) / `regCli` (guarded). Registrar name IS the guard decision; each command id written once (no Set/flag duplication). 15 regCli + 29 reg. Updated architect source-sentinel tests to match.
- `Update via npm`: kept auto-run (button click = the confirmation). Reviewer OK'd.
- `install.md`: added Node.js ≥20 prerequisite note (engines.node >=20.0.0, CI on 20; VS Code's bundled Node doesn't count).

Commits 2b87f216..(install note). check-types/lint/test:unit(155)/esbuild all green. Pushing → porch done → dev-approval gate.

### dev-approval gate (in-gate revisions)
Reviewer ran the Extension Dev Host. Two refinements during the gate: (1) wired `codev.cliReady` context key in preflight + repointed walkthrough Verify step to `onContext:codev.cliReady` (ticks on real outcome, not on recheck attempt); (2) renamed walkthrough title → "Get started with Codev". First two walkthrough steps left as check-on-view (read-and-do). Committed ccb5bb5f. Gate approved by human.

## Review phase
Wrote `codev/reviews/791-vscode-startup-preflight-verif.md`. Updated arch.md (VS Code Extension key-decisions: startup CLI preflight + reg/regCli pattern) and lessons-learned.md (2 UI/UX entries: walkthrough completion semantics; bundled-Node≠system-Node). Next: commit review+arch+lessons, open PR, porch done → 3-way consult (single advisory pass), pr gate.
40 changes: 39 additions & 1 deletion packages/vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,11 @@
"command": "codev.addReviewComment",
"title": "Codev: Add Review Comment"
},
{
"command": "codev.recheckCli",
"title": "Codev: Recheck CLI",
"icon": "$(refresh)"
},
{
"command": "codev.viewDiff",
"title": "Codev: View Diff"
Expand Down Expand Up @@ -303,6 +308,11 @@
}
],
"view/item/context": [
{
"command": "codev.recheckCli",
"when": "view == codev.status && viewItem =~ /^codev-cli-(missing|outdated)$/",
"group": "inline@1"
},
{
"command": "codev.removeArchitect",
"when": "view == codev.workspace && viewItem == workspace-architect-sibling",
Expand Down Expand Up @@ -624,7 +634,35 @@
"description": "Show every open backlog issue. When off (the default), the Backlog view filters to items assigned to the current GitHub user. Toggleable via the Backlog title-bar eye icon."
}
}
}
},
"walkthroughs": [
{
"id": "codevGettingStarted",
"title": "Get started with Codev",
"description": "Install the Codev CLI and connect VS Code to Tower.",
"steps": [
{
"id": "detect",
"title": "Check your setup",
"description": "Codev needs the `codev` command-line tool installed globally, at a version at least as new as this extension. This walkthrough helps you install it and verify it.",
"media": { "markdown": "walkthroughs/detect.md" }
},
{
"id": "install",
"title": "Install the Codev CLI",
"description": "Install or update the CLI globally with npm.",
"media": { "markdown": "walkthroughs/install.md" }
},
{
"id": "verify",
"title": "Verify the installation",
"description": "Confirm the CLI is detected and at a compatible version.",
"media": { "markdown": "walkthroughs/verify.md" },
"completionEvents": ["onContext:codev.cliReady"]
}
]
}
]
},
"scripts": {
"vscode:prepublish": "pnpm --filter @cluesmith/codev-core --filter @cluesmith/codev-types build && pnpm package",
Expand Down
Loading
Loading