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/start/project-structure.md.
跳至主要内容
  • 简体中文
  • 项目结构

    Agent Bundle 项目就是普通的 Node 包,加上一份 agent-bundle.config.ts 和约定式源码树。 只创建插件需要的文件:静态 Skill 不需要 MCP 服务器,工具不需要浏览器 App,App 也不需要自己的服务器注册表。

    约定负责发现应用,配置提供身份、策略和显式例外。 冲突声明会产生诊断,而不是一律按“配置总是胜出”静默处理。

    目录布局

    下面是复合插件的示意结构,不是最小模板。这里是普通的手写源码;宿主清单和可执行包装器属于生成输出。

    my-plugin/
    ├── agent-bundle.config.ts
    ├── package.json
    ├── tsconfig.json
    ├── assets/                         # 可选静态资源
    ├── src/
    │   ├── mcp/ops/
    │   │   ├── tools/
    │   │   │   ├── inspect.tsx          # 唯一操作实现、schema 和 Agent 文档
    │   │   │   └── inspect.cli.ts       # 该操作的可选 CLI 投影
    │   │   ├── resources/policy.tsx     # MCP 资源
    │   │   ├── prompts/review.tsx       # MCP 提示
    │   │   ├── apps/dashboard.tsx       # 浏览器入口,不是 Agent Server Component
    │   │   └── layout.tsx               # 可选的共享智能体文档布局
    │   ├── events/tool/
    │   │   ├── before.tsx               # tool/before 语义事件路由
    │   ├── hooks/session-start.ts       # 由配置引用的可选普通钩子
    │   ├── skills/review/SKILL.md
    │   ├── commands/review.md           # 可选原生提示或命令文档
    │   ├── rules/project.mdc           # 可选且宿主支持的规则
    │   ├── cli/doctor.tsx               # 真正独立的 CLI 工作流
    │   ├── scripts/check-service.ts     # 普通产物脚本
    │   ├── providers/project.ts         # 可选请求依赖
    │   ├── state.ts                     # 可选框架状态定义
    │   ├── layout.tsx                   # 可选根文档布局
    │   ├── components/                  # 普通可复用呈现代码
    │   ├── domain/                      # 普通业务逻辑、客户端与策略
    │   └── install-bin.ts               # 可选包绑定安装器的委托入口
    └── tests/
        ├── route-unit/
        └── projection/

    这份结构中没有手写的 application.ts 注册表、生成式 MCP 入口或原生钩子 JSON;框架按需生成它们。 domain/ 和 components/ 只是代码组织方式,不是新的框架约定。 预构建的非 TypeScript 资源或原生可执行文件应显式声明为 payload,不能假定任意源码目录都会被交付。

    各个根目录的含义

    路径含义重要边界
    src/mcp/<server>/tools/*.{ts,tsx}生成式服务器上的工具。渲染式工具导出 schema、可选静态 config 和默认组件,不需要手工注册。
    src/mcp/<server>/tools/<tool>.cli.ts同目录工具的命名 CLI 投影。复用工具,不是另一条 MCP 路由;可选 mapInput 改变 CLI 输入映射,而不是操作注册表。
    src/mcp/<server>/resources/* 与 prompts/*MCP 资源与提示。它们不是工具,协议元数据和结果契约不同。
    src/mcp/<server>/apps/*.{ts,tsx}浏览器 App 入口。声明 config.resourceUri,框架编译并注册自包含 HTML。
    src/events/**已支持的语义事件路由,例如 tool/before。路径必须对应支持的事件族,不是任意事件总线主题;原生 envelope 由 adapter 负责。
    src/hooks/*.tshooks 配置引用的普通处理器。目录本身不会注册它们;使用公开的 HookHandler 契约,不需要 JSX 或自定义 stdin 包装器。
    src/skills/<name>/SKILL.md静态 Skill 及其资源文件。不需要渲染 runtime 即可交付;渲染式和宿主专属形式见 Skills。
    src/commands/*.md原生命令或提示文档。不是 src/cli/ 命令;可用性和 frontmatter 取决于宿主。
    src/rules/*.mdc宿主支持的规则文档。选中了 target,不代表它支持规则。
    src/cli/**/*.{ts,tsx}独立的路由式 CLI 命令。嵌套就是命令路径;如果是同一个工具操作,优先用工具的 .cli.ts 投影。
    src/scripts/<name>.ts / .tsx普通或渲染式产物脚本。脚本是扁平的;共享辅助代码放在约定根之外或私有路径下;渲染式脚本接收 argv 和 signal。
    src/providers/<name>.{ts,tsx}请求上下文 provider。通过 agent() 读取生成的 provider 值,不再添加全局服务注册表。
    src/state.ts可选 defineState 声明。框架状态是可选能力,不接管领域数据库;state: false 禁用发现。
    src/layout.{ts,tsx}根 Agent 文档布局。包裹渲染式路由,不包裹原生事件响应或浏览器 App。
    src/mcp/<server>/layout.{ts,tsx}根布局内的服务器文档布局。作用于该生成式服务器的路由。
    assets/约定式静态资源。复制到产物的 assets/ 下;显式配置可以收窄选择。

    以 _ 或 . 开头的私有路径段和声明文件不参与路由发现。 事件文件使用 .ts 返回轻量结果,使用 .tsx 渲染 JSX;需要渲染前门控时,从 .ts 处理器调用 ctx.render() 请求同级 .view.tsx。 执行方式与 provider 访问见钩子。

    路由元数据使用有界静态语法。工具把它放入 defineTool 的内联对象;资源、提示、App 与兼容路由继续使用 config 导出。运行时工作保留在处理器或领域模块中,Schema 保持唯一权威定义,不要在 CLI 和浏览器里 分别重建协议类型。

    添加交互式 App

    工具中的 Agent.* JSX 描述面向智能体的文档;MCP App 入口在浏览器中运行,拥有自己的 DOM 或 React UI。 不要把服务器路由导入浏览器,这会把 Node API、领域服务和仅供服务器使用的依赖带入错误的运行环境。

    使用已有的 App 资源绑定连接两者。对于 src/mcp/ops/apps/dashboard.tsx,在浏览器入口中声明资源 URI:

    import type { AppRouteConfig } from 'agent-bundle';
    
    export const config = {
      resourceUri: 'ui://my-plugin/dashboard.html',
    } satisfies AppRouteConfig;

    这只是浏览器入口的元数据,不是完整 UI。默认 HTML 提供 #root;启动代码需要其他外壳时使用显式模板。 工具可以引用 App,而不重复写 URI 字符串:

    // Metadata in src/mcp/ops/tools/inspect.tsx
    import { appResourceUri, defineTool } from 'agent-bundle/routes';
    
    export default defineTool({
      description: 'Inspect project status.',
      annotations: { readOnlyHint: true },
      _meta: { ui: { resourceUri: appResourceUri('dashboard') } },
      inputSchema,
      resultSchema,
    }, handler);

    浏览器使用 agent-bundle/app 的 createAppClient。 它的 opening-input、result、error 监听器及工具调用就是集成边界;不要重新实现 postMessage 传输、 请求 ID 映射或 MCP 客户端。在连接之前注册 opening 监听器。 使用宿主提供的初始调用结果进行渲染,不要在挂载时自动重跑一次修改性操作。 所属 UI 退役时释放客户端和订阅。

    生成的路由声明提供 App 调用类型;它们必须是最新的,并且被浏览器的 TypeScript 项目包含。 这不能替代对不可信数据的运行时校验。导入是浏览器安全的前提下,可以共享纯呈现组件与已验证数据。 Node 渲染的文档组件不会仅因为也使用 JSX,就自动成为 DOM 组件。

    要通过可选的生产浏览器表面暴露同一个 App,在 web.apps 中配置已有的 server/app 身份和初始工具。 不存在第二份 src/web/ 注册表。完整示例与策略见 MCP 服务器与 Apps、可工作的 App 示例及 web 配置。浏览器呈现方式与启动服务器的宿主投影是两个不同选择。

    配置与约定

    约定式起点仍然很小:

    import { 
    const defineConfig: (config: AgentBundleConfig | ConfigFactory) => AgentBundleConfig | ConfigFactory
    defineConfig
    } from 'agent-bundle/config';
    export default
    function defineConfig(config: AgentBundleConfig | ConfigFactory): AgentBundleConfig | ConfigFactory
    defineConfig
    ({
    AgentBundleConfig.plugin: AgentBundlePluginConfig
    plugin
    : {
    AgentBundlePluginConfig.name: string
    name
    : 'my-plugin',
    AgentBundlePluginConfig.description?: string | undefined
    description
    : 'Project tools for an agent.' },
    AgentBundleConfig.targets?: string[] | undefined
    targets
    : ['portable', 'claude', 'codex'],
    });

    仅对约定无法表达的内容增加显式配置,例如指定 target 的普通钩子、预构建 payload、远程服务器、 非标准路径、包专用 bin 或策略。必需能力仍需要支持它的宿主,或者明确限制目标范围。

    手写的 src/mcp/<server>.ts 是已声明服务器的互操作路径。 与同名生成式路由共存时,需要明确决定模式,而不是依赖文件系统顺序。 同理,src/cli.ts 与 src/cli/ 是两种备选 CLI 模式。 src/index.ts 是可选库入口,不是应用注册入口;bin: false 和 lib: false 可以退出这些包约定。

    声明故意偏离约定时,检查实际路由图,而不是猜测哪个文件胜出:

    npx --no-install agent-bundle inspect --routes
    npx --no-install agent-bundle validate

    正确的编译器必须已经安装到当前项目中。 源码选择与迁移诊断的细节见配置和包入口。

    输出落在哪里

    区分以下职责:

    位置所有者与用途
    src/、配置、package.json手写应用与包身份。
    .agent-bundle/生成的路由声明与开发基础设施,不是手写注册表,也不是持久化应用数据的契约。
    默认的 artifact/已校验的组合插件树。
    启用包输出时的 dist/生成的 npm 根目录:产物字节,加上包元数据和包专用入口。
    解析后的可写状态根框架状态与应用明确选择的数据位置,和已安装代码分离。

    复合插件根目录

    产物示意如下:

    artifact/
    ├── agent-bundle.manifest.json
    ├── agent-bundle.compile-evidence.json
    ├── INSTALL.md
    ├── .claude-plugin/          # 所选宿主清单
    ├── .codex-plugin/
    ├── .cursor-plugin/
    ├── .amp/plugins/<name>/     # 选择 Amp 时的原生目录插件
    ├── plugin.json             # 选择 portable 时的清单
    ├── mcp/                    # 编译后的服务器入口及其 runtime 文件
    ├── hooks/                  # 生成的原生包装器与钩子文档
    ├── bin/<plugin-name>.mjs    # 声明后生成的路由 CLI / web 可执行文件
    └── skills/, scripts/, assets/, mcp-apps/, ...

    只有已声明的相关表面才会输出。精确的原生文档和其他 runtime 文件由清单记录; 应用代码不应该根据这张示意图重新推断可执行文件清单。 不存在 artifact/<host>/ 分区。Amp 使用嵌套的原生目录,而框架的清单感知安装入口接受组合根, 并选择正确的宿主表面。

    output.distPath 或 CLI --output 移动组合根,不改变其内部布局。 CLI 优先级是 --output、配置、默认 artifact/。 编程式 build() API 的包输出与默认行为另有约定;应查阅它的参考,不要把 CLI 默认值复制到自定义构建中。

    清单记录文件摘要和规范的可执行文件身份。重排 targets 不会创建另一个应用。 字节冲突或意外的跨宿主发现应通过校验解决,不应通过手改生成清单修复。 见 Target 与产物。

    npm 包构建

    dist/ 是完整的生成式 npm 包根目录,不只是 JavaScript 文件夹:

    dist/
    ├── package.json                  # 生成的包相对路径与 bin 映射
    ├── agent-bundle.manifest.json
    ├── INSTALL.md
    ├── ...                          # 原样复制的组合产物
    ├── bin/<plugin-name>.mjs         # 同一个生成式路由 CLI(如果存在)
    ├── bin/<authored-bin>.js         # 可选的显式包专用可执行文件
    └── <library>.js, <library>.d.ts  # 可选库输出

    路由式 CLI 不会为 npm 再编译一份竞争的 .js 实现;生成的 package.json 指向产物中的可执行文件。 显式包专用 bin 与库入口是不同的输出,仍有自己的编译过程。

    组合输出与 npm 输出不得重叠:包输出已使用 dist/ 时,再把产物放到那里是无效配置。 构建输出不是源码输入。应打包生成的 npm 根,而不是源码仓库或猜测的 dist/artifact/ 嵌套目录。 校验与安装流程见交付捆绑包。

    可写状态不是已安装代码

    请求内部使用框架提供的 plugin/context 绑定。独立代码可使用公开的 runtime resolvePluginRoot, 它区分 root 与 stateRoot;AGENT_BUNDLE_STATE_ROOT 独立于代码根覆盖值。

    不要因为加载器位于已安装代码树中,就把运行时缓存、刷新后的凭据或数据库也放在那里。 应用数据保留自己的 schema、显式迁移和覆盖策略,并且不能与框架存储冲突。 框架不会自动接管或清除任意插件数据。 见配置与状态和安装生命周期。

    下一步

    快速开始运行一条真实约定路由。 Skills、钩子、MCP和 脚本与资源说明各表面契约。 编译器架构用于理解实现细节,不是额外的设置步骤。