# 项目结构

pi-kit 是一个 Pi 工具集包，工具 UI 是其中一个模块。按职责组织实现，而不是把所有功能都放进入口文件，也不按每个功能拆成独立 npm 包。

## 目录布局

```text
index.ts                         # 旧路径兼容与原有公开导出
extensions/
└── index.ts                     # Pi 扩展 factory：加载配置、装配、注册
src/
├── config.ts                    # liuovo.json 持久化、串行原子保存、显示偏好
├── config/open-tui.ts           # 外观配置类型、默认值、规范化（无 UI 依赖）
├── commands/
│   ├── liuovo.ts                # 唯一 /liuovo 命令、面板保存与操作事务
│   └── setup.ts                 # setup / teardown 确认、通知与 reload
├── tools/
│   ├── composition.ts           # 原生工具定义、reasoning 包装、Write diff 捕获
│   └── imagegen.ts              # generate_image 执行、图片落盘与结构化结果
├── integrations/
│   └── pi-fff/
│       ├── controller.ts        # 启动路由与集成状态
│       ├── adapter.ts           # 校验源工具、注册计划与执行转发
│       ├── integration.ts       # settings 所有权、日志、setup / teardown 恢复
│       ├── loader.ts            # 使用运行中 Pi 的模块加载与依赖映射
│       └── profiles.ts          # 支持的 FFF 包、版本与能力声明
└── ui/
    ├── settings.ts             # 复用上游分页面板；仅绘制和键盘交互
    ├── shell/                  # Open TUI 展示与生命周期
    │   ├── index.ts            # 注册展示事件；返回设置应用/关闭回调
    │   ├── header.ts           # Pi Header、模型/思考级别和命令提示
    │   ├── footer.ts           # 响应式底栏及内联底栏
    │   ├── editor.ts           # CustomEditor 边框、光标、思考预览挂载
    │   ├── git.ts              # 只读 Git 状态探测
    │   ├── runtime.ts          # 项目运行环境探测及有界缓存
    │   ├── telemetry.ts        # 回合计时统计（不修改宿主 usage）
    │   ├── peek.ts             # 思考尾部预览状态和宽度限制
    │   ├── state.ts            # 底栏状态与 usage 读取缓存
    │   ├── session-lifecycle.ts # 会话代际与异步结果有效性
    │   ├── icons.ts            # 上游 Nerd/Unicode/ASCII 图标
    │   └── utils.ts            # 外观模块自己的格式化和布局函数
    ├── tools/
    │   ├── index.ts             # 注册 renderer、展示事件与共享刷新器
    │   ├── render.ts            # 工具标题、目标、状态和详情布局
    │   ├── block.ts             # 宽度感知组件、耗时与结果摘要
    │   ├── format.ts            # 文本统计与兼容的格式化函数
    │   ├── source.ts            # 源码行号、语法高亮与 diff 行
    │   └── nested.ts            # codemode 子调用观察、快照与展示
    ├── interaction/
    │   ├── index.ts             # TUI 绑定、刷新、清理与跨 reload 所有权
    │   └── viewport.ts          # 展开、收起时保持 fullscreen 视口锚点
    ├── status/
    │   └── title.ts             # 终端标题与 agent 活动状态
    └── theme.ts                 # 语义色、状态色与呼吸动画样式
themes/                          # Pi 可发现的 JSON 主题资源
vendor/                          # 第三方源码快照，保留来源与许可证
test/                            # 模块行为与宿主集成测试
scripts/                         # 测试运行器、打包检查、宿主与 TUI 验收
docs/                            # 项目结构与集成约定
.agents/skills/                  # 项目开发技能及其脚本，不是产品扩展
.upstream/                       # 上游来源、报告进度与评估报告
```

## Pi 入口与兼容

`extensions/index.ts` 导出 Pi 要求的默认 factory，接收 `ExtensionAPI`。它只负责选择和装配模块：无条件注册统一设置命令和独立的外观生命周期、初始化 FFF 路由，再按工具增强开关注册工具、工具 UI 和标题状态。外观关闭时仍保留设置入口；不注册独立的上游扩展或命令。

根目录 `index.ts` 是兼容入口，同时导出 `createLiuovoExtension`、`withReasoning`、`formatElapsed`、`toolBlock` 和依赖类型。`package.json` 的 `pi.extensions` 继续指向它，避免已有 `+index.ts` 等包资源过滤配置失效。

本地开发可用任一入口：

```bash
pi -e ./index.ts
# 或
pi -e ./extensions/index.ts
```

不要把两条路径同时加入配置。包清单只声明一条路径，因此正常包安装只注册一次。

`themes/` 保持为单独的 Pi 主题资源目录。`src/ui/theme.ts` 是运行时样式实现，不是可安装的主题文件，两者不要混放。

## 模块职责与依赖

- **`tools/` 管执行。** 接受 Pi 的工具上下文，处理参数、取消、文件操作、结果和 usage；不导入 UI 实现。原生工具的行为继续委托 Pi，图片生成继续使用 Pi 模型运行时。
- **`integrations/` 管外部包适配。** 包版本约束、加载器、注册校验和 settings 恢复集中在同一个集成目录。FFF 可以使用 `tools/composition.ts`，但不负责卡片样式。
- **`ui/` 管展示。** renderer、展示所需的有界元数据、TUI 交互、主题样式和标题状态放在这里。codemode 的执行、激活和计费仍由 Pi 管理。
- **`commands/` 管人的操作。** 打开面板、保存偏好、请求确认和 reload。面板挂载、外观应用、刷新与清理通过入口传入的回调完成；命令和 UI 仅通过配置模块中的共享面板数据契约通信，不相互导入；命令层不依赖 TUI 组件类。FFF 操作和 reload 在面板释放焦点后执行，不从已替换的 runtime 继续操作。
- **配置模块管共享配置。** `config.ts` 统一读写 `liuovo.json`，Open TUI 设置位于 `openTui` 字段。`config/open-tui.ts` 定义外观类型、默认值和规范化；UI 使用这些类型，配置模块不反向导入 renderer。不写独立的上游配置文件，启动不自动创建或改写用户配置。
- **入口管装配。** 不把命令处理、图片保存或具体绘制逻辑放回 `extensions/index.ts`。

依赖方向：

```text
extensions/index.ts
├── commands ──────── config、integrations
├── tools ─────────── Pi SDK
├── integrations ──── tools、Pi SDK、第三方包
└── ui ────────────── config、Pi SDK / pi-tui、vendor
```

## 新功能放哪里

| 新增内容 | 放置位置 | 注册位置 |
| --- | --- | --- |
| 模型可调用的工具 | `src/tools/<tool>.ts` | `extensions/index.ts` 中的 `pi.registerTool()` |
| 第三方包集成 | `src/integrations/<integration>/` | 入口选择和初始化 |
| `/` 命令 | `src/commands/<command>.ts` | 入口注册命令模块 |
| 工具卡片或摘要 | `src/ui/tools/` | 工具 UI 的 renderer 注册 |
| 键盘、鼠标或视口逻辑 | `src/ui/interaction/` | UI 的绑定与清理流程 |
| 标题或其它状态展示 | `src/ui/status/` | 入口注册状态模块 |
| 通用 UI 语义样式 | `src/ui/theme.ts` | 调用方使用当前 Pi 主题 |
| 可选择的主题资源 | `themes/<name>.json` | `package.json` 的 `pi.themes` |

单文件功能先保持单文件。只有实现确实变大、需要集中多份相关代码时，再改成目录；例如更复杂的源码浏览或 diff UI 可以从 `source.ts` 拆出专用模块。不要为未来功能先创建空目录、插件管理器或全量导出的 barrel 文件。

公共代码优先留在拥有它的模块里。两个以上模块确实共享、且职责清楚时再提取；不要把工具摘要、配置 IO 和集成校验一起塞进 `utils/`。

## 上游评估

`upstream` 项目技能负责登记迁移来源、参考项目及 Pi 等宿主依赖，生成增量变更评估，不自动更新实现。脚本随技能放在 `.agents/skills/upstream/scripts/`，便于在其他项目复用；`npm run upstream -- --help` 查看操作接口。

`.upstream/sources.json` 是来源、报告游标与候选处置的权威记录；`.upstream/reviews/` 保存可追溯报告，缓存位于自带忽略规则的 `.upstream/cache/`。技能和台账属于开发资源，不随 npm 包发布。报告进度不代表代码已同步或升级。

## 测试与发布

测试保留 `test/` 的现有文件名与运行方式，导入指向 `src/` 与 `extensions/` 下的实现。命令行为仍通过扩展注册接口验收；`entrypoint.test.ts` 验证新旧入口和公开导出一致。

- `tsconfig.json` 检查 `extensions/`、`src/`、兼容入口和 vendor。
- `package.json.files` 按目录发布源码，不再逐个列举根目录实现文件。
- `scripts/test-pack.mjs` 验证新目录被打包、旧实现路径不再发布，并在解压后的包中加载两个入口。
- 修改模块后运行 `npm run check`、`npm test`、`npm run test:pack`。
- 涉及宿主注册或 UI 生命周期时，再运行 `npm run test:host-smoke` 与 `npm run test:tui`；FFF 的网络验收见 [FFF 文档](pi-fff.md)。

Pi 行为基线见 [Pi 1.1 集成约定](pi-1.1.md)；上游来源、迁移文件映射和适配点见 [Open TUI 迁移记录](open-tui.md)。当前实现位置以本文为准。
