Skip to content

Hub 消息注入与 Claude Code 权限弹窗冲突导致自动 deny #18

Description

@NorveraFlorent

问题描述

当 Claude Code 弹出权限确认弹窗(如文件写入、bash 命令等未在 allowlist 中的操作)时,Hub 通道持续注入的消息(包括其他用户发给主人的微信消息、系统消息等)会被 CC 当成用户对弹窗的回复。由于消息内容不是 "yes" 或确认格式,被解读为 deny。

复现步骤

  1. Hub 正常运行,微信通道活跃(主人的微信会收到其他人的消息)
  2. Claude Code 执行一个需要权限确认的操作(如写入非白名单路径的文件)
  3. CC 弹出权限确认弹窗
  4. 此时 Hub 注入了任何通道消息(哪怕是系统消息或非白名单用户的消息)
  5. CC 把注入的消息当成用户回复 → deny

影响

  • 所有 CC 实例受影响:Hub 作为 MCP server 配置后,每个新启动的 CC 实例都会自动连接 Hub 并被注册,全部会被通道消息干扰
  • 所有未加白名单的操作在通道活跃时都无法通过权限确认
  • 形成死循环:连修改 settings.json 加白名单的操作本身都会被撞掉
  • 用户被迫把所有可能用到的操作都预先加入 allowlist,失去了权限确认的安全意义
  • 唯一的 workaround 是先停掉 Hub,操作完再重启

当前 workaround

  1. 把常用操作加入 ~/.claude/settings.jsonpermissions.allow(治标)
  2. 需要执行新操作时先 fh hub stop,操作完再重启(很不方便)

建议方案

在 Hub 的 instance manager 层增加消息暂存机制:

  1. 当 CC 弹权限弹窗时,Hub 暂存入站消息不注入(enqueue)
  2. 弹窗结束(用户从终端确认或 deny)后,flush 暂存的消息

实现思路

  • Instance 增加一个 permission_pending: boolean 状态位
  • Hub 收到来自 CC 的 permission request(approval.ts 的 pending 注册)时,标记该 instance 为 pending
  • Pending 期间,入站消息暂存到队列而不是立即 send 给 instance
  • 收到 permission response 或 TTL 超时后,切回正常并 flush 队列

这个改动在 Hub 侧闭环,不依赖 Claude Code 上游改动。

环境

  • Claude Code (claude-opus-4-6)
  • Forge Hub,微信通道
  • macOS Darwin 25.4.0

附加发现

Hub 作为 MCP server 注册后,用户无法启动一个"干净"的(不连 Hub 的)CC 实例。这在需要不受干扰地操作时是个问题,建议考虑:

  • 支持 CC 启动时选择是否连接 Hub
  • 或 Hub 侧支持 per-instance 的通道订阅粒度控制

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions