Files
my-pi/README.md
T
云服务部-叶林立 dc925e1eeb Merge branch 'my-pi-worktree1'
# Conflicts:
#	AGENTS.md
#	pi-tool-search/CHANGELOG.md
#	pi-tool-search/docs/dynamic-tool-loading.md
2026-08-25 15:18:58 +08:00

360 lines
30 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.
# my-pi
个人维护的 Pi 扩展组合包。安装一次即可加载并配置:
- `@ff-labs/pi-fff@0.10.5`:使用官方 `override` 模式接管 `find``grep``multi_grep`
- 本仓库维护的 `pi-rtk-optimizer`:只处理 Bash/read 等输出压缩,默认不改写命令,也不处理搜索工具结果。
- `context-mode@1.0.169`:通过 Pi adapter 提供 `ctx_*` 工具、上下文隔离和会话连续性。
- `@tavily/pi-extension@0.1.2`:提供 Tavily 广泛搜索与页面提取;通过本地 override 暴露为 `tavily_web_search` / `tavily_web_fetch`
- `@keenable/pi-search@0.1.2`:提供紧凑的 `keenable_search` / `keenable_fetch`,并加载其搜索 skillAPI key 可选。
- `pi-mcp-adapter@2.26.0`:通过单个共享 adapter 实例接入机器现有的 CodeGraph 和 Exa 托管 MCP,避免重复注册 Pi 的全局 MCP flag 与命令。
- `pi-context-view@0.4.2`:查看上下文占用。
- 本仓库维护的 `pi-extension-codex-fast-mode`:基于 `@firstpick/pi-extension-codex-fast-mode@0.1.1`,为 Codex provider 提供跨会话持久化的 `/fast-mode`
- `pi-lsp@0.1.7`:为 TypeScript/JavaScript、Kotlin 和 Java 提供 LSP 诊断、跳转与符号工具;TypeScript 后端由组合包内置。
- `hippo-memory-pi/`:从官方 `hippo-memory v1.33.0` 源码导入的 Pi Extension,提供项目记忆注入、错误捕获和 sleep consolidation。
- `@ogulcancelik/pi-codex-compaction@0.1.3`:为 `openai-codex` 提供原生远程压缩。
- 本仓库维护的 `pi-minimal-footer`:基于 `@ogulcancelik/pi-minimal-footer@0.1.10`,用紧凑的上下文仪表和订阅用量条替换默认 footer,并在 Codex Fast 模式开启时显示 `Fast on`
- 本仓库维护的 `pi-notify`:基于 `@smoose/pi-notify@0.1.1`,使用 Kitty OSC 99 在 Pi 完全 settled 后通知,并支持点击精确聚焦来源 Kitty 窗口。
- `pi-condense@2.9.1`:把已完成的工具调用批次总结为可恢复的短摘要,并通过 `context_tree_query` 按需取回原始输出;组合包首次加载时默认开启。
- 本仓库维护的 `pi-ask-user`:提供模型主动调用的 `ask_user_question`,用一个顺序 TUI 同时支持单题、多题、选择题、文本题、自定义回答与提交前复核。
- 本仓库维护的 `pi-tool-search`:从完整工具定义生成并缓存经过校验的工作流分组,以最多 3 个动态组的 LRU 策略按组加载原始完整 schema。
- 本仓库维护的 `pi-permission-auto-review`:作为 `pi-permission-system` authorizer,使用 Codex Guardian 风格策略自动复核 `ask` 请求。
- 本仓库维护的 `pi-permission-system`:从 `@gotgenes/pi-permission-system@26.2.1` 源码导入,负责工具、路径、MCP、硬拒绝和兜底权限基线。
- 本仓库维护的 `pi-ssh`:通过纯 Node `ssh2` 持久连接、显式 `ssh_cd` 远端工作区切换、SFTP 与自适应有界搜索提供独立的远端工具;Agent 只在用户明确指定已导入主机及具体任务后发起受 AutoReview 复核的连接。
- `extensions/tool-routing.ts`:保留 Pi 默认系统提示词,并按当前激活工具追加简短的工具与搜索路由规则;提供 `/dump-system-prompt` 导出当前有效提示词。
## 安装、升级与卸载
推荐从仓库检出目录运行安装脚本:
```bash
./install.sh
```
脚本会先执行:
```bash
pi install git:git@bitbucket.org:siakitem/my-pi.git
```
安装组合包成功后,脚本会依次检查终端环境和机器级 CLI。所有缺失项目都逐项显示
`[y/N]`,默认拒绝,仅在用户明确选择 `Y` 后修改机器或用户配置:
- 检查 KittymacOS 使用 Homebrew cask 安装,其他系统使用 Kitty 官方安装器。Kitty
可用后继续检查并可通过官方 `themes` kitten 配置 `Solarized Dark`
- 检查 Oh My Zsh。安装采用官方 unattended 模式,不切换默认 shell、不立即启动 Zsh,
也不覆盖现有 `.zshrc`
- 检查 Powerlevel10k;可克隆到 Oh My Zsh 的 custom themes 目录,并把仓库内置的
`config/p10k.zsh` 原子同步到 `~/.config/my-pi/p10k.zsh`(遵循 `XDG_CONFIG_HOME`)。
该配置来自当前使用的 Powerlevel10k Rainbow/ASCII 单行紧凑主题;用户自己的
`~/.p10k.zsh` 不会被覆盖。脚本只在 `.zshrc` 中写入带首尾标记的主题和加载受管块。
- 逐项检查 `git``zsh-autosuggestions``zsh-syntax-highlighting` 是否已经在
`.zshrc``plugins` 数组中启用。后两个插件缺少源码时会先克隆到 Oh My Zsh 的
custom plugins 目录;语法高亮按最后一个插件处理。
- 最后继续检查 `codegraph``kotlin-lsp`、Java 21+ 和 `jdtls`。Kotlin、Java 和 JDT LS
的自动安装使用 Homebrew。
脚本首次实际改动 `.zshrc` 前会在同目录创建带时间戳的备份。Oh My Zsh loader、
Powerlevel10k 主题/配置和各 Zsh 插件使用 `# >>> my-pi:<id> >>>`
`# <<< my-pi:<id> <<<` 的受管块协议;以后只替换块内内容,块外用户配置保持不变。
标记缺失、重复或不完整时脚本会拒绝修改。若机器没有所需的 Homebrew、`curl``git`
脚本会保留已完成的安装结果、继续检查其他项目,并最终返回非零状态。
`rtk` 只供默认关闭的命令改写使用,因此不会作为必装依赖检查。
也可以绕过脚本,直接运行上面的 `pi install` 命令,此时机器级 CLI 不会被检查。
升级已安装的组合包请使用独立脚本:
```bash
./update.sh
```
升级脚本先执行:
```bash
pi update git:git@bitbucket.org:siakitem/my-pi.git
```
随后只处理已经安装的项目,未安装项直接跳过且不会询问安装:Kitty 及已启用的
Solarized Dark、Oh My Zsh、Powerlevel10k、两个第三方 Zsh 插件、CodeGraph,以及由
Homebrew 管理的 Kotlin LSP、Java 21 和 JDT LS。升级前会先刷新或查询对应的远端版本:
Git checkout 在 `fetch` 后比较本地与上游提交,Homebrew 包在刷新元数据后通过 `brew outdated`
判断,Kitty 官方安装和 CodeGraph 则比较本地版本与官方最新发布版本。只有检测到版本不同时才
下载并替换;无法确认安装来源或无法可靠比较版本时保留现状并报告。
日志中的“Zsh 插件未安装,升级流程跳过”不是升级失败:升级脚本不会新增用户此前未选择的
插件。需要补装时重新运行 `./install.sh`,并在对应的逐项询问中明确选择 `Y`
升级时会优先从 `pi update` 后的已安装组合包目录读取最新 `config/p10k.zsh`,再与受管副本比较,
只在内容不同时备份并原子同步;`.zshrc` 也只更新已有的 my-pi 受管块,不触碰块外配置。因此安装流程负责补齐缺失项,升级流程只升级
已安装项并同步已受管配置。
卸载组合包:
```bash
./uninstall.sh
```
卸载脚本只调用 `pi remove`,不会删除 Kitty、终端主题、Oh My Zsh、Powerlevel10k、Zsh
插件、CodeGraph、Kotlin LSP、JDT LS 或 Java,因为这些用户环境或机器级工具可能仍被其他
项目使用。三个脚本都可通过 `PI_PACKAGE_SOURCE` 覆盖默认包源,
例如在本地检出中测试:
```bash
PI_PACKAGE_SOURCE="$PWD" ./install.sh
PI_PACKAGE_SOURCE="git:git@bitbucket.org:siakitem/my-pi.git" ./update.sh
```
`package.json` 对外部依赖使用精确版本,对本仓库维护的包(包括 Codex Fast mode)使用 `file:` 路径;`package-lock.json` 固定完整依赖树。不要再用项目级 `.pi/settings.json` 重复安装这些扩展,否则同一扩展可能被加载两次。
Hippo 官方 Pi Extension 存在于上游 Git 仓库的 `extensions/pi-extension/`,但没有包含在
`hippo-memory@1.33.0` npm tarball 中。本仓库从官方 `v1.33.0` /
`e928179a3b35e8fe5837878aed071d6025ced45c` 导入源码到 `hippo-memory-pi/` 并直接加载;
匹配的 CLI 版本由 `config/hippo-memory-version` 声明。`install.sh` 会在 CLI 缺失时询问是否执行
`npm install -g hippo-memory@<固定版本>`,但安装脚本不会选择或初始化项目。进入目标项目后可在 Pi 中执行
`/plugin_init`:命令会显示当前目录并要求确认,以 `.codegraph/codegraph.db``.hippo/hippo.db`
初始化标志,只为缺失状态运行 `codegraph init``hippo init`;全部成功后通过 Pi 官方热重载重新连接 CodeGraph MCP 并重新触发 Hippo
session start。也可以继续在终端手动执行两个 CLI 的 `init` 命令。
默认配置不需要系统 `rtk` CLI。只有以后在 `/rtk` 中主动开启 RTK command rewriting 时,才需要另外安装 `rtk` 可执行文件。
CodeGraph 本体不由组合包安装。需要使用 CodeGraph 的机器应自行确保 `codegraph`
启动 Pi 的 `PATH` 中。组合包只有在用户显式调用 `/plugin_init` 并确认当前项目后才会创建
`.codegraph/`;安装、升级和普通启动流程不会创建或维护索引,也不会修改 CodeGraph 的更新或遥测设置。
## 组合行为
### 模型主动提问
`pi-ask-user/` 把 Pi 上游的单题与多题示例合并为唯一的 `ask_user_question` 工具;不提供 `/qna` 或其他用户命令。模型只有在继续任务确实缺少用户决定、偏好、确认或澄清时才应加载 `user-interaction` 组并调用它,不得重复询问直接消息中已有的信息。工具仅在交互式 TUI 中运行,最多一次提交 8 个问题,支持选择、自由文本、显式跳过、返回修改和最终复核;取消结果不会作为 AutoReview 的授权证据。
### 工具与搜索路由
`extensions/tool-routing.ts` 不替换 Pi 默认系统提示词,而是在每轮开始前根据当前激活工具追加简短规则。代码结构、调用关系和待修改 symbol 优先使用 CodeGraph,定义、引用、类型和修改后诊断优先使用 LSP;仓库字面搜索先用 FFF `find` 缩小文件或目录范围,再在已收敛的路径中用 `grep`/`multi_grep` 获取行号。宽泛搜索命中大量结果、发生截断或达到上限时,应继续缩小路径、glob 或 pattern,而不是提高 limit 或输出全部结果。
在线搜索默认按任务只选一个服务:关键词不确定、新闻/近期话题或需要较多候选来源时优先 Tavily;官方/API 文档、版本信息、论文和高确定性事实确认优先 Exa;中文政策、政府公告、中文网页、站点限定和日期筛选优先 Keenable。只有来源质量或不确定性确实需要时才跨服务复核,避免默认把三套结果全部塞进上下文。
日志、测试/构建输出、工作区内大文件的探索/分析/总结以及不可预测的大输出优先交给 Context Mode。只有确实需要精确源码或准备修改时,才用带 `offset/limit` 的 Hashline `read` 读取最小区域并取得 `LINE#HASH` 锚点,随后用锚定 `edit` 修改;成功编辑返回的新锚点可继续复用,只有锚点过期或下一目标区域尚未展示时才重新读取。已有工具结果足够时停止检索,避免对同一问题依次重复调用 CodeGraph、FFF 和 `read`
使用 `/dump-system-prompt` 可将当前扩展所见的有效提示词写入当前项目的 `.pi-debug/effective-system-prompt.md``.pi-debug/` 属于本地诊断输出,默认不提交。
### 按需加载工具 schema
`pi-tool-search/` 从上游 <https://github.com/tuansondinh/pi-tool-search> 的 `v0.3.6`、commit `ddfb23646fd3957b791214de278e23aa393c9b13` 导入,并像 `pi-rtk-optimizer/` 一样由本仓库直接维护;它不是 submodule,不加载 npm 预编译入口,也不保留嵌套 `.git`、上游 `.pi` 状态或构建产物。来源、许可证说明和本地差异记录在 `pi-tool-search/UPSTREAM.md`
本地源码直接使用 `@earendil-works/pi-coding-agent`、当前 `typebox``ModelRegistry.complete()``setActiveTools()`,不安装、别名映射或加载旧 `@mariozechner` runtime,也不使用 provider payload 改写、代理执行或隐藏 `sendMessage` 循环。
新 session 默认常驻 Pi 核心 `read``write``edit``bash``grep``find`,以及 `codegraph_explore``lsp_diagnostics``tool_search`。组合包在 `pi-tool-search/extensions/bundle-groups.ts` 中为自身暴露的工具预置权威分组,包括本地文件导航、SSH 远端文件/命令、用户交互、CodeGraph/LSP、Tavily、Exa、Keenable、Context Mode 执行/知识库/观测/管理、Memory 查询/维护、Skill 和 MCP 管理。不可用的可选工具会自动从组中滤除,固定工具也不占动态组额度。
标准组合包的全部隐藏工具都能命中预置目录,因此首次使用不调用模型、不生成用户缓存,也不把完整隐藏 schema 发送给 provider。只有用户另外安装了未识别工具时,才先为新增工具提供确定性分组,并可在第一次 `tool_search` 时使用当前已认证模型补充目录;模型结果必须保留组合包预置分组,否则直接拒绝。有效增强缓存以 `0600` 写到 agent 目录的 `tool-search/catalog-v1.json`,调用用量计入工具结果。用户 `groupOverrides` 的优先级高于预置目录;`/tool-search-rebuild` 会立即恢复预置目录,只有仍存在额外工具时才可能在下次搜索惰性增强。
动态组默认最多同时加载 3 个、每个模型生成组最多 8 个工具、全部动态组最多 20 个工具。加载或调用组内工具会更新 LRU;加载第 4 组或超出工具总量时先卸载最久未使用的非固定组。首次纯增加载继续使用 Pi 原生增量传播;发生卸载和加载的替换不是纯增量,Pi 会自动走安全 fallback。
首次加载仅在 `settings.json` 缺少对应字段时写入:
```json
{
"toolSearch": {
"alwaysEnabled": ["codegraph_explore", "lsp_diagnostics"],
"showToolSearchFooterStatus": false,
"maxActiveGroups": 3,
"maxToolsPerGroup": 8,
"maxDynamicTools": 20,
"groupOverrides": {}
}
}
```
用户已有配置不会被覆盖;结构无效时也不会重写原文件。`alwaysEnabled` 中的精确工具名属于固定工具,不占动态组额度;`groupOverrides` 可把指定工具强制归入命名组。默认关闭状态行,避免与 minimal footer 叠加。
### 精确读写归 Hashline
组合包固定加载 `pi-hashline-edit@0.8.3`,以带 `LINE#HASH` 行锚点的实现覆盖 Pi 内置 `read``edit``extensions/hashline.ts` 在加载扩展前把 `config/pi-hashline-edit.json` 同步到 `~/.pi/agent/hashline.json``hashLength` 保持最小的 `2``grep` 强制关闭以避免与 FFF 冲突,`replaceText` 关闭以要求修改使用可验证锚点。
Hashline 不负责压缩大文件;每行锚点本身还会增加少量 token。上下文节省来自先用 CodeGraph/LSP 定位、再用 Context Mode 隔离分析,最后只对真正准备修改的区域执行小范围 Hashline `read`。因此不应为了探索、计数、比较或总结而直接读取完整大文件。
### 搜索归 FFF
`extensions/fff-override.ts` 强制设置 FFF 官方的 `PI_FFF_MODE=override`(显式传入
`--fff-mode` 仍按 FFF 官方优先级覆盖它)。FFF 替换
Pi 的 `find``grep`,并提供 `multi_grep`RTK 对所有 `grep` 工具结果直接跳过,
也默认关闭 Bash 命令改写,因此不会把 `rg``grep``find``fd` 改写到 RTK。
### 输出压缩归 RTK
RTK 保留 Bash、read、build、test、lint 和 Git 输出压缩。默认 `read` 的有损压缩
仍关闭;可用 `/rtk` 查看或调整。旧机器已有的 RTK 配置若没有
`commandRewritingEnabled` 字段,也会按 `false` 归一化,不需要迁移配置。
### 大输出归 Context Mode
Context Mode 直接加载 npm 包内置的 Pi adapter 和 skills,不需要额外写入
`~/.pi/agent/mcp.json`,也不需要全局安装 `context-mode` 命令。它提供 `ctx_*` 工具,
将批量读取、命令研究和网页内容先在隔离进程中处理,再把收敛后的结果送入上下文。
FFF 仍负责精确字面搜索;RTK 继续压缩未走 Context Mode 的 Bash、build、test、lint
和 Git 输出。Context Mode 不替换这两个扩展的现有配置。
### SSH 服务器配置
`pi-ssh` 运行时使用纯 `ssh2`,不依赖系统 `ssh``sshpass`。首次使用前显式导入需要的 OpenSSH alias
```bash
./ssh_config.sh import packaging-server
```
脚本只在导入阶段调用 `ssh -G` 解析用户选中的 alias,随后交互选择 Key 或密码认证、显示并确认服务器 Host Key、测试连接,再把完整配置写入 `${XDG_CONFIG_HOME:-$HOME/.config}/my-pi/pi-ssh/hosts.enc`。邻接的随机 `vault.key` 用于 AES-256-GCM 解密;目录与两个文件在 POSIX 上分别是 `700` / `600`。该加密只避免误看或单独泄漏密文,能读取两文件的同一用户仍可解密。
可用 `./ssh_config.sh list|update|remove|rotate-key` 管理已导入主机。第一版拒绝 `ProxyJump` / `ProxyCommand`,且不会自动读取远端 `AGENTS.md``CLAUDE.md`。连接不再通过 `/ssh``--ssh` 或 session resume 建立:用户在具体远端任务中明确指定已导入 host ID 后,Agent 把受复核、串行且可取消的 `ssh_connect` 作为独立步骤调用并等待成功,再使用其他 `ssh_*` 工具;连接动作及后续操作均进入 `ask → auto-review`,相对远端路径会在预览中显示请求值和解析后的绝对路径,会话结束自动断开。SSH transport 在会话内持久,独立命令最多使用 4 路有界并发 exec channel,但每次 `ssh_bash` 都启动独立的非交互 Shell;需要持续改变后续远端操作的工作目录时,Agent 同样必须把受复核且串行执行的 `ssh_cd` 作为独立步骤调用并等待成功,而不是依赖某次 Shell 中临时执行的 `cd`
远端文件搜索使用独立的 `ssh_find` / `ssh_grep`:在每次获批调用内按服务器现有能力选择 `fd/fdfind → git ls-files → find``rg → git grep → find+grep`,不安装远端软件,并以最大 200 条结果、单行截断和 `truncated` 标记约束返回。搜索目标作为绝对参数与当前远端执行 cwd 分离,因此 `ssh_grep` 可直接搜索单个文件而不会尝试把文件当目录进入;30 秒超时会报告解析后的 root 并提示先用 `ssh_find` 缩小范围。远端 HOME/cwd 通过可取消、有界随机标记探测获得,畸形结果不会更新连接状态。RTK 只压缩 `ssh_bash` 的非搜索输出,不改写远端命令,也不处理 `ssh_find``ssh_grep``ssh_read`。详细说明见 [`pi-ssh/README.md`](pi-ssh/README.md)。
### 在线搜索服务
运行 `./search_config.sh` 可用隐藏输入依次配置 Tavily、Exa 和 Keenable;也可一次无交互配置:
```bash
./search_config.sh --tavily '...' --exa '...' --keenable '...'
```
只传部分参数时保留其他服务的已有值。脚本把 key 原子写入
`${XDG_CONFIG_HOME:-$HOME/.config}/my-pi/search.env` 并设置权限为 `600`
`MY_PI_SEARCH_CONFIG``--config` 可覆盖路径。组合包在搜索扩展初始化前加载该文件,
但调用 Pi 时显式传入的同名环境变量优先。配置文件不属于仓库,不会随安装包提交。
Tavily 通过 `extensions/tavily-override.ts` 加载官方扩展。override 只改工具身份,不改官方执行逻辑:上游 `web_search` / `web_fetch` 被注册为 `tavily_web_search` / `tavily_web_fetch`,label 和提示词中的内部工具引用也同步带上 Tavily 标识。使用前需设置 `TAVILY_API_KEY`。Tavily 适合广泛发现,但来源可能混杂且输出较长,应从较小的 `max_results` 开始,非必要不返回 raw content。
Keenable 直接加载 npm 包的扩展和 skill,默认无需 key;设置 `KEENABLE_API_KEY` 可提高速率限制。它适合中文内容、`site` 限定和发布日期筛选。搜索结果保持紧凑,只对选中的 URL 调用 `keenable_fetch`
`extensions/mcp.ts` 通过单个 `pi-mcp-adapter` 实例同时连接 Exa 与 CodeGraph,避免两个 adapter 重复注册 `--mcp-config``/mcp``/mcp-auth`。其中 Exa 连接 `https://mcp.exa.ai/mcp`,并把 MCP 原始工具映射为统一的来源前缀形式:`exa_web_search``exa_web_fetch``exa_web_search_advanced`。配置 `EXA_API_KEY` 后通过 `x-api-key` 请求头认证,不把 key 放进 URL。Exa 适合官方文档、技术资料、版本信息和论文;高级搜索必须显式限制结果数量与返回文本长度,避免响应过大。
根测试会扫描所有本地扩展入口,强制只有 `extensions/mcp.ts` 可以创建或导入 `pi-mcp-adapter`。新增 MCP 服务必须合并进这个共享实例,不能再增加独立 adapter 入口;隔离 Pi 加载仍作为发布前的运行时验证。
### CodeGraph 只负责连接
同一个 `extensions/mcp.ts` adapter 配置启动
`codegraph serve --mcp`,不会读取或覆盖用户已有的 MCP 配置。连接采用
`keep-alive`,并只把官方当前主工具 `codegraph_explore` 作为同名 Pi 工具暴露;
CodeGraph 的文件 watcher 由该 MCP 进程自身维护。
若机器没有 `codegraph`,或当前项目尚未建立索引,CodeGraph 会报告连接/初始化错误,
其他扩展仍可正常工作。安装与索引状态可在机器上自行检查:
```bash
codegraph --version
codegraph status
```
在当前项目需要同时初始化 CodeGraph 和 Hippo 时,可直接执行:
```text
/plugin_init
```
该命令拒绝文件系统根目录和用户主目录,先确认两个 CLI 均可用,再依次初始化缺失数据库状态。任一步失败都不会热重载,也不会回滚此前已成功完成的初始化;两者已初始化时仍可用该命令快速热重载扩展。
### 权限基线自动部署
`pi-permission-system/` 从上游 `pi-permission-system-v26.2.1` tag 导入,初始源码快照为 `ec4fdb11343dc94f7185b113e559a4cf9f8dc035`。根包通过本地 `file:` 依赖提供其运行时依赖,并由包装入口直接加载仓库源码,不再加载 npm 包中的实现。
`extensions/permission-system.ts` 在权限扩展注册前,把仓库中的
`config/pi-permission-system.json` 同步到 Pi agent 目录。仓库文件是权威配置;直接在
运行目录通过 UI 修改的策略会在下次加载组合包时被覆盖,长期调整应提交到本仓库。
当前策略按类别划分:
- 默认工具:默认允许,避免常规编码操作反复确认;FFF 的 `grep``find`
`multi_grep` 明确允许。
- 搜索边界:直接通过 Bash 调用 `rg``grep``find``fd``git grep` 拒绝,统一走 FFF。
- 路径与凭据:外部目录询问;环境文件、SSH/GPG、云凭据、Keychain 和 Pi 认证文件拒绝;
`.env.example` 作为无密钥模板允许。
- Git:状态、diff、日志、对象查看等只读命令允许;其他 Git 命令进入 `ask`,由自动复核 authorizer 裁决。
- Bash 变更操作:Git 非只读操作、包管理、文件变更、系统操作、网络访问和环境导出均由权限基线先判定;命中 `ask` 后再进入自动复核。
- MCP 与 Skill:列举 MCP 状态允许,调用其他 MCP 工具进入 `ask`;本地 Skill 加载允许。
`permissionReviewLog` 已开启,后续可依据真实命中记录继续收敛规则。
### Permission Auto Review 与权限基线的边界
`pi-permission-auto-review/` 从上游源码仓库的 `@mzwing/pi-permission-auto-review@0.2.0` tag 导入,初始源码快照为 `8d196e4ef0884cac8326c366191dad3f585d470a`。该目录与 `pi-rtk-optimizer/` 一样由本仓库直接维护,不依赖 npm 中的预编译扩展包。
扩展以 `auto-review` 名称注册到 `pi-permission-system` 的 authorizer chain。只有权限基线先得到 `ask` 时才调用 reviewer:模型返回 `allow` 时自动批准,返回 `deny` 时直接拒绝,配置、模型、认证、超时或响应异常时返回 `defer` 并继续走正常人工提示。这样只有一条权限链,不再存在两个独立 `tool_call` gate 造成的重复审批。
边界保持如下:
- `allow`:权限基线已明确允许的常规操作不会调用 reviewer。
- `deny`:Bash 直搜、敏感凭据路径等硬拒绝不会交给 reviewer,也不能被其绕过。
- `ask`:Git 非只读操作、包管理、文件/系统/网络/环境操作和普通 MCP 调用交给 reviewer`path` 仍全部受 delegation envelope 保护。`external_directory` 允许内置只读路径工具(`read``find``grep``ls`)接受 reviewer 的 `allow``write``edit`、Bash、未知工具及其他外部目录访问仍降级为人工确认。
reviewer 默认使用 `openai-codex/codex-auto-review`、low reasoning 和内置 Codex Guardian 风格策略,并读取当前 session active branch 中的可信用户证据。可通过 `/permission-auto-review` 查看或调整全局/项目配置;无配置时使用源码内置默认值。
### TypeScript、Kotlin 与 Java LSP
`extensions/lsp.ts` 会把 `config/lsp.json` 部署到全局 `~/.pi/agent/lsp.json`,其中启用:
- `typescript-language-server@5.3.0 --stdio`:匹配 TypeScript/JavaScript 及 JSX/TSX、MTS/CTS、MJS/CJS;组合包同时固定 `typescript@6.0.3` 作为 `tsserver` 后端。
- `kotlin-lsp --stdio`:匹配 `.kt``.kts`
- `jdtls`:匹配 `.java`;官方 wrapper 会按当前项目工作目录选择 cache data 目录。
TypeScript LSP 通过组合包内 Node 和 `typescript-language-server` CLI 直接启动,不依赖、调用或拉起 VS Code GUI;部署配置时会把包内 CLI 的绝对路径写入全局配置。它优先使用项目自身可用的 TypeScript,否则回退到组合包固定的 TypeScript 6 后端。
Kotlin 与 Java 按 Gradle、Maven 或 Git marker 定位项目根,忽略常见构建输出,并为大型 Android/Gradle
项目预留 120 秒启动时间。Kotlin 与 Java 的 language server 可执行文件不由根包安装;使用前需
确保 `kotlin-lsp``jdtls` 位于启动 Pi 的 `PATH`。Kotlin 官方 Homebrew 安装方式为:
```bash
brew install JetBrains/utils/kotlin-lsp
```
JDT LS 需要 Java 21 或更高版本;可使用带 `jdtls` wrapper 的官方发行包或系统包。
### Hippo Memory
官方扩展要求全局 `hippo` CLI,并要求目标项目存在 `.hippo/`。组合包加载仓库内官方扩展源码,
注册 `hippo_recall``hippo_remember``hippo_outcome``hippo_status``hippo_context` 五个工具。
Session 启动时它注入项目记忆上下文,失败工具结果经过噪声过滤、每 Session 上限和去重后自动记录,
Session 关闭时运行 `hippo sleep`,从 Git 学习、整理记忆并执行官方共享逻辑。项目 `.hippo/`
本机记忆状态,本仓库默认忽略提交。
Hermes 的 `memory_add` / `session_search` / `skill_manage` 与 Markdown/SQLite 数据不会被 Hippo 自动迁移;
切换扩展不会删除 `~/.pi/agent/pi-hermes-memory/``~/.pi/agent/projects-memory/` 中的旧数据。需要保留的
旧记忆应另行审核后导入,不在安装、升级或卸载流程中自动转换或删除。
`install.sh` 只对缺失的 Hippo CLI 询问一次,默认拒绝;缺少 npm 时保留已完成的组合包安装并报告失败。
脚本不会扫描仓库、选择目录或执行 `hippo init``update.sh` 只处理已经存在且确认属于 npm 全局安装的
Hippo CLI:从升级后的组合包读取固定版本,先通过 npm 确认版本存在,再比较本地版本,只有不同时才升级。
`uninstall.sh` 移除组合包后询问是否一并执行 `npm uninstall -g hippo-memory`,默认保留;无论选择什么,
`.hippo/` 和用户记忆数据都不会被脚本删除。
### Kitty 完成通知
`pi-notify/` 直接加载本地维护源码。它只在交互式 TUI 中监听 `agent_settled`,因此自动重试、自动
compaction 和排队 follow-up 完成前不会提前通知。Kitty 后端使用 Base64 OSC 99、每个 Pi Session
独立的稳定通知 ID、显式 `a=focus`,并默认设置 `o=unfocused`:来源 Kitty window/pane 有键盘
焦点时不打扰,切到其他 Kitty 窗口、tab 或 pane 后才通知,点击通知由 Kitty 返回原始来源。
默认忽略不足 3 秒的短任务。`/notify on|off|test|status` 可控制当前 Session;持久默认通过
`PI_NOTIFY_ENABLED``PI_NOTIFY_MIN_SECONDS``PI_NOTIFY_VISIBILITY``PI_NOTIFY_ACTION`
`PI_NOTIFY_MESSAGE_SOURCE` 等环境变量配置。`PI_NOTIFY_MESSAGE_SOURCE=none` 可避免把回复摘要发送到
macOS 通知中心。Kitty 位于 tmux 内时需要 `set -g allow-passthrough all` 并重启 tmux server。
完整配置和上游差异见 [`pi-notify/README.md`](pi-notify/README.md)。
### Codex 原生远程压缩
远程压缩只对 `openai-codex/openai-codex-responses` 生效,使用上游默认配置:在 turn boundary
达到 90% 上下文占用时触发,并写入 Pi 原生 compaction boundary。失败时保持原历史且不静默
回退到文本摘要;checkpoint 与创建它的 Codex model 绑定。
### Pi Condense
组合包首次加载时会在 `contextPrune.enabled` 尚未配置的情况下写入 `true`,因此 `pi-condense` 默认开启;用户通过 `/pruner off` 写入的显式 `false` 会被保留,后续启动或升级不会重新覆盖。它使用上游默认的 `agent-message` 触发模式:同一用户任务中的多轮工具调用会在最终文本回复后统一触发整理,默认仍按每个 assistant turn 分别生成摘要;后续上下文只保留摘要和 `t1``t2` 等引用。需要原文时,模型可调用 `context_tree_query({ toolCallIds: ["t1"] })` 恢复。
常用命令:`/pruner status` 查看状态,`/pruner settings` 调整配置,`/pruner now` 立即处理待总结批次,`/pruner tree` 浏览已归档调用,`/pruner stats` 查看累计成本和节省,`/pruner off` 关闭。配置保存在 Pi agent 目录 `settings.json``contextPrune` 字段。建议保留默认的 skill 路径保护,并把必须逐字复用输出的工具加入 `protectedTools`
它与 Context Mode 的职责不同:Context Mode 避免大型原始输出进入当前模型上下文,Pi Condense 则压缩已经进入会话、且已完成使用的历史工具结果。它也不替代 Codex 原生远程 compaction;不希望自动整理历史时可运行 `/pruner off`
### Codex fast mode
该扩展只在 `openai-codex` provider 的 Responses 请求上加入
`service_tier: "priority"`。使用 `/fast-mode on|off` 修改当前分支状态时,也会把全局默认值原子写入 Pi agent 目录下的 `extensions/pi-extension-codex-fast-mode/config.json`;新会话继承该默认值,恢复已有会话时仍由分支内最新记录优先。`/fast-mode status` 同时显示当前分支状态和新会话默认值。配置目录与文件分别使用 `0700` / `0600` 权限;配置缺失或无效时安全回退为关闭。其他 provider 不受影响。