{"_id":"@andares/pi-toolkits","_rev":"4-2332c7e79629dd6f54dccc28118cfdc4","name":"@andares/pi-toolkits","dist-tags":{"latest":"0.3.1"},"versions":{"0.1.0":{"name":"@andares/pi-toolkits","version":"0.1.0","keywords":["pi","pi-extension","ask-mode","readonly","toolkit"],"license":"MIT","_id":"@andares/pi-toolkits@0.1.0","maintainers":[{"name":"andares","email":"andares@outlook.com"}],"pi":{"extensions":["./src/index.ts"]},"dist":{"shasum":"e4e08f673ab14ee20645a548c474d37537cac020","tarball":"https://registry.npmjs.org/@andares/pi-toolkits/-/pi-toolkits-0.1.0.tgz","fileCount":10,"integrity":"sha512-KyDw4rJPItzYMlw8hTD5euGTFEob9nGvhtpdQUHmpZDII+Kbda63ffoBK6z1hEj+cMqmOcFm/L6Q4oai7rshrg==","signatures":[{"sig":"MEYCIQDSJooSu6nwKOJkhdjDcd10JY6j8nhEVSK5+MX3EXZdswIhANzXuOvvrNTmgvITvUlB6JzTOZUpOKwhGZ3IbnW7f1KK","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":12861},"type":"module","scripts":{"test":"vitest run","typecheck":"tsc --noEmit"},"_npmUser":{"name":"andares","email":"andares@outlook.com"},"repository":{"url":"git+https://github.com/andares/pi-toolkits.git","type":"git"},"description":"Integrated toolkit extension for pi — currently provides ask mode (read-only Q&A); more features to come","directories":{},"_nodeVersion":"26.0.0","dependencies":{"@dreki-gg/pi-command-sandbox":"^0.4.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.10","typescript":"^5.6.0","@earendil-works/pi-coding-agent":"^0.84.0"},"peerDependencies":{"@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-toolkits_0.1.0_1786089379945_0.5511224110482336","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@andares/pi-toolkits","version":"0.2.0","keywords":["pi","pi-extension","ask-mode","readonly","toolkit"],"license":"MIT","_id":"@andares/pi-toolkits@0.2.0","maintainers":[{"name":"andares","email":"andares@outlook.com"}],"pi":{"extensions":["./src/index.ts"]},"dist":{"shasum":"dfa9cd1caffe7d96fe6854102aac2179da4f1d99","tarball":"https://registry.npmjs.org/@andares/pi-toolkits/-/pi-toolkits-0.2.0.tgz","fileCount":19,"integrity":"sha512-wel7jj/qRdJSHjDxfSmlLwk2yCxg4gRO4daqDfopnCsXnH+V7Y84urbiBjghk82ne2+QcgmYDOYW2BJxDS30AQ==","signatures":[{"sig":"MEUCIQDCU7qRvdjq3uXNrV6xOK7sUmLLylwky5rkjMTd9XUUmgIgW2N+S3ySPSGugMv7MnpcE27aYQQyQ8fH6A4dU8jMgXc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":70816},"type":"module","scripts":{"test":"vitest run","release":"node ./scripts/publish.mjs","typecheck":"tsc --noEmit"},"_npmUser":{"name":"andares","email":"andares@outlook.com"},"repository":{"url":"git+https://github.com/andares/pi-toolkits.git","type":"git"},"description":"Integrated toolkit extension for pi — currently provides ask mode (read-only Q&A); more features to come","directories":{},"_nodeVersion":"26.0.0","dependencies":{"@earendil-works/pi-tui":"^0.84.0","@dreki-gg/pi-command-sandbox":"^0.4.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.10","typescript":"^5.6.0","@earendil-works/pi-ai":"^0.84.0","@earendil-works/pi-coding-agent":"^0.84.0"},"peerDependencies":{"@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-toolkits_0.2.0_1786178650908_0.9167822570949875","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@andares/pi-toolkits","version":"0.3.0","keywords":["pi","pi-extension","ask-mode","readonly","toolkit"],"license":"MIT","_id":"@andares/pi-toolkits@0.3.0","maintainers":[{"name":"andares","email":"andares@outlook.com"}],"pi":{"extensions":["./src/index.ts"]},"dist":{"shasum":"2a875728787b78766942b11cce08e1549499da6c","tarball":"https://registry.npmjs.org/@andares/pi-toolkits/-/pi-toolkits-0.3.0.tgz","fileCount":24,"integrity":"sha512-MyH0S3AsQL4jjTQmgrWQMGvfgcpCtER2bgZXo7+uAfx4C67eU7mo7xmDdFj4Xj39+Algi+XZ2uVlJWgMMaA6WA==","signatures":[{"sig":"MEYCIQCKybUtLIKZ5HdvByDC7oLFz9O73vEcCp+gPwamJaw8sAIhANz1RupLkY5KNHCty7P/JP/4YT9neWiGRJHrSWUtpZQO","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":102252},"type":"module","scripts":{"test":"vitest run","release":"node ./scripts/publish.mjs","typecheck":"tsc --noEmit","tag-current":"node ./scripts/tag-current.mjs"},"_npmUser":{"name":"andares","email":"andares@outlook.com"},"repository":{"url":"git+https://github.com/andares/pi-toolkits.git","type":"git"},"description":"Integrated toolkit extension for pi — currently provides ask mode (read-only Q&A); more features to come","directories":{},"_nodeVersion":"26.0.0","dependencies":{"@earendil-works/pi-tui":"^0.84.0","@dreki-gg/pi-command-sandbox":"^0.4.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.1.10","typescript":"^5.6.0","@earendil-works/pi-ai":"^0.84.0","@earendil-works/pi-coding-agent":"^0.84.0"},"peerDependencies":{"@earendil-works/pi-coding-agent":"*"},"_npmOperationalInternal":{"tmp":"tmp/pi-toolkits_0.3.0_1786554380728_0.0794665635724987","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@andares/pi-toolkits","version":"0.3.1","description":"Integrated toolkit extension for pi — currently provides ask mode (read-only Q&A); more features to come","type":"module","license":"MIT","repository":{"type":"git","url":"git+https://github.com/andares/pi-toolkits.git"},"publishConfig":{"access":"public"},"keywords":["pi","pi-extension","ask-mode","readonly","toolkit"],"peerDependencies":{"@earendil-works/pi-coding-agent":"*"},"dependencies":{"@dreki-gg/pi-command-sandbox":"^0.4.3","@earendil-works/pi-tui":"^0.84.0"},"devDependencies":{"@earendil-works/pi-ai":"^0.84.0","@earendil-works/pi-coding-agent":"^0.84.0","typescript":"^5.6.0","vitest":"^4.1.10"},"pi":{"extensions":["./src/index.ts"]},"scripts":{"typecheck":"tsc --noEmit","test":"vitest run","release":"node ./scripts/publish.mjs","tag-current":"node ./scripts/tag-current.mjs"},"_nodeVersion":"26.0.0","_id":"@andares/pi-toolkits@0.3.1","dist":{"integrity":"sha512-7apM5vw8T1/Nhn6o6KtRpGjo+GMwh0ST73SgdBueBPfHUSrZ9wrXYrCHq5X4Cr42j4tVgZ3Aoaa47kyNebyrIA==","shasum":"9948e300d1eecc7e22738952b1a55aa6a43c60ea","tarball":"https://registry.npmjs.org/@andares/pi-toolkits/-/pi-toolkits-0.3.1.tgz","fileCount":24,"unpackedSize":100671,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD9u0NjHDI+Nrce/T/ivaPqr+ymCQKm2LcP7CGNjwG+vAIgXGLZQzTlmsjyqPu5PtZVzaJ85BuYwBmaU1wQzMRvPIY="}]},"_npmUser":{"name":"andares","email":"andares@outlook.com"},"directories":{},"maintainers":[{"name":"andares","email":"andares@outlook.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pi-toolkits_0.3.1_1786603197273_0.342655135710874"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-07T07:56:19.727Z","modified":"2026-08-13T06:39:57.622Z","0.1.0":"2026-08-07T07:56:20.085Z","0.2.0":"2026-08-08T08:44:11.071Z","0.3.0":"2026-08-12T17:06:20.856Z","0.3.1":"2026-08-13T06:39:57.453Z"},"license":"MIT","keywords":["pi","pi-extension","ask-mode","readonly","toolkit"],"repository":{"type":"git","url":"git+https://github.com/andares/pi-toolkits.git"},"description":"Integrated toolkit extension for pi — currently provides ask mode (read-only Q&A); more features to come","maintainers":[{"name":"andares","email":"andares@outlook.com"}],"readme":"<!-- markdownlint-disable MD033 -->\n<!-- Inline <a name> anchors are the only reliable TOC targets for CJK headers on GitHub. -->\n# ⚙️ @andares/pi-toolkits\n\n> pi 编码代理的集成扩展工具包 — 一个包,持续生长新能力。\n> Integrated toolkit extension for [pi](https://github.com/earendil-works/pi-coding-agent) — one package, growing new capabilities over time.\n\n[![npm version](https://img.shields.io/npm/v/@andares/pi-toolkits?label=npm&logo=npm)](https://www.npmjs.com/package/@andares/pi-toolkits)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![Package Manager](https://img.shields.io/badge/package%20manager-pnpm-orange?logo=pnpm)](https://pnpm.io)\n[![pi >= 0.84](https://img.shields.io/badge/pi-%3E%3D0.84.0-blueviolet)](https://github.com/earendil-works/pi)\n[![GitHub](https://img.shields.io/badge/github-andares%2Fpi--toolkits-181717?logo=github)](https://github.com/andares/pi-toolkits)\n\n一句话介绍:目前包含四个开箱即用的功能——**只读咨询模式** `ask`、**模型收藏** `favorites`、**提示词暂存** `stash`、**第三方代码评审** `third-review`,后续持续追加。\nCurrently ships four ready-to-use capabilities — **ask mode**, **model favorites**, **prompt stash** and **third-party code review** — with more to come.\n\n---\n\n## 📦 安装 Installation\n\n<a name=\"install\"></a>\n\n```bash\n# 从 npm 安装(推荐)· from npm\npi install npm:@andares/pi-toolkits\n\n# 本地开发安装 · local development\npi install .\n\n# 单次会话加载,不安装 · one-off session, no install\npi -e ./src/index.ts\n```\n\n安装后在任意 pi 会话中验证:\n\n- `/ask` → footer 出现灰色 `ask` 状态,`write`/`edit` 被硬禁用\n- `/model`(或 `ctrl+l`)→ 选择器顶部出现收藏提示行\n- 输入框内按 `ctrl+alt+y` → 当前提示词被暂存并清空输入框\n- 完成一个开发任务后输入 `/third-review` → 切换到评审模型执行查+修\n\n---\n\n## 📚 目录 Contents\n\n- [安装 Installation](#install)\n- [功能总览 Features at a glance](#features)\n  - [🛡️ ask — 只读咨询模式](#ask)\n  - [⭐ favorites — 模型收藏](#favorites)\n  - [📥 stash — 提示词暂存](#stash)\n  - [🔎 review — 第三方代码评审](#review)\n- [开发 Development](#development)\n- [贡献 Contributing](#contributing)\n- [许可 License](#license)\n\n---\n\n## ✨ 功能总览 Features at a glance\n\n<a name=\"features\"></a>\n\n| 功能 | 入口 | 一句话说明 |\n| --- | --- | --- |\n| 🛡️ **ask** 只读咨询模式 | `/ask` | 进入只读问答模式,`write`/`edit` 硬禁用,`bash` 只读沙箱 |\n| ⭐ **favorites** 模型收藏 | `/model` 内 `ctrl+F` / `ctrl+J` | 收藏常用模型(加粗亮黄标记),`ctrl+p` 仅在收藏间循环 |\n| 📥 **stash** 提示词暂存 | `ctrl+alt+y` | 一段提示词的暂存槽,按键交换 / 连按两次暂存并清空输入框 |\n| 🔎 **review** 第三方代码评审 | `/third-review` | 召唤配置的评审模型,对刚完成的任务做查+修,重点检查「本轮需求实现 / 是否有遗漏 / 是否有错误」 |\n\n---\n\n## 🛡️ ask — 只读咨询模式\n\n<a name=\"ask\"></a>\n\n用 `/ask` 进入(再按一次退出)。适合只想要\"问问题、读代码\",绝不希望模型改动任何文件的场景。\n\n**进入后**:\n\n- **`write` / `edit` 硬禁用** —— 从活跃工具集中移除,pi 运行时对未激活工具的调用直接拒绝(\"Tool not found\"),文件修改在机制上不可能发生\n- **`bash` 保留但只读沙箱** —— 基于 shell 分词 + 写盘意图检测(`curl -o/-O`、`wget -O`、`dd of=`、`tee`、重定向等一律拦截)。启发式,非安全边界\n- **系统提示词追加** —— 追加一段模式说明,模型会遵守只读约束行事\n- **灰色 `ask` footer 状态** —— 常驻提示当前处于只读模式\n\n**退出**:再按 `/ask`,完整恢复进入前的工具集快照。\n\n---\n\n## ⭐ favorites — 模型收藏\n\n<a name=\"favorites\"></a>\n\n标记常用模型,让模型切换「粘」在收藏上。收藏**跨会话、跨项目全局持久化**。\n\n**在 `/model` 选择器内**(`/model` 或 `ctrl+l` 打开):\n\n- 顶部提示行显示按键与当前过滤状态\n- `ctrl+F` —— 对当前选中模型开/关收藏;收藏的模型文字显示为**加粗亮黄**\n- `ctrl+J` —— 开/关「仅显示收藏模型」过滤(可与内置搜索叠加使用)\n\n**模型循环**:只要存在 ≥1 个收藏,`ctrl+p` / `ctrl+shift+p` 就**只在收藏模型间循环**。当前模型不是收藏时,`ctrl+p` 跳到第一个收藏、`ctrl+shift+p` 跳到最后一个;收藏仅 1 个时停在原地(`Only one model available`)。`ctrl+l` / `/model` 始终可自由选择任意模型(含非收藏)。在状态文件中设 `\"cycleOnlyFavorites\": false` 可恢复全量循环。\n\n**状态文件**:`<agent-dir>/pi-toolkits-favorites.json`(默认 `~/.pi/agent/`,与 auto-naming-session 配置同目录):\n\n```json\n{\n  \"favorites\": [\"anthropic/claude-sonnet-4\"],\n  \"config\": { \"cycleOnlyFavorites\": true }\n}\n```\n\n`/favorites` 命令列出当前收藏与循环模式。\n\n> **实现说明**:pi 的 `app.model.cycleForward`(`ctrl+p`)与 `cycleBackward` 是**保留键位**,扩展快捷键无法覆盖;且扩展快捷键只在编辑器聚焦时生效。因此本功能不重绑任何按键,而是在运行时 patch 两个内置原型(带版本守卫、`/reload` 幂等):`ModelSelectorComponent`(提示行、`ctrl+F`/`ctrl+J`、亮黄渲染、仅收藏过滤——按键仅在选择器内消费,编辑器里 `ctrl+f` 光标右移、`ctrl+j` 换行不受影响)与 `AgentSession.cycleModel`(收藏循环)。若 pi 升级导致 patch 无法应用,会 warn 并优雅降级,不影响其它功能。\n\n---\n\n## 📥 stash — 提示词暂存\n\n<a name=\"stash\"></a>\n\n一个热键 + 一个暂存槽,在「当前提示词」与「暂存提示词」之间腾挪,方便把一段提示词先放一边、空出输入框写新的,需要时再取回。\n\n| 操作 | 效果 |\n| --- | --- |\n| 按一次 `ctrl+alt+y` | 当前提示词 → 入缓存;缓存内容 → 填入输入框(**交换**) |\n| 间隔再按 | 在两段提示词之间**来回切换** |\n| **400ms 内连按两次** | 当前提示词入缓存 + **清空输入框**(旧暂存被丢弃),直接开写新提示词;之后按一次取回 |\n\n缓存为空时,单按一次即「暂存 + 清空」。缓存为**进程内内存、不落盘**(提示词可能含敏感内容);`/new` 切会话不清缓存,`/reload` 清空。选择器(`/model`、`/tree` 等)打开时按键不生效(焦点在组件,不在编辑器)。\n\n**为什么是 `ctrl+alt+y`**(四级兼容性调研结论):\n\n| 层面 | 状态 | 说明 |\n| --- | --- | --- |\n| pi 键位 | ✅ | 无默认 `ctrl+alt+字母` 绑定;扩展快捷键在编辑器内最先分发 |\n| Linux 终端 | ✅ | `alt` 以 ESC 前缀编码(`ctrl+alt+y` = `ESC + ctrl+y`),不依赖 kitty 协议即可区分 |\n| Windows Terminal | ✅ | 无默认 `ctrl+alt` 绑定 |\n| Windows 操作系统 | ✅ | 系统级仅保留 `ctrl+alt+del` |\n\n**被排除的候选**:`ctrl+shift+字母` —— Linux 与 Windows 的终端 emulator 都占用复制/粘贴/标签页;且无 kitty 协议的终端上会坍缩成 `ctrl+字母`(`ctrl+shift+m` 即回车,会直接提交提示词,危险)。纯 `ctrl+字母` —— pi 几乎全部占用,唯一空闲的 `ctrl+q` 是 XON 流控字符,有历史包袱。\n\n---\n\n## 🔎 review — 第三方代码评审\n\n<a name=\"review\"></a>\n\n开发任务完成后,输入 `/third-review` 指令召唤**另一个模型**以第三方身份,对刚完成的代码做「查 + 修」:评审模型拥有**完整工具权限**,确认的问题直接改,不是只读审计。评审回合留在当前会话记录里,评审完成后**会话保持评审模型**(不自动切回)。\n\n> **仅指令触发**:只有 `/third-review` 能发起评审。聊天中直接输入 `third-review` 不会触发(作为普通消息发给模型),避免误发。\n\n**评审提示词重点检查三点**(逐项给出结论):\n\n1. **本轮需求实现** —— 需求是否已完整、正确地实现,与需求描述是否一致\n2. **是否有遗漏** —— 功能点、边界情况、异常处理、兼容性、测试等\n3. **是否有错误** —— 逻辑错误、潜在 bug、类型/编译错误、安全与性能隐患等\n\n**范围强约束** —— 评审仅限**当前本轮修改内容**,避免扩大范围;本轮改动范围内确认的问题才直接修复,范围外的历史遗留/无关问题只记录提示、不动手改。\n\n**评审模型配置**(`<agent-dir>/pi-toolkits-review.json`,默认 `~/.pi/agent/`):\n\n```json\n{ \"model\": \"anthropic/claude-sonnet-4\" }\n```\n\n- `/review-model` —— 查看/更换评审模型:弹出模型列表(标题显示当前配置),选中即写入;取消则不修改配置\n- **未配置 / 配置的模型已不可用**(如在 pi 的 models.json 里删掉了该模型)→ 提示「评审模型不存在」,弹出**可用模型选择列表**(与 `/model` 同源);选中后**写回配置并立即执行**\n- 任务仍在进行中(agent 未空闲)时触发 → 提示等待,不执行;同一时间只允许一个评审\n- footer 出现灰色 `review` 状态 = 已配置评审模型\n\n---\n\n## 🛠️ 开发 Development\n\n<a name=\"development\"></a>\n\n**pnpm is the only supported toolchain** — never use `npm install` / `npm publish` in this repo.\n\n```bash\npnpm install      # install deps\npnpm typecheck    # tsc --noEmit\npnpm test         # vitest (all feature unit tests)\n```\n\n### 项目结构 Project structure\n\n```text\nsrc/\n├── index.ts              # entry point: aggregates feature modules\n├── lib/                  # shared infrastructure (tool-set snapshot/restore)\n└── features/             # feature modules — one directory per feature\n    ├── ask/              # ask mode: command + state machine, bash sandbox,\n    │                     #           system prompt banner, tests\n    ├── favorites/        # model favorites: selector + cycle patches,\n    │                     #           persisted store, tests\n    ├── review/           # third-party review: input/command triggers,\n    │                     #           review-model config store, prompt, tests\n    └── stash/            # prompt stash: hotkey state machine + tests\n```\n\n**新增功能 · adding a feature**:create `src/features/<name>/` exporting `registerXxx(pi)` and call it from `src/index.ts`. Existing modules stay untouched. Each feature ships its own `*.test.ts` (vitest) — keep them deterministic (inject clocks/state, no real agent-dir writes).\n\n**发布 · publishing**(pnpm-only,one command):\n\n```bash\npnpm release patch   # 0.1.2 → 0.1.3\npnpm release minor   # 0.1.2 → 0.2.0   (patch zeroed)\npnpm release major   # 0.1.2 → 1.0.0   (minor + patch zeroed)\npnpm release patch --dry-run   # preview without changing anything\n```\n\n`release` 要求且仅要求 `major | minor | patch` 之一;上级递增清零下级。执行链:校验 → `typecheck + test` 门禁 → 改版本 → git commit + `vX.Y.Z` tag → `pnpm publish`(`prepublishOnly` 二次门禁)。\n\n---\n\n## 🤝 贡献 Contributing\n\n<a name=\"contributing\"></a>\n\nPRs and issues welcome. A few conventions:\n\n- **pnpm only** — never `npm install` / `npm publish`; use `pnpm add` / `pnpm publish`\n- **Feature-module pattern** — one directory per feature (`src/features/<name>/`), export `registerXxx(pi)`, register in `src/index.ts`; shared infra goes in `src/lib/`\n- **Tests** — every feature ships vitest cases; keep them deterministic (injectable clocks/state), no writes to the real agent dir\n- **Built-in patches** (favorites) must stay **version-guarded and idempotent** — verify the target prototype members exist before patching, guard against double-apply, degrade with a `console.warn` instead of breaking the extension\n- **Keybindings** — before picking a new shortcut, check pi defaults + reserved keys, terminal control chars, and OS/terminal-emulator grabs; prefer `ctrl+alt+<letter>` for cross-platform safety\n- **Quality gate** — `pnpm typecheck && pnpm test` must pass before submitting\n\n---\n\n## 📄 License\n\n<a name=\"license\"></a>\n\nMIT © 2026 Andares Cui. See [LICENSE](LICENSE).\n","readmeFilename":""}