i-have-adhd扩展API全解:registerFlag、registerCommand与on(input)实战
【免费下载链接】i-have-adhdA skill to stop your coding agent from burying the answer. ADHD-friendly output.项目地址: https://gitcode.com/GitHub_Trending/ih/i-have-adhd
i-have-adhd 是一款让编码 Agent 输出"ADHD 友好"回复的技能插件——答案先行、步骤编号、没有废话开头。本文带你拆解它的 Pi 扩展 API:registerFlag、registerCommand与on(input)三个核心接口的实战用法,全部实现就在 extensions/i-have-adhd.ts 一个文件里,约 220 行,是学习 Agent 扩展开发的上佳样本。
先认识 i-have-adhd 扩展:规则与行为的分工
这个项目把"内容"和"行为"拆开了:
| 文件 | 职责 |
|---|---|
| skills/i-have-adhd/SKILL.md | 10 条 ADHD 友好输出规则(内容) |
| extensions/i-have-adhd.ts | Pi/OMP 运行时扩展,负责开关、命令、拦截(行为) |
| extensions/context-compat.ts | 上下文探测工具,判断规则是否还"活着" |
| package.json | 声明pi.extensions入口,Pi 靠它发现扩展 |
扩展启动时先读取 SKILL.md 正文(去掉 frontmatter),然后在 Pi 提供的扩展 API 上挂三样东西:一个启动标志、一个斜杠命令、一组事件监听。下面逐个拆解。
registerFlag 实战:一行--adhd启动开关
pi.registerFlag("adhd", { description: "Start with ADHD-friendly output enabled", type: "boolean", default: false, });这段代码注册了一个布尔型 CLI 参数(extensions/i-have-adhd.ts#L163-L167)。注册后,用户启动 Pi 时就能带上参数:
pi --adhd扩展内部再用pi.getFlag("adhd")读回它的值,决定新会话是否默认开启 ADHD 模式。它与一个"常驻标志文件"互为兜底:
pi.getFlag("adhd") === true→ 本次启动显式开启;existsSync(alwaysOnFlag)→ 检测到~/.pi/agent/.i-have-adhd-always空文件,等于"每次默认开启"。
要点:registerFlag只负责"声明 + 默认值",真正的使用发生在session_start恢复状态时,两个时机分离是这类扩展的常见模式。
registerCommand 实战:/i-have-adhd会话级开关
pi.registerCommand("i-have-adhd", { description: "Toggle ADHD-friendly output for this session", handler: async (args, ctx) => { /* 解析 on/off 参数 */ }, });注册后,用户在对话框输入/i-have-adhd即可切换模式。handler 的参数解析很简单(extensions/i-have-adhd.ts#L169-L191):
| 输入 | 行为 |
|---|---|
/i-have-adhd(不带参数) | 翻转当前状态(开→关、关→开) |
/i-have-adhd on | 显式开启 |
/i-have-adhd off/stop | 显式关闭 |
| 其他参数 | 弹出用法提示Usage: /i-have-adhd [on\|off] |
切换时做的三件事值得注意:
pi.appendEntry(STATE_ENTRY_TYPE, { enabled })—— 把开关状态写入会话分支,重开会话能恢复;ctx.ui.setStatus(STATUS_KEY, "● ADHD ON")—— 在底部状态栏打上绿色标记;ctx.ui.notify(...)—— 弹一条 "ADHD mode enabled/disabled" 通知。
要点:registerCommand提供的是"确定性入口",用户随时能精确控制模式,这比让模型自己决定何时切换更可靠。
on(input) 实战:拦截用户输入做"关键词魔法"
on(input)是扩展监听用户每条输入的机会,返回不同的 action 决定这条输入的命运:
pi.on("input", async (event, ctx) => { const input = event.text.trim().toLowerCase(); if (input === "/skill:i-have-adhd") { setEnabled(true, ctx); return { action: "handled" }; // 拦截,不发给模型 } if (enabled && STOP_PHRASES.has(input)) { setEnabled(false, ctx); if (ctx.hasUI) return { action: "handled" }; return { action: "transform", text: `Reply with exactly: ADHD mode disabled.` }; } return { action: "continue" }; // 放行,正常处理 });三种返回值各有用途(extensions/i-have-adhd.ts#L193-L217):
| 返回值 | 效果 | 本项目的用法 |
|---|---|---|
{ action: "handled" } | 输入被吞掉,模型完全看不到 | 把/skill:i-have-adhd当作开启别名,避免规则被重复注入 |
{ action: "transform", text } | 替换成指定文本再发给模型 | 无 UI 环境下,把"stop adhd mode"改写为"只回复确认句" |
{ action: "continue" } | 原样放行 | 绝大多数输入 |
最巧妙的地方是自然语言停止词:用户直接输入stop adhd mode或normal mode(不是斜杠命令)也能关闭模式。停止词集合就一行:new Set(["stop adhd mode", "normal mode"])。
会话事件与上下文同步:保证规则"永远在场"
除了input,扩展还监听了三个会话事件:
pi.on("session_start", async (_e, ctx) => restoreState(ctx)); pi.on("session_tree", async (_e, ctx) => restoreState(ctx)); pi.on("session_compact", async (_e, ctx) => syncContext(ctx));- session_start / session_tree:新会话、恢复或分叉时,从分支历史读回保存的开关状态,必要时把规则注入对话;
- session_compact:会话压缩会丢掉已总结的旧消息,此时检测规则是否还在上下文里,不在就重新注入。
"规则是否还在"的判断在 extensions/context-compat.ts 中:contextMessages()兼容探测不同运行时的 sessionManager API(探测失败时安全降级为"不在",宁可重复注入也不破坏启动);latestMarkerIsActive()只看最新一个标记——后出现的 "disabled" 通知可以覆盖之前的规则集。注入本身用pi.sendMessage完成,display: false保证用户看不见这条规则消息,triggerTurn: false保证不会触发模型额外回复。
核心 API 速查表
| API | 作用 | 本项目用途 |
|---|---|---|
pi.registerFlag(name, opts) | 注册 CLI 启动参数 | --adhd布尔开关 |
pi.getFlag(name) | 读取标志值 | 判断本次启动是否默认开启 |
pi.registerCommand(name, opts) | 注册斜杠命令 | /i-have-adhd [on\|off] |
pi.on("input", handler) | 拦截用户输入 | 停止词关闭、skill 命令别名 |
pi.on("session_start", handler) | 会话开始事件 | 恢复上次的开关状态 |
pi.on("session_compact", handler) | 上下文压缩事件 | 重新注入被压缩掉的规则 |
pi.sendMessage(msg, opts) | 向会话注入消息 | 静默注入/撤销规则集 |
pi.appendEntry(type, data) | 写会话自定义数据 | 持久化开关状态 |
ctx.ui.setStatus / notify | 状态栏 / 通知 | ● ADHD ON标记、切换提示 |
快速验证效果
- 按 INSTALL.md 中 Pi 章节安装扩展;
- 输入
/i-have-adhd,状态栏出现● ADHD ON; - 提问一个多步骤任务,观察回复是否"命令先行 + 编号步骤 + 无寒暄";
- 输入
stop adhd mode,确认模式即被关闭——这正是on(input)的功劳。
总结:三个 API 各司其职
registerFlag:管"启动时"——pi --adhd让默认状态由用户掌控;registerCommand:管"会话中"——/i-have-adhd提供随时可预测的开关;on(input):管"每条输入"——自然语言停止词和别名拦截让体验更顺滑。
配合session_start/session_compact两个事件,整个扩展做到了规则"注入一次、压缩后补注、随用户意愿关闭"。想动手实践?通读 extensions/i-have-adhd.ts 全文,再对照 AGENTS.md 里的仓库地图,你会对 Agent 扩展的事件模型建立完整认知。
【免费下载链接】i-have-adhdA skill to stop your coding agent from burying the answer. ADHD-friendly output.项目地址: https://gitcode.com/GitHub_Trending/ih/i-have-adhd
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考