npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

kimi-code-feishu

v0.1.1

Published

让 Kimi Code CLI 通过飞书机器人远程通信:派任务、看进度、批权限

Readme

kimi-code-feishu

Kimi Code CLI 连上飞书机器人:在任何地方用手机跟你的本机 Kimi Code 持续对话、看实时进度、批准/拒绝权限请求、接管终端会话。

机制

┌─────────────┐  飞书长连接(WebSocket)  ┌───────────────────────────────────┐
│  手机飞书    │ ◄────────────────────► │             本桥接服务             │
│ (消息/卡片)  │                        │  FeishuChannel ⇄ Bridge           │
└─────────────┘                        │  HookServer(127.0.0.1:17781)      │
                                       │  ChatSessionManager(tmux 托管)    │
                                       │  WireWatcher(wire.jsonl 转录监听) │
                                       └──────────┬────────────────────────┘
               send-keys 注入 / capture-pane 抓屏  │  hooks(审批/进度事件)
        ┌──────────────────────────────────────────┼───────────────────────────┐
        ▼                                          ▼                           ▼
┌───────────────┐                        ┌──────────────────┐       ┌──────────────────┐
│ 0 号会话       │                        │ 终端会话(tmux)    │       │ 终端会话(pts)     │
│ kcf-chat-xxx  │                        │ kimi-code-feishu │       │ 裸终端里的 kimi   │
│ 每聊天一个常驻 │                        │ tmux 启动        │       │ TIOCSTI 注入      │
│ 交互式 kimi    │                        │ send-keys 注入   │       │ wire 转录代替抓屏 │
└───────────────┘                        └──────────────────┘       └──────────────────┘

核心设计:

  • 每聊天一个常驻交互式 kimi 会话(0 号):桥在 tmux 里为每个飞书聊天拉起 kimikcf-chat-xxx)。消息用 send-keys 注入,结果从该会话的 wire.jsonl(kimi 磁盘实时转录)聚合回推,防抖判定轮次结束。进程常驻 = 上下文连续,服务端 prefix cache 吃同一会话前缀;交互模式下模型还能调 AskUserQuestion 反问你(飞书弹答题卡,点选后真实按键作答)
  • hooks 是审批与监控通道PreToolUse → 飞书审批卡片(点击内联更新,全端同步);PostToolUse/Stop/SessionStart 等 → 进度推送;PermissionRequest → 终端权限等待的兜底通知
  • 终端会话可发现可接管ps 全量扫描发现所有 kimi 进程——tmux 会话用 send-keys/capture-pane 注入与抓屏;普通终端(pts)用 TIOCSTI 注入(屏幕读不到,用磁盘转录代替)
  • fail-closed:桥掉线 = 需审批操作默认拒绝;桥启动通知 + systemd 常驻保证在线
  • Dashboard 按需开启:用的时候才拉起(新 token、可选 cloudflared 公网隧道、闲置自动关、页面只读)

一、安装

| 依赖 | 说明 | |---|---| | Node.js ≥ 18 | 用到全局 fetchAbortSignal.timeout | | Kimi Code CLI | 已安装并完成 /login | | 飞书账号 | 能创建企业自建应用 |

npm install -g kimi-code-feishu        # 发布后
# 或从源码安装
npm install && npm run build && npm link

安装后得到 kimi-code-feishu 命令。

二、创建飞书应用(约 1 分钟)

kimi-code-feishu onboard

onboard 提供两种接入方式,启动后按提示选择:

方式 1:扫码即创(推荐)

终端显示二维码,用飞书手机 App 扫码并在官方确认页点确认即可——飞书服务端自动创建好带机器人能力和消息权限的应用,app_id / app_secret 和你的 open_id(自动加入 allowed_user_ids)会直接写入配置,无需手动创建应用。

原理:飞书官方账号体系的 Device-Flow 应用注册协议(与官方开源 larksuite/cli 相同),全程匿名调用、无需公网回调,配置写入后仍需手动 run 启动桥。 扫码创建用的是官方预置模板(PersonalAgent),审批卡片所需的 card.action.trigger 等配置已包含;如后续需要额外权限(文档、日历等),仍需到开发者后台补配。 应用名默认为官方模板名(如「CLI 助手」):扫码时在手机确认页上可以直接修改;事后改名请到开发者后台「凭证与基础信息」页(https://open.feishu.cn/app/<appId>/baseinfo),需创建新版本并发布才生效。

方式 2:手动输入已有应用的凭证

在 onboard 菜单选 2,粘贴已有的 App ID / App Secret(open_id 可留空,之后私聊机器人发 /id 获取再补填)。适合已经有配置好的应用、或需要自定义权限模板的场景。也可用 kimi-code-feishu init 生成配置模板后手动编辑。

手动创建应用的步骤:

  1. 飞书开放平台创建企业自建应用(如「Kimi 遥控器」)。
  2. 添加应用能力 → 机器人。
  3. 权限管理 开通:im:messageim:message:send_as_botim:message:readonly
  4. 事件订阅
    • 接收方式选 使用长连接接收事件(不需要公网 IP 的关键);
    • 添加事件 im.message.receive_v1
    • 添加回调 card.action.trigger(审批按钮依赖它)。
  5. 版本管理与发布 → 创建版本并发布。
  6. 凭证与基础信息 页复制 App ID / App Secret

三、配置与启动

kimi-code-feishu onboard               # 扫码创建应用并自动写入配置(推荐,见上一节)
# 或手动方式:kimi-code-feishu init 生成 ~/.kimi-code-feishu/config.toml 后自行填入凭证
kimi-code-feishu run                   # 启动桥(保持运行)
# 手动方式还需:手机飞书私聊机器人发 /id → 把返回的 ou_xxx 填入 allowed_user_ids → 重启桥

# 另一个终端:把 hooks 写入 Kimi CLI 配置(自动探测 ~/.kimi 或 ~/.kimi-code,自动备份)
kimi-code-feishu install

install 写入的 hook 命令形如:

[[hooks]]
event = "PreToolUse"
command = " /usr/bin/node /path/to/dist/hook.js pre_tool_use"
timeout = 180

重启正在运行的 kimi 会话后生效;CLI 内 /hooks 可确认。hook 用绝对路径直接调用。

后台常驻(推荐 systemd 用户服务,崩溃自动重启、开机自启):

sh deploy/install-service.sh     # 渲染并启用 ~/.config/systemd/user/kimi-code-feishu.service
journalctl --user -u kimi-code-feishu -f   # 看日志
# 或简单方式:nohup kimi-code-feishu run > ~/.kimi-code-feishu/bridge.log 2>&1 &

桥在线很重要:fail-closed 设计下桥掉线 = 需审批操作全部默认拒绝。桥每次启动会往最近活跃的聊天发一条「✅ 桥已上线」(附 Dashboard 地址),出门在外能确认它活着。

四、使用方法

会话模型

每个飞书聊天 = 一个桥托管的常驻交互式 kimi 会话(tmux 里跑 kimi,命名 kcf-chat-xxx,编号 0):

  • 直接发消息 = send-keys 注入该会话;上下文连续(进程常驻 + 磁盘转录),服务端 prefix cache 友好
  • 结果从会话的 wire.jsonl 转录聚合回推;进度消息滚动更新工具调用
  • 模型可以提问(交互模式)——AskUserQuestion 会弹出飞书选项卡片,点选后真实按键作答
  • 会话落在包安装路径(可用 /bind 改);/new 杀掉重开;/stop 发 Esc 中断;/i 用 Ctrl+S 优先插话

终端模式/a 序号 绑定任何其他终端会话后):纯文本自动注入那个会话;/0 <文本> 发回 0 号会话;/a free/a 0 切回。终端的 /命令(/model /yolo…)一律 /t /model 注入。注入后的轮次结果也会从磁盘转录聚合回传到飞书(防抖判定轮次结束)。

飞书里(手机/电脑均可)

全部命令

| 输入 | 作用 | |---|---| | 任意普通文本 | 发给当前会话(飞书模式=0 号会话;终端模式=绑定的终端会话) | | /0 <文本> | 发给 0 号会话(飞书本身的常驻会话;终端模式下用它发回) | | /new | 杀掉 0 号会话,下一条消息全新开始 | | /stop | 中断当前轮次(发 Esc) | | /status | 当前状态:模式、任务、目录、会话、待审批数 | | /bind <目录> | 绑定 0 号会话的工作目录(同时重置会话) | | /a | 列出所有终端会话(序号/目录/可控性/当前绑定) | | /a <序号> | 绑定终端会话,进入终端模式(纯文本自动注入) | | /a free/a 0 | 释放绑定,切回飞书模式 | | /t <文本> | 注入绑定会话(含终端的 /命令/t /model/t /yolo) | | /i <文本> | 优先插话(Ctrl+S,立即插入运行中的轮次) | | /s | 查看绑定会话:tmux=实时抓屏;pts=读磁盘转录尾部 | | /c | 审批池列表(各终端会话在池状态;🔓=已释放审批) | | /c <序号或路径> | 切换某会话/目录的池状态(进池才弹审批卡/推进度) | | /c free <序号或路径> | 释放/恢复该目录会话的审批 hook(释放后直接放行,回落终端原生权限) | | /p | 审批黑白名单(按目录):显示当前模式与名单 | | /p mode | 切换白名单/黑名单模式(黑名单模式=未命中黑名单都直接放行) | | /p allow\|deny <规则> | 加规则:Bash 整工具 或 Bash:/rm|git push/ 内容正则(命中黑名单仍弹卡) | | /p del allow\|deny <序号> | 删规则 | | /d | = /dashboard:开启实时输出面板(本地链接) | | /d public | 开启并拉 cloudflared 公网隧道(手机外用) | | /d off | 关闭面板(页面「关闭 Dashboard」按钮等效) | | /id | 查看你的 open_id(配白名单用) | | /help | 帮助 |

远程操控终端会话(tmux / pts 注入)

/a 列出所有活着的 kimi 终端会话(ps 全量扫描 + 进程树匹配),分两级:

  • ⌨️可控(tmux)kimi-code-feishu tmux 启动的会话,/t send-keys 注入、/s capture-pane 抓屏
  • ⌨️仅注入(pts)/ 👀仅发现:普通终端里的 kimi。本机已启用 legacy_tiocsti=1 + 免密 sudo 时可注入(TIOCSTI 把按键塞进终端输入队列);不满足时降级为仅发现。注意 pts 终端永远无法抓屏(pts 只写不读,原理限制),/s 改读磁盘转录尾部;审批卡走 hook 不受影响
kimi-code-feishu tmux     # 在 tmux 里启动 kimi(kcf-* 命名),Ctrl+B D 脱离
  • 飞书发 /a 列出会话(序号/目录/可控性),/a 2 绑定进入终端模式(纯文本自动注入);/s 看一眼屏幕/转录再决定敲什么
  • /t 注入等价于坐在终端前打字:回答 AskUserQuestion 提问、对权限提示敲 y、下新指令都行;终端的 /命令(/model /yolo…)也一律 /t /model 注入
  • pts 注入依赖:/etc/sysctl.d/90-kcf-tiocsti.conflegacy_tiocsti=1)+ 免密 sudo;其他机器不满足时自动降级,不影响其余功能

工作目录绑定(/bind)

一个聊天 ≈ 一个项目的远程遥控窗口。/bind 决定三件事:

  1. 会话工作目录:0 号会话以绑定目录为 cwd 拉起,AI 读写文件、跑命令都在这个目录下;不绑则用配置里的默认 work_dir(默认包安装路径)。
  2. 会话转录位置:kimi 的 wire.jsonl 按工作目录组织(~/.kimi-code/sessions/wd_<目录>_*),换绑目录即开启另一条会话线,上下文互不串。
  3. 终端会话路由:终端里手动跑 kimi 时产生的审批卡片和进度推送,按会话 cwd 匹配到绑了同目录的聊天。

不同聊天(多个私聊/群)可各绑各的项目,互不影响;/bind 会同时重置该聊天的会话(等同 /new)。

审批卡片

  • ✅ 批准:放行这一次;🔁 本会话允许:同会话同类工具自动放行;❌ 拒绝:阻断并把原因反馈给模型
  • 超时未点(默认 150s)按 on_timeout 处理,默认拒绝
  • 不弹卡片的情况:只读工具(auto_allow_tools)直接放行;命中 auto_deny_patterns(如 rm -rf /)直接拒绝
  • 配置了 dashboard_public_url 后,卡片底部附「📊 查看实时输出」链接,点开看清现场再决定

提问卡片(tmux 交互会话)

tmux 会话里模型调 AskUserQuestion 时,hook 直接放行让 TUI 出题,同时飞书弹出选项卡片:

  • 点选项 = 桥把对应数字键敲进终端,模型拿到的是真实 UI 作答(不是 hack 回传)
  • 多选题可多点后「✔️ 确认选择」;「🚫 拒绝回答」= 敲 Esc
  • 自定义答案:用 /t 直接打字输入
  • 目前支持单题卡片;多题提问或会话不在 tmux 里时回落普通审批/终端作答

监控终端会话

终端里跑 kimi --yolo,审批闸门即完全交给飞书卡片,出门在外也能远程点头。

审批池(/c)

多个终端会话同时跑时卡片会刷屏,审批池控制哪些会话走飞书:

  • 按目录(cwd)记池/c 列出的会话对应目录进池后,它的 PreToolUse 才弹审批卡、进度才转发;池外会话 hook 直接放行,回落终端原生权限流程(你在机器前正常点,飞书完全安静)
  • 0 号会话(飞书聊天自己的常驻会话)不受池限制,永远弹卡
  • 兜底:池外会话在终端进入权限等待时,桥发一条被动通知(PermissionRequest 事件)——不会无声无息卡住,/c 加池或 /a 绑定后 /t 作答即可;终端弹出 AskUserQuestion 选择器时同样会收卡片或被动提醒
  • 池持久化在 state.json,重启不丢
  • /c free <序号或路径> 彻底释放某目录会话的审批 hook:桥直接放行,完全回落终端原生权限(再执行一次恢复)

审批黑白名单(/p)

进池(或 0 号会话)的会话默认每个操作都弹卡。/p 按目录维护一份持久化名单,减少点卡次数:

  • 白名单模式(默认):命中白名单规则直接放行,其余弹卡
  • 黑名单模式/p mode 切换):未命中黑名单的全部直接放行,命中才弹卡——适合信任本机操作、只盯危险命令
  • 规则写法:Bash(整工具)或 Bash:/rm|git push/(工具+内容正则,能精确放过 ls 但拦住 rm
  • 优先级:全局 auto_deny_patterns(直接拒)> /c free(全放行)> /p 名单 > 审批卡;名单只对接管的会话(进池目录或 0 号会话)生效

五、Dashboard(按需开启的 WebUI)

Dashboard 采用按需开启的安全模型——桥启动时开启,用的时候才临时拉起:

/dashboard          # 默认开本地/局域网链接(本机浏览器直接开,方便排查)
/dashboard public   # 才拉 cloudflared 公网隧道(手机/外出用)
/dashboard off      # 手动关闭(页面上的「关闭 Dashboard」按钮等效)
  • 页面只读,唯一操作是「关闭 Dashboard」按钮;SSE 断开时显示断连横幅(不会装死空白页)
  • 每次开启:新随机 token/dashboard public 才拉 cloudflared quick tunnel(新随机域名),上次的公网链接全部作废;默认本地模式不产生任何公网暴露
  • 双阈值自动关闭:没有打开的页面约 3 分钟关;页面停看(心跳停)10 分钟关——离开后不会一直挂在公网上
  • 配置见 [dashboard] 节:dashboard_idle_timeout_page / dashboard_idle_timeout_nopage / dashboard_public_url(固定域名才填)/ cloudflared_bin

页面结构(自上而下):

  • ⏳ 待你处理:待审批(工具+命令)与待回答提问(原文+选项),标注怎么回(飞书卡片 / /t
  • 🖥 终端会话(实时画面,2s 刷新):tmux 会话内嵌 capture-pane 实时屏幕——和 tmux attach 看到的一样;pts 会话标注「仅注入」
  • 🏃 任务:进行中的任务与耗时
  • 💬 对话与事件:飞书消息(👤 绿)/ 桥回复(🤖 蓝)/ 任务输出 / 审批进度
  • 📡 本地会话转录(紫色):桥监听 ~/.kimi-code/sessions/**/wire.jsonl(kimi 实时会话转录),把任何会话(含普通终端 pts)的用户输入、思考、回复、工具调用与结果流式推送——pts 屏幕读不到,但对话全在这里

⚠️ 终端输出可能包含敏感信息,带 token 的链接等同于终端内容本身,请勿转发;cloudflared 隧道全程 HTTPS。

六、安全设计

分层暴露原则:无认证的只给本机,有认证的才暴露

  • hook 服务(17781)只听 127.0.0.1,这是刻意的:hook 端点没有任何认证(无 token/签名/来源校验),回环绑定本身就是它的全部访问控制。它承载每次工具调用的完整细节(命令、路径、会话)并左右审批——绑到局域网等于让同网段任何人都能窥探你的执行、伪造请求轰炸审批卡片、甚至把恶意 kimi 的审批引到你的飞书上。本机进程与你在同一信任域,所以本机不需要认证;要开放网络访问,必须先给 hook 加认证
  • Dashboard(17772)可以绑 0.0.0.0 或走公网隧道:因为它有 token 认证(无 token 401),暴露面由 token 兜底。但带 token 的链接等同于终端内容本身,请勿转发
  • 白名单:仅 allowed_user_ids 中的 open_id 能发指令、点卡片;其他人点击被忽略并记日志
  • 飞书侧无入站端口:走 WebSocket 长连接
  • Dashboard 生命周期:按需开启 + 一次性 token/域名 + 双阈值自动关 + 页面只读,公网暴露窗口最小化
  • fail-closed:桥掉线时默认拒绝需审批操作(fail_closed = false 可改回官方 fail-open)
  • 紧急旁路KCF_DISABLED=1 后所有 hook 直接放行
  • 对话日志:完整对话落盘 ~/.kimi-code-feishu/logs/YYYY-MM-DD.jsonl(含终端输出,可能敏感;文件 600/目录 700,默认保留 30 天自动清理)
  • Kimi hooks 是 Beta 且 fail-open 设计,不要当作唯一安全防线

七、开发与自检

npm install
npm run build          # tsc → dist/
node dist/selfcheck.js # 104 项端到端自检(假通道 + 假 kimi,不需要真实飞书)
npm pack               # 产出可分发的 .tgz(约 20KB)

八、常见问题

Q:支持 Telegram / 微信吗? src/channel.ts 是抽象接口,照 feishuChannel.ts 实现 Telegram long-polling 通道即可复用全部逻辑;个人微信无官方机器人 API,建议走企业微信。

Q:交互式会话的权限怎么管? 0 号会话和 tmux 会话都是交互模式,工具调用的闸门是 PreToolUse hook:每次调用先问飞书卡片(或命中自动规则/审批池)。请保持桥在线(fail-closed 保证桥不在线时默认拒绝)。

Q:WSClient 断线重连? SDK 1.71+ 已修复旧版 reConnect() 定时器泄漏(上游 #177),autoReconnect: true 开箱即用;feishuChannel.ts 里留有注释说明。

Q:Windows? 核心逻辑跨平台;hook 命令不含 shell 变量前缀,但进程组终止在 Windows 上退化为单进程 kill。

项目结构

src/
├── cli.ts            # bin 入口:onboard / init / install / uninstall / run / doctor
├── appRegistration.ts # 扫码创建飞书应用(官方 Device-Flow 注册协议)
├── config.ts         # 配置加载(smol-toml + KCF_* 环境变量)
├── bridge.ts         # 核心编排:审批、进度、指令三条链路
├── feishuChannel.ts  # 飞书长连接通道(@larksuiteoapi/node-sdk)
├── channel.ts        # 通道抽象接口
├── hook.ts           # Kimi CLI hook 入口(stdin JSON → 桥 → 退出码/结构化输出)
├── hookServer.ts     # 127.0.0.1 HTTP 服务
├── chatSession.ts    # 飞书聊天的常驻交互会话(tmux 托管 + wire 结果流)
├── sessionWire.ts    # wire.jsonl 转录监听(结构化解析 + 多订阅)
├── dashboard.ts      # 按需开启的 WebUI(SSE 实时输出,双阈值自动关)
├── tunnel.ts         # cloudflared quick tunnel 托管(/dashboard 开启时拉起)
├── tmux.ts           # tmux/pts 会话发现 + 注入 + 抓屏
├── chatLogger.ts     # 飞书对话日志落盘(JSONL 按天分文件)
├── streamParser.ts   # stream-json 容错解析
├── approvals.ts      # 待审批注册表(Promise 挂起/唤醒)
├── state.ts          # 聊天绑定、会话路由持久化
├── installer.ts      # hooks 注入/移除(自动备份)
└── selfcheck.ts      # 104 项端到端自检

License

MIT