feat(workbench): compiler-manifest-driven navigation and route catalog (#105 stage 1) - #211
Conversation
…piled route graph (#105 stage 1) The dev server projects the prepared project's existing CompiledRouteGraph into one browser-safe DTO behind a new read-only route (GET /api/routes/manifest), so the Workbench reads the same compiler pass the build, inspect, and test harness use rather than discovering routes again. A Routes page under Build renders that catalog grouped by MCP server and by project surface, with per-route id, source, provenance, config summary, the compiled CLI argv projection, and the graph's own diagnostics. Page availability is now the union of the artifact catalog and the compiled graph: Hooks, MCP playground, and Playground open from either source, and an absent or refused manifest degrades only the Routes page. All nine existing pages, the single shell, navigation rail, and hash router are unchanged.
…stop repeating descriptions Three catalog rules carried a literal line-number prefix, so the CSS parser dropped them and provenance ran into its source path unstyled. The Routes page also printed each route's description twice — once as the route label and again inside the config summary. Adds the flagship audiobook-curator example to the browser example suite as the seven-kind catalog proof (one generated server, 15 tools, a resource, and a prompt), and asserts computed provenance layout so a dropped stylesheet fails the suite rather than only the screenshot.
… with positionals The routed CLI landed for audiobook-curator, so the compiled catalog now shows 15 CLI routes beside the curator server's 17. The usage line puts positionals first in argv order instead of following the compiler's key ordering, which put a positional between two flags.
🦋 Changeset detectedLatest commit: d5eedc1 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d5eedc1a02
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Closes the stage 1 slice of #105: Workbench navigation and its catalog now derive from the compiled route graph instead of artifact counts alone. This is additive — all nine existing pages, the single shell, the single navigation rail, and the single hash router are unchanged.
How the manifest flows dev-server → UI
ProjectService.prepare()already compiles the route graph once per revision.workbench-server.tscomposes aRouteManifestRouteServicethat projectslatestValidPreparedProject.routeGraphthroughrouteManifestFor(graph, sourceRevision)— no second discovery pass.RouteManifestRoutesserves it from one new read-only route,GET /api/routes/manifest, behind the existing same-session guard. No existing status or artifact DTO was widened, sosourceStatusSchema/artifactEpochSchemaare untouched.RouteManifestClientfetches and strictly decodes the response with its own Zod schema (z.strictObjectthroughout), so an unknown field fails loudly in tests rather than silently in the browser.routeCatalogFor()projects the decoded manifest into aRouteCataloggrouped by MCP server then by project surface, and compares the manifest'ssourceRevisionagainst the published epoch'sprojectRevisionto label the catalogcurrentorstale.loadWorkbenchCapabilities()carries the catalog onWorkbenchCapabilities.routes. Page availability is the union of artifact counts and the compiled graph:hooks,mcp, andplaygroundopen from either source, androutesis always present. A refused or absent manifest yields anunavailablecatalog that degrades only the Routes page.The Routes page shows per-route id, kind, project-relative source, provenance, a flattened static config summary, the compiled CLI argv projection, the graph digest and source revision, MCP server packaging mode, context providers, and the graph's own diagnostics.
Pages preserved — browser proof
packages/workbench/tests/examples-real.e2e.test.tsandoverview.e2e.test.tsat 1440×900 in real Chrome: 18/18 passing.audiobook-curator(new): the flagship catalog — one generatedcuratorserver with 15 tools, 1 resource, 1 prompt, plus 15 conventional CLI routes with their argv projections (library-audit [<sources>…] [--concurrency] --report [--strict]), 32 routes total, no invented event routes, scripts, or providers; then navigates back to Overview and asserts it still renders.hooks-and-scripts: shows the one compiler-discovered script route (script:verify-release) and not the configuredscript:detect-risk, plus a computed-style assertion that the catalog stylesheet reached the document.mcp-app: empty compiled graph renders "This project declares no conventional route modules." while all nine other navigation links stay visible.skills-starterand the capability reveal/repair/remove flow pass unchanged.Plan-doc amendments
Both superpowers docs carry explicit supersession notes stating that the compiled graph is now a navigation input, that the page set is ten pages, and that the "must not create another shell/navigation/router" invariant still holds because the catalog is a page inside the existing shell:
docs/superpowers/specs/2026-08-25-capability-aware-workbench-design.mddocs/superpowers/plans/2026-08-25-capability-aware-workbench.mdVerification
tsc --noEmit(root andpackages/workbench): clean.rslint .: 0 errors, 0 warnings across 840 files.route-manifest-routes.test.ts: 683 tests, 0 failures.rstest.route-unit.config.ts: 0 failures.Known-flaky on
mainas well: the full 20-file workbench integration run reports ~3 failures whose set changes every run (overview.e2e,runtime-playground.e2e,mcp-app-real.e2e) and none reproduce in isolation. Confirmed by running the same suite onorigin/main(also 3 failures, different set), which is the same reload-budget flake #200/#203 tracks.What stage 2 needs
annotations: 2 keys) rather than shipping nested JSON. Stage 2 needs the routeinputSchemaon the wire — add it as a new field onRouteManifestRouteand extendrouteSchemainroute-manifest-client.tsin the same PR.RouteManifestProvenanceis already a discriminated union so a non-conventional provenance is additive rather than a wire break.