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

122 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 规划目录
本文描述 `Kernel + Extensions` 架构下的源码与运行数据目录。目录服务于依赖关系和可理解性,不要求为尚未实现的能力预建空 package。
## 源码仓库
当前采用一个 TypeScript package
```text
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 同时启用一个或多个产品入口:
```ts
const factories = [
...sharedExtensions,
...product.extensions,
];
```
清单使用 Factory 而不是复用 Extension 实例,避免多个 Kernel 或测试之间共享可变生命周期状态。产品逻辑一律留在对应 Extension 中。
## Package 调整原则
当前单包能够提供最短依赖链和最低维护成本。满足以下真实需求之一时,才将目录提升为独立 package
- Web 或 Desktop 构建工具无法与 Runtime 共用配置;
- 原生依赖或平台依赖需要单独安装;
- 能力需要独立测试、版本、分发或进程隔离;
- 单包依赖导致实际构建或启动成本无法接受。
拆包只改变物理构建边界,不改变 `products → extensions → kernel` 的依赖方向。
## Supervisor 目录
Supervisor 到 P3 自进化发布闭环时再建立。它必须位于当前 Runtime 发布物之外,才能在新 Kernel 启动失败时切回旧版本,但它不是 Runtime 内部的第三种架构模块。
## 运行数据目录
运行数据不进入源码仓库:
```text
~/.agent/
├── tasks/
├── registry.json
├── extensions/ # 本地安装的扩展
├── releases/ # Installed Releases
├── runtime/
└── config/
```
Project 专属 Agent 数据位于项目根目录的 `.agent/`。候选 worktree 和 Installed Release 由 `~/.agent/` 下的运行数据管理。
## 调整判断
- 新功能默认进入某个 Extension
- 多个 Extension 需要同一种不可绕过的机制时,才调整 Kernel
- 两个产品线复用私有代码时,将复用部分提升到 `shared/`
- 目录需要独立构建或发布时再拆 package
- 调整后同步文档,但不保留没有实际价值的兼容层。