Skip to content

fix(routes,mcp,package): movie-library port findings — config augments generated servers, result _meta, conditional outputSchema, no tsc shadowing - #405

Merged
ScriptedAlchemy merged 2 commits into
mainfrom
fix/movie-library-port-findings
Sep 3, 2026
Merged

fix(routes,mcp,package): movie-library port findings — config augments generated servers, result _meta, conditional outputSchema, no tsc shadowing#405
ScriptedAlchemy merged 2 commits into
mainfrom
fix/movie-library-port-findings

Conversation

@ScriptedAlchemy

Copy link
Copy Markdown
Owner

Summary

Framework defects and wire deviations surfaced while re-porting the external movie-library plugin onto route mode on current main.

  • Config validation rejects any mcp.servers declaration for a route-generated server (AB4304/AB4322), though normalize supports env/args/targets/apps on it #380 — config beside a route-generated server. A mcp.servers.<id> block whose <id> the route graph compiles in generated mode now augments that server (env, args, targets, apps, transport: 'stdio') instead of failing AB4304/AB4322. Redeclaring entry/command/url under an explicit routes.servers.<id>: 'generated' is the new precise AB4340 (message + recovery); without an explicit mode the same collision stays AB4800. validateMcp now sees the discovered route graph and applies the same judgment normalization already did. Precedence table in docs/entry-conventions.md; code in docs/diagnostics.md.
  • agent-bundle's typescript-5 alias dependency shadows the consumer's tsc bin under npm (tsc 5.6.1-rc rejects ES2024 tsconfig) #381tsc bin shadowing. The typescript-5 parser alias moves from dependencies to devDependencies (pinned typescript@5.9.3) and is bundled into the package, so npm install agent-bundle never links a tsc bin over the consumer's own TypeScript. The bundled parser's eager getNodeSystem() reads CommonJS __filename/__dirname, so the rslib build prepends an import.meta.url-derived shim to the chunk that references them. New packed-tarball proof packed-consumer-typescript.test.ts installs the tarball beside the consumer's TypeScript and asserts .bin/tsc is the consumer's, no typescript-5 is hoisted, and the packed CLI still statically parses route config.
  • Generated MCP tool routes cannot emit CallToolResult._meta (Agent.Result metadata is decoded but never projected) #383 — result _meta. Agent.Result metadata now projects to CallToolResult._meta (JSON-snapshotted like structuredContent). MCP _meta is an object, so a non-object fails the projection closed with McpProjectionError('invalid-result-metadata'). Listing _meta (static config._meta) is unchanged, so the MCP Apps convention stamps _meta.ui.resourceUri on both halves. The mcp-in-memory harness result exposes _meta.
  • Wire deviation 4a — unconditional outputSchema. Generated tools advertise outputSchema only when resultSchema describes an object (object keywords, or a oneOf/anyOf/allOf of objects — the same judgment the SDK applies before stamping type: "object"). Text-only routes (z.undefined(), z.string(), arrays) advertise none and return no structuredContent, as the spec requires; object schemas keep the SDK's fail-closed output validation.
  • Wire deviation 4b — [tool_error] prefix. Intentional: Agent.Error code message lowers to isError: true plus one text block [<code>] <message> because the wire has no error-code field, and the routed CLI prints the same **[code]** message form. It was undocumented; it is now documented in docs/framework-mode.md ("What reaches the MCP wire") rather than removed.

Closes #380, closes #381, closes #383.

Tests

  • route-graph.test.ts: augmentation accepted end to end through validate + inspect (env/args/targets/config App on the generated server); AB4340 with message/recovery and no AB4304/AB4800; local-entry field rules (AB4308AB4310) still apply to an augmenting block.
  • generated-route-server.test.ts: builds an augmented generated server, checks mcp.json env/args, then over real stdio asserts tools/list _meta + conditional outputSchema, tools/call _meta + structuredContent for the object route and a bare text result for the text-only route, and reads the config-side App resource.
  • mcp-projector.test.ts / mcp-in-memory.test.ts: _meta projection, frozen snapshot, fail-closed on scalar and array metadata.
  • mcp-server-runtime.test.ts (new): advertisedOutputSchema on object/record/discriminated-union vs. undefined/void/string/number/array/mixed-union vs. opaque schema.
  • packed-consumer-typescript.test.ts (new, packed pool): the agent-bundle's typescript-5 alias dependency shadows the consumer's tsc bin under npm (tsc 5.6.1-rc rejects ES2024 tsconfig) #381 proof above.

Verification

pnpm typecheck, pnpm lint, pnpm test:unit, pnpm test:route-unit, pnpm test:projection, pnpm build && pnpm test:integration:run (936 pass; three load-induced timeouts re-run green in isolation), pnpm test:packed (the new tsc proof passes; public-api-packed npm-install timeouts on a load-140 host — npm install of the tarball alone measured 27 s there — are load, CI is the arbiter), pnpm test:mcp-conformance.

Not changed

@changeset-bot

changeset-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 4cb9b5d

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

This PR includes changesets to release 2 packages
Name Type
@agent-bundle/runtime Minor
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

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-03T08:11:45.394756Z 4cb9b5d Manual request
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

…, #383)

- #380: a `mcp.servers.<id>` block for a route-generated server augments it
  (env, args, targets, apps, transport: 'stdio') instead of failing
  AB4304/AB4322; redeclaring entry/command/url under an explicit generated
  mode is the new AB4340.
- #381: bundle the TypeScript parser (devDependency, pinned 5.9.3) so an
  npm install of agent-bundle never links a `tsc` bin over the consumer's
  own TypeScript; packed-tarball proof added. The emitted chunk gets an
  import.meta.url-derived __filename/__dirname shim for the parser's
  eager getNodeSystem().
- #383: `Agent.Result metadata` projects to `CallToolResult._meta`
  (object only; a non-object fails closed with
  McpProjectionError('invalid-result-metadata')).
- Generated tools advertise `outputSchema` only when `resultSchema`
  describes an object, so text-only routes need no `structuredContent`.
- Document the `[<code>] <message>` error text form on the MCP wire.
@ScriptedAlchemy
ScriptedAlchemy force-pushed the fix/movie-library-port-findings branch from cd85b48 to 5828cc9 Compare September 3, 2026 07:16
@pkg-pr-new

pkg-pr-new Bot commented Sep 3, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle@405
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/create-agent-bundle@405
npm i https://pkg.pr.new/ScriptedAlchemy/agent-bundle/@agent-bundle/runtime@405

commit: 4cb9b5d

@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5828cc96bb

ℹ️ 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".

Comment thread packages/agent-bundle/src/config/validate.ts
…r's route-declared Apps

A config App beside a route-generated server now shares the AB4325 name and
AB4330 resourceUri collision checks with the src/mcp/<server>/apps/* routes,
so the same resource URI can no longer reach the generated server twice.
@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

Reviewed commit: 4cb9b5d38f

ℹ️ 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".

@ScriptedAlchemy
ScriptedAlchemy merged commit 56b77db into main Sep 3, 2026
10 checks passed
@ScriptedAlchemy
ScriptedAlchemy deleted the fix/movie-library-port-findings branch September 3, 2026 08:14
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…fter #405

#405 projects Agent.Result metadata to the result _meta; with the route-harness
layouts in place every harness tool now carries the root and server layout
keys beside its own, so the in-memory pin asserts the merged object rather
than the route-only one. The layout-free 'no metadata => no _meta' case stays
pinned by mcp-projector.test.ts and generated-route-server.test.ts.
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
… Pages delivery (#384)

## Summary

Lands the Rspress documentation site (`website/`, private workspace `@agent-bundle/docs`) designed in `docs/superpowers/specs/2026-09-02-agent-bundle-rspress-docsite-design.md` and planned in `docs/superpowers/plans/2026-09-02-agent-bundle-rspress-docsite.md` (both versioned here). Continues the prior `docs/rspress-website` branch (Tasks 1–5, rebased onto main) and completes Tasks 6–7 plus generated reference pages.

- **Site**: Rspress 2.0.21 with `@rspress/plugin-typedoc` (11 public export entry modules, mirrored into `zh/`), `plugin-twoslash` (type hovers on guide samples), `plugin-llms` (`llms.txt`/`llms-full.txt` per locale + per-route Markdown), `plugin-sitemap`; dead-link, dead-anchor, dead-image, and language-parity checks on. Complete English + Simplified Chinese parity for Guide (start/authoring/development/distribution), Reference, Examples, Contributing, and home.
- **Generated reference pages** (new `website/plugins/generated-reference.ts`, run in the `config` hook, gitignored output; the Reference overview links every generated page, so Rspress's dead-link check fails the build if generation is skipped): **Host capability matrix**, **Event and hook matrix**, **Notice delivery matrix** rendered from `packages/agent-bundle/src/adapters/capabilities/*.json`, and **Diagnostics reference** copied from `docs/diagnostics.md`. Source of truth stays in the repo; the docs cannot drift.
- **Content**: documented event routes (`src/events/**`) and the full hook wire (stdin → IPC → warm runtime → projection → stdout, fail-closed semantics), verified against `events/ipc.ts`, `adapters/hook-contract.ts`, `events/projection.ts`; config reference now links every field to its TypeDoc-generated type (the config is a TS contract, not a Zod schema); fixed the hook entry shape (`handler`, not `entry`); family-parity homepage (Introduction / Quick start actions, nine linked feature cards) whose MDX body renders below the feature grid through a `Layout` override on the `afterFeatures` slot (`website/theme/index.tsx`): a write-vs-emit comparison with per-host output trees, a Describe → Develop → Prove → Ship walkthrough, a host table, and start-here links, authored per locale; Examples/Contributing nav entries.
- **CI / delivery**: `.github/workflows/docs.yml` runs `pnpm docs:site:build` (typecheck + build with dead-link/anchor/image and language-parity checks; the standalone `verify-build.mjs` was dropped in favor of the built-in checks) on every PR and push to `main` (no path filter), and deploys `website/doc_build` to GitHub Pages from `main` only (Pages source set to GitHub Actions via API; target `https://scriptedalchemy.github.io/agent-bundle/`). `scripts/classify-docs-only.mjs` now treats `website/**` as docs-only (unit-tested), so website-only PRs skip the heavy `ci.yml` jobs. Root scripts: `docs:site:build`, `docs:site:dev`, `docs:site:preview`. READMEs link to the hosted docs.
- **Accuracy fixes from review and browser acceptance**: host path-token table (Cursor and Codex do not accept `${PLUGIN_DATA}`), `pnpm example:*` prints the Workbench URL (`--open` launches the browser), zh Node-resolution order, zh `技能` → `Skill`, `AB4707`–`AB4709` descriptions, `AGENT_BUNDLE_WORKBENCH_API_PROXY` row, Development/Distribution overview titles no longer repeat their sidebar group, TypeDoc member titles emit unescaped underscores (API sidebar and prev/next labels showed `FOO\_BAR`), and over-wide code samples wrapped.
- **Fix**: Twoslash could not resolve `zod` in package-entry samples on current main; the website package now declares it (`4.5.4`, matching the package).

No package source is changed. The `packages/agent-bundle/README.md` link is a shipped-tarball change, so it carries one `agent-bundle` patch changeset (`.changeset/docs-site-readme-link.md`) per the policy `main` now enforces.

## Since consolidation

- **Final-review corrections** (all verified against source, both locales): `reference/api.mdx` lists all eleven entry points and puts `build`/`validate`/`inspect`/`prepack` under `agent-bundle/api`; the hook `reason` rule follows `nativeHookWrapperSource` (denied `agentStop` requires a reason; `agentStart` cannot deny); `cursor` emits `.cursor-plugin/marketplace.json` when `marketplace: true` and `plugin` emits all three manifests; wrapper names carry a digest of their declaration, not a content hash; the diagnostics index gains `AB48xx`–`AB49xx`; `languageParity` now covers the homepages; `llms-full.txt` is emitted with `mdxToMd` (no raw theme imports/JSX); `docs.yml` lints website-only PRs and deploys on `workflow_dispatch` from `main`; the TypeScript 6 pin the docsite needs for `typedoc@0.28` is recorded in `docs/effect-conventions.md`.
- **Review-thread fixes**: quick start installs only the hosts its configs build; the examples index counts all six examples and links the two advanced references; `dev.contracts` (`fixtures`, `server`, `AB7210`/`AB7211` gating) is in the configuration reference; the security page no longer denies the native eval harnesses; `agent-bundle.manifest.json` sits at the output root in the structure tree; the generated hosts page derives Claude's MCP path-token fields from its plugin path-substitution table; a duplicate changeset was removed.
- **Artifact root**: `agent-bundle build` writes host artifacts to `artifact/` by default (it always runs the package build, which owns `dist/`), so the site now says `artifact/` everywhere it means host artifacts, explains the `artifact/`/`dist/` split in the configuration, CLI, and project-structure pages, and the CLI's `--output` help text no longer claims `default dist`. The Cursor and portable capability tables record the marketplace path and path tokens their adapters emit, so the generated host matrix stops rendering empty cells; the changeset covers both.
- **`AGENTS.md`**: new "Documentation site" section — which user-facing changes must update `website/docs` in both locales, which pages are generated and must not be hand-edited, and `pnpm docs:site:build` as the gate.
- **Merged `main`** (through #405, #395): the lockfile was regenerated on top of `main`'s; the generated diagnostics page now rewrites repo-relative `docs/*.md` links to GitHub URLs, since `docs/diagnostics.md` started linking to `entry-conventions.md`.

## Evidence

- `pnpm docs:site:build` (website typecheck → `rspress build`): green (1424 sitemap pages on the merged head), language parity checked, no warnings.
- `pnpm lint`: 0 errors / 0 warnings (1032 files).
- `pnpm exec rstest --config rstest.unit.config.ts packages/agent-bundle/tests/classify-docs-only.test.ts`: 4/4 pass (new website-only and mixed website+source cases).
- Root `pnpm build`, `pnpm typecheck`, `pnpm test:projection`: pass. `test:unit` (2665/2671) and `test:route-unit` (34/35) each had one timeout while running concurrently with the TypeDoc build; both tests pass in isolation. `test:integration:run` fails only `host-install-proof :: installs through Codex` against the locally installed real Codex CLI (`logo` field in the emitted manifest) — environment-specific and unrelated to this branch, which changes no package source.
- Browser acceptance at 1440×900: crawled all 66 authored routes in both locales plus generated reference and API samples — every page renders with title, sidebar and outline; no raw MDX/JSX, `undefined` leaks, broken images, or non-`pre` overflow; Twoslash hover shows the real `defineConfig` signature; search returns prose and code-block hits; locale switch preserves the route both ways; dark mode clean. Earlier pass (Playwright, `rspress preview`): `/`, `/zh/`, `/reference/hosts`, `/reference/events`, `/guide/authoring/hooks`, `/api/` all render with no loading state and no broken images; nav shows Guide / Reference / Examples / Contributing / Type API + locale switch; LLM "Copy Markdown / Open in chat" actions present; per-route `.md` resolves under `/agent-bundle/`; `llms.txt` links use `https://scriptedalchemy.github.io/agent-bundle/`; `sitemap.xml` uses the same origin + base; Twoslash hover markup present in built HTML.

## Test plan

- [ ] `Docs` workflow green on this PR (`pnpm docs:site:build`)
- [ ] `CI` workflow: website+ci+scripts changes are not docs-only, so the full matrix runs and must be green
- [ ] After merge: `Docs` deploy job publishes to https://scriptedalchemy.github.io/agent-bundle/ (Pages source already set to GitHub Actions)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment