git:20260601.0b6be9e to git:20260602.fbc4668

39 added, 28 removed. Audit A to A.

---
name: yoooclaw-tunnel-debug
- description: 用 yoooclaw CLI 排查手机端推送链路是否通。当用户说"手机推送收不到""通知没同步过来""检查一下隧道/连接""daemon 还活着吗""手机连不上"时激活。组合使用 daemon status / tunnel status / tunnel +test / gateway test 自检整条接收链路。多数命令需要 daemon 在运行(🟡)。
+ description: 用 yoooclaw CLI 排查手机端推送链路是否通。当用户说“手机推送收不到”“通知没同步过来”“检查一下隧道/连接”“daemon 还活着吗”“手机连不上”时激活。组合使用 auth status / daemon status / tunnel status / tunnel +test / gateway test / daemon logs 定位本地配置、daemon、本地 ingest 鉴权与 Relay WebSocket 状态。多数命令需要 daemon 在运行(🟡)。
---
- # yoooclaw 隧道 / 接收链路排查
-
- 独立 daemon 当前以**直连 HTTP** 接收手机推送(`POST /notifications`),
- 配合用户自建 `cloudflared` / `tailscale serve` 反代到 daemon 的本地地址即可让手机端推达。
-
- ## 何时激活
+ # yoooclaw Relay / 接收链路排查
- - "手机推送收不到 / 通知没同步过来"
- - "检查隧道 / 连接 / daemon 状态"
- - "手机连不上 / 一直没新消息"
+ 独立 daemon 默认用 account api-key 连接托管 Relay WebSocket,手机 App 绑定同一账号后经 Relay 收发。也可以在 Relay 未启用或不可用时,将 `POST /notifications` 通过用户自建 `cloudflared` / `tailscale serve` 暴露为直连 HTTP fallback。
## 排查顺序
```bash
- # 1) daemon 是否在跑、监听哪个地址端口
+ # 1) 本地凭据是否存在;不调 daemon
+ yoooclaw auth status --format json
+
+ # 2) daemon 是否在跑、监听哪个地址端口
yoooclaw daemon status --format json
- # 未运行 → {"ok":false,"error":{"code":"YOOOCLAW_DAEMON_NOT_RUNNING",...}} → yoooclaw daemon start
+ # 未运行 → yoooclaw daemon start --format json
- # 2) 隧道状态(relay 模式 / 是否连接 / relay URL)
+ # 3) Relay 模式、连接状态、URL、多隧道状态
yoooclaw tunnel status --format json
- # → {"ok":true,"mode":"standalone-http","connected":false,"relayUrl":"...","note":"..."}
- # 3) 端到端回环自检:daemon 通过本地 HTTP 给自己发一条 echo 通知,验证 ingest+鉴权链路
+ # 4) daemon 本地回环:验证本地 ingest + 鉴权
yoooclaw tunnel +test --format json
- # → {"ok":true,"loopback":{"ok":true,"status":200}} 表示本机接收链路 OK
- # 4) 模拟手机端调 /notifications,验证鉴权与连通
+ # 5) 模拟手机端直接调本地 /notifications
yoooclaw gateway test --format json
- # → {"ok":true,"status":200,"response":{"ok":true,"ingested":1,...}}
- # 要强制走 relay 旁路:yoooclaw gateway test --via-relay
+
+ # 6) 看 Relay 连接与重连日志
+ yoooclaw daemon logs --lines 200 --format json
+ yoooclaw log +errors --format json
```
+ `tunnel +test` 会让 daemon 给本地 `/notifications` 发一条 echo 通知。它可以确认本地 ingest + 鉴权链路,但不会让流量真正绕行远端 Relay。`gateway test --via-relay` 当前也是复用这条本地回环路径,不应单独作为远端 Relay 可达性的证据。
+
## 判读
- - `daemon status` 报 `YOOOCLAW_DAEMON_NOT_RUNNING` → daemon 没起,先 `yoooclaw daemon start`。
- - `tunnel +test` 的 `loopback.ok=true` 且 `gateway test` `ok=true`:**本机接收链路正常**。
- 手机仍收不到 → 问题在网络可达性:检查防火墙、反代(cloudflared/tailscale)、手机端填的地址是否指向 daemon 的对外地址。
- - `gateway test` 返回 `401 / YOOOCLAW_UNAUTHORIZED`:token 不一致。
- 用 `yoooclaw auth status` 看 token 来源,必要时 `yoooclaw auth token-rotate` 后重启 daemon、并更新手机端 token。
- - 想看 daemon 自身日志定位 ingest 失败:`yoooclaw daemon logs --lines 200`(或 `yoooclaw log +errors`)。
+ - `auth status` 中 api-key 不存在:先用 `yoooclaw auth set-api-key -` 从 stdin 设置,再启动或 reload daemon。
+ - `daemon status` 报 `YOOOCLAW_DAEMON_NOT_RUNNING`:运行 `yoooclaw daemon start`。
+ - `tunnel status` 的 `mode=relay` 且 `connected=true`:daemon 当前已连上 Relay WebSocket。
+ - `tunnel status` 的 `mode=relay` 但 `connected=false`:结合 `lastDisconnectReason`、`reconnectAttempt` 和 daemon 日志排查 api-key、网络与 Relay 服务。
+ - `tunnel status` 的 `mode=standalone-http`:当前没有 Relay 隧道;按返回的 `note` 检查 `relay.enabled` 和 api-key。只有明确采用直连 fallback 时才检查防火墙、反代和手机端地址。
+ - `tunnel +test` 或 `gateway test` 失败:先排查本地 gateway token。运行 `yoooclaw auth status`,必要时 `yoooclaw auth token-rotate`;daemon 已运行时随后执行 `yoooclaw daemon restart`。
- ## 鉴权前置检查(不调 daemon)
+ ## 多 clientLabel
+ 多 api-key 模式下,每个 label 对应一条 Relay 隧道。按 label 缩小排查范围:
+
```bash
- yoooclaw auth status --format json # api-key / gateway token 是否存在、来源、daemon 是否可达
- yoooclaw auth check --format json # 端到端:用本地 token 调 daemon /daemon/status 验证一致性
+ yoooclaw auth list-api-keys --format json
+ yoooclaw tunnel status --client work --format json
+ yoooclaw tunnel +test --client work --format json
+ yoooclaw tunnel reconnect --client work --format json
```
+
+ ## 鉴权检查
+
+ ```bash
+ yoooclaw auth status --format json
+ yoooclaw auth check --format json
+ ```
+
+ `auth status` 只读本地凭据与 daemon lock。`auth check` 会用本地 gateway token 调 daemon `/daemon/status`,用于确认 CLI 和 daemon 的 token 是否一致。