Extension:改变系统,而不是堆配置
理解扩展加载、事件生命周期、工具与命令注册,以及同进程执行带来的真正能力与风险。
5bc1c2c0为什么 Pi 把“功能”推向 Extension
插件不是给成品多加一个按钮。Pi Extension 更像把一块新电路接入底盘:它可以新增工具、监听生命周期、改变上下文,甚至重做界面。
Extension 是导出默认注册函数的 TypeScript module。它通过 ExtensionAPI 注册 tools、commands、shortcuts、renderers 与 event handlers,并可向 session 追加 custom entries。
DefaultResourceLoader 汇总全局、项目、CLI 与 package resources;project trust 决定项目级 extension 是否加载;jiti 负责执行 TypeScript 模块。
能力表面
| 能力 | 例子 | 影响范围 |
|---|---|---|
registerTool |
新增部署、查询或审批能力 | 模型行动空间 |
registerCommand |
/review、/handoff |
用户工作流 |
on(event) |
阻断 tool call、改 system prompt | runtime 生命周期 |
appendEntry |
保存扩展状态 | session tree |
registerMessageRenderer |
自定义消息表现 | TUI |
| provider hooks | 改 payload/header | 模型边界 |
生命周期不是一条直线
Extension 可以观察 session start/switch/fork/tree/compact、input、before agent start、turn/message/tool call、model change、shutdown 等事件。不同事件允许不同返回值:有的只能观察,有的可以 cancel、block 或替换。
session_start
→ input
→ before_agent_start
→ agent_start
→ turn_start
→ tool_call (可 block)
→ tool_result (可改写)
→ turn_end
→ agent_end
→ session_shutdown
packages/coding-agent/docs/extensions.md:407-922extension events
资源发现与优先级
Pi 可从全局目录、项目 .pi/、设置路径、packages 和 CLI -e 加载资源。资源碰撞会进入 diagnostics;这比“最后一个静默覆盖”更适合可调试系统。
Project Trust 在这里发挥作用:未经信任的项目,项目级 settings、packages、extensions 等不会加载,但 AGENTS.md / CLAUDE.md 仍会作为 context files 读取。
状态:Custom entry 与 Custom message
customentry 保存扩展状态,不进入 LLM context。custom_messageentry 会投影进 context,可选择是否在 UI 显示。
这个区别能让扩展保存选择、缓存或 UI 状态,而不必向模型重复描述;只有真正影响推理的信息才进入 context。
Trade-off
同进程扩展拥有极强表现力,能避免核心被每个团队需求撑大;代价是组合冲突、启动风险和安全责任都转移给使用者。Pi 的理念是“暴露足够原语”,不是“保证任意插件可安全组合”。