pi-candy-toolbox1.0.0
pi 的小工具聚合箱 — 收纳零散小功能,每个工具独立开关、独立配置
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
pi-candy-toolbox 🍬🧰
pi 的小工具聚合箱 —— 收纳零散的小功能、小工具。与其为每个小功能单独装一个插件,不如都收进这个工具箱:一个插件、一个配置文件、每个工具独立开关。
安装
npm 安装
pi install npm:pi-candy-toolbox
pi -e npm:pi-candy-toolbox # 临时试用,不写入配置
本地安装
git clone https://github.com/CandyMuj/pi-candy-extensions.git
cd pi-candy-extensions/pi-candy-toolbox # 进入插件目录
pi install . # 安装当前目录
pi -e . # 临时试用,不写入配置
无第三方运行时依赖,两种方式都无需额外 npm install。安装完成后 /reload 生效,启动时控制台会打印每个工具的启用状态。
配置文件
配置文件位于 ~/.pi/agent/candy-toolbox.json,不存在时所有工具按默认值启用。
每个工具拥有一个独立的顶层 key(工具 id),key 下放该工具的具体配置(插件级配置另见下方 $toolbox)。开关支持三种写法:
{
"$toolbox": { "debug": false, "logDir": "~/.pi/candy-toolbox-logs" },
"hello": true,
"some-tool": false,
"fancy-tool": {
"enabled": true,
"optionA": "自定义值",
"optionB": 42
}
}
| 写法 | 效果 |
|---|---|
"tool-id": true |
启用,使用该工具的默认配置 |
"tool-id": false |
禁用 |
"tool-id": { ... } |
启用,字段与默认配置浅合并覆盖(也可写 { "enabled": false } 禁用) |
| (未提及) | 按工具的 defaultEnabled 决定,默认启用 |
插件级配置 $toolbox
以 $ 开头的顶层 key 是插件级配置,不是工具 id;工具 id 不得以 $ 开头。
| 字段 | 默认 | 说明 |
|---|---|---|
debug |
false |
日志总开关:true 时所有工具都写日志(工具级 debug: true 仍可单独开启某个工具,两者是「或」关系) |
logDir |
~/.pi/candy-toolbox-logs |
日志目录,支持 ~ 展开与相对路径;各工具写入 <logDir>/<工具 id>.log,插件自身写入 <logDir>/$toolbox.log |
日志只写文件,不打印终端:终端输出会污染 pi --help 等大部分命令的 stdout、非交互模式的 stderr,以及 /reload 时的 TUI 画面。$toolbox.log 记录启动摘要(加载开始/启用/禁用/加载完成)与注册失败,同样由 $toolbox.debug 控制。
编辑配置文件后需重启 pi(或 /reload)生效。
已有工具
| 工具 id | 说明 | 文档 | 默认 |
|---|---|---|---|
hello |
示例工具:注册 /candy-hello 命令 |
— | 关闭 |
session-title |
生成/重新生成会话标题:/candy-title [提示词],config 子命令查看/修改配置 |
docs/session-title.md | 启用 |
click-cursor |
全屏模式点击输入框移动光标(无命令) | docs/click-cursor.md | 启用 |
transcript-jump |
打开提问列表并跳转到对应位置:/candy-jump(快捷键 alt+j,仅全屏) |
docs/transcript-jump.md | 启用 |
添加新工具
每个工具一个文件或一个目录,互不干扰。渐进式:简单工具用单文件,变复杂后随时可以升级为目录:
extensions/
├── index.ts # 入口:加载配置 + 工具清单
├── core/
│ ├── config.ts # 配置读取与归一化(一般不用改)
│ ├── log.ts # 统一日志出口(写文件,不打印终端)
│ └── entries.ts # 会话 entry 公共工具(各工具共享的类型与纯函数,避免重复实现)
└── tools/
├── _template.ts # 新工具模板(复制它)
├── hello.ts # 示例:简单工具 = 单文件
└── notify/ # 示例:复杂工具 = 目录(目录名 = 工具 id)
├── index.ts # 入口,导出 ToolDefinition(与单文件完全一致)
├── host.ps1 # 资源文件
├── utils.ts # 私有子模块
└── tests/ # 工具自带测试(不会被加载)
三步添加新工具:
- 复制
extensions/tools/_template.ts为extensions/tools/<tool-id>.ts(简单)或extensions/tools/<tool-id>/index.ts(复杂),改id、description、defaultConfig,实现register(); - 在
extensions/index.ts的TOOLS清单中 import 并加一行(目录工具 import 路径到目录即可,自动解析index.ts); - 可选:在
candy-toolbox.json中用工具 id 配置开关。
约定:
- 工具文件/目录默认导出一个
ToolDefinition:id(配置 key)+defaultConfig+register(pi, config, log),目录工具的入口同样是index.ts导出ToolDefinition,接口一致 register只在工具启用时被调用,不用自己判断开关;拿到的是合并后的最终配置- 第三个参数
log是统一日志出口(core/log.ts):写<logDir>/<工具 id>.log,不打印终端;开关由入口按$toolbox.debug || config.debug === true算好,工具在defaultConfig里留一个debug: false字段即可,不必自己读 - 配置中未提到的工具默认启用;有副作用、需要用户确认的工具可设
defaultEnabled: false - 单文件升级为目录是纯增量操作:把文件移入新目录改名为
index.ts,清单中 import 路径加目录名即可 - 新增工具后顺手更新本 README 的「已有工具」表格
- 顺手补测试:简单工具
tests/<tool-id>.test.ts,复杂工具tests/<tool-id>/;插件级(core/等非工具模块)放tests/$toolbox/(见下一节)
测试
npm install # 首次:装 devDependencies(typescript / @types/node)与 peer 依赖
npm test # node --test,直接跑 TypeScript(无需构建)
npm run typecheck # tsc --noEmit
测试文件与工具的形态一一对应,统一放在 tests/:
| 被测对象 | 命名 |
|---|---|
| 简单工具(单文件) | tests/<tool-id>.test.ts(如 session-title.test.ts、click-cursor.test.ts) |
| 复杂工具(目录) | tests/<tool-id>/ 目录,内放多个 *.test.ts |
core/ 等非工具模块(插件级) |
tests/$toolbox/<模块名>.test.ts(如 config.test.ts、log.test.ts) |
| 公共 stub / 辅助函数 | tests/helpers.ts |
约定:某个测试需要自定义 agent 目录时,先调 useTempAgentDir() 再动态 import() 被测模块——
core/config.ts 在模块加载时就用 getAgentDir() 算好了 CONFIG_PATH,静态 import 会先于 env 设置执行。
工具文档
每个工具配一篇文档,说明功能、用法、配置与方案逻辑,避免本 README 过度膨胀。存放规则:
- 单文件工具(简单):文档统一放
docs/<tool-id>.md,例如docs/session-title.md - 目录工具(复杂):文档放工具目录内
README.md(与代码同处,便于随工具整体移动/分发) - 「已有工具」表格的「文档」列引用对应文档;新增工具后同步补充
统一文档模板:功能说明 → 命令用法 → 配置项表 → 方案逻辑 → 实现要点。