Commit de6dd450d8e35de60a699c8d457c41289ff04655
1 parent
63214cff
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>
Showing
3 changed files
with
442 additions
and
0 deletions
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 | 302 | ├── HERMES_WECHAT_ARCHITECTURE.md |
| 303 | 303 | ├── REVERSE_ENGINEERING_LOG.md |
| 304 | 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 | 307 | └── plan.md |
| 306 | 308 | |
| 307 | 309 | server/services/wechat/ # 主 plugin(Node.js) | ... | ... |