llm-to-agent/docs/directory-plan.md
2026-07-23 17:49:50 +08:00

5.4 KiB
Raw Blame History

规划目录

本文描述 Kernel + Extensions 架构下的源码与运行数据目录。目录服务于依赖关系和可理解性,不要求为尚未实现的能力预建空 package。

源码仓库

当前采用一个 TypeScript package

llm-to-agent/
├── src/
│   ├── kernel/
│   │   ├── kernel.ts          # 生命周期与总入口
│   │   ├── extension.ts       # Extension 契约与扩展点
│   │   ├── registry.ts        # Extension 注册的能力
│   │   ├── events.ts          # 运行事件
│   │   └── ...                # 后续 Space、Conversation、Run、Store、权限等稳定机制
│   │
│   ├── extensions/
│   │   ├── shared/            # 跨产品公共能力
│   │   ├── cli/               # CLI 私有能力
│   │   ├── web/               # Web 私有能力
│   │   └── desktop/           # Desktop 私有能力
│   │
│   ├── products/
│   │   ├── product.ts         # 产品定义
│   │   ├── index.ts           # 产品查找
│   │   ├── shared.ts          # 公共 Extension 装配清单
│   │   ├── cli.ts             # CLI 私有装配清单
│   │   ├── web.ts             # Web 私有装配清单
│   │   └── desktop.ts         # Desktop 私有装配清单
│   │
│   └── main.ts                # 创建 Kernel 并执行装配
│
├── docs/
├── tests/                     # 跨进程或跨版本测试
├── tooling/                   # 构建和开发辅助
├── package.json
└── tsconfig.json

单元测试与所属源码放在一起。

Kernel 目录

src/kernel/ 只保存所有能力共同依赖的稳定运行机制。首批内容是 Extension 生命周期、能力注册和事件Space、Conversation、Run、Store、取消、权限等在对应功能实际实现时进入。

Kernel 不导入 src/extensions/src/products/。具体能力流入 Kernel 的唯一方式是安装 Extension 后注册公开抓手。

Extensions 目录

Extension 按完整能力纵向组织,不按 Adapter、Tool、Hook、Behavior 等技术名词横向切分。

例如未来的 shared/browser/ 可以同时包含浏览器连接、可调用能力、运行事件处理和自己的测试;无需把同一能力拆散到四种模块目录。

只有真实能力开始开发时才创建目录和源码。README 可以说明边界,但不再使用空 index.ts、空 package 或预留导出伪造进度。

公共与产品私有边界

  • shared/:不认识单一产品界面,并可被至少两条产品线或后台 Runtime 能力复用;不要求三条产品全部启用。
  • cli/终端输入、ANSI 渲染、REPL、斜杠命令和 TUI。
  • web/HTTP 接入、事件流、路由、页面与受控远程访问。
  • desktop/:窗口、原生桥接、托盘、快捷键、通知、安装与更新。

产品私有目录不能互相依赖。Web 和 Desktop 共用的聊天界面、状态或组件应进入 shared/ 下的合适能力目录Desktop 不直接引用 web/ 私有实现。

CLI 与 Desktop 需要进程外启动器时,启动器源码可以与该产品的私有 Extension 放在同一能力目录中,但必须保持轻量:只负责 Runtime 拉起、连接和输入输出转发,不能复制状态与 Agent 执行逻辑。

这里的“私有”表示产品归属,不自动构成权限边界。若未来需要限制某项能力只对特定产品可见,再由 Kernel 提供通用作用域机制,而不是硬编码三个产品名。

Products 目录

src/products/ 只负责选择 Extension Factory并允许 Runtime 同时启用一个或多个产品入口:

const factories = [
  ...sharedExtensions,
  ...product.extensions,
];

清单使用 Factory 而不是复用 Extension 实例,避免多个 Kernel 或测试之间共享可变生命周期状态。产品逻辑一律留在对应 Extension 中。

Package 调整原则

当前单包能够提供最短依赖链和最低维护成本。满足以下真实需求之一时,才将目录提升为独立 package

  • Web 或 Desktop 构建工具无法与 Runtime 共用配置;
  • 原生依赖或平台依赖需要单独安装;
  • 能力需要独立测试、版本、分发或进程隔离;
  • 单包依赖导致实际构建或启动成本无法接受。

拆包只改变物理构建边界,不改变 products → extensions → kernel 的依赖方向。

Supervisor 目录

Supervisor 到 P3 自进化发布闭环时再建立。它必须位于当前 Runtime 发布物之外,才能在新 Kernel 启动失败时切回旧版本,但它不是 Runtime 内部的第三种架构模块。

运行数据目录

运行数据不进入源码仓库:

~/.agent/
├── tasks/
├── registry.json
├── extensions/       # 本地安装的扩展
├── releases/         # Installed Releases
├── runtime/
└── config/

Project 专属 Agent 数据位于项目根目录的 .agent/。候选 worktree 和 Installed Release 由 ~/.agent/ 下的运行数据管理。

调整判断

  • 新功能默认进入某个 Extension
  • 多个 Extension 需要同一种不可绕过的机制时,才调整 Kernel
  • 两个产品线复用私有代码时,将复用部分提升到 shared/
  • 目录需要独立构建或发布时再拆 package
  • 调整后同步文档,但不保留没有实际价值的兼容层。