Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/render-lowered-bundler-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"agent-bundle": patch
---

Make `inspect --bundler` render lowered Rspack configurations, rename
`BundlerInspectionEntry.kind` from `mcp-apps` to `mcp-app`, require `source`, surface the lowering
reason in `AB7001`, and serve Workbench assets with production cache and content-type headers.
(#649)
2 changes: 2 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ jobs:
node-version: 22.19.0
# Website-only PRs skip every ci.yml job that lints, so lint here too.
- run: pnpm lint
# TypeDoc consumes the declarations shipped from package dist trees.
- run: pnpm build
# Typecheck the site config, run the locale-drift and diagnostics-
# coverage checks (website/scripts), build with the persistent Rspack
# cache off, then walk the emitted HTML for dead links and anchors.
Expand Down
3 changes: 2 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@
dead-link, dead-anchor, dead-image, and language-parity checks. Parity
fails the build if one locale gains a page the other lacks. Run it before
pushing anything under `website/`, and after any change to public
exports, since TypeDoc compiles `packages/agent-bundle/src` directly.
exports, after `pnpm build`, since TypeDoc compiles the declarations under
`packages/agent-bundle/dist`.
- The site is desktop-first, like the Workbench. Wide tables scroll; code
samples wrap at roughly 90 columns so they render without horizontal
overflow at the default content width.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ The same config also owns the npm package build — no second bundler config, bi

- `build` — validate the project and write the plugin root (plus the `bin`/`lib` package build when declared)
- `validate` — check project source, or a built artifact with `--artifact <dir>`
- `inspect` — show the normalized configuration and each selected host's projection plan; `--bundler` dumps the synthesized bundler configs (post-`tools`-hatch merge)
- `inspect` — show the normalized configuration and each selected host's projection plan; `--bundler` dumps the lowered Rspack config of every compiled output (post-`tools`-hatch merge, as Rslib/Rsbuild hand it to the compiler)
- `dev` — serve the local development workbench and rebuild the `dist/` package build when its inputs change; `--install-host <claude|codex|cursor>` installs a development variant whose stable `dev proxy` MCP command hot-swaps epochs behind the host's open connection and re-syncs hooks and Skills on every adopted rebuild (see [Framework mode › Live development into hosts](docs/framework-mode.md#live-development-into-hosts))
- `mcp list` / `mcp invoke` / `mcp run` — list, invoke, or run an artifact's MCP servers locally
- `hooks list` / `hooks simulate` — inspect and simulate generated hooks
Expand Down
2 changes: 1 addition & 1 deletion docs/diagnostics.md
Original file line number Diff line number Diff line change
Expand Up @@ -1898,7 +1898,7 @@ the uninstall refusals `AB7007`–`AB7009`, have their own sections above.
| Code | Severity | Meaning | Recovery |
| --- | --- | --- | --- |
| `AB7000` | error | Install/uninstall: `Unsupported install host <host>.` / `Unsupported uninstall host <host>.` — the exhaustive host switch received a host that is not `claude`, `codex`, or `cursor`. Project preparation: `Unable to load project source.` — evaluating the configuration module or discovering source threw before validation. | Install: pass `--host claude`, `codex`, or `cursor`. Preparation: fix the Agent Bundle configuration and source files, then inspect again. |
| `AB7001` | error | Install/uninstall/doctor: the bundle identity or authoritative file inventory is unreadable from `agent-bundle.manifest.json` — no manifest directly under the `--from` directory (the composite root is every selected host's bundle root, so `<from>/<host>` is never probed and host documents are never read for identity); a manifest that is not the canonical `manifestVersion: 2` document (the message carries the parser's reason); a manifest with no projection whose `builtInHost` is the requested host (identity is the shipped adapter, never the selected name), whose projection has no `documents.plugin`, or whose `documents.plugin` / `documents.marketplace` pointer names a file the root does not contain; a `files[]` row whose path is missing or whose bytes differ from its `sha256`; a Cursor `application.name` that is not a safe local plugin name; a Claude or Codex projection with no `marketplace.name`. Project preparation: `Unable to validate project source.`, `Unable to normalize project source.`, `Unable to validate normalized project.`, or `Unable to create project context.` — the source validator, normalizer, adapter planner, or project-context factory threw; `inspectProject` adds `Unable to prepare inspection plans.` and `Unable to compose the bundler inspection.` | Install: point `--from` at the unchanged composite root `agent-bundle build` wrote, rebuilt with the host among `targets`; if a listed file is missing or changed, rebuild or restore that file from the matching artifact. Preparation: fix normalized project configuration and source references, then inspect again. |
| `AB7001` | error | Install/uninstall/doctor: the bundle identity or authoritative file inventory is unreadable from `agent-bundle.manifest.json` — no manifest directly under the `--from` directory (the composite root is every selected host's bundle root, so `<from>/<host>` is never probed and host documents are never read for identity); a manifest that is not the canonical `manifestVersion: 2` document (the message carries the parser's reason); a manifest with no projection whose `builtInHost` is the requested host (identity is the shipped adapter, never the selected name), whose projection has no `documents.plugin`, or whose `documents.plugin` / `documents.marketplace` pointer names a file the root does not contain; a `files[]` row whose path is missing or whose bytes differ from its `sha256`; a Cursor `application.name` that is not a safe local plugin name; a Claude or Codex projection with no `marketplace.name`. Project preparation: `Unable to validate project source.`, `Unable to normalize project source.`, `Unable to validate normalized project.`, or `Unable to create project context.` — the source validator, normalizer, adapter planner, or project-context factory threw; `inspectProject` adds `Unable to prepare inspection plans.` and, for `inspect --bundler`, `Unable to compose the bundler inspection: <reason>` — loading entries, generating the declaration tsconfig, or lowering and asserting the build's own Rslib/Rsbuild configuration failed. The reason carries the underlying source, project-tsconfig, toolchain, or invariant error, including a `tools` value the build would refuse. | Install: point `--from` at the unchanged composite root `agent-bundle build` wrote, rebuilt with the host among `targets`; if a listed file is missing or changed, rebuild or restore that file from the matching artifact. Preparation: fix normalized project configuration and source references, then inspect again. Bundler inspection: fix the source, project tsconfig, toolchain, or refused `tools` value named by the reason. |
| `AB7002` | error | Install/uninstall: `<host> is not installed or is not available on PATH.`, `Cursor is not installed in "<root>".` / `Cursor home "<root>" is not a directory.`, or `git` is missing for `--mode marketplace`. Project preparation: `Unable to prepare project paths.` — the project root or a configured output root could not be resolved inside the project. | Install: install the host CLI the message names; for the `git` refusal, install git or use `--mode local`. Preparation: ensure the project root and configured output roots are readable and remain inside the project root, then inspect again. |
| `AB7003` | error | Install/uninstall scope and mode refusals: `--mode` on a host other than `cursor`; `--scope` other than `user` for Codex or Cursor; `--mode marketplace` without `.cursor-plugin/plugin.json` or with bundle-internal Git metadata. Project preparation: `Unable to snapshot project source.` — the source snapshot could not be taken. | Install: use `--scope user`, drop `--mode` for non-Cursor hosts, or — as the message says — stage a Cursor Plugin bundle without `.git`, or use `--mode local`. Preparation: ensure project source files and ignore rules are readable and remain inside the project root, then inspect again. |
| `AB7004` | error | Install/uninstall command and safety failures: `<host> plugin <operation> failed: <detail>` (a host CLI verb exited nonzero); `<host> plugin list --json` was unusable when `--replace` or an uninstall needed it; an installed copy could not be compared and `--replace` was not given; a rollback after a failed install also failed (the message lists the host verbs to run by hand); a Cursor marketplace `git` step failed or the committed tree differs from the staged bytes; any non-diagnostic error thrown by a Cursor installer or reaching the `install-entry` CLI. `inspectProject`: `Requested inspection target "<name>" is not selected for this project.` | Install: read the host's detail in the message, then rerun (with `--replace` where the message says so). Inspection: choose a target selected by the project configuration, then inspect again. |
Expand Down
2 changes: 1 addition & 1 deletion docs/effect-conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ docs, or examples' user code. The four-concept newcomer ledger is untouched.
| --- | --- |
| npm `effect` | **`4.0.0-rc.112`** (exact). Latest published `rc` dist-tag on 2026-09-01. The Wave 3.5 brief named `4.0.0-rc.113`; that version was not on the registry. Re-pin chores take the next published RC. |
| Vendored tree | `repos/effect` via `git subtree` from [Effect-TS/effect](https://github.com/Effect-TS/effect.git) `main` (v4). Squash commit tracks `packages/effect` version **4.0.0-rc.112**. |
| `website` `typescript` | **`6.0.3`**, behind the root's TypeScript 7, because `typedoc@0.28` peers on `<= 6.0.x`. TypeDoc and twoslash compile `packages/agent-bundle/src` with it, so TS7-only syntax in the package breaks `pnpm docs:site:build` first. Re-pin chores check whether a newer `typedoc` lifts the ceiling. |
| `website` `typescript` | **`6.0.3`**, behind the root's TypeScript 7, because `typedoc@0.28` peers on `<= 6.0.x`. TypeDoc compiles the built `packages/agent-bundle/dist` declarations with it, while Twoslash compiles documentation samples against package source. Re-pin chores check whether a newer `typedoc` lifts the ceiling. |

Application code imports the npm package. Never import from `repos/**`.

Expand Down
54 changes: 36 additions & 18 deletions docs/entry-conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -1425,24 +1425,42 @@ kind whose row is not `supported`. The full matrix is in
agent-bundle inspect --bundler [--target <t>] [--json]
```

Dumps the synthesized bundler configuration for every output the build
composes — artifact scripts, MCP entries, hook wrappers, the composite root's
MCP Apps Rsbuild config, and the `dist/` package build — exactly as the build
lowers it: in production mode whatever `NODE_ENV` says, the framework profile
with the consumer `tools` hatch merged over it and the invariant hook appended
last (functions render as `[function <name>]`). Entries the framework wraps also carry the generated
wrapper module source (`generatedEntry`). The composition comes from the same
functions the build uses, so the dump cannot drift from what compiles.

Nothing is redacted (this is a local debugging surface), but two build-time
values are replaced with stable tokens so output is deterministic for one
project: the composite artifact root (chosen per build) appears as
`<output>`, and the synthesized declaration tsconfig (a temporary
file generated per package build) appears as `<generated-dts-tsconfig>`. The
package build's output root appears as its published destination, `dist`,
although each real build stages outputs before publishing them atomically.
Resolved post-bundler internals stay Rslib's domain; this surfaces
agent-bundle's own composition, which is where the `tools` hatch lands.
Dumps the **lowered Rspack configuration** of every output the build
compiles — artifact scripts, MCP entries, hook wrappers, the routed CLI bin,
each MCP App view, and the `dist/` package build's `bin` and `lib` entries —
one entry per compiler. The framework profile, the consumer `tools` hatch,
and the invariant layer are composed exactly as the build composes them, then
handed to the build's own engine — Rslib for executables, Rsbuild for MCP App
views — and stopped where the build would start compiling. What prints is
what the compiler receives: resolved `resolve.alias` entries (the
`agent-bundle/*` runtime modules and the project-rooted
`.agent-bundle-virtual/` generated modules beside the consumer's own
aliases), the `externals` list, the framework plugins
(`[object VirtualModulesPlugin]`, `[object ArtifactDependencyAuditPlugin]`),
`output.path`, module rules, and every default the engine fills in. The
lowering runs in production mode whatever `NODE_ENV` says and restores it
afterwards, and it runs the build's invariant assertions: a `tools` value the
build would refuse (a reserved alias, an `externals` entry naming a framework
runtime module) makes the inspection `invalid` with an `AB7001` diagnostic
carrying the refusal, instead of a config that never compiles. Entries the
framework wraps also carry the generated wrapper module source
(`generatedEntry`).

The JSON rendering keeps the config's shape without dropping values JSON
cannot carry: functions render as `[function <name>]` (Rslib lowers each
entry's file name to `[function jsFilename]`), plugin instances as
`[object <ClassName>]`, regular expressions as `[regexp /<source>/]`.

Nothing is redacted (this is a local debugging surface; the lowered configs
carry absolute paths of the project and of agent-bundle's installed
toolchain), but two build-time values are replaced with stable tokens so the
output is deterministic for one project: the composite artifact root (chosen
per build) appears as `<output>` — as `output.path` and inside any path
beneath it — and the synthesized declaration tsconfig (a temporary file
generated per package build) appears as `<generated-dts-tsconfig>`. The
package build's `output.path` is its published destination,
`<project root>/dist`, although each real build stages outputs before
publishing them atomically.

## Dev-watch of the package build

Expand Down
3 changes: 2 additions & 1 deletion docs/framework-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,8 @@ Every synthesized bundler config — both stages plus the `dist/` package build
`tools.rsbuild` fragment, then the `tools.rspack` hatch, then the framework
invariant layer that no hatch value can override
(`src/build/compose-layers.ts`; see the `tools` section of the configuration
reference). `agent-bundle inspect --bundler` prints the result.
reference). `agent-bundle inspect --bundler` prints the lowered Rspack
configuration each engine receives from that composition.

Builds are byte-reproducible: two builds of one unchanged source tree emit
identical artifacts (same manifest, same digests, same bytes) regardless of
Expand Down
2 changes: 1 addition & 1 deletion packages/agent-bundle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ manifests at files inside those payloads without compiling them. Payload files c
| `agent-bundle doctor` | Read-only host inspection: host probes, installed inventory, effective and legacy state roots with existence and writability, store receipts cross-checked against the host, and, with `--from`, the installed copy compared against the built artifact by version and content hash (`current`, `stale`, `version-mismatch`, `foreign`, `not-installed`) plus the lifecycle stage (placed → registered → enabled → active, unobservable stages typed `unavailable`). |
| `agent-bundle validate` | Validate project source, or an artifact with `--artifact`. |
| `agent-bundle inspect` | Inspect the normalized model and each selected host projection's plan from source, with per-host component accounting: which skills, commands, rules, hooks, MCP surfaces, and scripts each host emits and, for every omission, whether the author excluded it or the host's pinned capability judgment (`degraded`/`unavailable`/`prohibited`, with reason) ruled it out. |
| `agent-bundle inspect --bundler` | Dump the synthesized Rslib/Rsbuild configs (post-`tools`-hatch merge) for every generated output. |
| `agent-bundle inspect --bundler` | Dump the lowered Rspack config (post-`tools`-hatch merge, as Rslib/Rsbuild hand it to the compiler) for every generated output. |
| `agent-bundle mcp list` / `mcp invoke` | List or invoke one MCP tool from an artifact. |
| `agent-bundle mcp run` | Run one built stdio MCP server in the foreground, resolving its hashed entry, loading the project-root `.env` set (`--env-file`/`--no-env` to override), and expanding env state anchors to the project root (`--plugin-root` to override). Environment precedence: manifest env < `.env` files < operator `process.env`. |
| `agent-bundle hooks list` / `hooks simulate` | List generated hooks, or run one emitted wrapper. |
Expand Down
5 changes: 3 additions & 2 deletions packages/agent-bundle/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
featureCapabilityName,
type AgentComponentKind,
} from './core/components.ts';
import { errorMessage } from './core/errors.ts';
import { isInsideOrEqual } from './core/paths.ts';
import {
stateDefinitionProjection,
Expand Down Expand Up @@ -1220,12 +1221,12 @@ export const inspect = async (options: InspectOptions): Promise<InspectResult> =
projectRoot: prepared.root,
...(prepared.tools === undefined ? {} : { tools: prepared.tools }),
});
} catch {
} catch (error) {
return invalidInspection(freezeDiagnostics([
...prepared.diagnostics,
projectDiagnostic(
'AB7001',
'Unable to compose the bundler inspection.',
`Unable to compose the bundler inspection: ${errorMessage(error)}`,
{ sourcePath: prepared.configPath },
),
]));
Expand Down
Loading
Loading