配置
概念模型,配置拥有什么、src/ 约定拥有什么,在配置模型中。本页是
字段契约。
顶层字段
宿主作用域的扩展键(claude、codex、cursor、portable)由各 target 适配器通过对
AgentBundleConfigExtensions 的声明合并贡献。扩展值必须是严格的有限 JSON(AB4500),且宿主特定的值
留在各自的适配器中,而不进入编译器核心。每个适配器所拥有的键的逐字段清单见
宿主作用域声明。
生成的类型定义
配置是一份 TypeScript 契约,而不是运行时 schema:defineConfig 接受一个 AgentBundleConfig(或返回
它的工厂函数),validateSource 则用结构化诊断强制执行本页的规则。evals 与 routes 是例外:二者都不是
AgentBundleConfig 的成员,它们经由 [key: string]: unknown 索引签名传入,因此 tsc 不会检查它们的
形状;evals 的规则要到 eval 运行时才生效(EVAL_CONFIG_INVALID),agent-bundle validate 不会报告它们,
而 routes 覆盖块由路由图在发现阶段校验,其诊断随 validateSource 一并报告。同位置已有
<tool>.cli.ts 投影模块的工具会从 routes.mcpCommands 中排除,避免为同一个操作再编译一条批量
<bin> <server> <tool> --input 命令。参见
将一个工具投影为惯用命令。
下面这些精确形态在每次文档构建时由 TypeDoc 从包源码生成,因此不会与已发布的类型产生偏差。
plugin
共享描述元数据
author、homepage、keywords、license 与 repository 只声明一次,而不是在每个宿主块里重复。
每个字段按同一顺序解析:
- 该产物对应的宿主块,
portable.license、cursor.license、codex.license或claude.marketplace.plugin.license; plugin.metadata.license;- 项目
package.json的license字段。
null 表示有意的缺失而不是一个值:plugin.metadata.homepage: null 让 package.json 的 homepage
不进入任何产物,而 cursor: { homepage: null } 只让共享的 homepage 不进入 Cursor 清单,其他宿主仍然携带它。
唯一的例外是 codex: { author: null }:Codex 清单始终要有作者,因此它会回退为生成的插件名,而不是省略该字段。
每个宿主只输出其固定 schema 允许的字段,并且该值仍然要通过该宿主自己的校验。Cursor 的 author 对象只允许
name 与 email,因此共享的 author.url 对 Cursor 会被丢弃、对其他宿主保留;Cursor、Codex 与 Claude Code
都要求 author.name,因此只有邮箱地址的 package.json author 不会共享给它们,而 portable 清单仍然携带它。
会读取 package.json 的两种形状:npm 的 person 字符串("Ada <ada@example.com> (https://ada.example.com)")
及其对象形式;对 repository,则是绝对 http(s) URL 或 npm 为其写入的
git+https://github.com/owner/repo.git URL,其 git+ 前缀与结尾的 .git 会被去掉。像 owner/repo
这样的简写、SSH URL 与 git+http:// URL 不会被转换成某个托管商的网页 URL:该字段会被扣留并报告
AB4015 警告,改用 plugin.metadata.repository 显式声明。被固定宿主 schema 拒绝的 URL 或邮箱地址
同样会被扣留,而不会输出给宿主去拒绝。
package.json 中的空字段等于缺失字段:"keywords": [] 与 "license": "" 既不共享也不报告。而
plugin.metadata 下的同样取值出自配置作者之手,因此 plugin.metadata.license: '' 报告 AB4014;
null 才是退出某个字段的方式。
Claude Code 的 .claude-plugin/plugin.json 不携带描述字段,其固定 schema 不允许,且其
author.name 仍是生成的插件名。共享值经由 marketplace 条目到达 Claude Code。
package.json 对发布标识具有权威性。发布版本只在那里声明。若 package.json 没有有效版本,
发布构建会被 AB4013 拒绝,而不是交付 0.0.0-dev.<short-revision> 这个开发期回退值。已退役的
plugin.version 键会被 AB4001 拒绝,避免未经过类型检查的配置悄悄忽略它。
targets
build 铺进组合插件根目录的宿主投影:amp、claude、codex、cursor 与 portable 的任意组合。顺序无关,
选择会按名称排序,因此 ['codex', 'claude'] 与 ['claude', 'codex'] 构建出相同的字节。省略该键时只输出
portable 投影。命令行上的 --target 会在单次运行中替换配置里的列表。其他任何名字(包括 plugin)都是
未知 target(AB4100)。每个投影在根目录中放置什么,见 Target 与产物。
hooks
键是七个标准事件:sessionStart、beforeTool、afterTool、stop、agentStart、agentStop、
workspaceOpen。值是一个条目或条目数组,每个条目要么是模块路径,要么是
{ handler, tools?, targets?, timeout?, args? }。每个规范事件与工具选择器如何降级为宿主原生事件与
匹配器,见生成的事件与钩子矩阵。
钩子结果契约完整地记录在钩子中。有一个字段值得在此重复,因为它很
容易搞错:reason 是一个非空字符串,仅在拒绝 beforeTool、stop 或 agentStop 钩子时有效,而拒绝
其中之一却不给出 reason 会失败。
output 与 runtime
output.repositoryMarketplace: true 让显式 build 在项目根目录生成所选宿主的市场清单,
其中本地插件来源指向产物输出目录。Cursor 还需要 marketplace: true。将这些文件与产物目录
一起提交后,即可从 GitHub 直接安装。编译器会替换所选市场清单,请勿手工编辑。它会拒绝符号链接、
与产物目录重叠的路径、自定义适配器,以及手写的市场来源或 metadata.pluginRoot 覆盖。
这些生成文件不计入源码快照。开发与评估的暂存构建不会发布项目根目录市场清单。
MCP 命令、钩子查看或模拟以及 serve-app 使用的临时构建也不会修改这些文件,即使操作失败。
output.distPath 是相对项目根目录的产物输出目录,每个所选宿主都读取的组合插件根目录,其下没有逐宿主
子目录。命令行(build、prepack、dev)把它默认为 artifact,
因为命令行同时运行包构建,而包构建拥有 dist/;编程式 build() 除非传入 packageOutputs: true,否则默认为
dist。逐次调用的 --output 标志优先,但同样
受相同的项目根包含性检查约束;绝对或外部输出路径、形态无效的路径,或落入保留编译器命名空间的路径
均不受支持(AB4707–AB4709)。
output.sourceMap 是生成式可执行文件的 source map 显式开关,默认为 false。设为 true 时,编译器
profile 会把打包器的 output.sourceMap 设为内联 JS map,让 map 留在可执行文件内部,同级的 .map
文件不属于计划中的产物文件集合。非布尔值是 AB4707。MCP App 视图仍保持自身的默认值(关闭),并继续
通过 tools.rsbuild.output.sourceMap 选择加入。
生成式可执行文件保持代码可读。编译器 profile 只用 SWC 压缩器移除注释,压缩、混淆和空白压缩均关闭,
因此被打包依赖的文档注释不会随产物发布。法律注释(例如 /*! … */ 许可证头)以内联方式保留。将
tools.rsbuild.output.minify 设为 false 可保留全部注释。
runtime.node 是 major.minor[.patch] 形式的最低 Node.js 版本。它只能抬高生成式可执行文件的默认下限,
绝不能降低,且所选下限会作为 runtime.node 记录在产物清单中。这个下限本身在
配置模型中介绍。
notices
notices.retention 设置有状态项目在 src/state.ts 旁共同挂载的通知账本的保留策略。终态通知,
expired、unavailable、withdrawn、acknowledged,以及重试预算已耗尽的 attempted,在结算满
terminalTtl 后会从账本中清理;当终态通知超过 maxTerminal 条时,最早结算的会先被清理;存储的日志
超过 maxJournalBytes 时会被压实到当前头部。清理只在被接纳的事件和显式的 retain() 调用时运行;
不隐含任何定时器。
其他任何情况,未知键、非正数或小数、语法之外的时长写法,或在没有状态模块的项目中声明策略,都是
AB4833。inspect --state 与 Workbench 的 State 面板会显示解析后的策略以及它是声明的还是默认的;
实时计数与最近一次压实属于每个已安装的存储(AgentNoticeLedger.inspect())。
payload
键是产物根目录下的目标目录,一个位于编译器自有命名空间之外的安全单路径段,值是已经构建好的源目录。 payload 树按字节逐一复制,并且对编译器而言是不透明的:编译器无法改写其内部的同级引用,因此稳定的 名字就是正确性契约。完整性仍然通过产物清单保持内容寻址。
evals
只接受三个键;其他一律拒绝。
evals 块中的提供方凭据材料会被直接拒绝(EVAL_CREDENTIAL_REJECTED),Agent Bundle 复用宿主 CLI 已有
的已登录会话。见安全。
dev
仅用于开发、绝不会成为已构建产物一部分的设置。
web
产物内浏览器宿主的暴露与策略。web.apps 从已经声明在 mcp.servers.<id>.apps 下的 MCP App 中选择;
它不是第二套路由图,也不会从 src/web/** 发现 App。省略该键时,构建不写 web 节、不生成框架拥有的
web 命令,也不额外输出 bin。
无效的 web 是 AB4341(error):app 未被任何 mcp.servers.<id>.apps 声明;未知的 allow
能力;open 不在 browser | never 中;重复的 <server>/<app>;路由图未为该生成式服务器声明的
tool;在已配置 web 时,生成模式下 src/cli/** 命令(或顶层别名)拼作 web;或 web 面没有任何
可执行文件可以承载。所选目标的适配器若未发布受支持的 web 能力行,则是 AB4341 警告:其产物不承载
该面。消息形状与恢复方式见诊断参考。
web 命令只存在于框架生成的 bin/<plugin>.mjs 中。web 从不取代作者代码:手写的 src/cli.ts、
占用插件名的 bin 条目或 bin: false 都保留其所描述的可执行文件,并由 AB4341 报告 web 面无处
安放,把命令移到 src/cli/**(生成模式)下,或去掉 web。
web 合法时,组合产物的 agent-bundle.manifest.json 会增加 web 节,即使没有 src/cli/** 也会
输出 bin/<plugin>.mjs,见Target 与产物与
在浏览器中暴露 App。
tools
唯一的打包器逃生舱。两个片段都会以「最后但有界」的方式合并进框架合成的每一份打包器配置,并且产物不变式
断言仍会在合并之后运行,因此破坏产物契约的逃生舱取值是一条硬性诊断,而不是一次无声的覆盖(AB472x)。
AB4720–AB4723 检查 tools、tools.rsbuild 与 tools.rspack 的形状;AB4724 会拒绝在
tools.rsbuild.plugins 中再次添加框架自有插件(@rsbuild/plugin-react,rsbuild:react)的条目,
因为 plugins 数组会拼接、而 Rsbuild 从不按名称去重插件,框架会替你注册它。AB4725 会拒绝
并非 false 的 tools.rsbuild.output.autoExternal,以及在 tools.rsbuild.output 或对象形式的
tools.rspack 中、点名某个包(既不是 Node 内置模块、pnpapi,也不是相对路径)的字符串或对象 externals 条目。
AB4726 会拒绝 tools.rsbuild 中已废弃或移除的 Rsbuild v2 路径:source.alias、
source.aliasStrategy、performance.bundleAnalyze、performance.removeMomentLocale、
performance.profile、performance.chunkSplit、output.sourceMap.extract.js、provider、
tools.webpack、tools.webpackChain、dev.setupMiddlewares,以及旧版代理的 context / on*
事件键。每条诊断都会给出当前替代项。此检查只针对 tools.rsbuild 中的这些特定路径,不会套用到作者自定义的
html.templateParameters 变量或 tools.rspack 下的合法 Rspack 配置。
逃生舱在同一个打包器引擎上执行,即 agent-bundle 所固定的 @rsbuild/core 背后的那个 @rspack/core,
由 Rslib 编译的输出(产物脚本、MCP 入口、钩子、包构建)与 MCP App 视图共用,但这个引擎是 agent-bundle
的依赖,而不是你项目的依赖。绝不要基于导入的 @rspack/core 构造插件或执行 instanceof 检查,请使用
传给 tools.rspack 变更函数的 utils 参数((config, { rspack }) => ...),它总会交给你当前执行引擎
自己的 rspack 对象。
MCP App 构建保留 Rsbuild 默认的 resolve.aliasStrategy(prefer-tsconfig),因此项目
tsconfig.json 中的 paths 在编译出的视图内部与其他地方一样生效。保留标识符 agent-bundle/meta
是例外:编译器会在解析开始之前把这个精确的导入改写为生成的身份模块,先于 paths 与任何
resolve.alias,因此没有任何 paths 映射能够遮蔽它。已解析配置断言会拒绝移除这一改写的逃生舱取值,
就像它拒绝破坏自包含输出的取值一样。
合成的视图配置以 Chrome >= 144 为目标;设置这条基线时,它是当前发布的桌面 MCP App 宿主中
最旧的 Chromium 代际:Cursor 3.18 报告
Chromium 144,
Claude Desktop 官方 Linux 包报告
Chromium 148,Codex Windows 包报告
Chromium 151。配置仅对 react、react-dom 与
scheduler 去重,使 App 只解析到一份 React 运行时。作者 HTML 模板只会收到 Rsbuild 的安全默认参数
mountId、entryName 与 assetPrefix,编译及插件内部对象仍不会暴露;框架的脚本注入以及默认的
root 挂载点、语言和 App 标题保持不变。
插件
框架在它合成的配置中只注册一个 Rsbuild 插件:@rsbuild/plugin-react(插件名 rsbuild:react),
它作用于每个产物入口(路由以 TSX 编写,该插件选择自动 JSX 运行时)以及每个 MCP App 视图,无论其
入口扩展名是什么(关闭 fast refresh),因此导入 .tsx 组件的 .ts 入口也会编译到同一个自动运行时。
这个集合就是 packages/agent-bundle/src/build/framework-plugins.ts 中的
frameworkOwnedRsbuildPlugins;有一条单元测试从合成的配置中推导它,因此不会漂移,而 validateTools
读取同一个映射,在 tools.rsbuild.plugins 条目重复添加其中某个名称时报告 AB4724。
其他每个官方 Rsbuild 插件都以自己的名称注册,可以通过
tools.rsbuild.plugins 添加。该片段会到达每一份合成配置;下表说明每个插件与哪一类构建面相关:
不适用:Vue、Vue JSX、Preact、Solid 与 Svelte 插件(路由与视图都是 React;这些插件会重新配置
React 插件所拥有的 JSX 转换)、@rsbuild/plugin-umd(框架输出 ESM),以及包发布检查
rsbuild-plugin-publint 与 rsbuild-plugin-arethetypeswrong(它们在构建后检查构建根目录的
package.json,而不是产物)。