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

clamicro

v2.19.0

Published

Watch Claude Code from your phone and approve what it wants to run. LAN-direct, zero dependencies.

Readme

Clamicro

English

在手机上看 Claude Code 的状态、审批它要执行的操作。

跑任务时不用一直盯着终端——需要授权时 Mac 会弹通知,在手机上打开页面,看清命令和一句摘要,滑动批准或拒绝,Claude Code 随即继续。

| 运行中 | 有事等你 | 做决定 | |:--:|:--:|:--:| | | | |

截图是真实界面,不是效果图。刘海那张是 Mac 上实拍的屏幕截图。

先说清楚默认行为,免得你以为它在拦一切:

| | 等多久 | 到点怎么办 | 会不会提醒你 | |---|---|---|---| | 普通操作 | 10 秒 | 自动通过 | 会 | | 高风险(rm -rf、force push、动 ~/.ssh) | 3 分钟 | 自动拒绝 | 会 |

也就是说:日常操作它是「告诉你」,高危操作它才是「拦住你」。 两档的等待时长和到点行为都能在设置页改——普通操作的 10 秒改成 0 就是每条都等你;高风险的 3 分钟最长可设到 570 秒(再长就会撞上 hook 的系统超时,审批反而失效)。

零依赖:只需要 Node ≥ 18 和 curl(macOS 自带)。运行时不含任何 node_modules。

仅支持 macOS + iPhone。服务用到 macOS 专有能力(scutil、osascript、Bonjour),界面是按 iOS Safari 做的。


安装

npx clamicro install

三步走完:

  1. 终端里:检查环境 → 展示将要对 ~/.claude/settings.json 做的改动 → 你确认 → 自动备份并写入 → 确认信任当前网络 → 启动服务 → 打印一个网址,外加这个网址的二维码(装了 qrencode 的话)。那张码里不含任何凭证,理由见下
  2. 手机打开那个网址(同一 Wi-Fi):进到配对页,点「在 Mac 上显示二维码」。码只出现在 Mac 屏幕上,用手机相机扫它。
  3. 回到 Mac 确认:会弹出一个框问你要不要放这台设备进来,并显示这个请求从哪来。不按「允许」就不会发出任何凭证。

配对完走一遍内置演示:它会造一条假审批,让你在还没有任何真实风险的时候先滑一次。走完这遍就算装好了。

为什么终端里不放凭证? 终端恰恰是东西会被留下来的地方——回滚缓冲、录屏、投屏、旁边那位的手机镜头。更早的版本在这里印的是永久主令牌;后来那版印的是 60 秒的一次性配对券,安全没问题,但通常在你掏出手机之前就过期了。

现在印的是那个不带凭证的局域网网址——正因为它什么都不带,所以顺手把这个网址的二维码也画出来,省得你在手机上手输 IP 和端口。回滚缓冲、录屏、旁人的镜头能从那张码里拿到的东西,和从它下面那行明文完全一样。凭证是你在手机上点了按钮之后才生成的,而且只出现在 Mac 屏幕上。

装完即可用:需要审批时 Mac 会弹通知并响一声,终端状态栏显示 ⏳ N 条待审批,手机网页随时能看和批。

没有远程推送:提醒只有 Mac 本地通知这一条,完全不联网。离开电脑后不会有东西叫你——高风险操作会等到超时被自动拒绝。详见下方「近场只用 Wi-Fi」。

安装程序只追加不替换。你已有的 hook 配置会完整保留,statusLine 若已被别的工具占用则不覆盖、只提示。改动前自动备份。

卸载:

npx clamicro uninstall

只摘掉自己加的东西,实测与安装前的配置逐字节一致。配置和历史保留在 ~/.claude/clamicro/,可手动删除。

运行时装在哪

npm 包只是安装器。运行时文件会被复制到 ~/.claude/clamicro/app/,hooks 指向那里。

这不是多此一举:hooks 里写的是绝对路径,而 npx 每次跑在会变的缓存目录、全局安装路径又随 node 版本 / nvm / homebrew 变化。指向 npm 包意味着某天路径失效,所有 hook 会静默失败——你不会看到任何报错,只是再也收不到通知。实测删掉 node_modules 后服务与 hook 照常工作。

升级就是重跑一次 npx clamicro install。


它做了什么

| 你在手机上看到 | 来自 | |---|---| | 会话状态、子状态(Thinking/Searching/Editing) | hooks 事件流 | | 5 小时 / 7 天用量、上下文占用、本次花费 | statusLine | | 待审批操作 + 一句人话摘要 + 影响面标签 | PermissionRequest | | 任务完成 / 出错通知 | Stop / StopFailure | | 事件时间线(每个会话的完整流水) | 全部 hooks | | 暂停 / 恢复 / 取消本轮 | PreToolUse 拦截点 | | 额度接近上限预警 | statusLine | | 这个会话用过哪些 skill | hooks 里的 Skill 工具调用 | | 装了多少个 skill —— 你自己的 / 已启用插件带的 | 读本机 ~/.claude |

最后一行是唯一不来自事件流的:它读盘。所以拆成两个数,而且每一档都能说 「数不出来」而不是报 0 —— 「已安装」根本不是一个数(商店目录里躺着的不算装了)。

这张表说的是 Claude Code。接了别的后端时,能做什么由那个后端的能力决定—— 见下面「不止 Claude Code」。


不止 Claude Code

2.14.0 起,同一块看板可以同时盯着多个后端。目前支持 Claude Code、 DeepSeek Harness(DSH), 以及 Codex(ChatGPT 那个 CLI,目前只做状态镜像)。

首页按模型分区:每个模型一个标题,下面是它自己的状态、履历和用量。 顺序按「谁先连上」固定,不会因为谁刚有动静就换位置。

待审批不分区,永远在最上面、跨后端一起显示——它有倒计时,被分进某个 区块意味着你得先找到那个区块才看得见,而漏看一条等于一次静默的自动决策。

不同后端能做的事不一样

| | Claude Code | DeepSeek Harness | Codex | |---|:--:|:--:|:--:| | 状态镜像 | ✓ | ✓ | ✓ | | 手机审批 | ✓ | ✓ | —(口子都在,但服务端确实关着,见下) | | 暂停 / 恢复 | ✓ | — | —(同上) | | 取消本轮 | ✓ | —(协议支持,尚未接) | —(同上) | | 从手机发消息 | ✓ | —(协议支持,尚未接) | —(同上) | | 用量 | 5h / 7d 滚动窗口 | 累计 token | 拿不到 |

界面按能力渲染:某个后端不支持的操作,入口直接不给。留一个点了没反应的 按钮比没有按钮更糟——你会以为暂停成功了,然后走开。

服务端也按这张表拦。 只靠界面不够:手机上缓存着升级前的页面时,那份页面 不知道新后端的能力,会把入口照常画出来。于是暂停、取消、发消息这三个端点, 以及审批的拦截,都会先查一遍这张表——不支持就明确拒绝,而不是收下之后 什么也不做。Codex 的「手机审批」写着 —,意思就是那个端点会直接回 「无意见」、不建审批记录,让 Codex 落回它自己的权限流程。

DSH 的用量只报 token、不折算金额:DSH 自己不算钱,折算需要一张按模型分档的 价目表,而它会在你不知情时过期,然后手机上安静地显示一个错的金额。

接 DSH

npx clamicro connect dsh

会装上桥接插件和那只像素猫(点一下直接打开手机看板;没配对过的话那一页就是二维码入口)。

install 只探测,不会自己接,它只把这条命令印出来。因为它写的是别人家的配置 (~/.dsh/profiles),这一问必须问在你答得回去的地方——而 install 走到那一步时 已经把你打发去掏手机了,它的 stdin 也已经关掉。接过之后重跑 install 会静默重接一遍, 让插件文件跟上新版本:那一步没有引入任何新的改动范围。卸载时会一并摘除。 手动接法和三条硬约束见 plugins/。

接 Codex

npx clamicro connect codex

往 ~/.codex/config.toml 里追加一段带哨兵注释的 hooks,卸载时按哨兵摘干净, 块外的字节一个不动。和 DSH 同一条规矩:install 只告诉你有这条命令。

装完还差一步:打开一次 Codex,同意它问的「是否信任这份 hooks 配置」。 没点之前 Codex 会把 hooks 静默跳过——不报错、不提示,clamicro 一条事件 都收不到,而所有地方都显示已安装。npx clamicro status 会把这个状态单独报出来。

Codex 现在只做状态镜像:审批的口子(PermissionRequest)和回包形状都已经接好, 但「拒绝」这一路还没在真机上跑通过,所以按能力矩阵的规矩当作没有。 猜错的代价不是按钮没反应,是手机上写着「已拒绝」而命令照样跑完。 验收方法和打开开关的位置见 docs/codex-bridge.zh-CN.md。

手势

审批卡片左滑拒绝、右滑批准,详情页和首页列表都支持。批准有 3 秒撤销窗口。 高风险操作(rm -rf、git push --force、密钥文件、越界写入)在详情页需要划得更远, 在列表里则完全不能滑动批准——列表是快速分诊的地方,真要放行危险操作得点进去看清楚。

暂停的真实语义

Claude Code 没有「运行时暂停」原语,没法在任意时刻冻结它。「暂停」实际是 在下一个工具调用前把它挂住,当前这一步仍会跑完。UI 上有明确提示, 免得你以为点了没反应。取消同理,也是在下一个拦截点返回 {continue:false}。

审批链路:

Claude Code 要执行需授权的操作
  → PermissionRequest hook(HTTP,timeout 600)
  → 服务建审批记录,Mac 弹通知,然后阻塞住
  → 你在手机上批准 / 拒绝
  → hook 返回 decision → Claude Code 继续或被拒

安全

这是一个把 Claude Code 的执行权限交到手机上的工具,值得把边界写清楚。

网络信任闸门

服务只在你显式信任过的网络里暴露到局域网。换到陌生网络(咖啡厅、机场、酒店)时自动只绑回环,手机连不上,同时 Mac 弹通知让你确认。

npx clamicro networks   # 看当前网络和已信任列表
npx clamicro trust      # 信任当前网络
npx clamicro untrust    # 撤销:不带参数撤当前网络,也可 untrust <id前缀> / untrust all

信任是可撤销的。误信任一个网络(比如在咖啡厅手滑点了「是」)不该是不可逆的——那个网络会永久留在列表里,下次再连上就自动暴露。

网络指纹用网关 IP + 网关 MAC + 网段 + SSID + DHCP 服务器 + 搜索域 + DNS 列表。

前三项不够:SSID 在新版 macOS 需要定位权限、走有线时根本没有;而 00:00:5e:00:01:xx 是 VRRP 虚拟 MAC,企业网里并不唯一。实测过一种会碰撞的组合——两个不同公司都用 192.168.1.0/24、网关都是 192.168.1.1、网关 MAC 都是 VRRP、又都拿不到 SSID,四个字段完全一样,于是 A 公司信任过之后 B 公司的网络被当成已信任。后面那三个信号来自 DHCP,不需要任何权限,在不同组织之间几乎不会全部相同。

但七项不一定真的有七项。 全隧道 VPN 接管默认路由时,route -n get default 给出的是点对点的 utun 接口、没有网关那一行——于是网关、MAC、SSID 和三个 DHCP 信号一起消失,指纹塌成只剩网段,也就是「任何一个发 192.168.0.x 的网络」。真机上复现过。缺掉的信号造不出来,所以改成说出来:安装时的确认、trust、networks 和启动日志,在指纹没有任何可辨识特征时都会警一句。想让它认得准,信任网络之前先断开 VPN——那样才拿得到真实的网关和 MAC。

已实现的防护

| 防护 | 挡住什么 | |---|---| | Host 头白名单 | DNS rebinding。恶意站点把域名重绑到你的局域网 IP 后浏览器视为同源,CORS 完全失效,能读看板、命令原文并批准操作——且攻击者不需要在你的 Wi-Fi 上 | | hooks / statusLine 仅回环 | 同网段的人伪造 hook 事件:刷审批通知、注入假时间线、伪造额度 | | /api/pair 要求自定义头 | CSRF。跨站「简单请求」浏览器会照发,副作用已发生——等于你访问的任何网站都能让这台 Mac 弹二维码 | | hooks / statusLine / pair-new 只认本机 | 同网段的人伪造 hook 事件:刷审批通知、往时间线注入假记录、伪造额度读数——更要命的是给自己造一张配对券。「本机」是三件事同时成立:回环来源 且 回环 Host 且 没有代理转发头。只看来源地址不够:开着 Cloudflare 隧道时,公网流量正是从 127.0.0.1 进来的 | | 配对要在 Mac 上确认 | 只是「看到」二维码的人——屏幕共享、投屏、旁边那位的镜头、拿到隧道 URL 的人——拿到设备令牌。看见码不再够用,得有人坐在 Mac 前面按一下。那个对话框出任何问题(超时、拿不到图形会话、崩了)一律算拒绝 | | 终端里不出现任何形似凭证的东西 | 安装器印的是纯网址,不带令牌也不会过期,所以回滚缓冲、录屏、肩窥都拿不到东西。凭证在你点了手机上那个按钮之后才生成,且只在 Mac 屏幕上渲染 | | CSP frame-ancestors 'none' | 点击劫持:恶意页面把审批页嵌进 iframe 诱导你滑动 | | 常数时间比较 | token 与审批 key 的时间侧信道 | | SameSite=Lax + HttpOnly | CSRF;同时保证从别的 App 点链接进来仍是登录态(Strict 会导致每次都要重新扫码) | | 单条审批专属 key | 拿到一条深链只能决定那一条;审批结束后 2 分钟失效(留这一小段是因为你点完之后结果页还要用它拉一次) |

说人话:配过对的手机等于你 Mac 的钥匙

设备令牌 = 批准任意操作的权限,包括 rm -rf、sudo、读你的 ~/.ssh/id_rsa。请像对待钥匙一样对待那台手机:

  • 二维码本身已经不足以配对:它一次性、60 秒过期,而且还要在 Mac 上按「允许」。 拍到码的人没有你按那一下也配不上。话虽如此,还是别把它留在屏幕上
  • 怀疑泄露了就立刻换发:npx clamicro rotate-token。所有设备上的登录当场失效, 对运行中的服务即刻生效,不用重启;之后手机需要重新扫码配对。 只想吊销某一台就用 npx clamicro forget <id>,其他设备不受影响
  • 登录 cookie 30 天过期,到期重新扫一次

剩下的风险:HTTP 明文

局域网内是明文。同网络的被动嗅探者能拿到你的 token,进而获得完整控制权,包括批准 rm -rf。命令原文同样是明文。

这在保持「扫码即用」的前提下无解——自签证书会让 Safari 报警并破坏整个体验。网络信任闸门把它从「你得记得别在咖啡厅用」变成了「陌生网络默认就用不了」,但如果你确实需要在不可信网络上用:

装 Tailscale。 WireGuard 端到端加密,没有任何第三方看到明文,且不限于同一 Wi-Fi。服务会自动识别 100.64/10 地址并绑上去,且不受网络信任闸门限制——覆盖网自带加密,不关心底下是什么物理网络。

另一条路是内网穿透(clamicro tunnel on),但穿透服务终结 TLS,技术上看得到命令原文——所以它是应急选项,不是默认。


近场只用 Wi-Fi

控制面不出局域网。命令原文、审批指令、时间线、额度全部走 http://<局域网IP>:8765 直连。

按"人在哪儿"分两层,两层都不出局域网:

| 场景 | 提醒方式 | 联网范围 | |---|---|---| | ① 人在电脑边 | macOS 本地通知 + 提示音 | 完全不联网 | | ② 离开电脑 | 没有提醒 | — |

② 为什么没有提醒:锁屏可达的通知只能走 APNs,那必然经过第三方服务器。

先后试过两条并都删掉了:ntfy 双 topic 中转(能在锁屏通知里直接点按钮批准,等于把控制面交给第三方)、Bark(只发一句「有个审批」,控制面留在局域网)。后者已经克制到极限,但它换来的仍然只是「离开电脑时能被叫一下」——而这个工具的前提本来就是你人在附近。为了这个把「有操作在等你审批」这个事实持续告诉一台外部服务器,不划算。

代价要说清楚:离开电脑后没有任何东西会叫你,高风险操作会等到超时(默认 3 分钟)被自动拒绝,那一轮任务失败。这是有意的默认——人不在就不该放行 rm -rf。想主动看的话,手机浏览器随时能打开看板。


设计要点

hook 必须先回包再提醒。 async: true 只对 command 类型有效,HTTP hook 一律阻塞等响应。所以所有端点立即返回 {},推送在响应之后异步发出。

自超时上限 570 秒。 不能走到系统 600s 超时——那会被当成「非阻塞错误」放行到正常权限流程,人不在电脑边时终端会空挂着等一个没人看的弹框。

四种终态:allowed / denied / expired(超时自动拒绝)/ abandoned(终端自己批了,或会话被 Ctrl-C)。同一条审批被多路重复决策时,第一个写入的赢,后到的返回当前真实状态而不报错。

Stop 的提醒阈值。 Stop 在每一轮回复结束时都触发,包括两秒就结束的对话。默认只有 turn ≥ 30s 才推送。turn_started_at 未知时(服务中途启动)按「要推」处理——宁可多推一次,也别漏掉一次任务完成。

状态栏由服务端渲染。 bin/statusline.sh 不解析 JSON,直接把载荷 POST 给服务,服务返回渲染好的文本。因此不依赖 jq,也不用付 Node 的 ~115ms 启动开销(实测 15ms)。有待审批时状态栏会显示 ⏳ N 条待审批。

子状态是推导的。 Claude Code 没有 Thinking/Searching/Editing 事件,全部从 PreToolUse.tool_name 推导;PostToolUse 到下一个 PreToolUse 之间视为 Thinking。

服务挂了不拖累 Claude Code。 回环端口拒绝连接是即时的,hook 拿到非阻塞错误后照常继续,只是收不到通知。而且 SessionStart 是个 command hook,会先把服务拉起来再转发事件——打开 Claude Code 就等于服务可用。

地址用 Bonjour 主机名而不是 IP。 macOS 已经在广播 <LocalHostName>.local,用它做基址,DHCP 换 IP 后旧链接依然有效,不必重新扫码。极少数路由器屏蔽组播,那种情况把 hostMode 改成 "ip"。

登录 cookie 必须是 SameSite=Lax 不能是 Strict。 从别的 App 点链接进 Safari(备忘录里存的地址、Mac 上弹的二维码)属于跨站导航,Strict 的 cookie 不会被带上,表现是每次都像没登录过。

额度是账号级的,不按会话存。 按会话存会出现旧会话的陈旧数字把最新数字顶掉。只认最新一次观测,并在界面上标出更新时间和来源会话。

审批与事件落盘。 ~/.claude/clamicro/history.json,防抖写入 + 临时文件原子替换。重启时仍挂起的审批一律转 abandoned——那些 hook 的连接早断了,再显示成「待审批」是在骗人。

hooks 是热加载的,statusLine 不是。 改完 hooks 当前会话立刻生效;statusLine 要新开会话。

吊销是即刻的,不用重启。 forget / rotate-token / untrust 都是独立的 CLI 进程,只改磁盘;而服务只在启动时读过一次配置。所以 2.14.0 之前这三条命令重启前全部无效——forget 却打印着「这些设备上的登录立即失效」。现在服务监听配置文件热加载 token / 设备簿 / 信任网络,那句话才是真的。

配置和 settings.json 都是原子写。 先写同目录临时文件再 rename。非原子写有两条会踩到的路径:热加载正好读到写了一半的 JSON;以及进程被打断时文件永久半截——config.json 半截等于令牌和已配对设备全没,settings.json 半截等于 Claude Code 起不来。权限也在 rename 之前设好,不留「文件已就位但还是 0644」的窗口。

杀进程之前先确认身份。 stop 和安装流程都会 kill 掉端口上的监听者,而 8765 不是保留端口。判据是 /healthz 回的 service: 'clamicro'(只对回环返回,局域网上的扫描者拿不到),不是匹配命令行——命令行的形状不稳定。不是我们的进程就拒绝并提示换端口,绝不硬抢。

风险判定不看工具名。 判据是「参数里有没有 command」。原来写的是 toolName === 'Bash',而 DSH 的工具名是小写 bash——精确匹配会让整套高危规则一条都不跑,rm -rf / 判普通风险、10 秒自动通过。名字差一个字母,安全核心静默失效且不报任何错。


常用命令

npx clamicro install      # 安装 / 升级
npx clamicro uninstall    # 卸载
npx clamicro qr           # 打印登录二维码
npx clamicro status       # 服务、网络、版本
npx clamicro doctor       # 装不上 / 连不上时跑它,输出一段脱敏的、可直接贴进 issue 的现场
npx clamicro connect dsh  # 接上另一个后端(connect dsh | connect codex)
npx clamicro trust        # 信任当前网络
npx clamicro untrust      # 撤销信任(untrust <id前缀> | untrust all)
npx clamicro networks     # 当前网络 + 已信任列表
npx clamicro rotate-token # 换发访问令牌(令牌可能泄露时)
npx clamicro test-push    # 发一条测试通知(Mac 本地)
npx clamicro logs         # 跟踪日志
npx clamicro stop         # 停止服务

平时不用手动启动——SessionStart hook 会在你打开 Claude Code 时自动把服务拉起来。

配置在 ~/.claude/clamicro/config.json(权限 600,含访问 token)。日常设置改手机网页即可,不用编辑这个文件。

ignoreCwds 里的工作目录不做阻塞审批——开发 clamicro 自身时用,正常使用应留空。


使用教程

第一次用、或者遇到「这是 bug 还是设计如此」的困惑,看 docs/guide.zh-CN.md · English。


维护笔记

踩过的坑和当时的判断依据记在 NOTES.md。


已知限制

  • 需与 Mac 同一 Wi-Fi(或同一 tailnet);公司网络若开启客户端隔离或 VLAN 隔离则不通
  • 局域网内明文传输,不可信网络请用 Tailscale,见上方「安全」
  • 纯 HTTP 非 secure context,拿不到 Service Worker / Web Push
  • 仅 iPhone + macOS
  • Pause 为「下一个可拦截点暂停」,不是运行时冻结
  • 手势为主的界面,VoiceOver 用户目前没有等价入口
  • 审批与事件保留一天、上限 300/3000 条,超出滚动丢弃