Skip to content

Commit d8d8e32

Browse files
Merge branch 'main' into test/576-rstest-config
2 parents 7a06344 + 97a5bfa commit d8d8e32

44 files changed

Lines changed: 2436 additions & 111 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"agent-bundle": patch
3+
---
4+
5+
Fix the MCP App view compiler path. `@rsbuild/plugin-react` is registered on every App view, so a `.ts` entry importing `.tsx` components compiles JSX with the automatic runtime instead of leaving a free `React.createElement` in the view, and the reserved `agent-bundle/meta` specifier is rewritten to the generated identity module before resolution, so a `tsconfig.json` `paths` entry can no longer shadow it (other `paths` entries keep resolving inside views). Compile failures now report one `AB4770` per Rspack error carrying the project-relative file, `line:column`, and the bundler's message (warnings not on the documented ignore list are `AB4771`) in place of the `AB5000` catch-all and the Workbench's `AB7100 "Unable to compile the build: Rspack build failed."`; the Overview Diagnostics table shows the same rows with the failing file as their source, and the last good epoch stays active. `agent-bundle build` prints one `MCP App <name> (<target>): mcp-apps/<name>.html <size> (<gzip> gzip)` line per view after `Built …` and carries the measured sizes in `--json` as `build.compiledMcpApps[].size`; `AB4772` warns when a production view reaches 1 MiB or any view exceeds the 2 MiB bound the Workbench and `serve-app` hosts accept, naming the largest modules — the author's own concatenated ESM modules included. `agent-bundle/api` exports the stats formatters `rspackStatsErrors`, `describeRspackStatsError`, and `formatRspackStatsError` so tools driving their own Rsbuild compile render errors the same way. Template-less Apps ship `<html lang="en">`, a `<title>` equal to the App name, and the `#root` mount point (a template that sets its own is left alone). `agent-bundle dev` compiles views unminified — still one self-contained HTML per App, falling back to the production profile when the readable document would not render in the hosts — and `AB7100`–`AB7102` are documented. Resolves the MCP Apps compiler-path and dev-loop findings of #572. (#585)

‎docs/diagnostics.md‎

Lines changed: 101 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,15 @@ even when no error diagnostic was reported.
2828
| `AB474x`/`AB4750` | Prebuilt payloads and prebuilt entries (see below). |
2929
| `AB4760` | The published `agent-bundle/meta` identity module evaluated outside every compiled surface and outside the Rstest presets (see below). |
3030
| `AB4765`–`AB4766` | Artifact-hosted routed CLI: a target without the `cli` capability omits `bin/<name>.mjs`; a host-emitted file collides with it (see below). |
31+
| `AB477x` | MCP App view compilation (`AB4770`: compile error with file, line, column and the bundler message; `AB4771`: compile warning; `AB4772`: emitted-size advisory; see below). |
3132
| `AB490x`/`AB492x` | Conventional host components (#100 stage 2): rules `src/rules/*.mdc` (`AB4900`–`AB4908`) and commands `src/commands/*.md` (`AB4920`–`AB4928`), including per-host feature-set enforcement (`AB4907`/`AB4908`, `AB4927`/`AB4928`); see below. |
3233
| `AB48xx`/`AB494x` | Route graph, state, layout (`AB4830`–`AB4832`), generated route declarations outside the TypeScript program (`AB4834`), route render budgets (`AB4835`), tool task support (`AB4836`), a route module that value-imports a compiler-carrying framework entry (`AB4837`), and provider conventions (see below). |
3334
| `AB5000` | General CLI and adapter failures. |
3435
| `AB60xx` | Built-artifact validation, including schema documents and referenced files (`AB6011`/`AB6012`: a target's required pinned-schema document is missing or invalid; `AB6025`: a manifest-declared `logo` path is missing from the artifact or escapes the deploy tree; `AB6034`: emitted Skill Markdown has no instruction body; `AB6035`–`AB6038`: Agent Plugins portable validation, see below). |
3536
| `AB700x` | Host installation and uninstallation: bundle identity, host availability, scope, command failure, and collision checks (`AB7005`: version collision, pre-receipt content collision, or foreign install; `AB7006`: the host lists the installed copy with load errors; see below), plus the `uninstall` refusals `AB7007`–`AB7009` (ownership or content mismatch, unconfirmed data purge, missing receipt; see below). |
3637
| `AB7010`–`AB7015` | npm prepack inventory, artifact freshness, package bin targets, release-version agreement, and installed-dependency hygiene (`AB7014`: a dependency no packed file references; `AB7015`: a git, remote-tarball, path, or unrewritten workspace-protocol dependency specifier). |
3738
| `AB7200`–`AB7202`, `AB7210`–`AB7211` | Development rebuilds and live host surfaces: rebuild admission and phase failures, development host install sync, and the dev-epoch contract gate (see below). |
38-
| `AB7xxx` | Project preparation and development rebuilds. |
39+
| `AB7xxx` | Project preparation and development rebuilds (`AB7100`–`AB7102`: a development rebuild's compilation, publication, and cleanup; `AB7103`: the development package build; see below). |
3940
| `AB7300`–`AB7331` | Read-only install Doctor: host probes, installed inventory, bundle comparison and registration proof, runtime endpoint health and identity, durable-state inventory, static bytes-at-rest validation, foreign-install detection (`AB7321`; see below), Cursor plugin hook registration / marketplace staging (`AB7322`–`AB7324`; see below), host load refusal (`AB7325`; see below), the Cursor Agent Plugins launch proof (`AB7326`; see below), a disabled Claude install (`AB7327`; see below), lifecycle receipts and activation states (`AB7328`–`AB7330`; see below), and the operator `.env` layer of an installed pack (`AB7331`; see below). `AB7311` and `AB7325` are also emitted by `build` and `validate --artifact` from the Claude load check (see "Claude Code host validation"). |
4041
| `AB8200`–`AB8209` | Workbench development runtime routes (`/api/runtime/**`): `AB8200` development runtime provider configuration, load, or lifecycle failure, `AB8201` runtime/session/run not available, `AB8202` invalid route path, `AB8203` invalid request shape, `AB8204` stale runtime generation or MCP session revision (409), `AB8205` runtime request could not be completed, `AB8206` Workbench runtime client failure, `AB8207` Agent Document decoding needs the optional `@agent-bundle/runtime` peer (503), `AB8208` stored Flight could not be decoded as an Agent Document (409), `AB8209` decoded Agent Document over the 16 MiB budget (413) or an invalid document response. |
4142
| `AB8210`–`AB8214` | Workbench semantic lifecycle replay routes (`/api/lifecycles`, `/api/lifecycles/replays`): `AB8210` invalid path, `AB8211` malformed replay request or native envelope (400, carries the shared validator message), `AB8212` replay unavailable or could not be completed, `AB8213` stale manifest binding (409; the page repairs it with refresh → explicit re-run), `AB8214` replay over the 16 MiB budget (413). |
@@ -261,6 +262,84 @@ its module does not export) are invisible to `tsc --noEmit`, so a green
261262
`tsc --declaration --emitDeclarationOnly` over the lib entry source
262263
directory.
263264

265+
## MCP App view compilation (`AB4770`–`AB4772`)
266+
267+
MCP App views compile through Rsbuild with its logging silenced
268+
(`logLevel: 'silent'`), so the bundler never prints on its own. The framework
269+
reads the Rspack stats of every App environment instead and reports **one
270+
`AB4770` error per Rspack error**, each carrying the failing module as a
271+
project-relative path (forward slashes; absolute when the module lives outside
272+
the project root), the `line:column` the bundler reported, and the bundler's
273+
message — ANSI colours, the miette frame glyphs, and code-frame lines
274+
stripped, the remaining lines joined into one — plus a `sourcePath` naming the
275+
failing module:
276+
277+
```text
278+
[AB4770] MCP App "status" failed to compile: views/status.ts:1:10: Module build failed
279+
(from builtin:swc-loader): Syntax Error: Expression expected
280+
[AB4770] MCP App "status" failed to compile: views/status.ts:1:1: Module not found:
281+
Can't resolve './missing-module' in '…/views'
282+
[AB4770] MCP App "status" failed to compile: Tsconfig not found …/does-not-exist.json
283+
```
284+
285+
The third line is the shape without a location: Rspack attributes a
286+
`tsconfig.json` whose `extends` target is missing to no module, so the message
287+
carries only the bundler text and `sourcePath` falls back to the App's entry
288+
source. A compile that fails without a single stats error still reports one
289+
`AB4770` with the bundler's own message. More than 20 errors on one App are
290+
cut at 20, and the last diagnostic ends with `… and N more errors (run the
291+
compile with logLevel error via tools.rsbuild for the full list)`. App compile
292+
failures never fall through to the `AB5000` catch-all, and `agent-bundle dev`
293+
shows the same `AB4770` rows in the Workbench Overview's Diagnostics table —
294+
the Source column is the failing file — instead of
295+
`AB7100 "Unable to compile the build: Rspack build failed."`.
296+
297+
Rspack warnings that are not on the framework's ignore list report as
298+
`AB4771` **warnings** of the same shape, with `produced a warning while
299+
compiling` in place of `failed to compile`. They never fail the build and are
300+
returned beside the compiled Apps (`build.diagnostics` in
301+
`agent-bundle build --json`). The ignore list is the documented constant in
302+
`packages/agent-bundle/src/build/mcp-app-diagnostics.ts` — one comment per
303+
entry citing the warning text it drops and why it is noise; it may be empty.
304+
305+
Every App is measured after it is emitted: the UTF-8 bytes of the
306+
self-contained HTML and their gzip size, what a compressing transport would
307+
carry. `AB4772` is the size advisory, one **warning** per App. Any view that
308+
imports `@modelcontextprotocol/ext-apps` starts at about 437 kB (104 kB gzip)
309+
— `zod` v3 and v4, `@modelcontextprotocol/sdk`, `zod-to-json-schema`, and
310+
`ext-apps` itself — so the advisory bound of 1 MiB (1,048,576 bytes) sits at
311+
roughly 2.4× that floor and at half the 2 MiB (2,097,152 bytes) bound above
312+
which the Workbench and `serve-app` hosts refuse the resource and the Rstest
313+
browser harness refuses to mount it. The advisory fires when a production
314+
build emits 1 MiB or more, and in either compile mode when the document
315+
exceeds 2 MiB (the view will not render in those hosts). The message names
316+
the raw and gzip sizes, the bound that was crossed, and the five largest
317+
modules from the stats (project-relative, or `node_modules/<package>/…`), with
318+
sizes 1024-based to one decimal, a trailing `.0` dropped (`427.1 KiB`,
319+
`1.3 MiB`, `2 MiB`). Both thresholds are fixed; no configuration key moves
320+
them.
321+
322+
`agent-bundle dev` compiles views unminified so the Workbench preview is
323+
readable — about 2.7× the production bytes. A view whose readable document
324+
would exceed the 2 MiB host bound is recompiled with the production profile
325+
so the preview still renders it, and one `AB4772` reports the substitution
326+
instead: `MCP App "<name>" readable development output compiled to <size>,
327+
above the 2 MiB bound the Workbench and serve-app hosts accept; the preview
328+
renders the production build (<size>, <gzip> gzip) instead; largest modules:
329+
…`. The production sizes in that notice stand in for the 1 MiB advisory, so
330+
a substituted view never carries two size advisories. When the production
331+
build itself exceeds 2 MiB the substitution buys nothing: the notice is not
332+
emitted, the preview receives that production document, and the ordinary
333+
over-bound `AB4772` names its sizes so the author knows the view does not
334+
render. The 1 MiB advisory is a production concern and never fires on
335+
readable output.
336+
337+
| Code | Severity | Trigger | Recovery |
338+
| --- | --- | --- | --- |
339+
| `AB4770` | error (build) | One Rspack error while compiling an App view — a syntax error, an unresolved import, a `tsconfig.json` whose `extends` target is missing, or any other module failure. `MCP App "<name>" failed to compile: <file>:<line>:<column>: <message>`, without the location prefix when Rspack attributes the error to no module; `sourcePath` is the failing module, else the App's entry. | Fix the reported error in the named file and rebuild; run `agent-bundle build` for the full message. |
340+
| `AB4771` | warning | One Rspack warning while compiling an App view that the framework's ignore list does not cover; `MCP App "<name>" produced a warning while compiling: <file>:<line>:<column>: <message>`. | Address the warning in the named file; a warning that is bundler noise inside the framework's own dependency graph belongs on the documented ignore list. |
341+
| `AB4772` | warning | The emitted App HTML is 1 MiB or larger in a production build, or larger than 2 MiB in any build; `MCP App "<name>" compiled to <size> (<gzip> gzip), above the … bound; largest modules: …`. In `agent-bundle dev`, a view whose readable output would exceed 2 MiB was recompiled with the production profile for the preview and that production build fits: `MCP App "<name>" readable development output compiled to <size>, above the 2 MiB bound …; the preview renders the production build (…) instead; largest modules: …` — the only size advisory that view receives; a production build that is itself over 2 MiB gets the ordinary over-bound message instead. | Trim the largest modules the message names — usually a dependency imported whole; a view over 2 MiB does not render in the Workbench or `serve-app` and must shrink before it ships. The development substitution costs only the readable source in the preview. |
342+
264343
## Release identity (`AB4001`, `AB4008`–`AB4011`, `AB4013`)
265344

266345
`package.json` is authoritative for release identity (issue #94): its `name`
@@ -586,8 +665,8 @@ object, a mutator function, or an array of both).
586665

587666
`AB4724` checks `tools.rsbuild.plugins` against the Rsbuild plugins the
588667
framework registers itself — currently `@rsbuild/plugin-react`
589-
(`rsbuild:react`), which every synthesized Rslib entry and every React-syntax
590-
MCP App view carries. The hatch merges *beside* the framework profile
668+
(`rsbuild:react`), which every synthesized Rslib entry and every MCP App
669+
view carries, whatever the view's entry extension. The hatch merges *beside* the framework profile
591670
(`mergeRslibConfig` / `mergeRsbuildConfig` concatenate `plugins` arrays), and
592671
Rsbuild's plugin manager appends every plugin it is handed without deduping by
593672
name, so re-adding `pluginReact()` would register it twice. The check is
@@ -1171,6 +1250,25 @@ host-facing build together with the failed checks.
11711250
| `AB8024` | error (MCP) | The epoch a live host connection was serving vanished from the epoch store mid-session. The connection is invalidated and the typed MCP error carries `{ code, epochId }`. | Reconnect from the host; the proxy binds to the currently adopted epoch. |
11721251
| `AB8025` | error (MCP) | `agent-bundle dev proxy` found no running development server for the project (cold start or shutdown), so the host-facing connection fails closed rather than serving stale bytes. | Start `agent-bundle dev` for that project root; installed hooks and Skills remain in place. |
11731252

1253+
## Development rebuild compilation and publication (`AB7100`–`AB7102`)
1254+
1255+
Every `agent-bundle dev` rebuild compiles the project into a build attempt,
1256+
validates the artifact, proves the project source did not change underneath
1257+
it, and publishes the result as an immutable epoch. Structured diagnostics
1258+
thrown along that path — the `AB4770` compile errors of an MCP App view, the
1259+
artifact validation codes — pass through to the failed attempt unchanged, so
1260+
the Workbench Overview and the `build.failed` Logs entry show the real
1261+
finding. `AB7100` is only what remains: the fallback for a throw in that pass
1262+
that carried no structured diagnostics, and the code of a cleanup failure
1263+
after the attempt settled. `sourcePath` on all three codes is the project's
1264+
config file.
1265+
1266+
| Code | Severity | Trigger | Recovery |
1267+
| --- | --- | --- | --- |
1268+
| `AB7100` | error / warning | `Unable to compile the build: <error>` — the compile, validate, or publish pass of a rebuild threw something that was not a `DiagnosticError` carrying diagnostics. Also `Unable to clean up build attempt after the build: <error>` or `Unable to clean up staging epoch after the build: <error>` when removing the attempt directory or closing an unpublished staging epoch fails: a **warning** on a succeeded attempt (the epoch is live), an error on a failed one. | Read the wrapped error; a structured cause reports under its own code instead. A cleanup failure names a path under `.agent-bundle/attempts` or `.agent-bundle/epochs` to repair or remove. |
1269+
| `AB7101` | error | `Project source changed while the artifact was compiling; publication was rejected.` — the source snapshot taken after compilation differs from the inputs the build read, so the attempt is discarded rather than published as an epoch built from mixed inputs. | Nothing to fix: the change that raced the build is already queued as the follow-up rebuild, and the last-good epoch stays active until it succeeds. |
1270+
| `AB7102` | warning | `Artifact epoch was committed, but follow-up work was incomplete: <error>` — the epoch is published and active, but the work after the commit failed: retention cleanup of older epochs (`Epoch publication committed, but retention cleanup failed.`) or confirming the active-epoch metadata reached disk (`… active metadata durability could not be confirmed.`). | The epoch itself is valid and serving. Check the epoch store under `.agent-bundle/epochs` for the retained or unsynced files the wrapped error names; the next publication runs the same follow-up work again. |
1271+
11741272
## Development package build (`AB7103`)
11751273

11761274
`agent-bundle dev` rebuilds the framework-owned package build (`dist/` bin

‎docs/entry-conventions.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,8 +1222,8 @@ The hatch merges *beside* the framework profile, not over it: `plugins`
12221222
arrays concatenate, and Rsbuild's plugin manager appends every plugin it is
12231223
handed without deduping by name. So a `tools.rsbuild.plugins` entry that
12241224
re-adds a plugin the framework already registers — `@rsbuild/plugin-react`
1225-
(`rsbuild:react`), carried by every synthesized Rslib entry and every
1226-
React-syntax MCP App view — would run it twice. `agent-bundle validate`
1225+
(`rsbuild:react`), carried by every synthesized Rslib entry and every MCP
1226+
App view — would run it twice. `agent-bundle validate`
12271227
reports that as `AB4724` (an error, like the other `tools` shape checks) with
12281228
the plugin and package name; remove the entry, the framework already
12291229
registers it.

0 commit comments

Comments
 (0)