Commit 85a1571a7c3b239810e6cc550ceed506c7915391

Authored by yibo
1 parent 98be58b0

docs(hermes-agent): Pixel 编译安装 hermes-agent + 配置 Kimi Coding Plan 文档

新增 HERMES_AGENT_PIXEL_SETUP.md,记录从 Mac 经 adb 把 NousResearch
hermes-agent 装到 Pixel Termux 的完整流程及两个坑(bootstrap 过期导致
node openssl 符号缺失需先 apt upgrade;wrapper /usr/bin/env shebang 在
su -c 下失效需改绝对路径),以及 Kimi Coding Plan 的原生配法(kimi-coding
provider + api.kimi.com/coding,运行时自动切 anthropic 协议 + claude-code UA)。

- README.md 目录清单登记新文档 + 补登 PIXEL_CLAUDE_CODE_OAUTH_SETUP.md
- API key 用占位符,未写真实凭证

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
wechat_plain/scripts/local-testkit/docs/HERMES_AGENT_PIXEL_SETUP.md 0 → 100644
  1 +# 在 Pixel 上编译安装 hermes-agent + 配置 Kimi Coding Plan
  2 +
  3 +> 目标设备:Pixel 8 Pro (husky),Android 16,已 root(Magisk)+ Termux。
  4 +> hermes-agent = **NousResearch 的自改进 AI agent**(github.com/NousResearch/hermes-agent,Python 3.11+/Node),提供 `hermes` CLI(`hermes` 聊天 / `hermes gateway` 消息网关 / `hermes setup` 配置)。本文记录从 Mac 经 adb 把它装到 Pixel Termux,并接 Kimi Coding Plan 作为 LLM 后端的完整流程。
  5 +>
  6 +> 相关记忆:`~/.claude/.../memory/hermes-agent-termux-install.md`、`magisk-su-android-inet-group.md`、`termux-path-convention.md`。
  7 +
  8 +---
  9 +
  10 +## 0. 前置
  11 +
  12 +- 设备已 root,Termux 已装(GitHub/F-Droid 版,非 Play 商店)。Termux 重装/设备 restore 后 **uid 会变**,先取当前 uid:
  13 + ```bash
  14 + adb shell 'su -c "stat -c %u /data/data/com.termux"' # 例:10302(low3 = 302)
  15 + ```
  16 +- 所有「以 Termux 用户身份联网」的命令必须带 inet 等 supplementary group,否则 DNS/网络全断。统一模板(uid=10302 为例):
  17 + ```
  18 + su -g 10302 -G 3003 -G 9997 -G 20302 -G 50302 10302 -c "<cmd>"
  19 + ```
  20 + 其中 `3003=inet 9997=everybody 20<low3>=cache 50<low3>=all_aN`。详见 memory `magisk-su-android-inet-group`。
  21 +- Termux 环境变量(脚本里统一 export):
  22 + ```bash
  23 + export PREFIX=/data/data/com.termux/files/usr
  24 + export HOME=/data/data/com.termux/files/home
  25 + export PATH=$PREFIX/bin:$PATH
  26 + export LD_LIBRARY_PATH=$PREFIX/lib
  27 + export TMPDIR=$PREFIX/tmp
  28 + export TERMUX_VERSION=0.118.3
  29 + ```
  30 +
  31 +---
  32 +
  33 +## 1. 编译安装 hermes-agent
  34 +
  35 +官方安装器原生支持 Termux:检测到 Termux 后用 stdlib venv+pip(不用 uv),自动 `pkg install` python/git/nodejs/clang/rust/ffmpeg/ripgrep,从源码编译 native wheel(maturin / pydantic-core / jiter…),装到 `~/.hermes/hermes-agent/venv`,并在 `$PREFIX/bin/hermes` 建 wrapper。**整机编译约 25–30 分钟**。
  36 +
  37 +### 1.1 ⚠️ 必做:先升级 Termux 全量包(否则 node 坏)
  38 +
  39 +全新 bootstrap 过期时,`pkg install nodejs` 装上的 node 链不上旧 openssl:
  40 +```
  41 +node: CANNOT LINK EXECUTABLE "node": cannot locate symbol "OSSL_PROVIDER_add_conf_parameter"
  42 +```
  43 +install.sh 因 `set -e` 在 Node 步骤 `rc=1` 退出。**先升级再装**:
  44 +```bash
  45 +export DEBIAN_FRONTEND=noninteractive
  46 +apt-get update -y
  47 +apt-get upgrade -y -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef
  48 +node --version # 应能正常打印版本(不再 CANNOT LINK)
  49 +```
  50 +
  51 +### 1.2 跑安装器(脱离 + 日志,扛 adb 掉线/doze)
  52 +
  53 +把下面脚本 push 到 `/sdcard`,再以 Termux 用户 `setsid nohup` 脱离运行:
  54 +
  55 +```bash
  56 +#!/data/data/com.termux/files/usr/bin/bash
  57 +# 见上方 export 块……
  58 +export DEBIAN_FRONTEND=noninteractive
  59 +cd "$HOME"; termux-wake-lock 2>/dev/null || true
  60 +echo "=== UPGRADE START $(date) ==="
  61 +apt-get update -y; apt-get upgrade -y -o Dpkg::Options::=--force-confold -o Dpkg::Options::=--force-confdef
  62 +node --version || { echo "NODE BROKEN"; exit 2; }
  63 +echo "=== HERMES INSTALL $(date) ==="
  64 +curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash -s -- --non-interactive
  65 +echo "=== HERMES INSTALL END rc=$? $(date) ==="
  66 +```
  67 +```bash
  68 +adb push install.sh /sdcard/install.sh
  69 +LOG=/data/data/com.termux/files/home/hermes-install.log
  70 +adb shell "su -g 10302 -G 3003 -G 9997 -G 20302 -G 50302 10302 -c \
  71 + 'setsid nohup /data/data/com.termux/files/usr/bin/bash /sdcard/install.sh >$LOG 2>&1 </dev/null & echo pid \$!'"
  72 +# 轮询:grep 'HERMES INSTALL END rc=0' $LOG
  73 +```
  74 +`--non-interactive` 跳过 setup 向导(无 TTY 也能跑)。
  75 +
  76 +### 1.3 ⚠️ 必做:修 wrapper shebang
  77 +
  78 +installer 生成的 `$PREFIX/bin/hermes` 首行是 `#!/usr/bin/env bash`。Termux 没 `/usr/bin/env`,交互会话靠 termux-exec 动态改写,但用 `su -c` 驱动(无 termux-exec)会报 `No such file or directory`(指解释器)。改成绝对路径(以 Termux 用户改,保留属主):
  79 +```bash
  80 +adb shell "su 10302 -c 'sed -i \"1s|#!/usr/bin/env bash|#!/data/data/com.termux/files/usr/bin/bash|\" /data/data/com.termux/files/usr/bin/hermes'"
  81 +```
  82 +> 注意:`hermes update` 会重新生成 wrapper、把 shebang 改回 `/usr/bin/env`,**每次更新后需重修**。
  83 +> `venv/bin/hermes` 的 shebang 是绝对 venv python,本就没问题,可用它绕过 wrapper 验证。
  84 +
  85 +### 1.4 验证
  86 +
  87 +```bash
  88 +adb shell 'su -g 10302 -G 3003 -G 9997 -G 20302 -G 50302 10302 -c "
  89 + export PREFIX=/data/data/com.termux/files/usr HOME=/data/data/com.termux/files/home
  90 + export PATH=\$PREFIX/bin:\$PATH LD_LIBRARY_PATH=\$PREFIX/lib TMPDIR=\$PREFIX/tmp
  91 + hermes --version"'
  92 +# → Hermes Agent v0.15.1 (2026.5.29) · Python 3.13.13
  93 +```
  94 +产物位置:代码 `~/.hermes/hermes-agent/`,配置 `~/.hermes/config.yaml` + `~/.hermes/.env`,skills `~/.hermes/skills/`。
  95 +
  96 +---
  97 +
  98 +## 2. 配置 Kimi Coding Plan(sk-kimi- key)
  99 +
  100 +hermes **原生支持** Kimi Coding Plan,**不要**用 `provider=anthropic`+`ANTHROPIC_BASE_URL` 绕路。
  101 +
  102 +### 2.1 源码逻辑(为什么这么配)
  103 +
  104 +| 文件 | 逻辑 |
  105 +|---|---|
  106 +| `hermes_cli/auth.py:248` | `kimi-coding` provider:`api_key_env_vars=("KIMI_API_KEY","KIMI_CODING_API_KEY")` |
  107 +| `hermes_cli/auth.py:515` | `KIMI_CODE_BASE_URL = "https://api.kimi.com/coding"`;`_resolve_kimi_base_url()` 把 `sk-kimi-` 前缀 key 自动重定向到这里 |
  108 +| `agent/anthropic_adapter.py:385` | `_is_kimi_coding_endpoint(base_url)` 检测到 `api.kimi.com/coding` → **自动切 Anthropic Messages 协议 + 注入 claude-code User-Agent** |
  109 +| `hermes_cli/main.py` `_model_flow_kimi()` | setup 向导:写 `model.provider/base_url/default`,清空 `KIMI_BASE_URL` override |
  110 +
  111 +**关键坑**:Kimi `/coding` 端点的 OpenAI 路径 `/coding/v1/chat/completions` 返回 **403** `access_terminated_error`("only available for Coding Agents such as Kimi CLI, Claude Code, Roo Code…");只有 Anthropic 路径 `/coding/v1/messages` 通(200)。hermes 通过上面的 UA 伪装自动绕过,所以**必须走 kimi-coding provider(anthropic 协议),不能用 OpenAI 协议**。
  112 +
  113 +### 2.2 落地配置(等价于 `hermes model` 选 Kimi)
  114 +
  115 +**`~/.hermes/.env`**:只放 key,**不要**设 `KIMI_BASE_URL`,也别留 `ANTHROPIC_*`(否则 `provider: auto` 会误判):
  116 +```
  117 +KIMI_API_KEY=sk-kimi-XXXXXXXX...
  118 +```
  119 +> 用 `cat /sdcard/x >> .env`(root 追加不改属主)或 `su <uid> -c 'sed ...'`(Termux 用户改,保属主)避免把 key 写进命令行/ps。
  120 +
  121 +**`~/.hermes/config.yaml`**(用 CLI 设,非交互):
  122 +```bash
  123 +hermes config set model.provider kimi-coding
  124 +hermes config set model.base_url https://api.kimi.com/coding
  125 +hermes config set model.default kimi-for-coding
  126 +```
  127 +可用模型:`kimi-k2.6 / kimi-k2.5 / kimi-for-coding / kimi-k2-thinking / kimi-k2-thinking-turbo`。
  128 +
  129 +### 2.3 验证
  130 +
  131 +```bash
  132 +# -z/--oneshot = 一次性 prompt,免 TTY
  133 +hermes -z "用中文只回答一个数字: 1+1=?"
  134 +# → 2
  135 +```
  136 +裸 `hermes`(不带 `-m/--provider`)直接走 Kimi 即配置成功。
  137 +
  138 +### 2.4 排错速查
  139 +
  140 +| 现象 | 原因 / 处理 |
  141 +|---|---|
  142 +| `HTTP 404 resource not found` | base_url 漏了协议路径或用了 `provider=anthropic`+错 base;改用 `kimi-coding` + `https://api.kimi.com/coding` |
  143 +| `HTTP 403 access_terminated_error` | 走了 OpenAI `/chat/completions` 路径;必须 kimi-coding(anthropic 协议,hermes 自动加 claude-code UA) |
  144 +| `no final response was produced` | config 残留错的 `model.base_url`(如 openrouter)或 provider 不对;按 2.2 重设三项 |
  145 +| `curl: Could not resolve host` | `su` 切 uid 时漏了 `-G 3003`(inet 组) |
  146 +
  147 +---
  148 +
  149 +## 附:一次性自检脚本
  150 +
  151 +```bash
  152 +adb shell 'su -g 10302 -G 3003 -G 9997 -G 20302 -G 50302 10302 -c "
  153 + export PREFIX=/data/data/com.termux/files/usr HOME=/data/data/com.termux/files/home
  154 + export PATH=\$PREFIX/bin:\$PATH LD_LIBRARY_PATH=\$PREFIX/lib TMPDIR=\$PREFIX/tmp
  155 + hermes --version
  156 + hermes config show | grep -iE \"provider|default|base_url\"
  157 + hermes -z \"ping, reply PONG\"
  158 +"'
  159 +```
wechat_plain/scripts/local-testkit/docs/PIXEL_CLAUDE_CODE_OAUTH_SETUP.md 0 → 100644
  1 +# Pixel + Termux 复用 Mac OAuth Token 跑 Claude Code
  2 +
  3 +> 在 Pixel 10 Pro Fold(Android 16)的 Termux + Ubuntu proot 容器里运行 `claude-run`,复用 Mac 上同款 Anthropic OAuth Token,**完全替换原来的 Kimi 反代方案**。
  4 +
  5 +---
  6 +
  7 +## 1. 背景
  8 +
  9 +- **设备**:Pixel 10 Pro Fold(代号 `rango`)/ Android 16,bootloader 已解锁,Magisk root
  10 +- **原方案**:claude-code 通过 Kimi Coding Plan 反代(`https://api.kimi.com/coding/`),用 Kimi token 走所有请求
  11 +- **新目标**:直连 `api.anthropic.com`,复用 Mac 上 `~/.zshrc` 里的 `CLAUDE_CODE_OAUTH_TOKEN`,使用真正的 Claude Opus 4.7
  12 +- **动机**:Frida 在 Android 16 无法跑(ptrace/CFI/SELinux 多重限制),后续工作转向 LSPosed + 真 Claude 模型,需要 Pixel 端本地也能跑 claude-code
  13 +
  14 +---
  15 +
  16 +## 2. 架构总览
  17 +
  18 +```
  19 +┌─────────────────────────────────────────────────────────────┐
  20 +│ Termux (Android shell, user u0_a327) │
  21 +│ │
  22 +│ ~/.bashrc │
  23 +│ └─ export CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-... │
  24 +│ │
  25 +│ /usr/bin/claude-run ←─ wrapper │
  26 +│ └─ proot-distro login --shared-home ubuntu │
  27 +│ -- env CLAUDE_CODE_OAUTH_TOKEN="..." claude "$@" │
  28 +│ │
  29 +│ ▼ │
  30 +│ ┌──────────────────────────────────────────────────────┐ │
  31 +│ │ Ubuntu proot container │ │
  32 +│ │ /root ←(--shared-home)─→ /data/data/com.termux/.../home│
  33 +│ │ ├─ .claude.json ← claude 主配置 │ │
  34 +│ │ └─ .claude/settings.json ← per-user settings │ │
  35 +│ │ │ │
  36 +│ │ claude (ELF/glibc, Node.js) │ │
  37 +│ │ └─→ HTTPS api.anthropic.com │ │
  38 +│ └──────────────────────────────────────────────────────┘ │
  39 +└─────────────────────────────────────────────────────────────┘
  40 +```
  41 +
  42 +**关键点**:
  43 +- Claude Code 是 ELF/glibc 编译,Android Bionic 跑不了 → 必须 proot 跑 Ubuntu
  44 +- `--shared-home` 把 Termux home 绑定为容器 `/root`,配置文件可以从 Termux 端直接编辑
  45 +- Token 通过 `env KEY=VAL claude` 在容器内瞬时注入,不进容器 shell 环境
  46 +
  47 +---
  48 +
  49 +## 3. Claude Code 的双重认证闸门
  50 +
  51 +这是整个迁移最关键的认知 —— claude-code 启动时有两道**独立**闸门:
  52 +
  53 +| 闸门 | 检查内容 | headless (`claude -p`) | 交互模式 (`claude`) |
  54 +|------|---------|----------------------|---------------------|
  55 +| ① Token 闸门 | `CLAUDE_CODE_OAUTH_TOKEN` env 或 `~/.claude/.credentials.json` 任一存在 | 必须过 | 必须过 |
  56 +| ② Onboarding 闸门 | `~/.claude.json` 的 `hasCompletedOnboarding === true` | **跳过** | **必须过** |
  57 +
  58 +**Kimi 反代为什么"屏蔽"了 Onboarding 闸门**:它的 `.env` 块在启动时被 claude-code 注入进进程,等价于一直在用 API key 模式,OAuth onboarding 检查被旁路掉了。一旦切回官方 Anthropic,闸门被激活,于是裸 `claude-run` 弹出 OAuth URL。
  59 +
  60 +---
  61 +
  62 +## 4. 完整改动清单
  63 +
  64 +按依赖顺序(缺一不可):
  65 +
  66 +### 4.1 改 wrapper:注入 OAuth Token
  67 +
  68 +**文件**:`/data/data/com.termux/files/usr/bin/claude-run`
  69 +
  70 +```sh
  71 +#!/data/data/com.termux/files/usr/bin/sh
  72 +# Claude Code via proot-distro with shared home + Mac OAuth token
  73 +exec proot-distro login --shared-home ubuntu -- env CLAUDE_CODE_OAUTH_TOKEN="sk-ant-oat01-<...>" claude "$@"
  74 +```
  75 +
  76 +权限:`chmod 711`(owner 可读,其他 app 不可读),owner `u0_a327:u0_a327`。
  77 +
  78 +> Token 直接 inline 到 wrapper,避免依赖 shell 启动文件。Android 沙箱保证其他 app 读不到 `/data/data/com.termux/` 下的文件。
  79 +
  80 +### 4.2 写 settings.json:清理 Kimi 痕迹
  81 +
  82 +**文件**:`/data/data/com.termux/files/home/.claude/settings.json`
  83 +
  84 +```json
  85 +{
  86 + "env": {},
  87 + "model": "opus",
  88 + "skipDangerousModePermissionPrompt": true,
  89 + "theme": "dark"
  90 +}
  91 +```
  92 +
  93 +权限:`chmod 600`。
  94 +
  95 +> **`env` 必须为空 `{}`** —— 之前 Kimi 配置在这里塞了 `ANTHROPIC_BASE_URL` / `ANTHROPIC_API_KEY` 等,会覆盖 wrapper 注入的 token。
  96 +
  97 +### 4.3 清理 `~/.claude.json` 的 env 块(最容易漏的一步)
  98 +
  99 +**文件**:`/data/data/com.termux/files/home/.claude.json`
  100 +
  101 +claude-code 的"主配置文件",顶层有个 `env` 字段会在进程启动时被 setenv 进去,**优先级高于 wrapper 传入的 env**。
  102 +
  103 +操作(用 jq 在 Mac 端处理后 push 回去):
  104 +
  105 +```bash
  106 +jq 'del(.env)
  107 + | .customApiKeyResponses.rejected = []
  108 + | .model = "opus"
  109 + | .hasCompletedOnboarding = true
  110 + | .lastOnboardingVersion = "2.1.144"' \
  111 + ~/.claude.json.backup > ~/.claude.json.cleaned
  112 +```
  113 +
  114 +需要保证:
  115 +- `.env` 字段被**删除**(不是设为空,是整个 key 不存在)
  116 +- `.hasCompletedOnboarding = true` ← **过 Onboarding 闸门**
  117 +- `.lastOnboardingVersion = "2.1.144"` ← 与当前 claude-code 版本对齐
  118 +- `.model = "opus"`(之前 Kimi 用的 `"opus[1m]"` 在官方 API 不存在)
  119 +- `.customApiKeyResponses.rejected = []`(清掉之前 reject 过的 Kimi key 历史)
  120 +
  121 +权限:`chmod 600`,owner `u0_a327:u0_a327`。
  122 +
  123 +---
  124 +
  125 +## 5. 完整执行脚本(从 Mac 端一键执行)
  126 +
  127 +```bash
  128 +#!/usr/bin/env bash
  129 +set -euo pipefail
  130 +
  131 +# 1. 从 Mac ~/.zshrc 提取 token
  132 +TOKEN=$(awk -F= '/^export CLAUDE_CODE_OAUTH_TOKEN=/{sub(/^export CLAUDE_CODE_OAUTH_TOKEN=/, ""); print; exit}' ~/.zshrc)
  133 +[ -z "$TOKEN" ] && { echo "ERROR: token not found in ~/.zshrc"; exit 1; }
  134 +
  135 +# 2. 构造文件
  136 +mkdir -p /tmp/claude-pixel
  137 +cat > /tmp/claude-pixel/claude-run <<EOF
  138 +#!/data/data/com.termux/files/usr/bin/sh
  139 +exec proot-distro login --shared-home ubuntu -- env CLAUDE_CODE_OAUTH_TOKEN="$TOKEN" claude "\$@"
  140 +EOF
  141 +chmod 711 /tmp/claude-pixel/claude-run
  142 +
  143 +cat > /tmp/claude-pixel/settings.json <<'EOF'
  144 +{
  145 + "env": {},
  146 + "model": "opus",
  147 + "skipDangerousModePermissionPrompt": true,
  148 + "theme": "dark"
  149 +}
  150 +EOF
  151 +
  152 +# 3. 处理 .claude.json(先 pull,patch,push)
  153 +adb shell "su -c 'cp /data/data/com.termux/files/home/.claude.json /sdcard/cc.json && chmod 644 /sdcard/cc.json'"
  154 +adb pull /sdcard/cc.json /tmp/claude-pixel/cc.json
  155 +adb shell "su -c 'rm /sdcard/cc.json'"
  156 +jq 'del(.env)
  157 + | .customApiKeyResponses.rejected = []
  158 + | .model = "opus"
  159 + | .hasCompletedOnboarding = true
  160 + | .lastOnboardingVersion = "2.1.144"' \
  161 + /tmp/claude-pixel/cc.json > /tmp/claude-pixel/cc.patched.json
  162 +
  163 +# 4. push & 安装
  164 +adb push /tmp/claude-pixel/claude-run /sdcard/claude-run.new
  165 +adb push /tmp/claude-pixel/settings.json /sdcard/settings.json.new
  166 +adb push /tmp/claude-pixel/cc.patched.json /sdcard/cc.json
  167 +
  168 +adb shell "su -c '
  169 +WRAPPER=/data/data/com.termux/files/usr/bin/claude-run
  170 +SETTINGS=/data/data/com.termux/files/home/.claude/settings.json
  171 +MAIN=/data/data/com.termux/files/home/.claude.json
  172 +
  173 +# 备份原版(只备份一次)
  174 +[ ! -f \$WRAPPER.prekimi ] && cp \$WRAPPER \$WRAPPER.prekimi
  175 +[ ! -f \$MAIN.prekimi ] && cp \$MAIN \$MAIN.prekimi
  176 +
  177 +# 安装新版
  178 +cp /sdcard/claude-run.new \$WRAPPER
  179 +chown u0_a327:u0_a327 \$WRAPPER && chmod 711 \$WRAPPER
  180 +
  181 +mkdir -p \$(dirname \$SETTINGS)
  182 +cp /sdcard/settings.json.new \$SETTINGS
  183 +chown u0_a327:u0_a327 \$SETTINGS && chmod 600 \$SETTINGS
  184 +
  185 +cp /sdcard/cc.json \$MAIN
  186 +chown u0_a327:u0_a327 \$MAIN && chmod 600 \$MAIN
  187 +
  188 +# 清理
  189 +rm /sdcard/claude-run.new /sdcard/settings.json.new /sdcard/cc.json
  190 +echo done
  191 +'"
  192 +
  193 +# 5. 清理 Mac 临时文件
  194 +rm -rf /tmp/claude-pixel
  195 +```
  196 +
  197 +---
  198 +
  199 +## 6. 验证
  200 +
  201 +### 6.1 headless 模式
  202 +
  203 +```bash
  204 +adb shell 'su u0_a327 -c "
  205 +export HOME=/data/data/com.termux/files/home
  206 +export PATH=/data/data/com.termux/files/usr/bin:\$PATH
  207 +cd \$HOME
  208 +claude-run -p \"reply with just OK\" < /dev/null
  209 +"'
  210 +```
  211 +
  212 +期望输出:`OK`(前面有几行 `proot warning: can't sanitize binding /proc/self/fd/...` 是 adb 非 tty 模式的良性警告,无视)。
  213 +
  214 +### 6.2 交互模式(用户在 Termux 里直接跑)
  215 +
  216 +```
  217 +$ claude-run
  218 +```
  219 +
  220 +期望:直接进入 Claude Code TUI 界面,**不**弹出 OAuth URL。
  221 +
  222 +### 6.3 排错检查清单
  223 +
  224 +| 症状 | 检查 |
  225 +|------|------|
  226 +| 报错指向 `kimi.com/code/console` | `~/.claude.json` 的 `env` 块没删干净 |
  227 +| 弹出 OAuth 登录 URL | `~/.claude.json` 的 `hasCompletedOnboarding` 不是 `true` |
  228 +| `Failed to authenticate. 401` | Mac 那边的 token 已失效,去 Mac 重新登录刷新 |
  229 +| `Warning: no stdin data received in 3s` | headless 模式没加 `< /dev/null`,等 3 秒后会继续,不是错误 |
  230 +| `which claude-run` 指向其他路径 | PATH 优先级问题 / 装了 alias |
  231 +
  232 +---
  233 +
  234 +## 7. 回滚
  235 +
  236 +之前的版本都备份在 `.prekimi` 后缀文件里:
  237 +
  238 +```bash
  239 +adb shell "su -c '
  240 +cp /data/data/com.termux/files/usr/bin/claude-run.prekimi /data/data/com.termux/files/usr/bin/claude-run
  241 +cp /data/data/com.termux/files/home/.claude.json.prekimi /data/data/com.termux/files/home/.claude.json
  242 +echo rolled back to Kimi config
  243 +'"
  244 +```
  245 +
  246 +---
  247 +
  248 +## 8. 安全注意
  249 +
  250 +- Wrapper 里 inline 的 OAuth token 是个**长效凭证**,泄露等于账号被借用
  251 +- 文件权限:wrapper `711`(不可读其他 app),`.claude.json` `600`
  252 +- Android 沙箱保证其他 app 无法访问 `/data/data/com.termux/` 下的文件
  253 +- 如果手机丢失或共享,**Mac 端立刻去 Anthropic console 撤销该 token**(一撤销 Mac/Pixel 同时失效,需要重新登录刷新)
  254 +
  255 +---
  256 +
  257 +## 9. 已知限制
  258 +
  259 +1. **网络出口**:直连 `api.anthropic.com` 需要稳定国际网络。Pixel 在 4G 蜂窝下不一定通,建议挂代理或走 Wi-Fi
  260 +2. **计费归属**:使用 Mac 同一个 Anthropic 账号配额,Pixel 跑多了会消耗 Mac 同账号的 quota
  261 +3. **Token 刷新**:OAuth access token 有效期约 1 年,过期后需要在 Mac 端重新执行 OAuth 流程刷新,然后把新 token 同步到 Pixel wrapper
  262 +4. **多设备 token 复用合规性**:Anthropic ToS 允许同一账号在多设备使用,但禁止把 token 分享给第三方
  263 +
  264 +---
  265 +
  266 +## 10. 相关文件索引
  267 +
  268 +| 路径 | 作用 |
  269 +|------|------|
  270 +| `/data/data/com.termux/files/usr/bin/claude-run` | wrapper(inline token) |
  271 +| `/data/data/com.termux/files/usr/bin/claude-run.prekimi` | 旧版备份 |
  272 +| `/data/data/com.termux/files/home/.claude.json` | claude-code 主配置 |
  273 +| `/data/data/com.termux/files/home/.claude.json.prekimi` | 主配置备份(含 Kimi) |
  274 +| `/data/data/com.termux/files/home/.claude/settings.json` | per-user settings |
  275 +| `/data/data/com.termux/files/usr/var/lib/proot-distro/containers/ubuntu/rootfs` | Ubuntu 容器 rootfs |
  276 +
  277 +Mac 端:
  278 +| 路径 | 作用 |
  279 +|------|------|
  280 +| `~/.zshrc` 里的 `CLAUDE_CODE_OAUTH_TOKEN` | Token 来源 |
  281 +| `~/.claude.json` | Mac 上对应的主配置(参照对比用) |
wechat_plain/scripts/local-testkit/docs/README.md
@@ -302,6 +302,8 @@ local-testkit/ @@ -302,6 +302,8 @@ local-testkit/
302 ├── HERMES_WECHAT_ARCHITECTURE.md 302 ├── HERMES_WECHAT_ARCHITECTURE.md
303 ├── REVERSE_ENGINEERING_LOG.md 303 ├── REVERSE_ENGINEERING_LOG.md
304 ├── NOTIFICATION_STRATEGY.md 304 ├── NOTIFICATION_STRATEGY.md
  305 + ├── PIXEL_CLAUDE_CODE_OAUTH_SETUP.md # Pixel 上 claude-run 复用 Mac OAuth
  306 + ├── HERMES_AGENT_PIXEL_SETUP.md # 在 Pixel 编译装 NousResearch hermes-agent + 配 Kimi Coding Plan
305 └── plan.md 307 └── plan.md
306 308
307 server/services/wechat/ # 主 plugin(Node.js) 309 server/services/wechat/ # 主 plugin(Node.js)