我如何为 Claude Code 构建移动审批系统,让我终于可以离开办公桌

发布: (2026年2月28日 GMT+8 14:01)
12 分钟阅读
原文: Dev.to

I’m happy to translate the article for you, but I need the actual text of the post. Could you please paste the content you’d like translated (excluding any code blocks or URLs you want to keep unchanged)? Once I have the text, I’ll provide a Simplified‑Chinese translation while preserving the original formatting and markdown.

每个 AI‑Coding‑Agent 用户都会遇到的问题

我端着咖啡回来,发现 Claude Code 已经卡死了 15 分钟。

随着 AI 编码代理获得更高的自主性——编写代码、执行构建、修改文件——人工监督变得至关重要。你希望代理持续工作,但也想知道它在做什么。权限提示是检查点,却也是瓶颈。

  • 将命令加入 allowlist 可以减少提示,但对未知命令和文件写入进行一刀切的批准风险很大。
  • 一直盯着终端也不现实。

于是我构建了 claude‑push —— 一个用于 Claude Code 的异步“人在回路中”批准层。它利用 PermissionRequest 钩子和 ntfy.sh 将 “允许/拒绝” 推送通知直接发送到你的手机。开源,3 分钟即可完成设置。

两难:留在桌前还是全部放行

When you delegate code generation and refactoring to Claude Code, you’ll inevitably see prompts like this:

Claude wants to run: rm -rf dist && npm run build
Allow? (y/n)

每次弹出此提示时,你必须返回终端并按 y。如果你正专注工作(或只是去喝咖啡),可能会错过,导致 Claude Code 处于空闲状态。

方法优点缺点
手动在终端批准安全不能离开座位
允许全部方便未知命令仍会通过
移动推送通知离开桌面 + 安全需要初始设置

claude‑push 让选项 3 成为现实。

Source:

先前技术

konsti‑web/claude_push 解决了相同的问题,但它依赖 Windows + PowerShell + 按键注入——在 macOS 或 Linux 上无法工作。我也遇到了同样的痛点,于是我从头重新实现了该概念,使用 Bash + PermissionRequest hooks

工作原理:PermissionRequest Hook + ntfy.sh

Claude Code 有一个 Hooks 系统,允许你在特定事件上运行外部脚本。通过在 PermissionRequest 事件上注册 hook,你可以拦截权限提示并返回自己的决定。

Claude Code requests permission
   → Hook script fires
      → Sends notification with Allow/Deny buttons to ntfy.sh
         → Phone receives the push notification
            → You tap Allow or Deny
               → Response received via ntfy.sh SSE
                  → Hook returns allow/deny JSON
                     → Claude Code continues or stops

ntfy.sh 是一个免费、基于 HTTP 的推送通知服务。无需账号——只要知道主题名称,就可以发送和接收通知。不同于 Pushover 或 LINE Notify,你只需使用一条 curl 命令即可发送通知,这使它非常适合作为 hook 脚本的实现方式。

实现细节

该钩子脚本约有 60 行 Bash。下面是三个关键设计决策。

1. 使用 ntfy.sh HTTP Actions 实现按钮

ntfy.sh 支持 Action Buttons。我使用 http 动作,使点击按钮时向单独的响应主题发送 POST 请求。

curl -s -H "Content-Type: application/json" \
  -d "$(jq -n \
    --arg topic "$TOPIC" \
    --arg title "[$PROJECT] $TOOL_NAME" \
    --arg message "$TOOL_INPUT" \
    --arg allow_url "https://ntfy.sh/${RESPONSE_TOPIC}" \
    --arg allow_body "allow|$REQ_ID" \
    --arg deny_url "https://ntfy.sh/${RESPONSE_TOPIC}" \
    --arg deny_body "deny|$REQ_ID" \
    '{
      topic: $topic,
      title: $title,
      message: $message,
      priority: 4,
      tags: ["lock"],
      actions: [
        {action:"http", label:"Allow", url:$allow_url, method:"POST", body:$allow_body},
        {action:"http", label:"Deny",  url:$deny_url,  method:"POST", body:$deny_body}
      ]
    }')" "https://ntfy.sh/"

关键细节: 通知主题和响应主题是不同的通道。这可以防止 SSE 流被你自己的外发通知污染。

2. SSE + 请求 ID 用于响应匹配

发送通知后,钩子会在 ntfy.sh SSE 端点上等待响应。

REQ_ID="$(date +%s)-$$"

while IFS= read -r line; do
  if [[ "$line" == data:* ]]; then
    DATA="${line#data: }"
    MSG=$(echo "$DATA" | jq -r '.message // empty' 2>/dev/null)
    if [[ "$MSG" == *"|$REQ_ID" ]]; then
      DECISION="${MSG%%|*}"
      break
    fi
  fi
done < <(curl -s -N --max-time "$WAIT_TIMEOUT" \
  -H "Accept: text/event-stream" \
  "https://ntfy.sh/${RESPONSE_TOPIC}/sse")

REQ_ID(时间戳 + PID)嵌入在通知正文中,并与响应进行匹配。这确保 即使多个权限请求同时触发,每个响应也能匹配到正确的请求。若没有此机制,之前通知的响应可能会被错误地应用到新请求上。

3. 超时回退到终端

如果在超时时间窗口内未收到响应,脚本不输出任何内容并以代码 0 退出。

if [ "$DECISION" = "allow" ]; then
  jq -n '{hookSpecificOutput:{decision:{behavior:"allow"}}}'
elif [ "$DECISION" = "deny" ]; then
  jq -n '{hookSpecificOutput:{decision:{behavior:"deny"}}}'
fi
# Timeout: no output → falls back to interactive prompt

在 Claude Code 的钩子规范中,无输出 + 退出码 0 表示“钩子未作出决定”,此时会回退到标准终端提示。

快速入门(≈ 3 分钟)

  1. 创建一个 ntfy.sh 主题(例如 myproject-perm)。
  2. 将钩子脚本 添加到 ~/.config/claude-code/hooks/PermissionRequest.sh(并设为可执行)。
  3. 设置环境变量(或编辑脚本)以指定:
    • TOPIC – 你创建的通知主题。
    • RESPONSE_TOPIC – 用于响应的第二个主题(例如 myproject-perm-resp)。
    • WAIT_TIMEOUT – 等待响应的秒数(默认 30)。
  4. 重启 Claude Code – 下一次权限请求将向你的手机发送推送通知。

就这样!现在你可以随时在任何地方批准或拒绝 Claude Code 的操作,而无需一直盯着终端。 🎉

Claude‑Push – Claude Code 的移动批准

即使您没有查看手机,也可以在超时后从终端处理批准。不会静默授予任何权限。

设置

先决条件

  • macOS 或 Linux
  • 已安装 bashjqcurl
  • 手机上已安装 ntfy 应用(ntfy.sh

安装

git clone https://github.com/coa00/claude-push.git
cd claude-push
bash install.sh

安装程序会引导您完成以下步骤:

步骤功能说明
依赖检查验证 jqcurl 是否可用
主题名称输入如果留空则生成随机名称(例如 claude-push-a1b2c3d4
配置文件创建写入 ~/.config/claude-push/config
钩子部署将脚本放置在 ~/.local/share/claude-push/hooks/claude-push.sh
Claude 设置注册使用 jq 安全地将钩子合并到 ~/.claude/settings.json
测试通知发送测试推送以验证一切正常

安装完成后,在 ntfy 应用中订阅您的主题,即可使用。

配置

编辑 ~/.config/claude-push/config。无需重新安装。

# 主题名称(充当 ntfy.sh 频道的共享密钥)
CLAUDE_PUSH_TOPIC="my-unique-topic"

# 超时时间(秒),超时后回退到终端提示
CLAUDE_PUSH_TIMEOUT=90

验证

# 发送带有“允许/拒绝”按钮的测试通知
bash scripts/test.sh test-notify

# 检查安装状态
bash scripts/test.sh status

status 的示例输出:

=== claude-push status ===
[OK] Config:    ~/.config/claude-push/config
     Topic:    my-unique-topic
     Timeout:  90s
[OK] Hook:      ~/.local/share/claude-push/hooks/claude-push.sh
[OK] Settings: hook registered in ~/.claude/settings.json
[OK] Dependency: jq
[OK] Dependency: curl

卸载

bash uninstall.sh

脚本会从 Claude 设置中移除钩子并清理所有已安装的文件。

实际操作示例

  1. Ask Claude Code 重构某些内容,然后离开你的桌子。

  2. 几分钟后你的手机震动:

    [myproject] Bash: npm run build
  3. 在手机上点击 Allow

  4. 当你回来时,构建已经完成。

你可以在会议中、散步时或喝咖啡时批准或拒绝命令——前提是你带着手机。

前后比较

功能之前(仅终端)之后(移动推送)
批准方式y / n in terminal手机上的 Allow / Deny 按钮
离开时Claude stops and waits通过推送通知处理
超时None (waits forever)90 s 后回退到终端
安全性Allowlist or manual check每条通知逐案批准
设置成本bash install.sh 大约 3 min 完成

安全考虑

  • ntfy.sh 主题名称 是一个 共享密钥。任何知道它的人都可以发送通知或伪造响应。
  • 为主题名称使用随机、难以猜测的字符串(安装程序默认会生成一个)。
  • 如需更严格的控制,请配置 ntfy.sh access control
  • 在允许列表中显式阻止危险命令(例如 rm -rf …),以提供额外的安全层。

总结

Claude Code 最初的权限系统要么让你一直盯着终端,要么把所有东西都加入白名单。claude-push 增加了 第三种选择——移动端批准

  • 实现方式:Bash + ntfy.sh HTTP 动作 + 服务器发送事件(Server‑Sent Events)。
  • Hook 本身只有约 60 行。
  • 它之所以能工作,是因为 Claude Code 的 Hooks API 只需要一个包含 allowdeny 的 JSON 对象。

这一模式适用于任何 AI 编码代理:随着代理能力的提升,我们需要轻量级、异步的批准机制,而不必一直盯着屏幕。移动端推送通知正好满足这一需求——足够快以保持代理运行,又足够可见以便监督。

最好的开发者工具就是让你可以把视线从屏幕上移开五分钟的工具。claude-push 就是这样的工具。

你是如何处理 AI 代理权限的? 无论你是白名单拥护者还是手动检查倡导者,试试 claude-push 并告诉我你的感受。

https://github.com/coa00/claude-push

References

0 浏览
Back to Blog

相关文章

阅读更多 »

当工作成为心理健康风险时

markdown !Ravi Mishrahttps://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fu...