Skip to content

feat(workbench): application explorer — shell, Application tree, route workspace, one invocation API, page cuts (#600 PR 1) - #629

Merged
ScriptedAlchemy merged 68 commits into
mainfrom
wb600-pr1-shell
Sep 5, 2026
Merged

feat(workbench): application explorer — shell, Application tree, route workspace, one invocation API, page cuts (#600 PR 1)#629
ScriptedAlchemy merged 68 commits into
mainfrom
wb600-pr1-shell

Conversation

@ScriptedAlchemy

@ScriptedAlchemy ScriptedAlchemy commented Sep 5, 2026

Copy link
Copy Markdown
Owner

PR 1 of 3 for #600: the Workbench becomes an application explorer. New shell and navigation, the Application tree from the compiled route catalog, a route workspace that renders every route as an Agent Document by default through one invocation abstraction, URL-addressable views, and every cut the issue's audit lists. PR 2 (unified live trace) and PR 3 (embedded host sessions) follow.

Navigation and IA

Primary rail: Application · Trace · Problems · Advanced (Sessions arrives in PR 3). Header: project name · build state and epoch · failure badge (links to Problems) · foreground connection.

/                                   Application tree (MCP → <server> → Tools/Resources/Prompts/Apps;
                                    Events / Hooks; CLI; Scripts; Skills; Rules / Commands)
/routes/mcp/<server>/tool/<name>    Route workspace: input editor · Run · Rendered (default) |
/routes/mcp/<server>/{resource,prompt,app}/<name>   Structured result | Raw AgentDocument |
/routes/events/<event…>             MCP / CLI / host projection | Trace · Inspector
/routes/cli/<path…>
/routes/scripts/<name…>
/routes/skills/<id…>                Skill leaf renders the emitted Skill document
/routes/commands|rules/<id…>
/routes/…?invocation=<id>           deep link to one invocation
/trace, /trace/<id>                 this session's route invocations (PR 2 widens this)
/problems                           contract-gate + build diagnostics with Repair
/advanced/{evals,artifact,protocol,hosts,logs}

The foreground server answers these paths with the shell (dev/workbench-shell-paths.ts is shared by server and client), so every view is a real URL with history.

One invocation abstraction

POST /api/routes/invocations renders any compiled route — MCP tool/resource/prompt, CLI route, script, event route (canonical or Claude/Codex/Cursor payload) — through the production RSC runtime in a forked child (route-invocation-child.ts, the same seam as agent-bundle/test's renderRouteEvents) and returns the render-event stream, final Agent Document, structured result, request context, providers, timings, and MCP/CLI/host projections. GET /api/routes/invocations[/<id>] lists and replays; every completion is a route.invocation project event. Plain main() scripts run through the existing ScriptPlaygroundService and surface stdout as a text document. Diagnostics: AB8231, AB8232, AB8236AB8238.

The Workbench talks to it through InvocationBackend with two implementations: createDevServerBackend (every project) and createRuntimeBackend (projects that declare devRuntime; run history, HMR-aware). The former Runtime Playground's Flight→AgentDocument renderer is extracted to application/rendered-document.tsx and is the default result view; the MCP App preview and session controller under mcp/** are reused via import (adapted to the #601 bridge / createAppClient), not forked.

Public surface (agent-bundle, changeset minor)

  • New: /api/routes/invocations routes and route.invocation event; shell deep-link paths.
  • Breaking for agent-bundle/test: inspectWorkbenchSurface() returns application (the ApplicationTree, with workbenchLeafPath(leaf)) and advanced instead of pages; WorkbenchPageName / workbenchPageLabel removed.
  • packages/workbench is private and not named in the changeset.

Deletion ledger

Workbench pages and their models/CSS/tests, deleted — replaced by the Application tree and route workspace:

Deleted Replaced by
overview-page.tsx, overview-model.ts, workbench-screen.tsx, skills-page.tsx shell header + Application tree; Skill leaf
routes/routes-page.tsx + css Application tree (routes-model.ts kept for input drafts/validation)
hooks/hooks-page.tsx, hooks-model.ts + css event-route leaves (event-route-workspace.tsx)
lifecycles/lifecycles-page.tsx, lifecycles-model.ts + css event-route leaf Replay tab
playground/playground-{page,model,client}.ts(x) + css route workspace; /api/playground/* server routes stay (used by agent-bundle tests and scripts)
runtime-playground.tsx, runtime-stage.tsx, runtime-inspector.tsx, runtime-evidence.tsx, runtime/agent-document-stage.tsx, runtime/agent-document-atoms.ts rendered-document.tsx + runtime-backend.ts (engine kept as runtime-controller.ts)
mcp/runtime-consent-dialog.tsx, runtime-consent-queue.ts, runtime-mcp-handoff.ts #601 bridge consent path
comparisons/** Evals Compare tab (evals/evals-compare*.ts(x))
Discovery page → /advanced/hosts cut to Host diagnostics (installed / version / path / plugin attach / errors / one MCP handshake); Artifact → path+size tree with hash/mode/provenance behind Details
25 workbench unit/browser/e2e test files for the above; the nightly evidence pool (rstest.evidence.config.ts, its CI job and script) whose only journey was the Runtime Playground capture; two skipped "legacy Runtime Playground" e2e cases

Net: 231 files, +13,970 / −20,395.

Not preserved, and why

  • Runtime Playground promotion/export/pinned-trace controls: provider-run controls with no destination in the new IA; the runtime backend keeps run history and HMR.
  • Overview "latest changed files" and separate source-vs-generated Skill trees: one Skill leaf owns both document tabs.
  • Direct Runtime deep links (#runtime-*): unknown paths resolve to /.
  • Mobile/responsive CSS in the cut pages (desktop-only per AGENTS.md).

Docs

website/docs/en/** and website/docs/zh/** rewritten for the new IA (workbench guide, testing, evaluations, quick start, authoring pages, the four example walkthroughs, references); docs/diagnostics.md registers the new codes. pnpm docs:site:build green (0 broken links, parity ok).

Browser acceptance

Real Chrome at 1440×900 against examples/audiobook-curator (audiobook-curator.acceptance.e2e.test.ts) plus skills-starter, mcp-app, hooks-and-scripts (examples-real.e2e.test.ts): populated Application tree, tool run with rendered document, Trace, Problems in the stale-diagnostic state and after Repair, Advanced sections. No capture while a loading/building state is visible. Acceptance surfaced and fixed two dev-server bugs: .js → .tsx specifier resolution and the react-server/JSX-runtime mismatch in the invocation child; plain scripts routed to the Agent renderer.

Gate

pnpm build && pnpm typecheck && pnpm lint && pnpm test:unit (4053 tests), pnpm test:integration:run (1128 passed, 4 skipped pre-existing), pnpm docs:site:build, all on the branch merged with origin/main at 8b0a6b9c0.

Deslop

Deslop: gpt-5.6-sol-medium + cursor-grok-4.6-high-fast, 47 edits (15 on the integrated lanes: duplicated App host context consolidated into workbenchMcpAppHostContext, as unknown as event narrowing removed, lane narration comments dropped, responsive CSS removed, pre-integration workbench-surface test shim deleted in favour of the public test surface; 21 on the e2e remediation: two dead skipped suites −1,231 lines, orphaned imports, restating comments; 11 on the self-review fixes: isProcessGone reused from tests/support/bin-process.ts, ! pid assertions → early throws, restating comments). Integrator follow-up: three modules with no production importer deleted (hooks-model, lifecycles-model, agent-document-atoms).

Self-review

Reviewer: gpt-5.6-sol-medium (change-risk-reviewer), two rounds against origin/main.

Round 1:

  1. Critical — route-invocation-child was not an Rslib entry, so the packed agent-bundle dev could not fork the renderer. Fixed: private entry beside lifecycle-render-child in rslib.config.ts; dev-workbench-packaging.test.ts now installs the tarballs into a clean consumer, starts the dev server from the installed package, and renders a tool route.
  2. High — prepared project promoted before lint/build succeeded, so a failed rebuild could expose unbuilt routes while plain scripts ran the old artifact. Fixed: manifest and invocations are pinned to the last published epoch (dev/coordinator.ts publish callback, workbench-server.ts); the current source revision still drives state: 'stale'. Test in route-invocation-dev-server.test.ts.
  3. High — render child leaked processes (exit listener removed without terminating; SIGKILL only to the immediate child). Fixed: child forked detached in its own process group, terminateProcessTree + waitForProcessTreeExit (existing services/process-tree.ts) after every reply/error/abort/close in a finally. Tests: fixture route keeps an interval and forks a descendant; both pids gone after success, timeout, and close().

Round 2 (after fixes; 1 and 3 confirmed closed, plus the config declaration chain confirmed peer-free in dist/):
4. Warning — stale invocations executed unpublished source (the child imports route modules from source while the pinned manifest is displayed). Fixed: while source is newer than the published epoch, or no epoch is published, every invocation kind answers 409 AB8232 ("rebuild to run"); the route workspace renders that diagnostic with an Open in Problems link instead of a route crash. The coordinator rebuilds on every change, so the gate only bites while a build is failing or in flight.
5. Warning — the initial failed build was treated as published (latestPublishedPreparedProject seeded from the pre-build snapshot at startup). Fixed: seeded only from a recovered active epoch whose revision matches; otherwise unavailable until the first publish. Tests: initial failure → 409 → fix → publishes; restart with recovered epoch + failing source stays on the recovered epoch.

CI (Release gates / packed pool) also caught: the config entry's .d.ts graph reached @agent-bundle/runtime through dev/types.ts → route-invocation.ts — split the peer-typed result types into dev/routes/route-invocation-result.ts; and two packed tests still waiting for the deleted "Bundle dashboard" heading — repointed to the new shell. pnpm test:packed: 35 passed, 1 skipped (pre-existing). Requiring a published build also surfaced that three dev-server test fixtures imported @agent-bundle/runtime/React/Zod without declaring them (AB7100 provenance) — fixtures now declare their dependencies; no product change.

Flake noted, not caused here: cli.test.ts :: answers --version… failed once under full-pool load (Node stderr noise before the JSON diagnostic), passes alone and in every other run.

…envelope, URL model, tree/backend/workspace types)
PR 1 deletes hash pages; point the browser pool at pathnames, the compiled
Application tree, and a testid contract so acceptance is ready when the shell lands.
# Conflicts:
#	packages/workbench/tests/examples-real.e2e.test.ts
# Conflicts:
#	website/docs/en/examples/mcp-app.mdx
#	website/docs/en/examples/skills-starter.mdx
#	website/docs/en/guide/development/workbench.mdx
#	website/docs/en/guide/start/quick-start.mdx
#	website/docs/en/reference/runtime-environment.mdx
…Artifact

Overview, Routes, Hooks, Lifecycles, and Playground pages go away; Comparisons folds into the Evals Compare tab. Host diagnostics and Artifact keep only the facts the Advanced section still shows.
…pr1-shell

# Conflicts:
#	packages/workbench/tests/artifacts-page.test.ts
#	packages/workbench/tests/hooks-page.test.ts
#	rstest.integration-tests.ts
Translate the 19 English pages from the docs-en lane into existing Simplified Chinese voice so locale parity can pass once integration registers AB8231–AB8235.
… (PR 1 minimal), Advanced, thin main.tsx

- shell/workbench-router.ts: History-API router over WorkbenchLocation (popstate, replace-on-same)
- shell/workbench-shell.tsx + shell.css: rail Application · Trace · Problems · Advanced, header
  project · build/epoch · failure badge → /problems · connection; ApplicationArea (320px tree column)
- shell/build-status-model.ts + shell-status.tsx absorb overview-model.ts (deleted); Problems model
- problems/problems-page.tsx: aggregated diagnostics with route deep links and the Repair (rebuild) flow
- trace/trace-page.tsx: this session's invocations from backend history/subscribe, /trace/<id>
- advanced/advanced-page.tsx: Evals[Runs|Compare] · Artifact · Protocol · Host diagnostics · Raw logs
- main.tsx rewritten thin: no hash routing, pages, or screens; backends + tree + router + shell
- workbench-capabilities.ts: pages/pagesFor/WorkbenchPage removed; routes manifest + features
- workbench-screen.tsx (dead) deleted; tests added/moved
Move foldAgentDocumentEvents and the node renderers out of
runtime/agent-document-stage.tsx into application/rendered-document.tsx
(RenderedAgentDocument({ events, emptyLabel? })), delete the stage and move
its tests. Extend workspace-contracts.ts with event codec result tabs, the
timings inspector tab, RouteInputFixture, RouteInvocationDraft and
RouteInvocationController.
RouteWorkspace dispatches on leaf.execution to the executable, event, app,
skill, or document workspace. Executable routes get the schema-driven input
editor (form / raw JSON / CLI args / fixtures / last input), Run with
Ctrl/Cmd+Enter, a status line, diagnostics linked to /problems, result tabs
(Rendered default, Structured, Raw AgentDocument, MCP and CLI projections,
Trace) and a closed-by-default inspector drawer. Event routes add the host
selector and codec tabs; app routes embed the MCP App preview beside the
bound tool editor.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@changeset-bot

changeset-bot Bot commented Sep 5, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 81d84b0

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
agent-bundle Minor

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

@pkg-pr-new

pkg-pr-new Bot commented Sep 5, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle@629
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/create-agent-bundle@629
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/rsc-markdown-stream@629
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/@agent-bundle/runtime@629

commit: 81d84b0

…ess tree

Finding 1: `dist/route-invocation-child.js` was never emitted, so the packed
`agent-bundle dev` failed every rendered invocation with "Unable to locate
the route invocation render child." Declare it as a private Rslib entry
beside `lifecycle-render-child`; the packed test proves the file is in the
tarball and renders a tool route from an installed consumer.

Finding 3: `renderInChild` dropped the child after its IPC reply, so route
or provider code that kept an event-loop handle leaked one process per
invocation, and abort only SIGKILLed the immediate child. The child is now
forked into its own process group and, after every reply, error, timeout,
or close, terminated through `services/process-tree.ts` (SIGTERM, SIGKILL
after a grace period) and awaited before the invocation settles, so
`RouteInvocationService.close()` drains the children with the pending
invocations. Unit tests render a fixture route that sets an interval and
forks a descendant and prove both pids are gone after success, timeout, and
close.
Drop restated comments, reuse isProcessGone, and narrow recorded pids without non-null assertions.
@ScriptedAlchemy
ScriptedAlchemy enabled auto-merge (squash) September 5, 2026 14:41
@ScriptedAlchemy
ScriptedAlchemy merged commit c9cc793 into main Sep 5, 2026
16 checks passed
ScriptedAlchemy added a commit that referenced this pull request Sep 5, 2026
@ScriptedAlchemy
ScriptedAlchemy deleted the wb600-pr1-shell branch September 6, 2026 08:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant