For AI agents: the complete documentation index is available at https://scriptedalchemy.github.io/agent-bundle/zh/llms.txt, the full documentation bundle is available at https://scriptedalchemy.github.io/agent-bundle/zh/llms-full.txt, and this page is available as Markdown at https://scriptedalchemy.github.io/agent-bundle/zh/guide/development/workbench.md.
跳至主要内容
  • 简体中文
  • 开发者 Workbench

    agent-bundle dev 通过 loopback 提供一个预构建的开发者 Workbench。它是你查看编译器实际输出了什么 (逐宿主、逐 epoch),以及运行输出的包装层的地方,而不是仅凭构建通过就相信插件可用。

    npx agent-bundle dev --root .
    npx agent-bundle dev --root . --port 3100 --no-open

    边界

    这些是契约,不是默认值:

    • 仅 loopback。 服务器只绑定 loopback,绝不会暴露到本机之外。
    • 前台开发会话,而不是托管服务。 关闭进程即结束会话。
    • 按 epoch 固定的读取。 没有任何东西会隐式跟随一次新构建;读取产物的表面会指明自己读取的 epoch。
    • 只做可信本地操作。 浏览器只能选择一项已编译的命令投影;它绝不提供任意可执行文件、工作目录、 原生模型或凭据。见安全。

    Workbench 导航

    主导航有五个目的地:

    • Application:已编译的应用树,以及所选叶子的工作区。
    • Trace:本次前台开发会话中观察到的应用活动关联时间线。
    • Host sessions:显式启动并附加到当前开发插件的 Claude Code 与 Codex 终端。
    • Problems:当前的编译器、运行时与契约诊断。
    • Advanced:Evals、Artifact、Protocol、Host diagnostics 与 Raw logs。

    页眉在这些目的地之间始终可见。它显示项目名、构建状态与 epoch、契约门控与诊断失败计数(链接到 Problems),以及前台连接状态。

    Application 树

    Application 是从已编译应用图派生出的一棵树:

    MCP
      <server>
        Tools
        Resources
        Prompts
        Apps
    Events / Hooks
    CLI
    Scripts
    Skills
    Rules / Commands

    每个叶子都是一个编写好的或配置好的插件表面。生成的 MCP 服务器把 tools、resources、prompts 与 Apps 归到各自的服务器之下。事件路由与已配置的钩子出现在 Events / Hooks 下。路由式命令构成 CLI 分支。 约定式与显式配置的脚本共用 Scripts。Skills、宿主规则与宿主命令即使没有可执行的路由 id 也仍然可见。

    仅存在于配置中的钩子与脚本,不会仅仅因为没有匹配的文件约定路由就被隐藏。这棵树把路由清单与拥有这些 声明的编译器检视结果合并在一起。过期或不可用的编译器目录会在树中被标出,而不是被呈现为一份空应用。

    路由工作区

    选中一个叶子会打开同一个工作区,而不是把你送到某个表面专用的页面。对于可执行路由,输入编辑器由其 config.inputJsonSchema 元数据生成(未声明时使用 JSON 输入),并提供适用的夹具以及为该叶子保留的上次输入。Run 在前台服务器上执行生产路由路径。

    结果首先打开 Rendered,即生产 Agent Document 的浏览器渲染。路由运行期间,流式进度与 Suspense 替换会就地更新该视图;Cancel 会停止子进程,被取消的调用不带 outcome。次要结果 标签是 Structured result、Raw AgentDocument、MCP projection、可用时的 CLI projection, 以及 Trace。检查器仅在请求时打开,其中包含 Source、Schema、Context、Providers、 Execution timings、Projection 与 Raw protocol。本次运行未测量的 provider 显示 unobserved 且不带时长,计时只列出已测量的阶段;0 ms 是测得的零,不是占位。

    浏览器不会导入或执行任意路由模块。服务器运行生成式可执行文件所用的同一条 RSC 路由路径,并把其语义 渲染事件流与最终的 Agent Document 发送给 Workbench。

    带有同目录 CLI 投影的工具在树中仍只有一个叶子和一个规范 tool:<server>/<tool> 操作。其表面选择器提供 MCP、CLI <command> 与 Unit render。CLI 选项会显示投影后的 argv,并运行生成 CLI bin 的 确认、默认值、mapInput 与规范校验;它不会创建第二个 cli: 操作。

    事件路由

    事件叶子的夹具选项是 Canonical、Claude、Codex 与 Cursor。运行一份宿主夹具会像该宿主 包装层一样解码原生信封,然后展示规范输入、请求上下文、providers、返回的决策或文档,以及投影后的宿主 结果。规范到宿主的映射与原生输入/输出是次要的投影细节。 对于 .ts 事件处理器,Canonical 会被禁用,选择器默认使用项目的第一个已生成宿主目标;不指定 具体宿主提交该路由会报告 AB8255。

    观察到的事件收据出现在该叶子的 Replay 标签与 Trace 中。在那里选中一份收据即可重跑其绑定到该 epoch 的输入;没有单独的生命周期目的地。

    App 与 Skill 叶子

    App 叶子把沙箱化的 MCP App 预览放在工作区中央,并绑定到它的服务器。其 Launch 选择器列出开发服务器 判定该服务器在已发布构建上可用的启动方式,按启动身份分组的声明 target,并参考已安装的宿主,会话以所选 启动方式的代表 target 打开,因此构建声明但没有宿主能启动的 target 不会被提供。调用工具会立刻挂载预览: 调用进行中 App 先收到 ui/notifications/tool-input,随后恰好收到一个终态,工具结果(包括 isError 结果)以 ui/notifications/tool-result 送达,或在 Cancel call 中止调用时收到 ui/notifications/tool-cancelled。工作区已不再展示的调用若迟到产出结果,会被丢弃而不会投递给更新的预览。 也可以从其工具的投影细节到达一个已绑定的 App。同一套宿主栈通过 agent-bundle serve-app 在普通浏览器标签页里独立托管一个 App;当项目配置了 web,agent-bundle dev 也会在前台服务器上提供 GET /web/<server>/<app>,同样的页面、中继、路由、沙箱代理与同意行为,绑定到当前 epoch 的服务器会话。 未列在 web.apps 中的 App 返回 404。启动方式从产物声明的 projection 解析(?target= 会被校验, 实质不同的启动方式以 409 应答并列出可选项);Web 会话按 epoch、服务器与启动身份缓存,只在重建发布 新 epoch 时退役;非只读的开场工具在每个会话、工具、App 与输入组合下只运行一次。即使保留的结果被淘汰 或调用失败,其有界执行记录仍然有效,因此刷新不会静默重复可能的变更;页面会改为要求用户从 App 显式运行该工具。见 在浏览器中暴露 App。

    Skill 叶子默认渲染输出的 Skill 文档。源码/生成差异、frontmatter、资源与 eval 覆盖位于检查器中。Skill Markdown 中的原始 HTML、JSX/MDX 与 Mermaid 保持惰性。

    宿主会话

    启动 agent-bundle dev 时,指定应跟随已采用 epoch 的开发期宿主安装:

    pnpm add -D @lydell/node-pty
    npx agent-bundle dev --install-host claude --install-host codex

    之后,Host sessions 可以在 PTY 中启动 claude [<prompt>] 或 codex [<prompt>]。命令与参数由 服务器固定,工作目录始终是项目根目录;只有选择 Launch Claude、Launch Codex、 Open in Claude 或 Open in Codex 后才会创建会话。路由操作会为 tool、event 与 CLI 叶子填入 提示词,并在 /sessions?session=<id> 打开新终端。

    终端下方的 authority 条显示项目根目录、已采用的 epoch、宿主安装目的地、运行时进程 id 与当前状态。 重启后的会话还会指出它替代的会话。最多可同时运行四个会话;每个会话最多保留 256 KiB PTY 输出供终端 重连。项目中必须安装 @lydell/node-pty;无法解析或加载时,启动会以 AB8260 禁用。

    前台服务器仍仅限 loopback,并对每条 /api/sessions 路由应用相同的会话 cookie 或 bearer 守卫。 请求不能选择可执行文件、参数、工作目录或环境;可选的提示词作为宿主的位置参数传入,为空或以 - 开头时会被拒绝(AB8261)。子进程不会收到前台会话 token,Agent Bundle 也不会向 任何宿主传入权限或审批绕过参数。终端继承开发服务器环境,并增加钩子收据变量、 AGENT_BUNDLE_DEV_SESSION=<hs_…>、TERM=xterm-256color 与 COLORTERM=truecolor。

    AGENT_BUNDLE_DEV_SESSION 是 Workbench 资源 id,不是凭据。每条生成的钩子收据都会把它作为 devSession,并同时携带宿主自己的 session_id。首条收据到达后,Trace 会把资源别名关联到宿主会话 id, 后续生命周期、钩子与 MCP 条目都按该 id 分组;携带新宿主 id 的 session/start 收据(Claude Code 在 /clear 时会签发新 id)会移动别名并再发布一条 session.attached 条目。在任何收据之前到达的条目仍按 hs_… id 分组。Claude 会把该变量传给 stdio MCP 服务器,因此代理通过 别名标头传递它。Codex 会过滤 stdio MCP 服务器的环境,因此代理无法继承该变量;代理始终改为发送自己的 进程 id,前台服务器沿代理的父进程链查找到拥有 Workbench 会话的 PTY 子进程。Codex 帧还可以通过 x-codex-turn-metadata.session_id 携带宿主会话 id。它的钩子仍继承 AGENT_BUNDLE_DEV_SESSION,并发送收据的 devSession 字段。Trace 链接在宿主 id 可用后始终使用它。

    Trace

    Trace 是前台服务器所观察到的应用活动的实时有序时间线。例如,运行 钩子与脚本中的 sessionStart 事件路由可能产生如下序列:

    22:41:04.101 invocation.started       event:session/start
    22:41:04.118 kernel.handler.start   session/start · claude
    22:41:04.121 kernel.execute.start     event:session/start
    22:41:04.126 kernel.providers.start
    22:41:04.129 kernel.providers.finish
    22:41:04.132 kernel.render.start
    22:41:04.146 kernel.render.finish
    22:41:04.149 invocation.completed     sessionStart succeeded

    通过 Protocol 检查器发起的调用还会向同一时间线加入 mcp.request、进度或日志通知,以及 mcp.response。由已附加宿主投递的钩子会加入 hook.received 以及 hook.completed 或 hook.failed;其不含载荷的内核阶段保留在终止行的详情中。

    条目、关联与分组

    时间线是对已有记录的降级表示,不会再次复制调用、协议帧、钩子收据、日志记录或诊断。 每一行都包含发生时间、source、由生产者所有的点分 kind、单行摘要、已知关联键、可选状态与耗时; 当完整记录可用时,还包含指向它的 href:

    来源Kind关联键目的地
    invocationinvocation.started、invocation.completed、invocation.failed、invocation.cancelledcorrelationId、invocationId、routeId、epochId,以及可用时的会话/对话标识带 ?invocation=<id> 的 Application 路由
    kernelkernel.handler.start、kernel.handler.outcome、kernel.execute.start、provider 与 render 的开始/结束,以及 kernel.failureexecutionId、路由、宿主,以及可用时的会话与对话标识对应的路由调用
    mcprequest、response、notification、progress、logging、session 与 stderr kindmcpSessionId、JSON-RPC mcpRequestId、requestId,以及已知的路由与宿主元数据带 ?session=<id> 的路由工作区,或绑定的 Protocol 会话
    hook收据/完成/失败与宿主会话开始/结束requestId、executionId、sessionId、conversationId、routeId、host事件路由与捕获的收据
    sessionsession.started、session.attached、session.exited、session.terminated宿主会话、宿主与 epoch 标识/sessions?session=<hs id>
    log具有共享键的记录对应的 log.<producer>.<kind>安全日志投影保留的任意关联键Advanced → Raw logs
    diagnostic构建、契约与宿主同步失败已知的构建、epoch、路由与共享请求标识Problems 或受影响的路由

    Trace 会根据共享标识传递式地分组条目。组标签按以下顺序采用最强的可用键:对话、会话、调用、内核执行、 MCP 请求,最后是浏览器生成的关联 id。MCP 请求 id 只在其 MCP 会话内参与关联。分组以证据 为依据:不会仅因活动发生时间相近就把无关活动合并。/trace?correlation=<value> 会选中包含具有该精确 关联值条目的组。

    检视与深度链接

    选择一行会在 /trace/<entry-id> 打开其详情。Open route 会沿该行的 href 前往 Application 工作区并加载不可变的调用快照,而不是重新运行路由。路由工作区的 Open in Trace 操作会返回匹配的 关联组。Advanced → Raw logs 中的记录若带有 correlationId、invocationId 或 mcpSessionId, 也会提供同一操作。

    Trace 重放从 GET /api/trace?after=<sequence> 加载,实时视图再从 GET /api/trace/stream?after=<sequence> 继续。重放窗口丢失会被明确表示为 gap;浏览器不会暗示剩余 行是完整记录。Trace 属于当前前台开发会话,服务器重启后不会持久保留。

    宿主钩子收据

    已附加的生成式钩子包装器可以向 POST /api/trace/receipts 提交一份最多 16 KiB 的收据。包装器通过 开发安装标记与项目中仅所有者可读的收据文件发现当前 loopback 端点及每次开发服务器随机生成的 bearer token;模拟调用直接从前台服务器取得这对值,服务器关闭时会移除该文件。这个只写路由拒绝非 loopback 对端以及任何带 Origin 标头的请求;Workbench cookie 与会话标头均不能授权它。收据包含执行标识、 不含载荷的内核事件、宿主/会话/请求 id 与解析后的 lineage,绝不包含原生钩子载荷。提交预算为 750 ms, 失败会被忽略,因此 Workbench 观察不会改变钩子结果。包装器会在写入 stdout 后等待该提交,因此同一个 750 ms 超时也限定了新增的钩子退出延迟。这是范围严格且经过认证的遥测,而不是远程控制或通用摄取端点。

    刻意排除的数据

    Trace 绝不包含请求或响应载荷正文、渲染后的 Agent Document、原生事件信封、环境变量、凭据、绝对路径或 错误堆栈。需要更多详情时,请打开已链接的调用、路由、Protocol 会话、Raw log 记录或 Problem 中可用的 有界完整记录。

    Problems 与过期目录修复

    Problems 收集当前诊断。失败的构建不会发布新的 epoch,因此页眉显示失败状态,而 Application 继续暴露 上一个可用的目录与产物。例如,MCP App 编译失败会为每个 Rspack 错误贡献一行 AB4770,包括出错源码 与位置;AB4771 警告与 AB4772 体积建议属于成功的 epoch。

    按此顺序修复过期目录:

    1. 从页眉失败计数打开 Problems,并修复所报告的源码。
    2. 重建,然后等待已完成的 Idle 状态;Building 不是修复证据。
    3. 回到 Application。新发布的 epoch 会替换过期的树,并清除已修复的诊断。

    Advanced

    • Evals 具有 Runs 与 Compare 视图,用于受理、取消、检视与对比 eval 运行。
    • Artifact 默认是一棵简单的输出文件树。选中一个文件并启用其详情,即可看到哈希、模式与 provenance。Provenance 就是该文件在 agent-bundle.manifest.json 中自己的 compiler.provenance 行:它所派生自的项目源输入。编译器为每个输出文件至少记录一个源输入; 没有任何源输入的行显示为 No source inputs recorded。不会从路径或文件内容推断任何内容。
    • Protocol 是底层的 MCP 会话检查器。它保留协议轨迹、任务控件、同意、重启/取消操作,以及独立的 MCP Inspector 启动器。
    • Host diagnostics 仅限于已安装状态、版本、路径、当前插件是否已附加、可操作的错误,以及一个 MCP 握手指示。
    • Raw logs 保留为完整且经过脱敏的生产者流,用于不属于类型化时间线的框架级细节。Trace 是常规的 可观测性视图;带有 correlationId、invocationId 或 mcpSessionId 的日志记录会提供 Open in Trace。

    MCP 协议会话仍然固定到 { epochId, target, serverName }。重启它会在所选 epoch 上重新拉起该生成式 服务器;要使用新发布的 epoch,请打开一个新会话。兼容的 App 通过同一个已绑定会话预览。见 开发构建与生产构建。

    独立的 MCP Inspector 仍然作为单独的 localhost 应用启动。Streamable HTTP 会话可以深度链接进 Inspector 2.x;stdio 会话使用可下载的、已解析的命令、参数与非机密环境。AB8112 报告启动失败或 超时,AB8113 报告启动器路由不可用。

    URL 模型

    Workbench 使用路径与浏览器历史,而不是 #page 哈希:

    /routes/mcp/<server>/tool/<name>
    /routes/mcp/<server>/resource/<name>
    /routes/mcp/<server>/prompt/<name>
    /routes/mcp/<server>/app/<name>
    /routes/events/<event...>
    /routes/cli/<command...>
    /routes/scripts/<name>
    /routes/skills/<id>
    /routes/commands/<id>
    /routes/rules/<id>
    /sessions
    /sessions?session=<hs-id>
    /trace/<entry-id>
    /trace?correlation=<correlation-value>
    /problems
    /advanced/<section>

    Advanced 的分区名是 evals、artifact、protocol、hosts 与 logs。 在一条 Application 路由后追加 ?invocation=<id> 即可加载一条已记录的调用。开发服务器为这些路径提供 Workbench 外壳,因此路由、trace、Problems 与 Advanced 的深度链接在刷新后仍然有效。

    路由调用 API

    路由工作区使用一套经过认证、受 origin 守卫的前台 API:

    • POST /api/routes/invocations 接受一条路由调用请求,并返回其已完成的调用信封。传入 stream: true 时会立即以 202 返回运行中的 id。
    • GET /api/routes/invocations/<id>/stream 通过服务器发送事件重放并实时发送 render、trace、 truncated 与终止 final 消息。重放的 render 事件即下文所述的渲染历史窗口;以 truncated 开头的重放表示更早的事件已被该窗口淘汰。
    • POST /api/routes/invocations/<id>/cancel 停止运行中或排队中的调用并返回取消后的最终信封;取消已经 终止的调用会报告 AB8256(409)。
    • GET /api/routes/invocations?limit=50 为 Trace 返回按最新优先的摘要。
    • GET /api/routes/invocations/<id> 返回一次调用。
    • /api/project/events 以 route.invocation 事件发布运行中记录与最终摘要。
    • GET /api/trace?after=<sequence> 返回一份关联的 Trace 重放。
    • GET /api/trace/stream?after=<sequence> 以 NDJSON 流式传输 Trace 条目与重放 gap。
    • POST /api/trace/receipts 接受来自开发包装器的一份有界且经过 bearer 认证的钩子收据;它不是浏览器路由。

    请求以 routeId 标识一个规范操作,并可选择一种有固定形状的 surface: { kind: "mcp" }、{ kind: "cli", command, args }、 { kind: "event", host?, fixtureId? }、{ kind: "script" } 或 { kind: "unit-render" }。省略时,表面由路由种类决定:tool/resource/prompt 使用 MCP, event 使用 event,script 使用 script,独立 CLI 路由使用其已编译命令和空 argv。 unit-render 绝不会成为默认值。

    生产表面从最近发布的编译器 epoch 执行所选路由,因此编译器 alias 与 define、生成入口的请求作用域、 providers、持久状态、CLI mapInput 与确认、事件门控以及渲染语义都与已安装制品一致。 显式的 unit-render 表面是组件预览后备模式:它通过 route-unit 测试工具加载实时源码并挂载一次性状态, 不能作为制品一致性的证明。投影后的 CLI 命令保留规范 tool: 路由 id;命令不匹配报告 AB8253, 使用看似重复的 cli: id 则报告 AB8254,并给出应使用的规范 id 与表面。

    生产表面会在子进程运行前,从已发布 epoch 的 agent-bundle.manifest.json 选择可执行项。渲染式 CLI 路由、投影后的工具命令与渲染脚本使用各自的 manifest worker;MCP 路由使用所属已编译服务器的 launch.worker;事件路由则使用宿主包装层以及 routes.events[].execution 选定的 worker: standalone hooks worker,或拥有该宿主共享运行时的第一个已编译服务器。绑定失败即关闭:已发布制品 不可用报告 AB8250;宿主或表面 不适用、缺少可执行项或缺少准备行报告 AB8251;准备模块无法导入或未导出其契约报告 AB8252。未指定 宿主提交带 handler 的路由报告 AB8255。这些失败绝不会到达处理函数,导入、handler 或处理函数 失败也绝不会触发另一个可执行项。 生产状态位于 <project>/.agent-bundle/state,在 retirement 会移除的已发布 epoch 之外。它通过 AGENT_BUNDLE_STATE_ROOT 与开发期 MCP 会话共享,因此能跨一次成功的重新发布保留;unit-render 仍为每次运行使用新的临时状态根。

    该信封在 routeId 旁记录解析后的 surface,并携带规范输入、请求上下文、providers、有序渲染事件、 最终的 Agent Document、结构化结果、投影、诊断与执行计时。渲染事件由同一个渲染历史窗口保留,该窗口 同样适用于实时流重放、已完成与已取消的信封、GET /api/routes/invocations/<id>、final 流消息以及 Workbench 的实时视图:至多 256 条事件、序列化后至多 2 MiB,且始终保留最新一条事件与最新一条携带文档 的事件(shell、replace 或 complete),仅这两条事件本身可能使窗口超过 2 MiB,因此即使发生 淘汰,events 折叠后仍是连贯的最新文档。更早的中间事件会被丢弃;子进程不会再次返回整条事件流。 一旦有事件被淘汰,信封会携带 retention,producedEvents、evictedEvents、evictedBytes 与 retainedBytes,流也会发送一次 truncated。已取消或失败的运行保留同一窗口以及它到达的最新文档。 最终的 document、result、outcome 与 correlationId 永不被该窗口截断;文档在到达服务之前已由 运行时自身的 maxDocumentBytes 约束。worker 报告观测值时,providers 只包含 它实际选择的 provider,并将状态报告为 mounted 或 failed;未选择的目录 provider 不会出现。只有 实际测到时长时才带 durationMs。子进程未报告观测值时(普通脚本、handler 短路,或在观测开始之前 失败),每个目录 provider 为 unobserved 且省略 durationMs;0 是测得的零,不是「未知」。 timings 只列出已测量的阶段:render(子进程的渲染或普通脚本运行时长)、projection(服务端的 宿主投影时间),以及观测到时的 handler、providers 与 provider:<name>。失败的调用记录 elapsed(失败前的墙钟时间), 不会伪造 failed 的 provider 行。被表示的 Agent.Error 仍是一份已渲染结果;未知路由或 invocation id(AB8231)、不可用的 epoch(AB8232)、渲染超时或崩溃(AB8236)、格式错误的请求 (AB8237)、未知 fixture id(AB8238)、在获得并发槽位前发布修订已变更的排队调用(AB8239)、不可用的编译制品 (AB8250)、缺失的已编译路由可执行项(AB8251)、已编译投影或 handler 失败(AB8252)、 CLI 命令/操作不匹配(AB8253)、投影形成的重复 CLI id(AB8254),以及未指定具体宿主的 handler 路由(AB8255),以及取消已终止调用(AB8256)会作为诊断报告。 各条触发条件与恢复指引见诊断参考。

    信封、route.invocation 事件载荷与路由工作区报告两个彼此独立的事实。status 表示执行边界是否完成; outcome 表示一次已完成的运行意味着什么,由该路由所经过的表面来判定。失败的边界不带 outcome, 已完成的运行总是带有一个,因此被表示的错误或非零退出码永远不会被报告为普通成功。 route.invocation 也会在调用开始时触发,此时记录的 status 为 "running",且没有 completedAt 或 outcome;读取完成字段前请先按 status 缩小类型。

    字段值含义
    statussucceeded子进程完成了最终文档(或普通脚本已退出)。
    statusfailed边界从未完成:崩溃、超时,或 AB825x 诊断。
    statuscancelled操作者取消了运行中或排队中的调用;不带 outcome。
    outcome{ kind: "success" }按该路由的表面判定,投影结果为成功。
    outcome{ kind: "represented-error", summary }MCP 投影带有 isError: true(非 success 的 Agent Document,例如 Agent.Error),或事件路由的决策为 deny。summary 列出 Agent.Error 的代码与消息,或 deny 的原因。
    outcome{ kind: "process-exit", exitCode }CLI 或脚本路由已完成,且其生成的可执行文件设置了非零退出码,即该 bin 自己的 exitCode 策略作用于已校验结果,或非 success 文档对应的 1。零退出码报告为 success。

    Workbench 状态行在执行状态(Running / Completed / Failed / Cancelled)旁展示 outcome 徽章,Trace 为每个条目同时列出两者。

    完整的浏览器侧 HTTP 形状(包括 Trace 条目与重放契约)见 开发服务器 HTTP 参考。

    以编程方式使用同一个会话

    公开的 startDevServer 导出接受 CLI 标志所映射的那些选项(root、port、open、agentApi、 installHosts、workbenchDevOrigins),并解析为一个 DevServerSession,它暴露 loopback 的 url、 一个 status() 快照以及 close():

    import { 
    const startDevServer: (options: StartDevServerOptions) => Promise<DevServerSession>

    Starts one loopback foreground session over the current project services.

    startDevServer
    } from 'agent-bundle';
    export const
    const serve: () => Promise<void>
    serve
    = async ():
    interface Promise<T>

    Represents the completion of an asynchronous operation

    Promise
    <void> => {
    const
    const session: DevServerSession
    session
    = await
    function startDevServer(options: StartDevServerOptions): Promise<DevServerSession>

    Starts one loopback foreground session over the current project services.

    startDevServer
    ({
    StartDevServerOptions.port?: number | undefined
    port
    : 3100,
    StartDevServerOptions.root: string
    root
    :
    var process: NodeJS.Process
    process
    .
    NodeJS.Process.cwd(): string

    The process.cwd() method returns the current working directory of the Node.js process.

    import { cwd } from 'node:process';
    
    console.log(`Current directory: ${cwd()}`);
    @sincev0 .1.8
    cwd
    () });
    var console: Console
    console
    .
    Console.log(...data: any[]): void

    The console.log() static method outputs a message to the console.

    MDN Reference

    log
    (
    const session: DevServerSession
    session
    .
    DevServerSession.url: string
    url
    );
    await
    const session: DevServerSession
    session
    .
    DevServerSession.close(): Promise<void>
    close
    ();
    };

    开发期宿主安装

    多次传入 --install-host <claude|codex|cursor>,即可把开发变体安装到所选宿主:

    npx agent-bundle dev --install-host cursor --install-host claude

    第一个成功的 epoch 使用普通的宿主安装器。Claude 与 Codex 从稳定、由收据归属的 <project>/.agent-bundle/dev/<host> 源注册插件,并从宿主自有的 plugins/cache/<marketplace>/<plugin>/<version> 目录读取它的文件;Cursor 读取 ~/.cursor/plugins/local/<plugin>。被安装的根目录带有一份 .agent-bundle-dev.json,其中记录 schema 版本 1、项目根目录、宿主以及已安装的 epoch。

    它的 MCP 文档始终通过运行中的开发服务器的 Node 可执行文件启动框架 CLI:

    agent-bundle dev proxy --root <projectRoot> --server <serverName> --target <host>

    重建绝不会用某个 epoch 路径替换这条稳定命令,而宿主进程 PATH 的内容也不影响项目本地的框架能否被 启动。

    在 Codex epoch 被报告为已同步之前,Agent Bundle 会通过已有的本地 app-server 控制 socket 发送 Codex 幂等的 plugin/install 请求。它会以原子方式采用稳定、由收据归属的源来刷新 app-server 的 MCP 与钩子 组件快照,而不重启服务器。没有正在运行的 app-server 时,后续 Codex 会话会照常加载已安装的注册项。

    所有选中宿主都从同一个复合 epoch 根目录安装。在 Codex app-server 未运行的路径以及其他宿主路径上,之后 每个 artifact.available 事件都会为每个宿主把该根目录复制成一个不可变的已安装世代。顶层目录通过原子的 符号链接(或 Windows junction)重命名切换,顶层文件通过原子的同级文件重命名切换,因此宿主看到的要么是 旧的、要么是新的完整条目。第一次直接发布完成后,任何被同步的目录都不会在两个世代之间消失。直接发布失败 且先前世代仍然存在时,会把指针回滚并在 dev.host.sync 上发出一条 AB7202 诊断;构建失败则根本不会发出 artifact.available,因此最后一次可用的安装不受影响。重新同步会直接写入宿主缓存,不会再次调用 Claude 或 Codex CLI。重新同步会在 .agent-bundle-dev/ 下记录顶层条目的归属,并且只会移除清单中记录为 由管理器发布的条目;相邻的宿主或用户条目绝不会被推断为由管理器所有。

    停止开发服务器会注销并移除 Claude 与 Codex 的开发安装。后续运行会再次注册同一个稳定源路径,因此重启 不会留下重复的 marketplace。如果由收据归属的 marketplace 源未经清理就被删除,Doctor 会报告 AB7333;uninstall <host> --from <bundle-dir> --force 会移除这条悬空注册。

    实时宿主 MCP 代理

    在 dev 于其背后重建生成式服务器的同时,宿主可以让一个 stdio MCP 进程保持连接。该命令、 /mcp/host/<serverName> 端点,以及它如何通过项目的开发锁完成发现,都记录在 MCP 服务器与 MCP App中。

    这里有一条重建规则值得注意:崩溃的生成式服务器不会在同一个 epoch 内被静默重启。在一次成功的重建 换入一个新预热的 epoch 会话之前,调用会一直保持失败。

    可选的 Agent API

    Agent API 是面向 Codex 客户端的、独立且需要认证的 Streamable HTTP MCP 端点。它默认关闭,并且只 挂载在既有 loopback 前台服务器的 /mcp 上:

    AGENT_BUNDLE_AGENT_API_TOKEN='replace-with-a-secret' \
      npx agent-bundle dev --agent-api --no-open --port 3100

    dev: { agentApi: true } 可从配置启用它,而 --no-agent-api 会覆盖该设置。如果端点被启用却没有 AGENT_BUNDLE_AGENT_API_TOKEN,启动会在开始服务之前失败。这个固定 token 只被读取一次,绝不会被 记录日志、持久化或返回,并且必须以标准的 Authorization: Bearer 认证方式提供。客户端可以省略 Origin;一旦提供了 origin,它必须与前台 URL 完全一致。端点被禁用时是不存在的,而不只是未授权。

    它恰好有十三个固定且有序的工具:

    #工具#工具
    1project_status8hooks_list
    2skills_list9hook_simulate
    3skill_inspect10evals_list
    4artifacts_list11eval_run
    5artifact_inspect12eval_get
    6mcp_servers_list13diagnostics_list
    7mcp_invoke

    eval_run 仅限确定性 harness;它无法选择原生宿主。工具 schema 会拒绝未声明的 root、path、command、 cwd、environment、harness、evidence 与 outcome 字段。以产物为后端的调用可以指名一个 epoch id;否则 它们会原子地租借当前活跃的 epoch,因此一次热重建会把之后的调用送往新的 epoch,而已被受理的调用仍固定 在它原本的 epoch 上。传输是无状态的,因此前台服务器恢复之后,已完成初始化的客户端可以在同一个固定 URL 上继续发起请求。

    贡献者 UI 的 HMR

    开发 Workbench 界面本身,与消费一个已发布的 Workbench 是两个不同的循环:由一个 Rsbuild 开发服务器带着 热模块替换提供界面,并把 /api 代理到另外启动的前台服务器。已发布的 agent-bundle dev 提供的是预构建 资源与项目事件;它不会运行 Rsbuild 开发服务器。这个循环需要两个终端。

    终端 A 启动前台服务器,并指明它应当接受的那个 Rsbuild origin:

    npx agent-bundle dev --root . --port 3100 --no-open \
      --workbench-dev-origin http://localhost:3000

    终端 B 针对该前台 URL 启动 Rsbuild 开发服务器:

    AGENT_BUNDLE_WORKBENCH_API_PROXY=http://127.0.0.1:3100 \
      pnpm --filter agent-bundle-workbench dev

    打开 http://localhost:3000。packages/workbench/scripts/dev.mjs 要求提供该代理 URL,并把其余参数原样 传给 rsbuild dev。Rsbuild 的默认值是主机 localhost、端口 3000; pnpm --filter agent-bundle-workbench dev --port 3001 会把界面挪到别的端口,此时请在终端 A 中改为放行 http://localhost:3001。只要设置了 AGENT_BUNDLE_WORKBENCH_API_PROXY, packages/workbench/rsbuild.config.ts 还会设置 server.strictPort: true,因此端口 3000 被占用时会明确 失败,而不是由 Rsbuild 悄悄把界面挪到一个未被放行的端口。

    哪些内容会被代理。 只有 /api,每一条类型化的 Workbench 客户端路由,加上 /api/project/events SSE 流,会被转发到前台服务器。HTML 文档、JavaScript 与 CSS,以及 HMR websocket 都来自 Rsbuild 服务器。 MCP App 预览的 iframe 绑定在前台 origin 上:App 沙箱只与前台 URL 交换 postMessage 帧。它们不在这个 循环的覆盖范围内,要开发那些页面,请直接打开前台 URL 本身(上例中为 http://127.0.0.1:3100)。

    origin 规则。 代理绝不会改写 Origin(Rsbuild 的 changeOrigin 只改写 Host),因此只要浏览器 发送了 Origin,每一次变更请求都会,前台服务器看到的就是 Origin: http://localhost:3000,而不是它 自己的 origin。--workbench-dev-origin <origin>(可重复;以编程方式则为 startDevServer({ workbenchDevOrigins }))让它除自身 origin 之外,还接受 Origin 为所列 origin 之一的 会话引导(GET /api/project/session)、变更(带 x-agent-bundle-session token 的 POST/DELETE)与 项目事件流(GET /api/project/events,会话 cookie)请求。其他任何 origin 仍是 AB8003,/mcp 上 Agent API 的 origin 规则也保持不变。每个取值都必须是裸的 loopback http: 或 https: origin, localhost、127.0.0.1 或 [::1],例如 http://localhost:3000,不带路径,否则前台服务器拒绝启动 (agent-bundle dev 会在开始服务之前退出;startDevServer 以代码 AB8000 拒绝)。当列表非空时, GET /api/project/session 还会额外返回 devOrigins: [...](该响应体中的 origin 仍是前台 URL),而 Workbench 界面会在页面 origin 等于前台 origin、或出现在 devOrigins 中时接受该会话。不带该标志时,这道守卫逐字节保持不变:这份放行列表绝不会 默认开启。

    Origin 守卫保护 loopback 前台服务器不受来自任何其他 origin 的请求伪造,包括其他 loopback origin (MCP App 沙箱 iframe 在独立的 loopback 端口上运行第三方插件代码,而 Rsbuild 开发服务器的默认 CORS 策略 放行所有 loopback origin),因此这份放行列表只点名你自己的那个 Rsbuild origin,并且前台看到的仍然是浏览器 真实的 Origin。

    不带 --workbench-dev-origin 时,位于 http://localhost:3000 的界面会以 AB8003 拒绝自己的引导 (会话响应体中写的是前台 origin,而不是页面的 origin),并停留在"Foreground connection unavailable" 门控页上,显示 AB8003 — Origin http://localhost:3000 is not allowed by the foreground server at http://127.0.0.1:3100. Open http://127.0.0.1:3100 instead, or start agent-bundle dev with --workbench-dev-origin http://localhost:3000 to allow this origin.。门控页只在前台响应本身失败时才会 追加 (HTTP <status>),例如前台回以 403 的 AB8003 会显示为 AB8003 — Request origin is not this foreground server. (HTTP 403),因此不带标志时这一行没有状态码: 前台回应的是 200,是界面拒绝了该响应体。页面保持打开时不带标志重启前台,最终也会停在同一行不带状态码的 AB8003 — Origin …:门控页先报告 Foreground project event stream disconnected.,待重连自身的 200 引导被界面 拒绝后再显示这条拒绝信息。前台仍会以 AB8003 拒绝携带该 Origin 的变更请求。前台 URL 本身无论如何都照常工作。

    什么变了

    • Overview 状态移入了持久页眉与 Problems。
    • Routes、Hooks、Skills 与 MCP 预览移入了 Application 叶子。
    • 事件重放移入了事件路由与 Trace;脚本执行移入了 Script 叶子。
    • Evals 与对比变成了 Advanced → Evals → Runs / Compare;artifact、protocol、host diagnostics 与 raw logs 也移到了 Advanced 下。

    下一步

    • 测试:Workbench 所演练表面背后的证明级别。
    • 评测:Advanced 下的 eval 运行与对比。