# 仓库说明

本仓库用于维护可通过一次 `pi install` 部署的个人 Pi 扩展组合包。根 `package.json` 是唯一的组合包安装入口；根 `install.sh`、`update.sh` 和 `uninstall.sh` 只是对 `pi install` / `pi update` / `pi remove` 的便捷包装，不形成第二套部署机制。依赖、默认行为和必要配置必须由组合包自身声明或部署，不把安装后的手工配置作为默认流程。每个自维护扩展使用独立的顶层目录，扩展源码、测试和说明应保留在各自目录内。

## 当前扩展

- `pi-rtk-optimizer/`：默认只负责非搜索工具输出压缩；RTK 命令改写为可选能力。
- 上游来源：<https://github.com/MasuRii/pi-rtk-optimizer>
- 初始导入快照：`d155d253cb2f1358e34e717d47a82ebccb08cb8e`（2026-07-03，`0.9.0`）。
- 该目录已纳入本仓库直接维护，不是 submodule，也不保留嵌套 `.git`。
- `pi-ssh/`：从上游源码导入并由根组合包加载的纯 `ssh2` 远程操作扩展，通过受权限链复核的 `ssh_connect` 建立 Agent 控制的持久连接，并以 SFTP 与有界自适应搜索提供独立的 `ssh_read`、`ssh_write`、`ssh_edit`、`ssh_find`、`ssh_grep` 与 `ssh_bash` 工具；运行时不调用 OpenSSH 或 `sshpass`。
- 上游来源：<https://github.com/pansapiens/pi-ssh>
- 初始导入快照：`e9a1059a0f37ab14b6a73ee608cb203edf803f31`（2026-06-23，`0.7.0`）。
- 该目录已纳入本仓库直接维护，不是 submodule，也不保留嵌套 `.git`、`node_modules` 或构建产物；纯 `ssh2` 设计参考 `99percentpeople/pi-extensions` 的明确 commit，来源记录保留在 `pi-ssh/UPSTREAM.md`。
- `pi-permission-auto-review/`：作为 `pi-permission-system` 的 `auto-review` authorizer，使用 Codex Guardian 风格策略复核权限基线产生的 `ask`。
- 上游来源：<https://github.com/mzwing/pi-packages/tree/main/packages/pi-permission-auto-review>
- 初始导入快照：`8d196e4ef0884cac8326c366191dad3f585d470a`（`@mzwing/pi-permission-auto-review@0.2.0`）。
- 该目录从上游源码仓库导入并由本仓库直接维护，不使用 npm 预编译产物，不是 submodule，也不保留嵌套 `.git`。
- `pi-permission-system/`：提供工具、路径、MCP、Skill、子代理转发与 authorizer chain 的确定性权限基线。
- 上游来源：<https://github.com/gotgenes/pi-packages/tree/main/packages/pi-permission-system>
- 初始导入快照：`ec4fdb11343dc94f7185b113e559a4cf9f8dc035`（`pi-permission-system-v26.2.1`）。
- 该目录从明确 tag 的上游源码导入并由本仓库直接维护，不使用 npm 预编译产物，不是 submodule，也不保留嵌套 `.git`。
- `extensions/fff-override.ts`：强制使用 FFF 官方 `override` 模式，统一接管 `find`、`grep`、`multi_grep` 和 FFF 的 `@` 补全；显式 CLI flag 仍遵循 FFF 官方优先级。
- `extensions/tavily-override.ts`：加载 `@tavily/pi-extension`，把上游工具重命名为 `tavily_web_search` / `tavily_web_fetch`，并同步改写 label 与工具提示中的内部名称。
- `@keenable/pi-search`：加载 `keenable_search` / `keenable_fetch` 及其 skill，默认 keyless，`KEENABLE_API_KEY` 仅用于提高速率限制。
- `search_config.sh` 与 `extensions/search-config.ts`：以交互式或参数方式把三家搜索 key 写入用户级 `search.env`（权限 `600`），并在搜索扩展初始化前加载；显式进程环境变量优先。
- `extensions/mcp.ts`：通过单个共享 `pi-mcp-adapter` 实例同时连接 Exa 托管 MCP 与机器现有的 `codegraph serve --mcp`，避免重复注册 Pi 的全局 MCP flag 与命令；Exa key 只通过 `x-api-key` 请求头发送，原始工具映射为统一的来源前缀形式，CodeGraph 只暴露 `codegraph_explore`。
- `extensions/plugin-init.ts`：注册用户显式触发的 `/plugin_init`，在确认当前项目后只初始化缺失的 CodeGraph/Hippo 状态，并在全部成功后调用 Pi 官方热重载。
- `context-mode`：加载上游 Pi adapter 与 skills，提供 `ctx_*` 工具、隔离式大输出处理和会话连续性。
- `extensions/hashline.ts`：部署组合包权威 `config/pi-hashline-edit.json` 后加载 `pi-hashline-edit`，以行哈希锚点覆盖内置 `read` / `edit`；Hashline 自带 `grep` 强制关闭。
- `extensions/permission-system.ts`：直接加载仓库内 `pi-permission-system/src/index.ts`，并在权限扩展注册前将 `config/pi-permission-system.json` 同步为全局权威配置。
- `extensions/lsp.ts`：把组合包内 TypeScript Language Server CLI 物化为绝对命令路径，部署 TypeScript/Kotlin/JDT LS 全局配置并加载 `pi-lsp`。
- `extensions/tool-routing.ts`：保留 Pi 默认系统提示词，在每轮开始前按激活工具追加简短路由规则，并提供 `/dump-system-prompt` 将扩展所见的有效提示词写入 `.pi-debug/effective-system-prompt.md`。
- `pi-tool-search/`：从上游 `v0.3.6` 源码导入并由本仓库直接维护；从完整工具定义生成并缓存经过校验的 Tool Cards/工作流分组，通过固定工具 + 有界动态组 LRU 加载当前 Pi 的原始 schema。
- 上游来源：<https://github.com/tuansondinh/pi-tool-search>
- 初始导入快照：`ddfb23646fd3957b791214de278e23aa393c9b13`（`v0.3.6`）。
- 该目录不是 submodule，不保留嵌套 `.git`、上游 `.pi` 状态、`node_modules` 或构建产物。
- `pi-ask-user/`：把 Pi 上游 `question.ts` 与 `questionnaire.ts` 示例整合为模型主动调用的 `ask_user_question` 工具，统一支持单题、多题、选择、自由文本、自定义回答与复核；不加载 `/qna`。
- 上游来源：<https://github.com/earendil-works/pi/tree/main/packages/coding-agent/examples/extensions>
- 初始参考快照：`dcd461925db2edf69a43c8135db1180d418afd54`（2026-08-24）。
- 该目录由本仓库直接维护，保留上游 MIT 许可证与来源说明；根组合包直接加载源码并通过本地 `file:` 依赖打包。
- `pi-lsp@0.1.7`：提供声明式 LSP 接入；组合包内置 `typescript-language-server@5.3.0` + `typescript@6.0.3`，并配置机器级 `kotlin-lsp --stdio` 与 `jdtls`。
- `hippo-memory-pi/`：从官方 `hippo-memory` 仓库的 `extensions/pi-extension/` 导入并由本仓库直接维护；提供 session start 项目记忆注入、工具错误过滤捕获、session shutdown sleep 和 5 个 `hippo_*` 工具。
- 上游来源：<https://github.com/kitfunso/hippo-memory>
- 初始导入快照：`e928179a3b35e8fe5837878aed071d6025ced45c`（`v1.33.0`）。
- 官方 npm tarball 不包含 Pi Extension；仓库保留官方 README、LICENSE 和来源说明，匹配 CLI 版本由 `config/hippo-memory-version` 声明。
- `@ogulcancelik/pi-codex-compaction@0.1.3`：为 `openai-codex` 提供原生远程 compaction，默认阈值为 90%。
- `pi-minimal-footer/`：基于上游紧凑 footer，保留上下文仪表、订阅用量条和扩展状态，并在 Codex Fast 模式开启时显示 `Fast on`。
- 上游来源：<https://github.com/ogulcancelik/pi-extensions/tree/main/packages/pi-minimal-footer>
- 初始导入快照：`77bd1e175003cd08e6d05d9e7fed695f86ae87b7`（`@ogulcancelik/pi-minimal-footer@0.1.10`）。
- 该目录从明确 commit 的上游源码导入并由本仓库直接维护，不使用 npm 预编译产物，不是 submodule，也不保留嵌套 `.git`。
- `pi-extension-codex-fast-mode/`：为符合条件的 Codex Responses 请求设置 priority service tier，并把新会话默认值跨会话持久化。
- 上游来源：<https://github.com/Firstp1ck/pi-coding-agent-forge/tree/main/pi-extension-codex-fast-mode>
- 初始导入快照：`f1d0efd24a7f4ae99d19e10c5f4c3770a3bdd845`（`@firstpick/pi-extension-codex-fast-mode@0.1.1`）。
- 该目录从上游源码仓库导入并由本仓库直接维护，不使用 npm 预编译产物，不是 submodule，也不保留嵌套 `.git`。
- `pi-condense@2.9.1`：总结已完成的工具调用批次，以短 stub 替换历史原始输出，并通过 `context_tree_query` 按需恢复；组合包在用户尚未配置 `contextPrune.enabled` 时默认开启。
- 根包还固定安装 `@tavily/pi-extension@0.1.2`、`@keenable/pi-search@0.1.2`、`pi-hashline-edit@0.8.3`、`typescript-language-server@5.3.0`、`typescript@6.0.3` 和 `pi-context-view`；`@firstpick/pi-extension-codex-fast-mode`、`@gotgenes/pi-permission-system`、`pi-ask-user`、`pi-minimal-footer`、`pi-ssh` 与 `pi-tool-search` 分别指向仓库内对应目录的本地 `file:` 依赖。
- `install.sh`：先安装根组合包，再交互检查 Hippo Memory CLI、Kitty/Solarized Dark、Oh My Zsh/Powerlevel10k/Zsh 插件、CodeGraph、Kotlin LSP、Java 21+ 和 JDT LS；缺失项目只在用户明确选择 `Y` 后安装或配置。Hippo 项目目录与 `hippo init` 始终由用户自行决定。Powerlevel10k 默认配置来自仓库内置的 `config/p10k.zsh`（当前 Rainbow/ASCII 单行紧凑主题）。
- `update.sh`：先通过 `pi update` 升级根组合包，再只升级当前已安装的终端环境和机器级依赖；未安装项直接跳过。升级前先查询并比较本地与远端版本，只有版本不同时才下载或替换；Powerlevel10k 配置优先从 `pi update` 后的已安装组合包读取，并与 `.zshrc` 受管块一起按内容比较后增量同步。
- `uninstall.sh`：先移除根组合包；若检测到 Hippo Memory CLI，再明确询问是否卸载确认属于 npm 全局安装的 `hippo-memory`，默认保留且始终不删除 `.hippo/` 或用户记忆数据。其他共享终端环境和机器工具不卸载。

## 当前职责与默认行为

- FFF 独占本地字面搜索；远端服务器由独立的 `ssh_find` / `ssh_grep` 结构化工具在已授权调用内自适应使用现有命令。RTK 不得处理本地或远端搜索工具的调用/结果，也不得通过默认命令改写接管 `rg`、`grep`、`find`、`fd`。
- RTK 默认只压缩非搜索输出，包括本地 `bash` 与远端 `ssh_bash` 的 ANSI 清理、测试聚合、构建过滤、Git 压缩、Lint 聚合和兜底截断；`ssh_bash` 只复用输出处理，远端命令不得进入 RTK rewrite。
- `commandRewritingEnabled` 默认 `false`。默认安装不依赖系统 `rtk` CLI；只有用户主动开启命令改写时才需要 `rtk rewrite`。
- `readCompaction.enabled`、`sourceCodeFilteringEnabled` 和 `smartTruncate.enabled` 当前均默认 `false`，源码读取保持原样。未经用户明确决定，不因节省上下文而改变这些默认值。
- 若以后开启 read 压缩，优先考虑 `readCompaction + smartTruncate`，源码过滤仍独立评估；必须保留精确 `offset/limit` 读取、短文件和行锚点的完整性。
- Context Mode 负责避免批量读取、命令研究和网页原始内容直接撑大上下文；FFF 仍负责精确字面搜索，RTK 仍处理未走 Context Mode 的普通输出。
- Hashline 默认以 2 字符行哈希覆盖内置 `read` / `edit`，`grep` 和 `replaceText` 均关闭；它保证锚定编辑而不负责压缩，大文件上下文节省必须来自先定位/隔离分析、再做最小范围 `offset/limit` 读取。
- 工具路由规则不得替换 Pi 默认系统提示词：代码结构、调用关系和待修改 symbol 优先 CodeGraph，定义/引用/类型/诊断优先 LSP；工作区内大文件探索、分析和总结优先 `ctx_execute_file`，日志、构建与不可预测命令输出优先 Context Mode；字面搜索先用 FFF `find` 收敛文件位置，再在收敛路径内用 `grep`/`multi_grep` 获取行号；真正修改前才用小范围 Hashline `read` 获取新鲜锚点并用锚定 `edit`。在线搜索按场景只先选一个服务：广泛发现、新闻和候选来源用 Tavily，官方/技术/论文和高确定性来源用 Exa，中文、站点限定和日期筛选用 Keenable；只有必要时才跨服务复核。遇到大量结果、截断或上限时继续缩小范围，不得靠提高 limit 或倾倒全部结果解决。
- `ask_user_question` 只用于模型继续任务所必需的用户决定、偏好、确认或澄清；不得重复询问直接用户消息中已有的信息。工具仅支持交互式 TUI、顺序执行和最多 8 题；取消或 abort 必须返回 `cancelled: true`，不得伪造答案，且 `/qna` 不属于该扩展。其成功 `details.answers` 必须保留 `question` / `answer` 字段，以匹配 AutoReview 已有的可信结构化用户交互边界。
- Tool Search 默认常驻核心 `read` / `write` / `edit` / `bash` / `grep` / `find`、`codegraph_explore`、`lsp_diagnostics` 与 `tool_search`；其余组合包工具必须优先使用 `pi-tool-search/extensions/bundle-groups.ts` 中提交的权威工作流分组。默认最多 3 个动态组、模型组最多 8 个工具、动态工具总数最多 20，加载或组内调用更新 LRU，超限先移除最久未用组。
- 标准组合包工具全部命中预置目录时 Tool Search 不得调用模型、创建用户缓存或发送隐藏 schema。只有存在未识别第三方工具时才允许惰性模型增强；生成结果必须保留全部预置 assignment，模型元数据不得替代真实名称、参数或 schema。缓存必须位于 agent 目录且权限 `600`；模型失败必须继续使用预置目录 + 确定性未知工具分组。`groupOverrides` 优先级高于预置分组。
- Tool Search 必须直接使用当前 `@earendil-works/pi-coding-agent`、`typebox`、`ModelRegistry.complete()` 和 `setActiveTools()`；首次纯增加载使用当前 Pi 的增量结果传播，LRU 替换允许走宿主安全 fallback。不得安装或映射旧 `@mariozechner` runtime，不得恢复 provider payload 改写、代理分发或隐藏 `sendMessage` steer/retry 兼容循环。
- `.pi-debug/` 是 `/dump-system-prompt` 生成的本地诊断目录，不提交到仓库，也不作为组合包运行时配置源。
- CodeGraph MCP 扩展只配置 Pi 到外部 `codegraph` 命令的连接。根包安装本身不安装 CodeGraph；便捷脚本仅在组合包安装完成且用户明确选择 `Y` 后调用官方安装器。安装、升级和普通启动流程不得执行 `codegraph init`；只有用户在目标项目显式调用 `/plugin_init` 并确认后，命令才可以 `.codegraph/codegraph.db` 与 `.hippo/hippo.db` 为权威标志初始化缺失状态。命令必须先预检两个 CLI，任一步失败不得热重载，也不得隐瞒此前已完成的部分初始化；不得改动 CodeGraph 更新或遥测设置。
- CodeGraph MCP 使用 `keep-alive` 并只直接暴露 `codegraph_explore`；命令缺失、项目未初始化或连接失败时不得阻止其他扩展加载。
- 所有 MCP 服务必须合并到 `extensions/mcp.ts` 创建的唯一 `pi-mcp-adapter` 实例；不得新增独立 adapter 扩展入口，否则会重复注册 `--mcp-config`、`/mcp` 等全局接口。根测试必须扫描全部本地扩展入口并强制这一不变量。
- Exa MCP 使用托管 Streamable HTTP 端点和 `eager` lifecycle；`EXA_API_KEY` 通过 `x-api-key` 请求头发送，不得放入 URL、仓库文件或日志。所有在线搜索工具统一采用“来源名 + 原始语义工具名”的命名形式，例如 `tavily_web_search`、`exa_web_search`、`keenable_search`。Exa 高级搜索必须显式约束结果数量和文本长度；Tavily 输出默认控制 `max_results` 且非必要不请求 raw content；Keenable 优先利用中文、站点和日期筛选能力。
- 搜索 key 默认保存在 `${XDG_CONFIG_HOME:-$HOME/.config}/my-pi/search.env`，文件必须为 `600` 且不得提交；`search_config.sh` 只输出配置状态，禁止回显 key。
- `pi-context-view` 只观察上下文占用，不参与压缩策略。
- `pi-condense` 负责压缩已经进入会话的历史工具结果，与 Context Mode 的输入隔离职责互补；`extensions/condense.ts` 只在 `settings.json` 尚无 `contextPrune.enabled` 时写入 `true`，必须保留用户显式设置的 `false`，配置无效时不得覆盖原文件。其他参数沿用上游默认，包括 `agent-message` 触发模式和 skill 路径保护。
- Codex fast mode 只为符合条件的 `openai-codex-responses` 请求设置 priority service tier。`/fast-mode on|off` 同时更新当前分支记录与 Pi agent 目录中的 owner-only 全局默认值；新会话继承全局值，已有分支记录优先，配置缺失或无效时回退为关闭。
- 权限策略默认允许常规工具，允许 FFF 工具；拒绝 Bash 直搜和敏感凭据路径；Git 非只读操作、包管理、外部目录、文件/系统/网络高风险操作与普通 MCP 调用先由 `pi-permission-system` 判为 `ask`。
- SSH 权限沿用同一条 `pi-permission-system` gate 与 `auto-review` authorizer chain：`ssh_connect`、`ssh_read`、`ssh_write`、`ssh_edit`、`ssh_find`、`ssh_grep` 默认 `ask`；连接前的证据解析已导入 host ID 为非秘密 target、port 与请求/default cwd，AutoReview 只可依据用户直接消息中的明确目标授权连接。`ssh_bash` 通过 `shellTools` 映射到完整 Bash 策略并设置 `decisionFloor: "ask"`，把普通 Bash `allow` 提升为复核请求，同时保留原有 `ask` 与硬 `deny`。远端路径不得送入基于本机 cwd 的 `path` / `external_directory` 归一化。
- `pi-permission-auto-review` 不是独立 `tool_call` gate，而是 `pi-permission-system` authorizer chain 中名为 `auto-review` 的链路；只复核权限基线产生的 `ask`，不会重复处理已 `allow` 或已 `deny` 的请求。
- reviewer 返回 `allow` 时自动批准、返回 `deny` 时直接拒绝，配置、模型、认证、超时或响应异常时必须 `defer` 到正常人工提示。`pi-permission-system` 的 delegation envelope 继续禁止 authorizer 自动批准全部 `path` 请求；`external_directory` 对内置只读路径工具（`read`、`find`、`grep`、`ls`）接受 reviewer 的 `allow`，写入、编辑、Bash、未知工具和其他外部访问仍转人工。
- 默认 reviewer 为 `openai-codex/codex-auto-review`、low reasoning、90 秒总重试预算和内置 Codex Guardian 风格策略；只把 active branch 中的直接用户消息与已识别结构化问答作为授权证据，assistant/tool/compaction 内容不能自行授权。
- `config/pi-permission-system.json` 必须显式配置 `authorizerChain: ["auto-review"]`，并把需要自动复核的 Git 非只读操作、包管理及其他类别声明为 `ask`；硬 `deny` 不得改成可由模型覆盖的 `ask`。
- `pi-lsp` 的 TypeScript/JavaScript 后端由根包固定依赖提供，`extensions/lsp.ts` 使用当前 Node 可执行文件直接启动包内 `typescript-language-server` CLI，不得依赖或调用 VS Code GUI；Kotlin/JDT LS 仍使用组合包部署的 `kotlin-lsp --stdio` 与 `jdtls` 配置，根包不安装这两个系统可执行文件，便捷脚本可在用户逐项明确确认后通过 Homebrew 安装 Kotlin LSP、Java 21 和 JDT LS。
- 终端环境配置只属于便捷脚本：Kitty 可选安装后可通过官方 kitten 启用 Solarized Dark；Oh My Zsh 使用不切换 shell 的 unattended 安装；Powerlevel10k 将仓库内置的 `config/p10k.zsh`（Rainbow/ASCII 单行紧凑主题）部署到 `~/.config/my-pi/p10k.zsh`（遵循 `XDG_CONFIG_HOME`），不得覆盖用户自己的 `~/.p10k.zsh`。`.zshrc` 中脚本拥有的内容必须使用 `# >>> my-pi:<id> >>>` / `# <<< my-pi:<id> <<<` 受管块，更新时只替换块内内容；标记不完整或重复时拒绝修改。实际修改前必须创建带时间戳的备份。`git`、`zsh-autosuggestions`、`zsh-syntax-highlighting` 在安装流程中逐项询问后才安装或启用。
- Codex 远程压缩只对 `openai-codex` 生效，默认在 turn boundary 达到 90% 时触发；官方 Hippo Extension 在已初始化项目的 session start 注入上下文、过滤捕获工具错误，并在 session shutdown 执行 `hippo sleep`。
- Hippo Extension 直接使用 PATH 中的官方全局 `hippo` CLI；`install.sh` 只在 CLI 缺失且用户明确确认后安装 `config/hippo-memory-version` 指定的 npm 版本，不得扫描项目、选择初始化目录或执行 `hippo init`。用户必须在自己选择的项目目录中手动初始化。
- `update.sh` 只升级已经安装且属于 npm 全局包的 Hippo CLI；必须从 `pi update` 后的组合包读取目标版本，先用 `npm view` 确认，再比较本地版本，版本相同不得重新安装，CLI 缺失或来源未知时保留现状。
- `uninstall.sh` 只在根包移除成功后询问是否卸载 npm 全局 Hippo CLI，默认拒绝；不得删除项目 `.hippo/`、全局记忆或旧 Hermes 数据。
- `install.sh` 默认从 `git:git@bitbucket.org:siakitem/my-pi.git` 安装，并允许用 `PI_PACKAGE_SOURCE` 覆盖来源；组合包安装失败时立即停止，机器级依赖安装失败时继续检查其余依赖并最终返回非零状态。
- CodeGraph 的可选安装使用官方远程安装脚本；macOS Kitty 使用 Homebrew cask，其他系统使用 Kitty 官方安装器；Kotlin LSP、Java 21 和 JDT LS 使用 Homebrew；Oh My Zsh 使用官方安装器，Powerlevel10k 与两个第三方 Zsh 插件从各自官方 Git 仓库克隆。升级时 Git checkout、Homebrew 包、Kitty 官方安装和 CodeGraph 都必须先比较本地与远端版本，版本一致时不得重新下载安装；无法可靠比较时保留现状并报告。缺少 Homebrew、curl 或 git 时保留已经完成的组合包安装并报告失败。
- `install.sh` 不检查默认不需要的 `rtk` CLI；`update.sh` 和 `uninstall.sh` 使用同一个 `PI_PACKAGE_SOURCE` 规则分别调用 `pi update` 和 `pi remove`。运行 `update.sh` 视为明确授权升级已安装组件及同步已有受管配置，但不得安装缺失组件或改写受管块之外的用户配置；卸载仅可在用户当次明确确认后移除 npm 全局 Hippo CLI，其他共享机器级工具保持不变。

## 修改边界

- 优先在目标扩展目录内完成改动；不要让一个扩展依赖另一个扩展的未公开内部实现。
- 保留原项目的 `LICENSE`、版权信息和必要的来源说明。
- 扩展运行目录中的 `config.json`、日志、构建产物、覆盖率目录和依赖目录属于本地状态，不应提交；`config/pi-permission-system.json`、`config/pi-hashline-edit.json` 与 `config/lsp.json` 分别是权限链、Hashline 默认行为和 LSP 后端的组合包权威源配置，必须提交并维护。
- 外部 Pi 扩展依赖必须在根 `package.json` 中使用精确版本，自维护 Fast mode 等扩展必须使用本地 `file:` 依赖，并更新根 `package-lock.json`；不要用仓库级 `.pi/settings.json` 代替组合包依赖。
- 需要原生构建的依赖只按锁定版本加入根 `allowScripts`；当前 `better-sqlite3@12.11.1` 仍由 Context Mode 使用并保持精确放行。官方 Hippo CLI 是独立机器级 npm 包，不得因此向根包批量批准其他 install scripts。
- Pi 核心包只作为宿主 peer dependencies，不得在组合包内再安装或打包一套 Pi runtime；保留根 `.npmrc` 的 peer 安装策略。
- `pi-tool-search/` 的根依赖必须保持 `file:./pi-tool-search`，组合包直接加载 `pi-tool-search/extensions/index.ts`；同步上游时先核对本地增量动态工具改造，禁止用旧 npm 入口或上游旧宿主实现直接覆盖。
- 上游仅作为参考来源。同步上游改动时先核对本仓库已有修改，再按明确范围移植；不要直接覆盖本地实现。
- `install.sh`、`update.sh`、`uninstall.sh` 和 `search_config.sh` 必须保持 POSIX `sh` 兼容和可执行权限，并包含在根 `package.json` 的 `files` 中；修改脚本行为时同步更新 README 和本文件。
- 安装流程中的机器级依赖和用户终端配置必须保持逐项询问且默认拒绝，不得在没有用户明确确认的情况下自动安装或改写。用户主动运行 `update.sh` 只授权升级已安装项和同步已有受管配置；缺失项仍必须跳过。`.zshrc` 修改必须局限于受管块并保留备份，卸载不得顺带删除或还原共享工具和用户终端配置。
- 未经明确要求，不执行发布、提交、推送、运行安装/卸载脚本或安装到用户 Pi 运行目录等外部写操作。

## 根目录 TypeScript 与 LSP 验证约定

- 根目录当前有意不安装 Pi runtime，也没有根级 `tsconfig.json`、`devDependencies` 或 `@types/node`；`@earendil-works/pi-*` 只作为 optional host peer dependencies。TypeScript LSP 因而会把根目录 `.ts` 文件放入 inferred project，不能把宿主 Pi 的运行时解析能力等同于仓库内静态类型环境。
- 每个任务首次对相关根目录 TypeScript 文件调用 `lsp_diagnostics` 时先建立并记录基线；后续只关注相对基线新增、消失或位置变化的诊断。文件和类型环境都未变化时不得重复调用 LSP 并重复报告同一组结果。
- 当前可预期的基线包括：宿主 peer 缺失导致的 `TS2307`（例如找不到 `@earendil-works/pi-coding-agent`），Node 类型缺失导致的 `node:*` / `node:test` / `node:assert` `TS2591`，以及由这些上游类型缺失级联产生的 `TS7006`、`TS18048`、`TS2722` 等。遇到级联错误时先确认其是否随缺失类型而产生，不要把它们直接归因于本次实现。
- 已知基线不等于忽略所有诊断：凡是无法由上述缺失依赖解释的新语法错误、结构类型错误、错误属性访问或本次修改所在代码的新诊断，必须修复并重新验证。交付时应把“已知类型环境基线”和“本次新增诊断”分开说明。
- 不得为了消除 LSP 基线而在根包安装第二套 Pi runtime、加入机器相关的宿主绝对路径或提交只在单机有效的 `paths` 映射。若确需新增根级 `tsconfig.json`、`@types/node` 或其他开发类型环境，必须作为明确的仓库设计变更评估，并同步更新依赖、锁文件和本文档。
- 不要从泛型或重载的 `ExtensionAPI` 方法直接用 `Parameters<...>` 猜取具体工具定义；解析失败时它可能退化为 `unknown`。包装第三方工具时优先使用上游导出的具体类型；没有稳定导出时定义覆盖实际访问字段的最小结构类型，并用运行时集成测试验证。
- `node --test` 可直接测试仓库内的纯 TypeScript helper，但测试入口不得静态导入 `node_modules` 中的 `.ts`；Node 原生 type stripping 会对这种路径报 `ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING`。第三方 TypeScript 扩展 wrapper 应拆出本地纯 helper 做单元测试，并通过隔离的临时 Pi agent/jiti 加载验证真实扩展入口。
- 对根目录扩展的最终验证优先组合使用：纯 helper 的 `node --test`、`git diff --check`、所需 npm 锁文件检查，以及隔离 Pi 环境的扩展加载。LSP 启动成功、单元测试通过和真实 Pi 加载通过是不同证据，不得互相替代或把类型环境基线误报为 LSP 后端启动失败。

## `pi-rtk-optimizer` 开发约定

- 组合包运行环境为 Node.js 22.19 或更高版本；RTK 子目录开发验证还需要 npm、Bun 和项目声明的开发依赖。
- 扩展入口是 `pi-rtk-optimizer/index.ts`，主要实现位于 `pi-rtk-optimizer/src/`。
- RTK 命令改写默认关闭；若用户主动开启，其命令支持策略由已安装的 `rtk rewrite` 决定，不在扩展内重复维护规则。
- FFF override 独占搜索工具与搜索输出；RTK 不得处理 `grep` 工具结果。
- read 压缩属于有损能力。任何默认值调整都必须同时说明哪些内容可能被省略、精确读取如何恢复原文，以及对 `edit` 文本匹配和排障证据的影响。
- 修改配置结构时同步检查默认值、归一化逻辑、设置界面、类型定义、README 示例和相关测试。
- 工具输出压缩可能损失证据。排障和审计相关改动应优先保证原始输出可恢复，并覆盖锚点完整性和截断边界。

## `pi-permission-system` 开发约定

- 扩展入口是 `pi-permission-system/src/index.ts`，公共跨扩展服务入口是 `pi-permission-system/src/service.ts`，测试保留在该目录的 `test/`。
- 同步上游必须从明确 tag/commit 移植并记录快照；保留上游 `LICENSE`、作者和来源，不导入 `dist/`、嵌套 `.git` 或上游包目录的 `.pi` 本地状态。
- 本地 delegation envelope 允许内置只读路径工具（`read`、`find`、`grep`、`ls`）对 `external_directory` 接受 authorizer 的 `allow`；`write`、`edit`、Bash、未知工具、未确定 surface 以及全部 `path` ask 必须继续 `defer` 到终端人工 authority。
- 修改 gate、authorizer chain、delegation envelope、子代理转发或公共 service 类型时，必须同步更新包内 README/架构文档和对应测试。
- 根包必须通过 `file:./pi-permission-system` 提供运行时依赖，包装入口必须直接加载仓库源码；不得同时加载 npm 预编译入口或第二个 permission-system 实例。

## `pi-permission-auto-review` 开发约定

- 扩展入口是 `pi-permission-auto-review/index.ts`，主要实现位于 `pi-permission-auto-review/src/`，测试保留在该目录的 `test/`。
- 同步上游时必须从源码仓库的明确 tag/commit 移植并记录快照；不得以 npm tarball、`dist/` 或 `node_modules` 中的编译产物覆盖本地源码。
- 保留上游 `LICENSE`、作者和来源信息；本地兼容改动优先保持在目标目录内，不依赖其他扩展的未公开内部实现。
- reviewer 只能处理 `pi-permission-system` 已判定为 `ask` 的请求；不得绕过硬 `deny`，不得另加并行 `tool_call` 审批层，也不得扩大 `pi-permission-system` 明确授予的 delegation envelope。
- 修改 reviewer 策略、可信证据边界、配置结构、模型解析或 authorizer 注册时，必须同步更新 README、schema 和相应测试。

## `hippo-memory-pi` 开发约定

- 扩展入口是 `hippo-memory-pi/index.ts`，来源记录是 `hippo-memory-pi/UPSTREAM.md`；只从官方 `kitfunso/hippo-memory` 的明确 tag/commit 移植 `extensions/pi-extension/`，保留官方 README、LICENSE 和版权。
- 官方 npm tarball 当前不包含 Pi Extension，因此根包直接打包并加载本地源码；不得同时加载第三方 `@the-forge-flow/hippo-memory-pi` 或第二个 Hippo Pi Extension。
- CLI 版本权威源是 `config/hippo-memory-version`；修改它时必须同步上游源码快照、README、AGENTS、安装/升级 mock 测试和扩展加载验证。
- 扩展依赖 PATH 中的全局 `hippo`。CLI 缺失时必须 fail-safe，不得阻止其他扩展加载；项目未执行 `hippo init` 时不得擅自创建 `.hippo/`。

## `pi-extension-codex-fast-mode` 开发约定

- 扩展入口是 `pi-extension-codex-fast-mode/index.ts`，测试保留在该目录的 `tests/`，来源记录是 `UPSTREAM.md`。
- 同步上游必须从明确 commit 移植并保留 `LICENSE`、作者和来源；不得导入嵌套 `.git`、`node_modules` 或构建产物。
- 全局默认配置必须位于 Pi agent 目录的 `extensions/pi-extension-codex-fast-mode/config.json`，使用原子写入和 owner-only 权限；无效或不可读配置必须安全回退为关闭且不得静默覆盖。
- 新会话使用全局默认值，已有分支的最新有效 custom entry 必须继续优先；修改持久化、分支恢复、provider/API 资格或请求 payload 时必须同步 README、技术文档和测试。
- 根包必须通过 `file:./pi-extension-codex-fast-mode` 提供依赖并直接加载仓库源码，不得同时安装或加载 npm 预编译入口。
- 修改该扩展后至少运行包内 `npm test`、`npm run check`、`npm run smoke` 与 `npm pack --dry-run --json`；加载或依赖入口变化还要运行根扩展联合加载测试和实际 packed tarball 的隔离安装验证。


## `pi-ssh` 开发约定

- 扩展入口是 `pi-ssh/index.ts`，`ssh2` transport 与 SFTP 实现在 `pi-ssh/src/ssh2-transport.ts`，有界自适应远程搜索位于 `pi-ssh/src/remote-search.ts`，AES-GCM vault 位于 `pi-ssh/src/vault.ts`，选择性导入入口是根 `ssh_config.sh` 与 `pi-ssh/scripts/ssh-config.mjs`，权限桥接位于 `pi-ssh/permission-integration.ts`，测试保留在 `pi-ssh/test/`，来源记录是 `pi-ssh/UPSTREAM.md`。
- 同步上游必须从明确 tag/commit 移植并保留 `LICENSE`、作者和来源；参考其他实现时记录明确 commit，不得导入嵌套 `.git`、`node_modules` 或构建产物。
- 运行时必须保持纯 `ssh2`，不得回退到系统 OpenSSH、`sshpass`、`SSH_ASKPASS` 或 ControlMaster；OpenSSH 只允许由显式配置脚本通过 `ssh -G` 解析用户选中的 alias，已导入配置变化必须由用户显式更新。第一版遇到 `ProxyJump` / `ProxyCommand` 必须拒绝，不能静默忽略。
- 根包必须直接固定安装 `ssh2@1.17.0` 与配置 CLI 所需的 `jiti@2.7.0`，因为 packed bundle 直接加载其内置 `pi-ssh/` 源码；`ssh2` 与 `cpu-features` 的 install scripts 只构建可选加速绑定，当前不得加入根 `allowScripts`，纯 JavaScript fallback 必须可运行。
- SSH vault 使用同目录独立随机 key 和 AES-256-GCM 整体加密，目录/文件在 POSIX 上必须保持 `700` / `600`；该设计只防止误看或单独泄漏密文，不防同一用户读取 key。密码、私钥 passphrase、私钥内容、vault key 与解密明文不得进入命令参数、日志、Pi session、权限证据或明文临时文件。
- 已导入主机必须固定 SHA256 Host Key；不匹配时 fail closed。私钥只保存路径，不复制内容；文件工具使用 SFTP，写入优先临时文件与原子 rename，远端断线不得自动重放命令。
- `ssh_connect` 是唯一运行时连接入口，只接受 vault 中已导入的 host ID 与可选绝对/`~/` remote cwd，并必须默认 `ask` 后进入 AutoReview；不得注册 `/ssh`、`--ssh`、session resume 自动重连或把用户 `!` 命令切换到远端。用户未在直接请求中明确服务器和具体远端任务时不得推断、替换或连接主机；新连接替换旧连接，会话结束自动断开。
- `ssh_find` / `ssh_grep` 必须在已授权工具调用内部按 `fd/fdfind → git ls-files → find` 与 `rg → git grep → find+grep` 顺序检测服务器现有能力，不安装或上传远端二进制；输入必须 shell-safe，结果数量/单行/总捕获必须有界并显式报告 backend 与 truncated。RTK 不得处理这两个搜索工具的结果。
- `ssh_read`、`ssh_write`、`ssh_edit`、`ssh_find`、`ssh_grep` 的远端路径不能按本机路径执行 `path` / `external_directory` gate；必须通过公共 `PermissionsService` 注册显式 extractor 关闭默认 `input.path` 推断，并保持五个工具的默认策略为 `ask`。
- `ssh_bash` 必须在权威权限配置的 `shellTools` 中映射 `commandArgument: "command"` 并设置 `decisionFloor: "ask"`，复用 Bash 命令拆分、硬拒绝、风险 `ask` 和 authorizer chain；全局 floor 必须在项目配置字段级合并时保留，不得新增第二个并行 `tool_call` 审批层。
- RTK 只把 `ssh_bash` 当作 Bash 输出别名执行 ANSI 清理、测试/构建/Git/Lint 聚合与兜底截断；不得对远端命令启用 RTK rewrite，也不得处理 `ssh_read`、`ssh_find` 或 `ssh_grep` 返回。
- SSH 工具的权限预览必须包含连接请求或当前远端的 host id、target、port、remote cwd 与有界操作摘要；连接预览只解密本地 vault 以提取非秘密目标字段，绝不包含凭据，远端 shell 的完整命令继续由 Bash payload 单独提供。权限服务缺失或注册失败时必须 fail-safe，不得转为无提示自动允许。
- `pi-ssh` 只用于从本地项目显式操作服务器，不得自动探测、读取或向系统提示词注入远端 `AGENTS.md`、`CLAUDE.md` 或其他项目说明；远端内容只能由明确且已授权的 `ssh_*` 工具调用获取。
- 修改 SSH transport、vault、导入、权限集成或加载入口后至少运行 `pi-ssh` 包内 `npm test`、根脚本语法与 mock 配置测试、`pi-permission-system` 的 `npm run typecheck` / `npm run test` / `npm run build`、根扩展联合加载和实际 packed tarball 隔离安装验证。未经明确要求不得连接真实服务器或把真实密码写入测试。
- 根加载顺序必须保持 `pi-permission-auto-review` → `pi-permission-system` → `pi-ssh` → `pi-tool-search`，确保 authorizer 先注册、权限服务先发布、SSH 桥接随后安装且 Tool Search 最后收集完整工具目录。


## `pi-ask-user` 开发约定

- 扩展入口是 `pi-ask-user/index.ts`，schema、归一化、TUI 与工具注册位于 `pi-ask-user/src/`，纯 helper 测试保留在 `pi-ask-user/test/`。
- 工具名必须保持 `ask_user_question`，并由 Tool Search 的独立 `user-interaction` 组按需加载；根加载顺序必须位于 `pi-tool-search` 之前。
- 参数必须有界并在运行时复核 question id、题型、选项和值的有效性；TUI 必须顺序执行、监听 abort、按 width 失效缓存，并把外层 `Focusable` 状态传播给内嵌 Editor。
- 成功结果的 `details` 必须保持 `version`、`cancelled: false` 与非空 `answers`，每个 answer 必须提供原始 `question` 和用户 `answer`；取消结果不得成为权限授权证据。修改结果结构时同步验证 `pi-permission-auto-review` transcript 解析。
- 同步上游示例时从明确 commit 移植并保留 `LICENSE`、`UPSTREAM.md` 与本地整合差异；不得恢复 `/qna`、重复的单题工具或多个扩展入口。
- 修改后至少运行包内 `npm test` / `npm run check`、Tool Search 的 typecheck/test/build、AutoReview transcript 测试、根扩展联合加载和 packed tarball 隔离安装验证。


## `pi-tool-search` 开发约定

- 扩展入口是 `pi-tool-search/extensions/index.ts`，组合包权威分组位于 `pi-tool-search/extensions/bundle-groups.ts`，目录生成/校验/缓存位于 `pi-tool-search/extensions/catalog.ts`，配置部署位于 `pi-tool-search/extensions/config.ts`，测试保留在 `pi-tool-search/test/`。
- 同步上游必须记录明确 tag/commit，保留 README、CHANGELOG、文档、作者和许可证说明；不得导入上游 `.pi`、嵌套 `.git`、`node_modules` 或构建产物。
- 修改 Tool Card 提示词、目录校验、分组、缓存、active-tool/LRU 生命周期、配置或工具结果时，必须同步更新包内 README、当前动态加载文档、CHANGELOG 和测试。
- 新增、删除或重命名组合包暴露工具时必须同步维护 `BUNDLE_GROUP_DEFINITIONS`；日常只读工具、provider 工具和高风险管理工具不得因名称相似而混入同一大组，根验证应确认标准组合包没有落入 unknown-tools 路径。
- 生成目录只能让模型提供摘要、使用边界、关键词与分组；工具名、参数和原始 schema 必须来自宿主。校验或模型调用失败必须 fail-safe 到确定性目录，缓存不得写入仓库或放宽权限。
- 根包必须通过 `file:./pi-tool-search` 提供本地依赖并直接加载仓库源码，不得同时安装或加载 npm `pi-tool-search` 实现。

## 验证

组合包依赖或加载入口变化时，至少验证根 `npm install` 幂等、锁文件有效、MCP adapter 唯一所有者不变量测试，以及全部扩展可在隔离的临时 Pi agent 目录加载。权限配置变化时使用仓库内固定快照的 `pi-permission-system` schema 校验，并验证包装入口部署后的文件与仓库源配置一致。

安装、升级、卸载、搜索或 SSH 配置脚本变化时，至少运行 `sh -n install.sh`、`sh -n update.sh`、`sh -n uninstall.sh`、`sh -n search_config.sh`、`sh -n ssh_config.sh` 和 ShellCheck，并核对脚本仍具有可执行权限、仍包含在根 `package.json` 的 `files` 中、README 描述与实际流程一致。搜索配置测试只能使用虚拟 key 和隔离 HOME；SSH 配置测试必须使用隔离 HOME、虚拟凭据与 mock transport，不得连接真实服务器或把真实密码写入测试输出。涉及真实 `pi install`、`pi update`、`pi remove`、Homebrew、远程安装器、Git 克隆、真实 SSH 连接或真实用户终端配置的端到端验证属于外部写操作，未经明确要求不得执行；可以使用隔离的临时 HOME 和 mock 命令验证分支行为。

Hippo 脚本变化必须额外用隔离 HOME/PATH 和 mock `pi`、`npm`、`hippo` 验证：安装缺失 CLI 但不调用 `hippo init`、相同版本不升级、不同版本精确升级、未知来源 CLI 不替换、卸载默认保留、明确确认后只卸载 npm 全局包且保留数据。不得在测试中执行真实全局 npm 写入或修改真实 `.hippo/`。

在 `pi-permission-system/` 内至少运行 `npm run typecheck`、`npm run test` 和 `npm run build`。在 `pi-permission-auto-review/` 内至少运行同样三项；涉及权限集成时还要使用仓库内 `pi-permission-system` 验证 authorizer 注册、`allow` / `deny` / `defer` 与 delegation envelope。

在 `pi-tool-search/` 内至少运行 `npm run typecheck`、`npm run test` 和 `npm run build`；涉及加载入口或 active-tool 行为时还要运行根扩展联合加载测试和实际 packed tarball 的隔离安装验证。


在 `pi-rtk-optimizer/` 内按改动范围选择最小充分验证：

- `npm run build`：TypeScript 转译检查。
- `npm run typecheck`：完整类型检查。
- `npm run test`：运行 Bun 测试。
- `npm run check`：类型、测试和打包检查的完整验证。

若环境缺少依赖或未执行某项验证，交付时明确说明，不以静态检查代替运行结果。

<!-- hippo:start -->
## Project Memory (Hippo)

At the start of every task, run:
```bash
hippo context --auto --budget 1500
```
Read the output before writing any code.

On errors or unexpected behaviour:
```bash
hippo remember "<description of what went wrong>" --error
```

On task completion:
```bash
hippo outcome --good
```

When Hippo's Codex wrapper is installed, session-end capture runs automatically.
If the wrapper is not installed, capture a brief summary manually:
```bash
hippo capture --stdin <<< '<decisions, errors, lessons — 2-5 bullets>'
```
<!-- hippo:end -->
