@andares/pi-toolkits

中文文档
0.13.0发布于 2026/11/12MITES Module构建来源已验证近 30 天下载 3494

Pi的综合工具包扩展——询问模式(只读QQA),浏览器审查规划,一个包含浏览器页面的接受分类账,会话范围权限检查,模型最爱,即时存储,第三方代码审查,会话自动启动,专用c

中文使用文档
文档目录20 节
  1. 📦 安装
  2. 📚 目录
  3. ✨ 功能总览
  4. 🛡️ ask — 只读咨询模式
  5. 🔐 permission — 会话级边界权限
  6. ⭐ favorites — 模型收藏
  7. 📥 stash — 提示词暂存
  8. 🔎 review — 第三方代码评审
  9. 🧭 plan — 先出计划,浏览器里评审,批准后再动手
  10. ✅ uat — 验收台账与浏览器页面
  11. 🗜️ compact — 独立压缩模型
  12. 🚀 autostart — 会话启动自动化
  13. 🧠 init — agent 记忆框架
  14. 🧯 quit-guard — 退出看门狗
  15. 命令
  16. 边界
  17. 🛠️ 开发
  18. 项目结构
  19. 🤝 贡献
  20. 📄 许可

⚙️ @andares/pi-toolkits

English · 中文

pi 编码代理的集成扩展工具包 — 一个包,持续生长新能力。

npm version Pi package gallery License: MIT Package Manager pi >= 0.99 GitHub

一句话介绍:目前包含十一个开箱即用的功能——只读咨询模式 ask、会话级边界权限 ask-perm、模型收藏 favorites、提示词暂存 stash、第三方代码评审 ask-review、独立压缩模型 compact-model、会话启动自动化 autostart、agent 记忆框架 ask-init、浏览器内计划评审 ask-plan、验收台账与浏览器页面 ask-uat、退出看门狗 quit-guard,后续持续追加。

版本要求:pi >=0.99.0。0.99.0 到 1.5.1 的每一个已发布版本都用完整门禁实测过(install → tsc --noEmit → 全量测试 → 键位审计 → 对 patch 目标宿主文件做哈希比对),每个版本都在沙箱中把整个 @earendil-works/* 家族钉在同一版本。更新的版本随发布逐个验证,下限只在实测结果允许时移动;pnpm check:compat 可复现该结论。注:pi ≥ 0.99 的宿主要求「宿主提供的包」一律声明为 peerDependencies "*" —— @earendil-works/pi-tui 与 typebox(ask 的 scratchpad 用它构造参数 schema)都按此声明;若放进 dependencies,pi 会告警。


📦 安装

# 从 npm 安装(推荐) —— 也已收录进 pi 官方包编目
# https://pi.dev/packages/@andares/pi-toolkits
pi install npm:@andares/pi-toolkits

# 本地开发安装
pi install .

# 单次会话加载,不安装
pi -e ./src/index.ts

安装后在任意 pi 会话中验证:

  • /ask → footer 出现灰色 ask 状态,write/edit 被硬禁用,同时出现 scratchpad 工具用于草稿笔记
  • /model(或 ctrl+l)→ 选择器顶部出现收藏提示行;对选中模型按 ctrl+A → 文字变加粗亮黄、收藏计数 +1(这一步同时就是真机按键检查,见「键位」约定)
  • 输入框内按 ctrl+alt+y → 当前提示词被暂存并清空输入框
  • 完成一个开发任务后输入 /ask-review → 切换到评审模型执行查+修
  • /compact-model 选一个便宜快模型 → 之后 /compact 与自动压缩的总结都由它执行(footer 出现灰色 compact 状态)

📚 目录


✨ 功能总览

功能入口一句话说明
🛡️ ask 只读咨询模式/ask进入咨询模式:write/edit/powershell 硬禁用,bash 只读沙箱,临时启用 grep/find/ls,并开放 scratchpad 把草稿写进会话临时目录
🔐 permission 会话级边界权限/ask-perm项目内/外 × 读/写四格模式,默认关闭且从不落盘;项目外写询问、凭据路径硬拒、破坏性命令必问;与 /ask 并行组合;另有滚动 JSONL 审批日志供事后挖规则
⭐ favorites 模型收藏/model 内 ctrl+A / ctrl+J收藏常用模型(加粗亮黄标记),ctrl+p 仅在收藏间循环
📥 stash 提示词暂存ctrl+alt+y一段提示词的暂存槽,按键交换 / 连按两次暂存并清空输入框
🔎 review 第三方代码评审/ask-review召唤配置的评审模型,对刚完成的任务做查+修,重点检查「本轮需求实现 / 是否有遗漏 / 是否有错误」
🧭 plan 浏览器内计划评审/ask-plan先调研、写 plan、在浏览器里逐段评审并逐块批注,批准之后才动代码
✅ uat 验收台账/ask-uat把待归类的实施记录聚成用户视角的验收项,在页面里勾选(只追加、无提交),看清哪些已交付但还没验过
🗜️ compact 独立压缩模型/compact-model给 /compact 与 auto-compact 配一个便宜快模型做总结,主模型专注对话;未配置零开销、任何异常回落 pi 默认
🚀 autostart 会话启动自动化.pi/autostart.toml项目内声明启动时自动执行的斜杠命令(首批用例:/add-dir 多仓库挂载);未信任不执行、未注册命令跳过不发给模型
🧠 init agent 记忆框架/ask-init安装或接管一套固定的记忆结构(AGENTS.md + specs/ + .agents/memory + .agents/implementations),带快照与覆盖表迁移旧文档,之后可随时审计漂移、预算与重复事实
🧯 quit-guard 退出看门狗/quit-guard交互式退出卡死时,无论发生在 TUI 收尾之后、还是信号触发路径的收尾之前,超时后写诊断报告并强制退出,把命令行提示符还给你;TUI 重启与 Ctrl+Z 恢复都会解除看守

🛡️ ask — 只读咨询模式

用 /ask 进入(再按一次退出)。适合只想要「问问题、读代码」的场景:模型不能改项目,但不会被剥夺思考的落点。

进入后:

  • 项目文件写入仍然机制上不可能 —— write / edit / powershell 从活跃工具集中移除,pi 对未激活工具的调用直接拒绝("Tool not found");闸门还会二次拦截,防止有东西把它们重新打开
  • 只留一个写通道:scratchpad —— 参数是相对笔记名(plan.md、notes/api.md),只能落到 <os.tmpdir()>/pi-ask/<session-id>。它注册时处于未激活状态(defaultActive: false),只在 ask 模式里启用,所以它的声明与「笔记不是交付物」的 guidelines 恰好在适用时才进入请求。单文件上限 256 KiB,路径上已存在的符号链接会被拒绝,里面的东西永不被执行—— bash 沙箱因此完全不需要写权限。宿主没有可写临时目录时工具保持未激活,模式降级为旧的纯只读(进入时的提示会说清楚,不做半开)
  • 临时启用只读检索工具 —— grep / find / ls(宿主已注册但默认不激活)在 ask 期间打开,让模型有正规搜索工具而不是只能走 bash;退出时按进入前快照完整恢复
  • bash 保留但只读沙箱 —— shell 分词 + 逐段校验 + 写盘意图检测。除常见读取命令外,放行 git 考古族(blame、grep、rev-parse、describe、shortlog、reflog show、stash list、tag -l、cat-file 等)、包元数据查询(pnpm view、pip show/list、python -m json.tool),以及网络读取 curl -s <url> / wget -O - <url>。仍拦截:重定向、tee、dd、sed -i、安装/构建、git 变更类命令、命令替换、会启动其它程序的选项(find -exec、git grep -O、rg --pre),以及一切写盘目标(curl -o、wget -O file、git diff --output=、tree -o)。启发式,非安全边界
  • 短横幅而不是清单 —— 系统提示词只追加三行:咨询模式、草稿通道、退出方式。不再重述 bash 白名单 —— 那是沙箱的职责,被拦时的拒绝理由会直接指出可用的替代,所以细节只在真用到的那一轮付费(旧横幅每个请求都要重申一遍,约 300 token)。横幅不含路径与时间戳,会话内字节稳定,可以稳定命中 provider 的提示词缓存
  • 拒绝理由指向下一步 —— 被拦的 write / edit 会说明草稿用 scratchpad、真正改动要 /ask 退出;被拦的重定向也同样指路,而不是只说「不能写」
  • 灰色 ask footer 状态 —— 常驻提示当前处于咨询模式

草稿生命周期:每个会话一个目录,位于系统临时目录(os.tmpdir(),所以 Windows 的 %TEMP% 也适用);进入时创建、退出时不删——续会话(pi -c)还能找回笔记,进程内切换会话(/new、/resume、fork)会重新绑定到新会话的目录;进入时清掉超过 7 天的旧目录。开启提示会打印路径;里面的内容不属于项目,也不会出现在 git status 里。

退出:再按 /ask,完整恢复进入前的工具集快照(含 scratch 工具与临时启用的只读工具)。


🔐 permission — 会话级边界权限

/ask-perm 只在当前会话开启边界检查。开关状态、四项模式、会话授权全部只存在扩展内存里:权限状态不落盘、默认关闭、关闭后不留任何状态。开启一次不会悄悄跟到下一个会话。另外,值得留档的判定会追加到本地审批日志(见下),供事后挖规则用;它是只写的遥测数据,判定时永远不会被读取。

开启

  • /ask-perm —— 打开模式面板。顶行按回车即应用,四行用空格循环、↑↓ 移动;光标默认在最上面,所以「输入指令 + 回车」就是按默认值开启
  • /ask-perm allow allow allow ask —— 位置参数形式(in-read in-write out-read out-write),不弹窗直接开启;没给全的参数回落到默认值。这也是 autostart 使用的形式
  • 再输入一次 /ask-perm —— 关闭

参数形式重复执行、且四项模式与当前一致时是空操作:不会再出一条「ON」提示,也不会清掉已经攒下的会话授权。只有模式真的变了才会提示并清空授权——那些授权是按旧策略给的。

默认值:项目内读/写全放行,项目外读放行,项目外写询问——但 os.tmpdir()、/var/tmp、/dev/shm 下的临时写入直接放行。显式把 out write 设为 deny 时仍然拒绝。

作用域读写 / 执行
项目内(工作目录 + /add-dir 加入的目录)in readin write
项目外out readout write

exec 折进 write:任何产生变更的执行都算写。

临时写入区:项目外、但落在操作系统临时根(os.tmpdir()、/var/tmp、/dev/shm)的写入,在 out write = ask 时直接放行(审计层记 temp)。/tmp 是共享草稿空间,这条是便利规则,不是隔离边界;删除临时根本身(rm -rf /tmp)仍然走破坏性表。

检查方式

  • bash 先拆成简单命令 —— &&、||、;、管道、$(…)、反引号、bash -c、eval、常见间接包装(sudo、env、xargs、find -exec…)、heredoc —— 再逐条判定;cd 向前折叠,取最严格的结果,所以 cd /tmp && rm x 不会靠第一段蒙混过关
  • 带路径的工具(read / write / edit / grep / find / ls)按自己的路径判定;其它工具按工作目录判定
  • 无法解析的输入 —— 非字面量 cd 或 git -C、路径里的未知 shell 变量、未闭合的 heredoc/命令替换 —— 一律询问,不看模式(fail closed),绝不猜测
  • git -C <dir> 按局部 cd 处理:相对路径参数(和仓库本身)按 <dir> 判定,而不是工作目录
  • 设备 sink 与数据参数 —— /dev/null、/dev/stdout、/dev/stderr 无论是重定向(cmd > /dev/null)还是普通操作数(curl -o /dev/null),都不算边界目标;echo / printf 的参数是数据,不按路径处理

回答:a 本次允许 · s 本会话允许该目录 · d 拒绝 · f 本会话拒绝该目录。会话授权在内存中按 (读|写, 目录) 保存、按包含关系匹配,关闭模式或会话结束时清空;会话授权优先于破坏性表——你按了 s 之后,重复同一操作不会再弹;解析不了完整路径的命令则按完整命令文本授权,重复同一条命令不会再问。

固定安全表(与四格模式无关):

  • 凭据路径任何模式都拒绝 —— ~/.ssh、~/.gnupg、~/.aws、~/.pi/agent/auth*.json、.env 文件(模板除外)。没有这一条,默认的「项目外读放行」就等于把 ~/.ssh/id_rsa 交出去
  • 破坏性命令永远询问 —— 对 /、家目录、工作目录或临时根(/tmp、/var/tmp、/dev/shm)的 rm;git reset --hard;git clean -f;git push --force;包 publish;dd 写裸设备;mkfs*;关机/重启;chmod -R 777;任何经 sudo 的命令。作用域本身表达不了「破坏性」

审批日志(只写遥测,默认开启)

每个值得留档的判定都会写成一行 JSON(JSONL),落在 ~/.pi/agent/approval-log/audit-NNNNNN.jsonl。策略层从不读它:删掉日志或把目录改成只读,不会改变任何判定结果。

  • 范围:/ask 模式的拦截同样算审批决定,也会记录(带闸门名与模型可见理由)。
  • 记录什么:交互弹窗(用户看到的原始行、bash 拆解结果、答复、授权与决策耗时)、自动拒绝/拦截、会话授权放行、/ask-perm 模式切换,以及每个会话一条 session 摘要(调用/弹窗/拦截计数)。普通自动放行的 read/grep 默认不记,避免把环形缓冲淹在噪声里;PI_APPROVAL_LOG=all 连普通自动放行也记,PI_APPROVAL_LOG=off 关闭日志。
  • 滚动:每文件 1000 条或 8 MiB,最多 10 个文件;创建第 11 个时删掉序号最小的那个。典型体积 15–30 MB(硬上限 80 MB),约保留最近 1 万条判定。
  • 保真度:四格模式、会话根目录、工具调用、每个命令单元(含 opaque 单元与解析器备注)、每个目标规范化后的路径/读或写/项目内或外、命中哪条规则层、弹窗原文、答复与产生的授权。write/edit 的文件正文永不记录(只记路径与字节数);bearer token、token=/password=、URL 内嵌凭据与已知密钥前缀会脱敏。
  • 失败与隐私:目录 0700、文件 0600,只在本机,可随时删除。日志故障只警告一次并被吞掉——判定链路不会因为日志不可用而失败。PI_APPROVAL_LOG_DIR 可改目录。
# 只看"本会话允许"的弹窗
jq -r 'select(.event=="ask" and .answer.choice=="allow-session")
       | [.ts,.tool,.verdict.target,.input.command] | @tsv' \
  ~/.pi/agent/approval-log/*.jsonl

# 目标根目录 × 答复 —— 找「临时目录直接放行」规则的最短路径
jq -r 'select(.event=="ask") | [.verdict.grantRoot,.answer.choice] | @tsv' \
  ~/.pi/agent/approval-log/*.jsonl | sort | uniq -c | sort -rn

# 解析不了的单元:定位 units.ts 的缺口
jq -r 'select(.event=="ask") | .units[] | select(.opaque) | [.command,.note] | @tsv' \
  ~/.pi/agent/approval-log/*.jsonl | sort | uniq -c | sort -rn

仓库内可用 pnpm approval-report 生成只读汇总(答复分布、目标根目录、候选规则、opaque 缺口、playwright 模式)。

与 /ask 的组合:两者是同一总线上的独立闸门,各自只回答自己的问题 —— ask 回答「会不会产生变更」,permission 回答「有没有越过边界」,任一拦截都生效。所以 ask 模式下凭据仍然读不到,permission 在只读沙箱下也照常工作;两个功能互不需要知道对方存在。

每个会话自动开启(状态本身不落盘,这就是持久化的替身;审批日志独立于它、默认开启):

# <项目>/.pi/autostart.toml;想对所有项目生效则用 <agent-dir>/autostart.toml
[command]
run = ["/ask-perm allow allow allow ask"]

实现说明:新会话在 session_start 重置状态(同一会话的重复 emission 保持状态);开启时 footer 显示 perm i:A/A o:A/ask(A allow、a ask、D deny)。子代理会话有自己的状态、不继承父会话的模式;需要子会话也受控时,通过项目 autostart 再开启一次。审批日志由闸门总线(弹窗/拦截/会话摘要)与 permission 闸门(模式切换、会话授权放行)追加;写入器懒初始化、不跨进程保存状态,也从不参与判定。实测目标是 POSIX 宿主(Linux/macOS/WSL);原生 Windows Git-Bash 的路径拼写只做了近似,未验证。bash 拆解使用 shell-quote;未知变量会展开成哨兵而不是空字符串,使该命令转为询问而不是被悄悄当成空路径。add-dir 目录从 pi-add-dir 的会话条目 add-dir:state 读取。启发式,不是沙箱:项目内的破坏性操作由固定表兜底,而不是靠沙箱。已知盲区一处:读命令的裸文件名参数(cat notes.txt)不被收集为目标,所以把 out read 调成 ask 时只有绝对路径形状的读目标会被问——读本身不会写,四格模式的写侧不受影响。


⭐ favorites — 模型收藏

标记常用模型,让模型切换「粘」在收藏上。收藏跨会话、跨项目全局持久化。

在 /model 选择器内(/model 或 ctrl+l 打开):

  • 顶部提示行显示按键与当前过滤状态
  • ctrl+A —— 对当前选中模型开/关收藏;收藏的模型文字显示为加粗亮黄
  • ctrl+J —— 开/关「仅显示收藏模型」过滤(可与内置搜索叠加使用)

模型循环:只要存在 ≥1 个收藏,ctrl+p / ctrl+shift+p 就只在收藏模型间循环。当前模型不是收藏时,ctrl+p 跳到第一个收藏、ctrl+shift+p 跳到最后一个;收藏仅 1 个时停在原地(Only one model available)。ctrl+l / /model 始终可自由选择任意模型(含非收藏)。在状态文件中设 "cycleOnlyFavorites": false 可恢复全量循环。

状态文件:<agent-dir>/pi-toolkits-favorites.json(默认 ~/.pi/agent/,与 auto-naming-session 配置同目录):

{
  "favorites": ["anthropic/claude-sonnet-4"],
  "config": { "cycleOnlyFavorites": true }
}

/favorites 命令列出当前收藏与循环模式。

实现说明:pi 的 app.model.cycleForward(ctrl+p)与 cycleBackward 是保留键位,扩展快捷键无法覆盖;且扩展快捷键只在编辑器聚焦时生效。因此本功能不重绑任何按键,而是在运行时 patch 两个内置原型(带版本守卫、/reload 幂等):ModelSelectorComponent(提示行、ctrl+A/ctrl+J、亮黄渲染、仅收藏过滤——按键仅在选择器内消费,编辑器里 ctrl+j 换行不受影响)与 AgentSession.cycleModel(收藏循环)。若 pi 升级导致 patch 无法应用,会 warn 并优雅降级,不影响其它功能。

为何是 ctrl+A 而不是 ctrl+F:pi 自 1.0 起 tuiMode 默认 fullscreen(0.87–0.99 默认 regular),而在 Windows/WSL 上宿主把 tui.altScreen.search 解析为 ctrl+f;TuiAltScreen.handleViewportInput() 在把输入交给聚焦覆盖层之前先检查该绑定,于是 ctrl+f 打开了会话记录搜索、根本到不了选择器。曾过渡性地选过 ctrl+alt+f——pi 层完全空闲,却被 Windows 侧截图工具作为全局热键截走:宿主表空闲 ≠ 机器层空闲。最终从 "favorite" 一词里逐字母审计:v 是 Windows Terminal 的粘贴键,o/r/t 是宿主 app 层动作,i 与 Tab 字节恒等(选择器的 scope 切换),e 可用但无记忆点;a 仅遮蔽搜索框内的行首跳转、读作 add favorite,且选择器上游无任何消费者。完整依据见 src/features/favorites/constants.ts 与 pnpm check:keybindings。


📥 stash — 提示词暂存

一个热键 + 一个暂存槽,在「当前提示词」与「暂存提示词」之间腾挪,方便把一段提示词先放一边、空出输入框写新的,需要时再取回。

操作效果
按一次 ctrl+alt+y当前提示词 → 入缓存;缓存内容 → 填入输入框(交换)
间隔再按在两段提示词之间来回切换
400ms 内连按两次当前提示词入缓存 + 清空输入框(旧暂存被丢弃),直接开写新提示词;之后按一次取回

缓存为空时,单按一次即「暂存 + 清空」。缓存为进程内内存、不落盘(提示词可能含敏感内容);/new 切会话不清缓存,/reload 清空。选择器(/model、/tree 等)打开时按键不生效(焦点在组件,不在编辑器)。

为什么是 ctrl+alt+y(四级兼容性调研结论):

层面状态说明
pi 键位✅无默认 ctrl+alt+字母 绑定;扩展快捷键在编辑器内最先分发
Linux 终端✅alt 以 ESC 前缀编码(ctrl+alt+y = ESC + ctrl+y),不依赖 kitty 协议即可区分
Windows Terminal✅无默认 ctrl+alt 绑定
Windows 操作系统✅系统级仅保留 ctrl+alt+del

被排除的候选:ctrl+shift+字母 —— Linux 与 Windows 的终端 emulator 都占用复制/粘贴/标签页;且无 kitty 协议的终端上会坍缩成 ctrl+字母(ctrl+shift+m 即回车,会直接提交提示词,危险)。纯 ctrl+字母 —— pi 几乎全部占用,唯一空闲的 ctrl+q 是 XON 流控字符,有历史包袱。


🔎 review — 第三方代码评审

开发任务完成后,输入 /ask-review 指令召唤另一个模型以第三方身份,对刚完成的代码做「查 + 修」:评审模型拥有完整工具权限,确认的问题直接改,不是只读审计。评审回合留在当前会话记录里,评审完成后会话保持评审模型(不自动切回)。

仅指令触发:只有 /ask-review 能发起评审。聊天中直接输入 ask-review 不会触发(作为普通消息发给模型),避免误发。

评审提示词重点检查三点(逐项给出结论):

  1. 本轮需求实现 —— 需求是否已完整、正确地实现,与需求描述是否一致
  2. 是否有遗漏 —— 功能点、边界情况、异常处理、兼容性、测试等
  3. 是否有错误 —— 逻辑错误、潜在 bug、类型/编译错误、安全与性能隐患等

范围强约束 —— 评审仅限当前本轮修改内容,避免扩大范围;本轮改动范围内确认的问题才直接修复,范围外的历史遗留/无关问题只记录提示、不动手改。

评审模型选择(每次 /ask-review 都会弹出选择界面):

  • /ask-review → 弹出 /model 同款选择器(限高滚动 + 模糊搜索):默认选中当前配置的模型(✓ 标记),直接回车即用它开始评审
  • 换选其他模型 → 立即写回配置(落盘 + 内存),下次默认使用该模型
  • 取消(Esc)→ 不执行评审,配置不变
  • 配置持久化于 <agent-dir>/pi-toolkits-review.json(默认 ~/.pi/agent/):
{ "model": "anthropic/claude-sonnet-4" }
  • 未配置 / 配置的模型已不可用(如在 pi 的 models.json 里删掉了该模型)→ 提示后照常弹出列表(此时无默认项)
  • 任务仍在进行中(agent 未空闲)时触发 → 提示等待,不执行;同一时间只允许一个评审
  • footer 出现灰色 review 状态 = 已配置评审模型

🧭 plan — 先出计划,浏览器里评审,批准后再动手

/ask-plan [主题] 进入计划期:模型先调研、把代码里看不出来的问题问清楚,然后写一份 spec——评审期间不改代码。写完调用 plan_submit,评审页在你的浏览器里打开,你逐段批注:每个空行分隔的块都可以挂批注,批注会作为下一条消息回到模型。

  • 块是评审单位。 一段一块,带徽标标出与上一版相比的变化:新增 / 已修改 / 位置移动 / 已删除。未变的块默认折叠,改三行不会被读成整篇重写;围栏代码块整块保留。
  • 只有两级批注:块级 + 全局。不做文本选区锚,改版后不需要重新锚定。
  • 批准和提意见都会带上批注,它们只决定下一步:批准 = 开始实施(批注照做);提意见 = 改完再提交。
  • 历史留档。 每次提交都存在 <agent-dir>/ask-plan/<slug>/,页头可以只读回看任意一版。
  • 计划期走边界闸门:进入时自动开启 /ask-perm 默认参数,退出时恢复;计划期唯一能写的文件是 markdown。
  • 绝不切模型。 计划评审与实施都用会话当前的模型。(/ask-review 是唯一会切模型的命令,那是你要求的。)

WSL 下的浏览器:评审服务器绑 0.0.0.0,打印的 URL 用 WSL 的地址——因为在 WSL 里只绑回环,Windows 根本连不上。打开器优先用 Windows 侧的启动器(wslview、cmd.exe /c start、powershell Start-Process),非 WSL 才用 xdg-open——这决定你是"打开了浏览器"还是"在 WSL 里开了个看不见的浏览器"。

/ask-plan 做导出功能     # 进入计划期
/ask-plan open           # 重新打开评审页
/ask-plan off            # 退出计划期(草稿留在原处)

spec 落在 specs/<slug>.md,与 /ask-init 的计划同一个位置。


✅ uat — 验收台账与浏览器页面

/ask-uat 只回答一个问题:这一批交付的东西,哪些还没验过? 它存在的原因是:agent 驱动的开发一周产出的行为变更,人根本记不住; 「回头再测」就是验收债变成返工的方式。

验收的单位是行为,不是提交。实施会话每轮用 record_change 写一条实施记录, 附一句「用户视角能做什么」;UAT 侧把多条记录聚成少数验收项——一条行为可能要十条记录, 一条记录也可能碰到多个行为。

record_change(实施)→ /ask-uat(聚类)→ 浏览器(勾选)→ 台账
命令做什么
/ask-uat把待归类的实施记录聚成验收项,然后打开页面
/ask-uat open只重开页面,不走模型回合
/ask-uat off关掉页面服务

页面按时间倒序列出未验收项:每条 2–3 句摘要,可展开测试方案(步骤、边界、 「这次不用测什么」)。勾选即写一条 check 事件——没有提交,关页不会丢决定。 已验收项折叠在底部,展开可反选;证据记录点一下就能看原文。

它靠这几条站得住:

  • 只追加的台账,没有提交。 .agents/uat/ledger.jsonl 是事件流(candidate、batch、item、 link、check、uncheck、amend、merge、drop),进 git,按事件 id 去重,两个进程同时追加也不丢事件。
  • 新证据会重开验收项。 勾选之后又有新记录落到同一项,页面标 reopened: 「已验收」的含义是「按当前证据集验过」。
  • 台账只属于主仓。 在 git worktree 里跑的会话,实施记录与事件都写主仓,验收历史不会被分裂。
  • 目录本身就是兜底索引。 手写的实施记录同样会出现在待验收列表;record_change 只是补上 行为句与测试提示,不是闸门。
  • 其他都不做。 不编辑、不排序、不评论、不指派。聚类不合适就在对话里要求 agent 调整(页面开着时 uat_item 可用:link / amend / merge / drop)。

实施记录格式(record_change 写的就是这个):

.agents/implementations/YYYY-MM-DD_HHMM_<slug>.md
# YYYY-MM-DDTHH:MM±HH:MM — 标题

旧记录(YYYY-MM-DD_<slug>.md、秒级首行)照样能读:读取端宽容,只有写入端严格。 新写的不合规记录由审计报 W-REC-01。


🗜️ compact — 独立压缩模型

pi 的 /compact 与 auto-compact 默认用当前会话模型做上下文总结——主模型往往贵且慢,而压缩总结是典型的「便宜快模型就能干好」的任务。本功能配置一个独立模型接管全部三种压缩触发的总结:

触发接管后
手动 /compact [instructions]压缩模型总结,自定义 focus 照常注入
auto-compact 阈值触发压缩模型总结
context overflow 恢复压缩模型总结,重试行为不变

接管后与 pi 内建行为完全一致的部分(逐字同步 pi 内建实现,复制自 0.87.1、在 1.2.0 → 1.5.1 内字节级不变 —— 除了此处采纳的两项 1.4.0 修正:摘要请求使用模型自身的输出上限而非 reserveTokens 的固定比例,以及 /compact <instructions> 也会进入 split-turn 前缀,外加 1.5.0 的 cost.totalFromProvider 合并规则(用量统计);只换执行模型;对话序列化函数(serializeConversation)是直接从宿主导入的,因此跟随宿主行为 —— 例如 1.2.0 起不再把 assistant thinking 回填进摘要请求):

  • 摘要格式 —— Goal / Progress / Key Decisions 结构化 checkpoint;已有摘要时用迭代更新版 prompt,信息延续不丢
  • 切分行为 —— 保留最近 keepRecentTokens 的策略、firstKeptEntryId / tokensBefore 原样回传,不动
  • 输出预算 —— 摘要请求使用模型自身的输出上限,与 1.4.0 起的内建一致(#9512:过去按 0.8×/0.5× reserveTokens 设上限,长思考会把摘要顶到 "generation hit the token cap" 而失败);reserveTokens 只决定何时开始压缩
  • 文件清单尾部 —— <read-files> / <modified-files> 标签照常拼在摘要尾部,details 同形状维护
  • 用量统计 —— 压缩模型的 token/cost 计入 session 统计
  • 可取消 —— 压缩进行中 Esc 干净取消(信号透传到底层调用)

配置(<agent-dir>/pi-toolkits-compact.json,默认 ~/.pi/agent/):

{ "model": "google/gemini-2.5-flash" }
  • /compact-model —— 查看/更换:/model 同款选择器(限高滚动 + 模糊搜索),默认选中当前配置的模型,回车即确认;换选即写入;取消则不变(清除配置:编辑 pi-toolkits-compact.json 把 model 置为 null)
  • 未配置 = 功能未启用,全部走 pi 默认,零开销;footer 出现灰色 compact 状态 = 已配置

无损回落(本功能永远不会把压缩「做挂」):

情形行为
未配置直接回落 pi 默认压缩
配置的模型不可用(如从 models.json 删除)warning 提示 + 回落
总结失败 / 摘要为空 / 命中 token 上限提示 + 回落 pi 默认压缩
用户取消(Esc)干净取消,无错误刷屏

实现说明:接管点是官方的 session_before_compact 扩展事件(三种触发都会先经过);返回压缩结果即完全接管,返回 undefined 即回落内建。auto-compact 路径绝不弹任何对话框(handler 内只 notify)。/tree 分支总结(session_before_tree)是另一个事件,本期不接管,留作后续迭代。


🚀 autostart — 会话启动自动化

多仓库项目的第一步:在项目内声明「开新会话时要自动执行的斜杠命令」,首批用例是 /add-dir 挂载兄弟仓库——新会话无需手动重放。

配置(<项目根>/.pi/autostart.toml,随项目进 git;.pi/ 是 pi 的项目级配置惯例,先例 .pi/mcp.json):

version = 1

[command]
run = [
  "/add-dir ../shop-frontend",
  "/add-dir ../shop-api",
]

无文件 = 功能未启用,零开销、静默跳过。

两个来源,按序执行,不做合并:

来源路径project trust
全局(操作者默认)<agent-dir>/autostart.toml(默认 ~/.pi/agent/autostart.toml)不需要 —— 文件属于操作者本人
项目<项目根>/.pi/autostart.toml需要

全局列表先执行,项目列表后执行,因此项目可以覆盖此前的设置(例如后面再执行一条不同参数的 /ask-perm)。只有希望所有项目都用同一套命令时才用全局文件;仍然建议以项目级配置为主。

完全相同的命令行若同时出现在两个来源,一次重放里只执行一次:重复项跳过,所以把全局的 /ask-perm ... 复制到项目里不会再跑一遍、也不会再提示一遍。不同的命令仍然各跑一次——这正是「项目覆盖全局」得以成立的原因。

执行时机:

session_start reason是否重放原因
startup / new,空会话✅新会话,按声明重放
startup,但会话已有历史❌这是「进程启动即带着旧会话」(pi -c / -r / --session / --fork),其分支已携带重放本该重建的状态
fork(进程内)✅分支点可能早于配置出现
resume(进程内 /resume)❌恢复的分支已携带当时的挂载状态,重放反而会冲突
reload❌扩展重建,重放会重复副作用

startup 这一行为什么要拆开:pi 对每一次进程启动都报 startup,包括「启动即打开旧会话」的情形;resume 只在进程内切换会话时发出,pi -c 永远不会报它。所以前两行的判定依据是会话内容(是否已有消息),不能只看 reason。

安全门(按序):

  1. project trust —— 未信任目录不自动执行任何命令(warning 提示);配置解析失败同样不执行(error 提示)
  2. 命令预校验 —— 只执行「扩展注册的命令」;未注册的命令名跳过并警告,绝不发给模型(sendUserMessage 对未处理的 /x 会当作普通消息发给 LLM,这是必须预校验的原因)

关键约束:只支持扩展命令。/add-dir(pi-add-dir)、/cd(pi-cd)等 registerCommand 注册的命令可以;内置命令(/compact、/reload、/resume…)在 TUI 层分发,扩展层触发不了;skill 命令(/skill:name)是展开机制而非执行机制。依赖的目标扩展(如 pi-add-dir)需要先安装。

实现说明:执行用 sendUserMessage(cmd, { expandPromptTemplates: true }) —— 该选项把 /cmd args 路由到命令分发而不是模型 prompt 路径(包装层默认 false;_tryExecuteExtensionCommand 在 1.2.0–1.5.1 全区间字节级一致,1.5.1 虽把 sendUserMessage 其余部分重构进 _preparePrompt,扩展命令分支仍是它最前面的早退路径,见 AGENTS.md 宿主兼容纪律)。预校验用 pi.getCommands()(只认 source: "extension")。依赖 smol-toml(零依赖、~10KB、TOML 1.0)。


🧠 init — agent 记忆框架

/ask-init 给项目安装一套有明确立场的记忆结构,或者接管项目里已经存在的文档。 重点不是目录名,而是把三样混在一起必然腐烂的东西分开:

家庭位置回答什么生命周期
计划specs/(PLAN.md + <unit>.md)要做什么、怎么验收开工前写,结项时更新状态
记忆.agents/memory/已知什么、定过什么、为什么长期;只追加、只压缩
证据.agents/implementations/改了什么、什么时候、证据在哪一次写定,不再改写

只有「纯给 agent 看」的东西进隐藏目录 .agents/,所以仓库根仍然清爽: AGENTS.md、specs/、design/、docs/、legal/ 都留在外面可读可审。

命令:

命令作用
/ask-init检测 → 出计划 → 确认 → 移动/脚手架/快照 → 把正文工作派发给模型
/ask-init plan [--deep]只打印计划,不写任何盘(--dry-run 同义)
/ask-init check审计已装的框架(只读;只在 .agents/framework/reports/ 留下运行期报告)
/ask-init roots把 pi-add-dir 添加的目录同步进框架状态
/ask-init refresh刷新框架拥有的文件(合同、门牌、验收合同)与 AGENTS.md 里的工作流块;手工改过的文件一概不动
/ask-init --yes跳过确认面板
/ask-init --lang zh|en框架生成文件的渲染语言(单次生效;默认按项目自身文档判定)

机械那一半保证什么:

  1. 先快照再动 —— 本次可能写的每一条路径(包括所有会被改写的引用文件)都复制到 .agents/framework/snapshots/<stamp>/,并带 sha256 清单与当时的 git status。
  2. 只写仓内 —— 扩展代码绝不写 added root;在那里建 scope card 是普通工具调用, 因此会经过权限闸门。
  3. 不覆盖 —— 创建时已存在的文件跳过;移动时目标非空则拒绝,并转成人工任务。
  4. 计数对账 —— 引用改写与检测用同一个「裸路径」判定,计划里的「N 处 / M 个文件」 就是运行时报告的数字(并附逐文件清单)。
  5. 不静默丢内容 —— 迁移的每个源章节在覆盖表里都有一行:命中、声明去向、或标记 OPEN 并写理由;只要还有 OPEN,审计就不算通过。

正文那一半是一份带验收标准的工作单:填空入口、合并旧计划、把 todos/ 收敛进 specs、 去重章节、登记预算债务、填覆盖表。模型用只在本轮激活的 framework_audit 工具自检收口。

迁移既有项目会把 memory/、implementations/、prompts/ 移到 .agents/ 下 (逐个 git mv),把 memory/PLAN.md 原样搬到 specs/PLAN.md,再改写路径引用, 前后计数都会报出来。todos/ 退役:需求原文原样进对应单元的 spec。默认是保守 pass: 装框架、修机械漂移(墓碑、重复章节、附录顺序),超预算的 AGENTS.md 只登记成债务; --deep 才允许结构性改写。

审计码(稳定,可跨次对比):E-PATH-01 裸旧路径、E-STATE-01 记忆被 gitignore、W-STATE-01 记忆尚未提交、E-INDEX-01 索引与实际文件不一致、E-LINK-01 内部链接失效、 W-BUDGET-01 AGENTS.md 超预算、W-DUP-01 同一章节出现在两个文件、 W-ORDER-01 附录之后又追加章节、W-COV-01 覆盖表仍有 OPEN、 W-TODO-01 仍存在退役的 todos/、W-ROOT-02 根下零字节文件、 W-SCAFFOLD-01 未填的 TODO(ask-init) 标记、I-INSTALL-01 尚未安装框架。

多仓库工作区:记忆只住主仓。pi-add-dir 会把每个 added root 的 AGENTS.md 全文注入每次请求,所以根里的入口只能是 scope card(≤30 行:这里放什么、它的命令、 去主仓哪个记忆文件读),绝不能是规则的第二份副本。

装进项目的框架契约用英文(给模型读、也随 npm 发布);框架生成的文件按项目语言渲染。 本包不会指示模型用哪种语言写文件或回复。

跑完记得 /reload,让新的 AGENTS.md 进入提示词。框架版本记在 .agents/framework/state.toml;若项目的状态版本比当前工具新,则拒绝迁移。

🧯 quit-guard — 退出看门狗

要解决的问题。pi 的 /quit 先停 TUI,然后逐个 await 每个扩展的 session_shutdown 处理器,且没有任何超时(runtimeHost.dispose() → emitSessionShutdownEvent();上游 issue #9997,1.5.1 与 main 至今未修,1.5.1 还在处理器循环前加了 await session.abort()、之后加了凭据写盘等待——同一条没有超时的链上又多了两个 await)。只要有一个处理器永不 settle,pi 就会在终端已还原、最后一帧已重绘之后,以 0% CPU 永远挂着:画面看起来像「停在退出界面」,提示符再也不回来;实测 Ctrl+C 与 SIGTERM 都无法结束这个进程(只有 SIGKILL 有效)——进了这段收尾,宿主自己也没有出口。20 个扩展的环境实测(2026-11-05):健康退出在这段收尾上花 0.1–3 秒,pi -ne 0.12 秒;同一环境三次 /quit 就有一次永远不结束。

这个功能做什么。看守盯的是终端写出的收尾序列,而不是事件流——所以即使卡死的处理器比本包先加载(那样我们自己的 session_shutdown 根本不会运行),它照样能触发。它在 TUI 收尾序列(\x1b[?2004l / \x1b[?1049l)出现时开始计时;信号触发的退出(kill -TERM、关窗 SIGHUP)另有一只触发源:session_shutdown 且 reason 为 quit——那条路是先跑完所有扩展处理器再停 TUI,处理器挂住时收尾序列永远写不出来,只靠序列就会漏掉。若 timeoutMs 之后进程还活着,它写一份诊断报告;若 TUI 从没恢复过终端,它先做恢复(退备用屏、关括号粘贴、显示光标)再强制退出。TUI 回来时自动解除:/settings 里切换 TUI 显示模式、Ctrl+Z 挂起后 fg 恢复,都会让 TUI 重新进入,绝不能误杀活着的会话。事件触发源只限 TUI 模式:RPC/JSON/print 的 stdout 是机器可读协议,绝不会被写入终端转义序列。

命令

命令作用
/quit-guard查看状态:开关、超时、报告开关、最近一份诊断报告
/quit-guard on / /quit-guard off开启/关闭,并持久化
/quit-guard <ms>设置超时(钳制在 2000–60000 ms),并持久化

配置 —— 看守默认开启(收尾序列写出后 8 秒、写诊断报告),装上就有保护,不用先配置。状态持久化在 <agent-dir>/pi-toolkits-quit-guard.json,由命令写入;所有字段都可省略:

{
  "enabled": true,
  "timeoutMs": 8000,
  "report": true
}

timeoutMs 从收尾序列写出那一刻开始算,不是从你按下 Enter 开始算——TUI 自己停下来的时间不计入,所以「慢但能完成」的收尾(记忆库 flush、MCP 关闭)不会被误杀。默认 8 秒;上例实测最慢的健康退出端到端 5 秒(其中约 2 秒发生在收尾之后),余量约 3 秒。

诊断报告 —— <agent-dir>/quit-guard/quit-hang-<时间戳>-<pid>.json,记录开始计时/触发的时间、触发用的收尾序列,以及截止时进程的状态(activeHandles、activeRequests、宿主 libuv 句柄表)。进程还活着但 libuv 表是空的,就是「有个 Promise 永远不会 settle」的特征,区别于阻塞的 socket 或残留子进程。报告文件仅本人可读(0700 目录下的 0600 文件),进程参数按审批日志同一套规则脱敏,所以 pi --api-key … 不会把密钥留在盘上。

PI_QUIT_GUARD_DEBUG=<文件> 会把每次 arm / disarm / fire(以及每次扩展注册)追加一行;TUI 已经没了的时候,这是唯一还能观察的通道。

边界

  • 只覆盖交互式 TUI。-p(print)、JSON、RPC 模式不会写这些收尾序列,看守在那里完全不生效。
  • 计时覆盖的是收尾之后的阶段;在 TUI 停下之前就卡住的情况(未观察到;drainInput 上限 1 秒)不在范围内。
  • 触发时按设计跳过剩余扩展清理——挂住的就是它。会话条目是随发生随写入 JSONL 的,所以最后一条已写入的记录不会丢。正常路径退出码 0;若 process.exit() 本身被 exit 监听器变成空操作,500 ms 后会补一记 SIGKILL。
  • 这是对宿主缺口的权宜之计:哪天 pi 给 session_shutdown 加上限时,看守就退化成无害的保险,可以直接删掉。

🛠️ 开发

pnpm 是本仓库唯一受支持的包管理器 —— 本仓库内不得使用 npm install / npm publish。

pnpm install      # 安装依赖
pnpm typecheck    # tsc --noEmit
pnpm test         # vitest(全部功能单元测试)

pnpm check:keybindings   # 用宿主自己的分发表审计本插件的按键
pnpm check:compat        # 校验声明的 pi 下限:强制 4 条线窗口 + 向后 4 条线探针 → public floor
pnpm approval-report     # 汇总本地审批日志(答复分布、目标目录、候选规则)

项目结构

src/
├── index.ts              # 入口:聚合各功能模块
├── lib/                  # 共享基础设施(工具集快照/恢复、
│                         # 组合 tool_call 策略的闸门总线、
│                         # 边界闸门会查询的自封闭工具登记表、
│                         # 滚动 JSONL 审批日志、
│                         # review 与 compact 共用的模型 key 解析)
└── features/             # 功能模块 —— 一个功能一个目录
    ├── ask/              # ask 模式:命令 + 状态机、bash 沙箱、
    │                     #           草稿空间(临时目录 + scratchpad 工具)、
    │                     #           系统提示词横幅、测试
    ├── autostart/        # 会话启动自动化:autostart.toml 解析、
    │                     #           命令预校验 + 重放、测试
    ├── compact/          # 独立压缩模型:session_before_compact 接管 +
    │                     #           /compact-model、配置存储、prompt、测试
    ├── favorites/        # 模型收藏:选择器与循环 patch、
    │                     #           持久化存储、测试
    ├── permission/       # 会话级边界权限:模式、面板、bash 拆解、
    │                     #           策略、会话授权、确认对话框、
    │                     #           审计 payload、测试
    ├── quit-guard/       # 退出看门狗:TUI 收尾 + quit 事件双触发、
    │                     #           配置存储、诊断报告、测试
    ├── review/           # 第三方评审:输入/指令触发、
    │                     #           评审模型配置存储、提示词、测试
    └── stash/            # 提示词暂存:热键状态机 + 测试

新增功能:新建 src/features/<name>/,导出 registerXxx(pi),在 src/index.ts 中调用;已有模块保持不变。每个功能自带 *.test.ts(vitest)——保持确定性(时钟/状态可注入,不写真实 agent-dir)。

发布(一条命令;上传由 CI 执行):

pnpm release patch   # 0.1.2 → 0.1.3
pnpm release minor   # 0.1.2 → 0.2.0   (patch 清零)
pnpm release major   # 0.1.2 → 1.0.0   (minor + patch 清零)
pnpm release patch --dry-run        # 预览,不做任何改动
pnpm release patch --prepare-only   # 准备到本地 tag,打印推送命令
pnpm release:github                 # 为当前版本创建/校验 GitHub Release(幂等)
pnpm release:github --audit         # 列出 npm 版本 vs GitHub Release vs 远端 tag

发版 = 推 tag。 pnpm release 跑完门禁(typecheck、test、UI 检查)、改版本、commit、打 vX.Y.Z tag、推分支和 tag,然后等 GitHub Actions 的 publish 工作流。该工作流用 npm trusted publishing(OIDC) 发布:不需要 npm token、不需要交互式 2FA,每个版本自动附 provenance。脚本只在 npm 上真的出现该版本、且 dist.attestations 非空时才报成功。

--prepare-only 是「都准备好、发不发最后再说」的开关:停在 commit+tag 后,打印确切的推送命令。--no-wait 推完就返回;--local 是应急路径(本机用旧 token 发布)。工作流失败后重跑同一个 tag 即可(gh workflow run publish.yml -f tag=vX.Y.Z):已发布的版本会跳过,所以重跑是幂等的。

维护者一次性配置(交互式 2FA):npm trust github @andares/pi-toolkits --repo andares/pi-toolkits --file publish.yml --env npm --allow-publish。GitHub Release 仍是 best-effort(需要 GITHUB_TOKEN);pnpm release:github 可以不动 npm 补建。


🤝 贡献

欢迎提交 PR 与 issue。几条约定:

  • 只用 pnpm —— 不得 npm install / npm publish;用 pnpm add / pnpm publish
  • 功能模块模式 —— 一个功能一个目录(src/features/<name>/),导出 registerXxx(pi),在 src/index.ts 注册;共享基础设施放 src/lib/
  • 测试 —— 每个功能自带 vitest 用例;保持确定性(时钟/状态可注入),不写真实 agent dir
  • 内建 patch(favorites)必须保持版本守卫 + 幂等 —— 打 patch 前先确认目标原型成员存在,防止重复应用,失败时用 console.warn 降级而不是把扩展搞挂
  • 内建提示词同步(compact) —— src/features/compact/prompt.ts 里的总结 prompt 逐字抄自 pi 内建压缩;升级 pi 依赖时 diff dist/core/compaction/compaction.js(及 utils.js),同步字符串与组装辅助函数,保持接管输出与内建字节级一致
  • 键位 —— 定新快捷键前先查 pi 默认键位 + 保留键、终端控制字符、OS/终端模拟器占用;跨平台安全优先选 ctrl+alt+<字母>。不得只验证「主屏下我这台机器能用」:自 pi 1.0 起默认 fullscreen,alt-screen 层在对话框看到按键之前就消费 tui.altScreen.*,且 Windows/WSL 上多个绑定与 Linux 默认值不同。用 pnpm check:keybindings [候选键...] 核查(pi 升级后跑 pnpm check:keybindings --all),它用宿主自己的 matchesKey 探测已安装宿主的已解析键位表。宿主表空闲 ≠ 机器层空闲:Windows Terminal 默认占 ctrl+v(粘贴)与 ctrl+shift+f(查找),第三方 Windows 工具常绑 ctrl+alt+<字母>(截图工具占过 ctrl+alt+f)——定键后必须在真机试按,确认按键真的到得了应用。
  • 宿主兼容 —— peer 区间是实测结论而非愿望,而且只往回指:最近 4 个已发布中版本线是强制窗口(不兼容就改我们的代码,绝不抬下限),窗口之下再向后探最多 4 条线找出兼容实际停在哪里,对使用者只展示一个数:由此得到的下限(pi >= <floor>,无上界)。宿主依赖一动就重跑 pnpm check:compat,读它的 verdict 段(声明下限与实测不一致会直接判失败)。详见 AGENTS.md「pi 宿主兼容」;升级中发现的键位冲突上报崔总决策,不得顺手换键。
  • 质量门禁 —— 提交前必须通过 pnpm typecheck && pnpm test

📄 许可

MIT © 2026 Andares Cui. 见 LICENSE。

版本与发布记录

@andares/pi-toolkits 共发布 35 个版本,首次发布于 2026/08/07;过去 12 个月发布了 35 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.13.0latest2026/11/12今天
0.12.42026/11/101 天前
0.12.32026/11/102 天前
0.12.22026/11/066 天前
0.12.12026/11/066 天前
0.12.02026/11/066 天前

关于 @andares/pi-toolkits 的常见问题

@andares/pi-toolkits 是什么?

Pi的综合工具包扩展——询问模式(只读QQA),浏览器审查规划,一个包含浏览器页面的接受分类账,会话范围权限检查,模型最爱,即时存储,第三方代码审查,会话自动启动,专用c

如何安装 @andares/pi-toolkits?

在项目目录运行 npm install @andares/pi-toolkits,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:typebox(*)、@earendil-works/pi-tui(*)、@earendil-works/pi-coding-agent(>=0.99.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@andares/pi-toolkits 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/andares__pi-toolkits 是否存在。

@andares/pi-toolkits 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@andares/pi-toolkits 可以商用吗?

@andares/pi-toolkits 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@andares/pi-toolkits 的下载量有多少?

根据 npm 官方下载统计,@andares/pi-toolkits 在 2026/10/06 – 2026/11/04 这 30 天内被下载 3,494 次,日均约 116 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@andares/pi-toolkits 还在维护吗?

最新版本 0.13.0 发布于 2026/11/12(今天);至今共发布 35 个版本,其中过去 12 个月发布了 35 个;首次发布于 2026/08/07。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。