docs(mcp): serveApp is a host-process API; a routed CLI command spawns agent-bundle serve-app (#558) - #560
Conversation
…s agent-bundle serve-app (#558) The #537 docs showed a plugin route doing await import('agent-bundle/api'). That does not build: routed CLI bins are self-contained, so the bundler inlines the compiler and fails on its runtime-relative module references, and the external or non-literal escapes are AB6005. State the real audience of serveApp (CLI, Workbench, tests, a plugin's own scripts), name the constraint, and show the child-process spawn pattern cargo-hauler shipped, with #558 linked.
|
| Name | Type |
|---|---|
| agent-bundle | Patch |
Click here to learn what changesets are, and how to add one.
Click here if you're a maintainer who wants to add a 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. |
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 06317fbf3d
ℹ️ 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".
…hboard sample A child stdout write can arrive split across data events; buffer to newlines before matching, as cargo-hauler's route does. Addresses the Codex P2 thread on #560.
Tracks #558.
What
Corrects the
serveAppdocumentation from #537, which showed a plugin's routed CLI route doingconst { serveApp } = await import('agent-bundle/api'). That shape does not build inside a plugin (constraints and options laid out in #558):agent-bundle/dist/api.js— the whole compiler — into the bin and fails on the framework's runtime-relative module references:Module not found: Can't resolve '../events'fromdist/8674.js.validate-artifact-modules.ts: an external bare import isAB6005 … uses unsupported specifier "agent-bundle/api", a non-literalimport(spec)isAB6005 … has a non-literal dynamic import.Proven by the first consumer: ScriptedAlchemy/cargo-hauler#83 (merged as 395cee062,
agent-bundlepinned at c2ffe5e; nothing invalidate-artifact-modules.ts,cli-bins.ts,rslib.ts,serve-app/**, orapi.tshas changed onmainsince) shippedhauler dashboardas a plain routed command that spawnsagent-bundle serve-app hauler/dashboard --tool hauler_status --allow call-tool …as a child process, and had to document it as a checkout-only command.Docs changes (en + zh)
guide/authoring/mcp.mdx, "Serving an App standalone":serveAppis a host-process API (the first-party CLI, the Workbench, tests, a plugin's ownpackage.jsonscripts or a hand-written.mjsrun from the checkout); a routed CLI command inside the artifact cannot import it today, with the exact failure modes above; the sample is replaced by the pattern that builds — framework CLI resolved by path from thebinofnode_modules/agent-bundle,serve-appargv, the child's stdout relayed to stderr withurlparsed from theMCP App <app> at <url>line, routesignal→ childSIGTERM, exit code relayed throughconfig.exitCode: 'result'— stated as a checkout-only command, with Let a plugin CLI route serve its own MCP App without bundling the framework #558 linked.reference/api.mdx(agent-bundle/apirow) andreference/cli.mdx(serve-app): one-clause corrections pointing at the guide section.docs/entry-conventions.md(agent-bundle serve-app) anddocs/framework-mode.md: the same correction in the internal docs.packages/agent-bundle/src/api.ts: theserveAppJSDoc — the source of the generated Type API page/api/functions/api.serveApp— no longer says a routed CLI route can call it. Comment-only, no behavior change, henceskip-changeset..changeset/514-serve-app.md(the pending feat(cli): serve a built MCP App standalone — agent-bundle serve-app and serveApp in agent-bundle/api (#514) #537 release note): its last clause promised the same route shape; now says the CLI route spawnsagent-bundle serve-app(Let a plugin CLI route serve its own MCP App without bundling the framework #558). Pending changeset text, notCHANGELOG.md.Verification
pnpm docs:site:build✓ — typecheck, TypeDoc, Rspress build, dead-link/anchor/image checks, language parity.examples/host-test/src/cli/dashboard.ts(not committed; the example already has routed CLI routes and@agent-bundle/runtime):tsc✓;agent-bundle build✓ forclaude/codex/cursor/portablewith artifact validation passing (noAB6005), and the emitted bins carry no residualagent-bundleimport.node dist/bin/host-test.js dashboard --helplists the command;node dist/bin/host-test.js dashboard --no-open --jsonresolved the framework CLI fromnode_modules/agent-bundle, spawnedserve-app, relayed the child's — expected,host-testhas nohaulerserver —AB5000diagnostic on stderr, and returned{"exitCode":1,"message":"agent-bundle serve-app exited with 1","url":null}with process exit code 1 throughconfig.exitCode: 'result'. Success path: the sample's spawn/parse code, verbatim except for the App and tool names, was run from a/tmpscript againstexamples/mcp-app's built artifact (serve-app status/status --tool show-status): the URL was parsed from theMCP App status/status at http://127.0.0.1:37915/ (…)line,GETon it returned 200 with<title>status/status</title>, and aborting the signal sentSIGTERMto the child, which exited 0 with the port released. The same argv shape is what cargo-hauler#83 verified live on641e230.pnpm typecheck✓ ·pnpm lint✓ ·pnpm test:unit3364/3372 with two load-induced 5 s timeouts (inspect-state.test.ts,rendered-skills.test.ts) that pass in isolation (19/19); the only package-source change is a JSDoc comment.Review threads (Codex, reviewed
06317fb)No PR comments are posted from this side; each thread is answered here.
website/docs/en/guide/authoring/mcp.mdx:746— accumulate stdout before parsing the served URL. Accepted.d6c4971buffers the child's stdout to whole lines before matching (a write can arrive split acrossdataevents), in the en and zh samples alike; the success-path run above exercises the buffered parse.Self-review
No reviewer subagent was spawned (the task ran with subagents disallowed); author self-review against
origin/main, findings and dispositions:--target portablewhere feat(cli): serve a built MCP App standalone — agent-bundle serve-app and serveApp in agent-bundle/api (#514) #537's sample passedcursor→ deliberate:portableisserve-app's default and the one target every build produces; cargo-hauler exposes the choice as--target, which the sample omits for brevity.import.meta.url(dist/bin/<plugin>.js→ two levels up), which is right for the package bin but not for the artifact-hostedbin/<plugin>.mjs, whose parent is the artifact target root → covered by the guard: the artifact-hosted copy finds noartifact/agent-bundle.manifest.jsonthere and returns the checkout-only message instead of spawning; the prose states the command is checkout-only.reference/cli.mdxstill documentsserve-appin full; only the "programmatic form" sentence changed, so no CLI behavior is described differently.serveAppJSDoc now namesAB6005and Let a plugin CLI route serve its own MCP App without bundling the framework #558; the TypeDoc build passed and the rendered page carries the text.No PR comments are posted from this side; notes live here.