开发并加载第一个扩展
从一个命令扩展开始,理解注册、发现、加载和运行权限,建立可检查的开发回路。
开发并加载第一个扩展
智能体已经能读文件、调用工具,却还没有“检查这个仓库”的专用入口。往提示词里加一句要求,可以影响模型选择;如果要增加可调用的工具、确定执行的命令或执行前的规则,就需要把能力接到宿主里。
扩展是宿主加载的代码模块。本文先做一个命令,确认加载路径和运行上下文,再逐步加能力。第一次验证只检查扩展加载,不需要模型 API Key。
本文示例固定使用 @earendil-works/pi-coding-agent@1.5.0,源码位于仓库 columns/coding-agent/examples/extension-development/。示例是独立包,先在该目录安装依赖;不需要修改专栏站点依赖。下面的命令均从这个示例目录运行。
用命令确认加载成功
创建 extensions/hello.ts。默认导出的函数接收注册接口 pi,在这里声明命令;真正执行时,宿主才把当前上下文 ctx 交给 handler。
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"
export default function (pi: ExtensionAPI) {
pi.registerCommand("lesson-hello", {
description: "确认扩展已经加载",
handler: async (_args, ctx) => {
if (ctx.hasUI) {
ctx.ui.notify(`扩展已加载,工作目录:${ctx.cwd}`, "info")
} else {
pi.appendEntry("lesson.hello", { cwd: ctx.cwd })
}
},
})
}pi 适合注册能力,ctx 提供本次调用的工作目录、UI 和会话。两者生命周期不同:不要在初始化时记住某个会话上下文,之后一直复用。
npm install
npx pi --extension ./extensions/hello.ts在交互界面输入 /lesson-hello,应看到加载提示和工作目录。如果只有未知命令,先看启动日志中的扩展加载错误,确认路径指向文件,再核对导出函数。此时改模型配置不能解决加载问题。
加载位置决定影响范围
开发期先显式指定单个扩展。这个系列的多个样例会注册同名教学工具,应分别加载;同时加载全部样例会制造名称冲突。宿主支持加载 TypeScript,这不代表模块随处复制后都能找到依赖;依赖解析仍需要正确的包目录。
项目发现也不是任意脚本自动执行的许可。信任流程可能分阶段加载资源,项目扩展不能假设自己能参与信任之前的决定。需要实现信任策略时,应查对应宿主版本的启动顺序,不能拿普通 session_start 代替。
先区分三种扩展材料
Skill 主要给模型提供任务方法,扩展把代码接到智能体宿主,资源包负责把这些文件组织分发。一个包可以同时包含 Skill 和扩展,但安装了 Skill 不等于注册了新工具。
后面两篇使用 Chord 构建应用内插件。它需要自己创建 host、定义契约和管理引用,并不能把一个 facet 文件直接放进 .pi/extensions/ 当作命令行扩展。先确认扩展点属于谁,才能选择入口。
用加载器排除模型干扰
配套的 src/audit.ts 只发现并加载指定文件,列出工具、命令、事件,不创建 Agent 或发模型请求:
npm run audit -- extensions/hello.ts应看到 errors: []、命令 lesson-hello 和空工具集合。这个结果证明文件可以被加载并完成注册;输入命令后的 UI 展示,仍要在宿主交互模式单独检查。
扩展和宿主运行在同一个 Node 进程权限下,可能接触文件、网络和凭据。事件拦截也不构成操作系统沙箱。只加载自己能够审查和信任的代码,并把定时器、监听器等运行资源放到会话生命周期内启动和释放。下一篇先把只读检查能力做成工具和命令。
依据与版本
代码以已发布的 1.5.0 包导出、类型声明和加载器为准。在线主分支会继续变化,遇到接口差异时先核对版本。