pi-lark-notify
pi 主对话 ⇄ 飞书双向桥:主对话完成时发送飞书通知;在飞书里回复通知,内容自动注入对应 pi 会话继续执行。
Package details
Install pi-lark-notify from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-lark-notify- Package
pi-lark-notify- Version
0.3.1- Published
- Aug 17, 2026
- Downloads
- 291/mo · 10/wk
- Author
- naoki326
- License
- MIT
- Types
- extension
- Size
- 44.3 KB
- Dependencies
- 0 dependencies · 1 peer
Pi manifest JSON
{
"extensions": [
"./extensions"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-lark-notify
🚀 把 pi 装进口袋——人在外面,手机飞书就能远程指挥 pi 连续干活。
✨ 它解决什么问题?
你是否有过这样的时刻——人在地铁上 / 工位上 / 回家路上,代码却还在跑?
- pi 在后台执行长任务,你想知道进展,却只能干等?
- 任务跑完了,你还得打开电脑才能看到结果?
- 想让 pi"顺手再改一下",却没法在手机上开口?
pi-lark-notify 让飞书变成 pi 的遥控器:
你发布任务 ─→ pi 开始干活
pi 完成 ───→ 飞书收到通知(完整回复原文)
你长按回复 ─→ "顺便把测试也跑了"
pi 继续干 ──→ 完成后又收到通知 → 循环往复……
双向、零公网成本、一条命令装完就能用:
- WebSocket 长连接,不需要服务器、不需要公网 IP
- 手机飞书即遥控器,任务完成、进度、追问随手掌控
🎯 功能亮点
- 📬 下行通知——主对话每次彻底完成(
agent_settled, 自动重试/压缩不算)时,把项目名、完成时间、最后一条回复 完整原文推送到飞书私聊或群聊 - 📤 上行回注——监听飞书
im.message.receive_v1事件 (WebSocket 长连接,无需公网 webhook),把你的回复通过pi.sendUserMessage注入对应会话继续执行,会话忙时自动排队 - 🎯 精确路由——回复某条通知 → 注入发出该通知的会话 (按 message_id 匹配,多窗口不串话);直接发消息 (非回复)→ 忽略,不注入任何会话
- 🛡️ 安全边界——只接受指定用户(
userId)的单聊消息, 他人给机器人发消息不会触发任何动作 - 👻 静默子 agent——pi-subagents 的子 agent 在同进程内以独立
AgentSession 运行,同样会加载本扩展;factory 执行时检测调用栈中的
pi-subagents 帧并整体静默(不订阅、不通知、不登记),
只有主对话完成才发通知。如需子 agent 通知可配
subagentNotify: true - 🔄 崩溃自愈——消费者进程崩溃自动重启(退避 3s→60s); pi 进程崩溃后,新进程自动清理孤儿消费者
- 💾 单例消费者——全局只起一个
lark-cli event consume子进程,多 session 共享事件流,不堆积进程
🚀 快速开始(3 步)
① 安装
pi install npm:pi-lark-notify
完全自包含,零手动依赖:首次启动会话时,扩展自动完成两件事—— ① 检测不到 lark-cli 时自动
npm install到~/.lark-cli(需联网,约十几秒); ② 将lark-notify节的 appId/appSecret 写入~/.lark-cli/config.json凭证文件(0600 权限)。 不依赖@amaster.ai/pi-lark及其附带技能。
② 创建飞书自建应用(可多台机器复用同一个)
在 飞书开放平台 创建企业自建应用, 或复用已有的:
- 开启机器人能力(应用能力 → 机器人)
- 开通权限(权限管理):
im:message(获取与发送单聊、群组消息)im:message:send_as_bot(以应用的身份发消息)contact:user.id:readonly(可选,用于通过手机号/邮箱查 open_id)
- 创建版本并发布(版本管理与发布)——权限必须发布后才生效
事件接收由 lark-cli
event consume与开放平台建立 WebSocket 长连接, 不需要在控制台配置事件订阅,也不需要公网回调地址。
③ 配置 ~/.pi/agent/settings.json
{
"lark-notify": {
"enabled": true,
"appId": "cli_xxx",
"appSecret": "${LARK_APP_SECRET}",
"domain": "feishu",
"userId": "ou_xxx"
}
}
appSecret支持${ENV_VAR}环境变量语法,避免明文- 从旧版迁移:若 settings 中凭证仍在
pi-lark节 (@amaster.ai/pi-lark的格式),扩展会兼容读取,无需改动配置 - 复用同一个应用时 appId/appSecret/open_id 全部不变 (open_id 是"应用 × 用户"维度,与机器无关),配置可直接照抄
- 不知道自己的 open_id?配好凭证后执行:
lark-cli api POST \
"/open-apis/contact/v3/users/batch_get_id?user_id_type=open_id" \
--data '{"mobiles":["你的手机号"]}' --as bot
✅ 验证
- pi 里执行
/reload(或重启会话) - 随便聊一句 → 对话完成后飞书应收到通知
- 长按通知 → 回复 → 该会话应自动收到
【飞书】...并继续执行,同时飞书收到"✅ 已转达"回执
⚙️ 配置项(lark-notify 一节)
| 键 | 默认 | 说明 |
|---|---|---|
enabled |
true |
总开关(下行 + 上行) |
appId |
— | 飞书自建应用 App ID |
appSecret |
— | 飞书自建应用 App Secret,支持 ${ENV_VAR} 语法 |
domain |
feishu |
应用域名:feishu 或 lark(国际版) |
userId |
— | 私聊接收人 open_id(与 chatId 二选一,优先) |
chatId |
— | 群聊 chat_id(需先把机器人拉进群) |
replyEnabled |
true |
上行回注开关(关闭则只发通知) |
receipt |
true |
转达后回执一条"已转达 ✅" |
subagentNotify |
false |
子 agent 完成也发通知(保险丝,栈检测误判时可显式恢复) |
全局配置在 ~/.pi/agent/settings.json,项目级可用
<项目>/.pi/settings.json 覆盖(例如不同项目发给不同群)。
🧠 工作原理
session_start ─→ getLarkClient()(进程级单例)
│ subscribe(handleEvent)
▼
唯一 `lark-cli event consume` 子进程
(NDJSON 事件流,崩溃自动重启,退避 3s→60s 持续重试)
│ 事件广播给所有订阅者
agent_settled ─→ client.sendMessage()
─→ 记录 通知message_id → 本会话
事件到达 ─→ 过滤(本人/单聊/去重/防过期)
─→ 路由(仅 reply_to 精确匹配,非回复忽略)
─→ 跨会话认领(ClaimDedup 状态文件目录锁)
─→ pi.sendUserMessage(followUp)
session_shutdown ─→ unsubscribe()
(只移除 handler,不关 consumer;consumer 随 pi 进程退出)
状态拆分(各自独立文件 + 目录锁,15s 死锁自动破除):
| 状态文件 | 职责 |
|---|---|
lark-notify-sessions.json |
SessionRegistry:崩溃残留清理 |
lark-notify-router.json |
NotificationRouter:通知 → 会话映射 |
lark-notify-claims.json |
ClaimDedup:事件认领去重,先到先得 |
会话身份:每个扩展实例随机 sid,注入前以 sid 认领事件, 杜绝多窗口重复注入。
⚠️ 注意事项
多机器同时使用
- 长连接模式是集群分发:同一应用的多台机器只有其中一台会收到事件, 因此请确保只有一台机器的 pi 扩展在监听事件 (其余机器只用于发送通知、不回复)
- 回复通知的路由是精确的(按 message_id 匹配),多机并存也安全
- 直接发消息(不回复通知)会被忽略,不注入任何会话。 多机场景请养成回复具体通知的习惯
装了 hermes 的机器(可选)
lark-cli 检测到 HERMES_HOME 等环境变量会误判运行环境并报
config bind 错误。本扩展内部的调用已自动清洗环境变量,不受影响;
但手动或让 agent 使用 lark 技能时,需要 lark-cli 包装脚本。
该脚本在 npm 包中不包含,从 git 仓库获取:
# 从 git 仓库检出后,拷到 PATH 靠前的目录(如 ~/bin)
cp bin/lark-cli bin/lark-cli.cmd ~/bin/ # Windows git-bash + cmd
# macOS/Linux 只需 cp bin/lark-cli ~/bin/
🖥️ 平台支持
- 理论支持 Windows / macOS / Linux 三平台
(lark-cli 依赖
@larksuite/cli声明os: ['darwin', 'linux', 'win32']) - 进程枚举跨平台:Windows 走 PowerShell
Get-CimInstance, macOS/Linux 走ps axww - 验证状态:Windows 已充分验证;macOS/Linux 的主流程
(发消息、事件监听)应可用,但孤儿 consumer 自愈逻辑未经实测,
若
ps不可用或输出格式异常会静默跳过(不影响主功能,仅失去自愈) - 已知限制:上行仅处理单聊(p2p)消息;长连接为集群分发
(详见「多机器同时使用」),
lark-cli event consume子进程退出后 自动重启(退避 3s→60s,持续重试) - 若你在 macOS/Linux 上遇到问题,欢迎反馈
📁 文件结构
pi-lark-notify/
├── package.json # pi 包清单(extensions 声明)
├── extensions/
│ └── lark-notify.ts # 扩展本体(单文件,零依赖)
├── bin/ # 仅 git 仓库包含,npm 包不含
│ ├── lark-cli
│ └── lark-cli.cmd
├── LICENSE
└── README.md
🗑️ 卸载
pi remove pi-lark-notify
删除 settings.json 中的 lark-notify 一节即可彻底清理
(~/.lark-cli 目录可手动删除)。
📄 License
MIT © Naoki326