← 返回更新日志

Pi v0.35.0

2026-01-05 · GitHub 原文
本次发布将 hooks(钩子)和 custom tools(自定义工具)统一为单一的“extensions(扩展)”系统,并将“slash commands(斜杠命令)”重命名为“prompt templates(提示词模板)”。([#454](https://github.com/badlogic/pi-mono/issues/454)) **迁移前必读:** - [docs/extensions.md](docs/extensions.md) - 完整 API 参考文档 - [README.md](README.md) - 包含示例的扩展部分 - [examples/extensions/](examples/extensions/) - 可运行的示例 ### 扩展迁移 钩子(Hooks)和自定义工具(Custom Tools)现已统一为**扩展(Extensions)**。两者原本都是导出一个接收 API 对象的工厂函数的 TypeScript 模块。现在统一为一个概念、一个发现位置、一个 CLI 标志和一个 settings.json 配置项。 **自动迁移:** - 启动时 `commands/` 目录会自动重命名为 `prompts/`(包括 `~/.pi/agent/commands/` 和 `.pi/commands/`) **需手动迁移:** 1. 将文件从 `hooks/` 和 `tools/` 目录移至 `extensions/`(启动时会显示弃用警告) 2. 更新扩展代码中的导入语句和类型名称 3. 如果配置了明确的钩子和自定义工具路径,请更新 `settings.json` **目录变更:** ``` # 之前 ~/.pi/agent/hooks/*.ts → ~/.pi/agent/extensions/*.ts ~/.pi/agent/tools/*.ts → ~/.pi/agent/extensions/*.ts .pi/hooks/*.ts → .pi/extensions/*.ts .pi/tools/*.ts → .pi/extensions/*.ts ``` **扩展发现规则**(位于 `extensions/` 目录中): 1. **直接文件:** `extensions/*.ts` 或 `*.js` → 直接加载 2. **带 index 的子目录:** `extensions/myext/index.ts` → 作为单个扩展加载 3. **带 package.json 的子目录:** `extensions/myext/package.json` 中包含 `"pi"` 字段 → 加载声明的路径 ```json // extensions/my-package/package.json { "name": "my-extension-package", "dependencies": { "zod": "^3.0.0" }, "pi": { "extensions": ["./src/main.ts", "./src/tools.ts"] } } ``` 递归深度不超过一层。复杂的包必须使用 `package.json` 清单。依赖项通过 jiti 解析,扩展可以发布到 npm 并从 npm 安装。 **类型重命名:** - `HookAPI` → `ExtensionAPI` - `HookContext` → `ExtensionContext` - `HookCommandContext` → `ExtensionCommandContext` - `HookUIContext` → `ExtensionUIContext` - `CustomToolAPI` → `ExtensionAPI` (已合并) - `CustomToolContext` → `ExtensionContext` (已合并) - `CustomToolUIContext` → `ExtensionUIContext` - `CustomTool` → `ToolDefinition` - `CustomToolFactory` → `ExtensionFactory` - `HookMessage` → `CustomMessage` **导入变更:** ```typescript // 之前(钩子) import type { HookAPI, HookContext } from "@mariozechner/pi-coding-agent"; export default function (pi: HookAPI) { ... } // 之前(自定义工具) import type { CustomToolFactory } from "@mariozechner/pi-coding-agent"; const factory: CustomToolFactory = (pi) => ({ name: "my_tool", ... }); export default factory; // 之后(现在均为扩展) import type { ExtensionAPI } from "@mariozechner/pi-coding-agent"; export default function (pi: ExtensionAPI) { pi.on("tool_call", async (event, ctx) => { ... }); pi.registerTool({ name: "my_tool", ... }); } ``` **自定义工具现在拥有完整的上下文访问权限。** 通过 `pi.registerTool()` 注册的工具现在会接收到与事件处理器相同的 `ctx` 对象。以前,自定义工具的上下文有限。现在所有扩展代码共享相同的能力: - `pi.registerTool()` - 注册 LLM 可调用的工具 - `pi.registerCommand()` - 注册类似 `/mycommand` 的命令 - `pi.registerShortcut()` - 注册键盘快捷键(在 `/hotkeys` 中显示) - `pi.registerFlag()` - 注册 CLI 参数(在 `--help` 中显示) - `pi.registerMessageRenderer()` - 为消息类型自定义 TUI 渲染 - `pi.on()` - 订阅生命周期事件(如 tool_call、session_start 等) - `pi.sendMessage()` - 向对话中注入消息 - `pi.appendEntry()` - 在会话中持久化自定义数据(重启/分支后保留) - `pi.exec()` - 运行 Shell 命令 - `pi.getActiveTools()` / `pi.setActiveTools()` - 动态启用/禁用工具 - `pi.getAllTools()` - 列出所有可用工具 - `pi.events` - 用于跨扩展通信的事件总线 - `ctx.ui.confirm()` / `select()` / `input()` - 用户提示框 - `ctx.ui.notify()` - 弹出通知(Toast) - `ctx.ui.setStatus()` - 在页脚设置持久化状态(多个扩展可各自设置) - `ctx.ui.setWidget()` - 在编辑器上方显示组件 - `ctx.ui.setTitle()` - 设置终端窗口标题 - `ctx.ui.custom()` - 带键盘处理的完整 TUI 组件 - `ctx.ui.editor()` - 支持外部编辑器的多行文本编辑器 - `ctx.sessionManager` - 读取会话条目,获取分支历史 **配置变更:** ```json // 之前 { "hooks": ["./my-hook.ts"], "customTools": ["./my-tool.ts"] } // 之后 { "extensions": ["./my-extension.ts"] } ``` **CLI 变更:** ```bash # 之前 pi --hook ./safety.ts --tool ./todo.ts # 之后 pi --extension ./safety.ts -e ./todo.ts ``` ### 提示词模板迁移 “斜杠命令”(通过 `/名称` 调用的定义可复用提示词的 Markdown 文件)现重命名为“提示词模板”,以避免与扩展注册的命令混淆。 **自动迁移:** 启动时 `commands/` 目录会自动重命名为 `prompts/`(如果 `prompts/` 不存在)。同时适用于普通目录和符号链接。 **目录变更:** ``` ~/.pi/agent/commands/*.md → ~/.pi/agent/prompts/*.md .pi/commands/*.md → .pi/prompts/*.md ``` **SDK 类型重命名:** - `FileSlashCommand` → `PromptTemplate` - `LoadSlashCommandsOptions` → `LoadPromptTemplatesOptions` **SDK 函数重命名:** - `discoverSlashCommands()` → `discoverPromptTemplates()` - `loadSlashCommands()` → `loadPromptTemplates()` - `expandSlashCommand()` → `expandPromptTemplate()` - `getCommandsDir()` → `getPromptsDir()` **SDK 选项重命名:** - `CreateAgentSessionOptions.slashCommands` → `.promptTemplates` - `AgentSession.fileCommands` → `.promptTemplates` - `PromptOptions.expandSlashCommands` → `.expandPromptTemplates` ### SDK 迁移 **发现函数:** - `discoverAndLoadHooks()` → `discoverAndLoadExtensions()` - `discoverAndLoadCustomTools()` → 已合并至 `discoverAndLoadExtensions()` - `loadHooks()` → `loadExtensions()` - `loadCustomTools()` → 已合并至 `loadExtensions()` **运行器与包装器:** - `HookRunner` → `ExtensionRunner` - `wrapToolsWithHooks()` → `wrapToolsWithExtensions()` - `wrapToolWithHooks()` → `wrapToolWithExtensions()` **CreateAgentSessionOptions:** - `.hooks` → 已移除(路径请使用 `.additionalExtensionPaths`) - `.additionalHookPaths` → `.additionalExtensionPaths` - `.preloadedHooks` → `.preloadedExtensions` - `.customTools` 类型变更:`Array<{ path?; tool: CustomTool }>` → `ToolDefinition[]` - `.additionalCustomToolPaths` → 已合并至 `.additionalExtensionPaths` - `.slashCommands` → `.promptTemplates` **AgentSession:** - `.hookRunner` → `.extensionRunner` - `.fileCommands` → `.promptTemplates` - `.sendHookMessage()` → `.sendCustomMessage()` ### 会话迁移 **自动。** 会话版本从 2 升级至 3。现有会话将在首次加载时自动迁移: - 消息角色 `"hookMessage"` → `"custom"` ### 破坏性变更 - **设置:** `hooks` 和 `customTools` 数组已替换为单个 `extensions` 数组 - **CLI:** `--hook` 和 `--tool` 参数已替换为 `--extension` / `-e` - **目录:** `hooks/`, `tools/` → `extensions/`;`commands/` → `prompts/` - **类型:** 参见上方的类型重命名 - **SDK:** 参见上方的 SDK 迁移 ### 其他变更 - 扩展可拥有独立的 `package.json` 及依赖(通过 jiti 解析) - 文档:`docs/hooks.md` 和 `docs/custom-tools.md` 已合并至 `docs/extensions.md` - 示例:`examples/hooks/` 和 `examples/custom-tools/` 已合并至 `examples/extensions/` - README:扩展部分已扩充,新增自定义工具、命令、事件、状态持久化、快捷键、参数及 UI 示例 - SDK:`customTools` 选项现在直接接受 `ToolDefinition[]`(从 `Array<{ path?, tool }>` 简化而来) - SDK:`extensions` 选项现在接受 `ExtensionFactory[]` 用于内联扩展 - SDK:`additionalExtensionPaths` 同时替代了 `additionalHookPaths` 和 `additionalCustomToolPaths`