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
6 changes: 4 additions & 2 deletions website/docs/en/guide/development/testing.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: 'Test agent-bundle routes through the framework harness: the rstest configuration helper, renderRoute, the nine proof levels, and the generated-plugin contract matrix.'
description: 'Test agent-bundle routes through the framework harness: the rstest configuration helper, renderRoute, the eleven proof levels, and the generated-plugin contract matrix.'
---

# Testing
Expand Down Expand Up @@ -79,11 +79,13 @@ and prints it in every failure, because a pass at one level is never a receipt f
| `mcp-in-memory` | `openInMemoryMcpServer`, `invokeMcpTool`, `readMcpResource`, `getMcpPrompt`, `listMcpSurface`, `runContractMatrix` | The real generated MCP server's protocol contract, over the SDK's in-memory transport. |
| `dev-epoch` | `runDevEpochContractMatrix` | An epoch-pinned generated stdio process opened through the Workbench session service; the caller owns the epoch lease and process lifetime, and MCP App routes are covered (surface plus `ui://` sweep). |
| `cli-dispatch` | `invokeCli`, `cliJson`, `cliNdjson` | A plain or rendered argv vector resolved and run through the routed CLI's own shell — including rendered Markdown, explicit TTY, JSON, and NDJSON modes — in-process. |
| `script-dispatch` | `runScript`, `scriptJson`, `scriptNdjson` | A conventional `src/scripts/*` module run through its generated executable's contract, without bundling: a rendered `.tsx` script through the rendered-script shell in-process (piped Markdown, TTY, `--json`, `--ndjson`, with the project's conventional providers mounted), a plain `.ts` script as a Node process of its own through the `main` envelope — real `process.exit`, exit code, stdout, stderr, optional `stdin`. `testManifest().scripts` lists the scripts that ship; a nested (`AB4808`) or conflicting (`AB4809`) script is never a target. |
| `workbench-surface` | `inspectWorkbenchSurface` | What the dev server would hand the Workbench for this project — route manifest, grouped route catalog, state declaration, lifecycle-replay fixtures, page availability — from the same compiler pass, with no browser and no dev server; a project the compiler rejects reports `manifest-unavailable` with its error diagnostics. |
| `packed-stdio` | `openPackedMcpServer`, `runPackedContractMatrix` | A built artifact's generated entry running as a real process over stdio. |
| `packed-deleted-source` | `removeProjectSource`, `openPackedMcpServer({ deletedSource })`, `runPackedContractMatrix` | The packed stdio process still runs after project source and configuration are removed and verified absent. |
| `host-install` | `openInstalledHostMcpServer`, `runInstalledHostContractMatrix` | A built bundle staged into an isolated host root, discovered in the emitted host format, and spawned from the installed layout. |

Two further levels sit alongside these seven, for nine in all. `agent-bundle/test/browser` supplies `mountBrowserApp`
Two further levels sit alongside these nine, for eleven in all. `agent-bundle/test/browser` supplies `mountBrowserApp`
for the browser-safe `browser-app` level — production-compiled MCP App HTML mounted over the
product bridge in a real browser page — and `simulated` reuses the installed-host helper
`openInstalledHostMcpServer` without `sessionEvidence`: an emitted bundle staged directly into
Expand Down
5 changes: 4 additions & 1 deletion website/docs/en/guide/distribution/installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ the root contains the selected host's target directory.
| --- | --- | --- |
| Claude Code | Delegates to `claude plugin marketplace add` and `claude plugin install`. | `user`, `project`, `local` |
| Codex | Delegates to `codex plugin marketplace add` and `codex plugin add`. | `user` |
| Cursor | Copies the bundle into `~/.cursor/plugins/local/<name>`, because Cursor publishes no non-interactive install verb. | `user` |
| Cursor | Copies the bundle into `~/.cursor/plugins/local/<name>` (`--mode local`, the default), because Cursor publishes no non-interactive install verb; `--mode marketplace` instead stages a committed local marketplace repository under `~/.cursor/agent-bundle/marketplaces/<name>` and prints the Customize → Plugins → "Add Plugins from Local Repository" step. Either way Cursor loads the plugin's `hooks/hooks.json` from its manifest, so plugin hooks run with `${CURSOR_PLUGIN_ROOT}` substituted and need no `~/.cursor/hooks.json` entry. | `user` |

Because Claude and Codex targets always ship local marketplace manifests, their public CLIs can
install the emitted directory directly. The installer fails with a typed diagnostic when the
Expand Down Expand Up @@ -103,6 +103,9 @@ installed bytes. It never repairs anything. With `--from`, it reports the instal
| `AB7317` | info | A live event runtime implements the older strict protocol and does not expose runtime identity. |
| `AB7318` | error | A live event runtime became unavailable, timed out, or returned an invalid status response during the bounded read-only identity probe. |
| `AB7319` | error | A host tree resolved from `doctor --from` violates its pinned document schemas or process-free loader rules; the message retains the originating build-validator code. |
| `AB7322` | info / error | Info when an installed Cursor plugin registers plugin-scoped hooks from its manifest and every command's script exists under the plugin root; error when the declared hooks file is missing or malformed, or an executed script is absent. |
| `AB7323` | warning | `~/.cursor/hooks.json` registers a command that points into an installed plugin directory, so Cursor would deliver that hook twice; manifest registration alone is sufficient. |
| `AB7324` | info / warning / error | A marketplace staged by `install cursor --mode marketplace` is imported (`registered`), still awaiting the Customize import step (`unregistered`), or incomplete (`corrupt`). |
| `AB7320` | error / info | Error when a `.cursor-plugin/plugin.json` install violates Cursor's pinned document schemas or token-location rules, or when a local plugin contains a symlink escaping `~/.cursor/plugins/local`; the inventory entry is reported as `corrupt`. Info when a `.claude-plugin/plugin.json` or root `plugin.json` install has no Cursor-side pinned static document contract, and the loader-recognized entry stays `installed`. |

## Next
Expand Down
4 changes: 2 additions & 2 deletions website/docs/en/guide/start/project-structure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ my-plugin/
| Path | Surface | Opt out |
| --- | --- | --- |
| `src/skills/<name>/SKILL.md` | A Skill. Everything else in the directory ships as its resources. Ships with no declaration at all. | Remove the directory, or narrow the `skills` config globs. |
| `src/commands/*.md` | Flat host command documents. | Remove the file. |
| `src/rules/*.mdc` | Flat host rule documents. | Remove the file. |
| `src/commands/*.md` | Flat host command documents. Frontmatter is judged per host: Claude Code documents `description`, `argument-hint`, `allowed-tools`, `model`, and `disable-model-invocation`, while Cursor's pinned commands surface is frontmatter-free Markdown. A command that explicitly targets a host which cannot express a field it uses is `AB4927`; an implicitly selected host receives the body minus the field and `validate` warns `AB4928`. `inspect` lists the same omissions as `omittedFeatures`. | Remove the file. |
| `src/rules/*.mdc` | Flat host rule documents, emitted by Cursor, which keeps `description`, `globs`, and `alwaysApply`. The same per-host judgment applies: `AB4907` for an explicit target, `AB4908` as a warning for an implicit one. | Remove the file. |
| `src/mcp/<server-id>.ts` | Stdio entry for a declared MCP server that names no `entry`, `command`, or `url`. | Declare `entry` explicitly. |
| `src/mcp/<server>/{tools,resources,prompts}/*` | Generated MCP server routes. The path supplies identity; each module supplies static `config`, schemas, and one async default Server Component. | Set `routes.servers.<server>` to `custom`, `command`, or `remote`. |
| `src/mcp/<server>/apps/*` | Browser MCP App entries compiled to self-contained HTML and registered on the generated server. Static `config.resourceUri` is required. | Use a custom server, or prefix the file with `_`. |
Expand Down
2 changes: 1 addition & 1 deletion website/docs/en/guide/start/quick-start.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ npx https://pkg.pr.new/ScriptedAlchemy/agent-bundle/create-agent-bundle@<sha-or-
| --- | --- |
| `minimal` | A Skills-only plugin: one `src/skills/<name>/SKILL.md` directory and nothing else. |
| `mcp-server` | A stdio MCP server from one `src/mcp/<server>/tools/<name>.tsx` route module plus one artifact script, with the framework test harness wired up. |
| `cli-tool` | An installable CLI through the `src/cli.ts` bin convention, plus a `src/index.ts` library export with declarations. |
| `cli-tool` | An installable routed CLI (`src/cli/greet.ts`) plus a conventional script (`src/scripts/hello.ts`) and a `src/index.ts` library export with declarations, proved by a generated projection pool at the `cli-dispatch` and `script-dispatch` levels. |

Every template ships a `check` script (validate, build, typecheck, tests) and validates with
zero diagnostics — including the `AB473x` migration nudges, because the templates are written
Expand Down
8 changes: 6 additions & 2 deletions website/docs/en/reference/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,15 @@ Both build package outputs when the project declares `bin` or `lib`.
## install

```sh
agent-bundle install <host> [--from <bundle-dir>] [--scope <scope>] [--replace] [--json]
agent-bundle install <host> [--from <bundle-dir>] [--scope <scope>] [--mode <mode>] [--replace] [--json]
```

| Option | Default | Meaning |
| --- | --- | --- |
| `<host>` | **required** | `claude`, `codex`, or `cursor`. |
| `--from <bundle-dir>` | `process.cwd()` | Target bundle directory or artifact root. |
| `--scope <scope>` | `user` | `user`, `project`, or `local`. Claude accepts all three; Codex and Cursor are user-scoped. |
| `--mode <mode>` | `local` | Cursor only. `local` copies the bundle into `~/.cursor/plugins/local/<name>`; `marketplace` stages a committed local marketplace repository under `~/.cursor/agent-bundle/marketplaces/<name>` and prints the Customize → Plugins → "Add Plugins from Local Repository" step that makes Cursor manage the plugin as a marketplace install. |
| `--replace` (alias `--force`) | off | Replace an existing agent-bundle install of this plugin even when its version differs. Without it, an identical copy is an `already-installed` no-op, a same-version copy whose content hash differs is replaced automatically, and a different version is `AB7005`. Foreign directories are always refused (`AB7005`). |

The emitted standalone `install.mjs` and the package-relative installer bin accept the same
Expand All @@ -105,7 +106,10 @@ before `add`.

Doctor exits `1` when it reports any error diagnostic, and never modifies anything. With `--from`,
it reports the installed copy per host as `current`, `stale` (same version, different content —
`AB7308`), `version-mismatch` (`AB7309`), `foreign` (`AB7321`), or `not-installed` (`AB7307`).
`AB7308`), `version-mismatch` (`AB7309`), `foreign` (`AB7321`), or `not-installed` (`AB7307`). For
Cursor it also proves plugin-scoped hook registration from the installed manifest (`AB7322`), warns
when `~/.cursor/hooks.json` would deliver a plugin hook a second time (`AB7323`), and tracks a
staged marketplace from `unregistered` to `registered` once Cursor imports it (`AB7324`).

## validate

Expand Down
6 changes: 4 additions & 2 deletions website/docs/zh/guide/development/testing.mdx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: '通过框架 harness 测试 agent-bundle 路由:rstest 配置辅助函数、renderRoute、九个证明级别,以及生成式插件的契约矩阵。'
description: '通过框架 harness 测试 agent-bundle 路由:rstest 配置辅助函数、renderRoute、十一个证明级别,以及生成式插件的契约矩阵。'
---

# 测试
Expand Down Expand Up @@ -70,11 +70,13 @@ export const summarizes = async (): Promise<void> => {
| `mcp-in-memory` | `openInMemoryMcpServer`、`invokeMcpTool`、`readMcpResource`、`getMcpPrompt`、`listMcpSurface`、`runContractMatrix` | 真实生成式 MCP 服务器的协议契约,经由 SDK 的内存内传输。 |
| `dev-epoch` | `runDevEpochContractMatrix` | 通过 Workbench 会话服务打开的、锁定到某个 epoch 的生成式 stdio 进程;调用方拥有 epoch 租约与进程生命周期,MCP App 路由被覆盖(表面加 `ui://` 扫描)。 |
| `cli-dispatch` | `invokeCli`、`cliJson`、`cliNdjson` | 一个普通或渲染式 argv 向量在路由式 CLI 自己的 shell 中被解析并执行——包括渲染式 Markdown、显式 TTY、JSON 与 NDJSON 模式——全部在进程内完成。 |
| `script-dispatch` | `runScript`、`scriptJson`、`scriptNdjson` | 一个约定式 `src/scripts/*` 模块按其生成可执行文件的契约运行,无需打包:渲染式 `.tsx` 脚本在进程内经由渲染式脚本外壳运行(管道 Markdown、TTY、`--json`、`--ndjson`,并挂载项目的约定式 provider),普通 `.ts` 脚本则作为独立 Node 进程经由 `main` 封套运行——真实的 `process.exit`、退出码、stdout、stderr 与可选的 `stdin`。`testManifest().scripts` 列出实际发布的脚本;嵌套(`AB4808`)或冲突(`AB4809`)的脚本绝不会成为目标。 |
| `workbench-surface` | `inspectWorkbenchSurface` | dev 服务器会交给 Workbench 的本项目内容——路由清单、分组路由目录、state 声明、生命周期回放 fixture、页面可用性——来自同一次编译器处理,无需浏览器也无需 dev 服务器;被编译器拒绝的项目报告 `manifest-unavailable` 及其 error 诊断。 |
| `packed-stdio` | `openPackedMcpServer`、`runPackedContractMatrix` | 已构建产物的生成入口作为真实进程通过 stdio 运行。 |
| `packed-deleted-source` | `removeProjectSource`、`openPackedMcpServer({ deletedSource })`、`runPackedContractMatrix` | 在项目源码与配置被移除并核实缺失之后,打包后的 stdio 进程仍然可以运行。 |
| `host-install` | `openInstalledHostMcpServer`、`runInstalledHostContractMatrix` | 一份已构建的捆绑包被投放到隔离的宿主根目录、以输出的宿主格式被发现,并从已安装布局中启动。 |

在这七个级别之外还有两个并列级别,共九个。`agent-bundle/test/browser` 为浏览器安全的 `browser-app` 级别
在这九个级别之外还有两个并列级别,共十一个。`agent-bundle/test/browser` 为浏览器安全的 `browser-app` 级别
提供 `mountBrowserApp`,用于在真实浏览器页面中把生产编译的 MCP App HTML 挂载到产品桥接层之上;
而 `simulated` 复用不带 `sessionEvidence` 的已安装宿主辅助函数 `openInstalledHostMcpServer`
—— 一份输出的捆绑包被直接投放到隔离的宿主形状根目录并在没有宿主自有安装的情况下启动,它比
Expand Down
5 changes: 4 additions & 1 deletion website/docs/zh/guide/distribution/installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ target 目录。
| --- | --- | --- |
| Claude Code | 委托给 `claude plugin marketplace add` 与 `claude plugin install`。 | `user`、`project`、`local` |
| Codex | 委托给 `codex plugin marketplace add` 与 `codex plugin add`。 | `user` |
| Cursor | 把捆绑包复制到 `~/.cursor/plugins/local/<name>`,因为 Cursor 未发布非交互式安装动词。 | `user` |
| Cursor | 把捆绑包复制到 `~/.cursor/plugins/local/<name>`(默认的 `--mode local`),因为 Cursor 未发布非交互式安装动词;`--mode marketplace` 则在 `~/.cursor/agent-bundle/marketplaces/<name>` 下暂存一个已提交的本地市场仓库,并打印 Customize → Plugins →“Add Plugins from Local Repository”这一步。无论哪种方式,Cursor 都从清单加载插件的 `hooks/hooks.json`,因此插件 hook 会在替换 `${CURSOR_PLUGIN_ROOT}` 后运行,无需 `~/.cursor/hooks.json` 条目。 | `user` |

由于 Claude 与 Codex target 始终随行本地市场清单,它们的公开 CLI 可以直接安装输出的目录。当所选宿主
二进制文件不可用时,安装器会以一条带类型的诊断失败,而不是报告一次它并未完成的成功。宿主安装诊断属于
Expand Down Expand Up @@ -91,6 +91,9 @@ Doctor 是只读的。它探测宿主、清点已安装的捆绑包、把它们
| `AB7317` | info | 某个活跃的事件运行时实现的是较旧的严格协议,不暴露运行时身份。 |
| `AB7318` | error | 在有界的只读身份探测过程中,某个活跃的事件运行时变为不可用、超时,或返回了无效的状态响应。 |
| `AB7319` | error | 由 `doctor --from` 解析出的宿主目录树违反了它被固定的文档 schema 或无进程加载器规则;消息中保留原始的构建校验器代码。 |
| `AB7322` | info / error | 已安装的 Cursor 插件从清单注册了插件级 hook 且每条命令的脚本都存在于插件根之下时为 info;声明的 hooks 文件缺失或格式错误、或被执行的脚本不存在时为 error。 |
| `AB7323` | warning | `~/.cursor/hooks.json` 注册了指向某个已安装插件目录的命令,Cursor 会把该 hook 投递两次;仅靠清单注册就已足够。 |
| `AB7324` | info / warning / error | 由 `install cursor --mode marketplace` 暂存的市场已被导入(`registered`)、仍在等待 Customize 导入步骤(`unregistered`),或不完整(`corrupt`)。 |
| `AB7320` | error / info | 当某个 `.cursor-plugin/plugin.json` 安装违反 Cursor 被固定的文档 schema 或 token 位置规则,或某个本地插件包含逃逸出 `~/.cursor/plugins/local` 的符号链接时为 error,该清点条目被报告为 `corrupt`。当某个 `.claude-plugin/plugin.json` 或根 `plugin.json` 安装没有 Cursor 侧被固定的静态文档契约时为 info,被加载器识别的条目仍为 `installed`。 |

## 下一步
Expand Down
4 changes: 2 additions & 2 deletions website/docs/zh/guide/start/project-structure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ my-plugin/
| 路径 | 表面 | 如何退出 |
| --- | --- | --- |
| `src/skills/<name>/SKILL.md` | 一个 Skill。目录中其余内容都作为它的资源随行。完全不需要任何声明即可随产物发布。 | 删除该目录,或收窄 `skills` 配置中的 glob。 |
| `src/commands/*.md` | 扁平的宿主命令文档。 | 删除该文件。 |
| `src/rules/*.mdc` | 扁平的宿主规则文档。 | 删除该文件。 |
| `src/commands/*.md` | 扁平的宿主命令文档。frontmatter 按宿主逐一判定:Claude Code 记录了 `description`、`argument-hint`、`allowed-tools`、`model` 与 `disable-model-invocation`,而 Cursor 固定的命令表面是无 frontmatter 的 Markdown。显式指向某个无法表达其所用字段的宿主的命令是 `AB4927`;隐式选中的宿主收到去掉该字段的正文,`validate` 给出警告 `AB4928`。`inspect` 以 `omittedFeatures` 列出同样的省略。 | 删除该文件。 |
| `src/rules/*.mdc` | 扁平的宿主规则文档,由 Cursor 发射,保留 `description`、`globs` 与 `alwaysApply`。同样的按宿主判定适用:显式 target 为 `AB4907`,隐式 target 为警告 `AB4908`。 | 删除该文件。 |
| `src/mcp/<server-id>.ts` | 某个已声明、但未指定 `entry`、`command` 或 `url` 的 MCP 服务器的 stdio 入口。 | 显式声明 `entry`。 |
| `src/mcp/<server>/{tools,resources,prompts}/*` | 生成式 MCP 服务器路由。路径提供身份;每个模块提供静态 `config`、schema,以及一个 async 默认 Server Component。 | 把 `routes.servers.<server>` 设为 `custom`、`command` 或 `remote`。 |
| `src/mcp/<server>/apps/*` | 浏览器 MCP App 入口,编译为自包含 HTML 并注册到生成的服务器上。必须提供静态 `config.resourceUri`。 | 使用自定义服务器,或给文件名加 `_` 前缀。 |
Expand Down
Loading
Loading