Skip to content

feat: setup wizard + auto-update + leak_guard#1

Merged
r266-tech merged 22 commits into
mainfrom
feat/setup-wizard
Apr 30, 2026
Merged

feat: setup wizard + auto-update + leak_guard#1
r266-tech merged 22 commits into
mainfrom
feat/setup-wizard

Conversation

@r266-tech

Copy link
Copy Markdown
Owner

Summary

22 commits 把 babata 从 "git clone + 手填 .env + 手装 launchd plist" 推到 bash install.sh 一键就位 + 自动跟主线 + PII 防护.

三条主线:

  • Setup wizard (wizard.py) — 交互引导填 token / 选 model / 装 channel (TG + WX), 实测验证 token + model 真可用. 不让用户手编 .env.
  • Auto-update 栈 (scripts/auto-update.sh) — systemd timer (Linux) / launchd plist (macOS), 每小时 git pull --ff-only + uv sync + claude update + 重启 service. 你推 main 1 小时内 ripple 到所有装了的 OSS 用户.
  • Leak guard (tests/leak_guard.sh) — pre-push 扫 push range 内每个 commit 的 patch (added lines), BLACKLIST 拦私人 path / phone / email / handle / employer 进入 public repo. CI 双 OS 兜底. codex 双轮对抗审过.

Test plan

  • bash tests/smoke.sh 全 11 项 PASS (constants / cc isolation / bot fail-closed / /provider degrade)
  • bash tests/leak_guard.sh tree-mode clean
  • --pre-push mode: dangling commit 注入 /Users/admin/oops/leak → exit=1 拦截 ✓
  • V global hooksPath chain 三场景验证 (clean push / leaking commit / 无 leak_guard.sh repo fallback)
  • CI matrix 双 OS (macos-latest + ubuntu-latest) — push 后 CI run 验证

Notes

  • Branch protection: enforce_admins=true 已开 — admin 也得过 CI 才能 merge
  • /Users/admin 历史在 main 6 个 commit 已存在 (0.1.0 release 引入), 不是新增. squash merge 后 feat 的 21 commit 不进 main 历史

🤖 Generated with Claude Code

r266-tech and others added 22 commits April 29, 2026 15:41
setup.py 自动配 .env, 用户全程不碰文件:
- 三档 Claude auth: Anthropic 官方 / 共享已登录 CC OAuth / 第三方兼容 endpoint
  (含 GET /v1/models 探测 + 模型列表 + 串行双 header fallback)
- TG channel: BotFather token getMe 验证 + binding mode 用 nonce + 二次确认
  抓 user_id (不用 @userinfobot, 防 race / 别人先发)
- WX channel: subprocess 调现成 weixin_bot._interactive_login (ASCII QR)
- write_env atomic, 渐进落盘 (Ctrl+C 不丢已验证步骤)

install.sh 装完 deps 自动 hand-off, TTY guard 处理非交互 case,
setup.py 失败状态 propagate 不会假装"安装完成".

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
WX 专用 (SILK 解码 + 终端 QR), TG-only 用户不该被 C 扩展拖累.
ARM/Linux + Python 3.13 没 prebuilt wheel → 必须本地编译, 沙盒
没 gcc 直接炸. 真用户踩坑触发 (V OrbStack Ubuntu 25.10 ARM).

- pyproject.toml: pilk + qrcode 移到 [project.optional-dependencies] wx
- setup.py step_wx: confirm 选 yes 后, subprocess `uv sync --extra wx`
  现装; 失败给清晰 build 工具提示 (apt build-essential / xcode)
- uv.lock: 更新 (TG-only 安装路径变薄)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
开箱即用: 用户不填任何 voice 相关 env 就能 TG 收发语音.
填 MIMO_API_URL+KEY → 升级到 MiMo Omni (中文最准, 视频理解必填).

- TTS: edge-tts dep 入主依赖 (之前 media.py 已有 fallback 但 dep 漏列,
  调用会 ImportError). 默认 zh-CN-XiaoxiaoNeural, ~150KB.
- STT: 加 _stt_local 走 faster-whisper, _stt_wav 改 dispatcher
  (有 MIMO env 走 MiMo, 否则 local). 默认 base 模型 (~150MB 首跑下载到
  ~/.cache/huggingface/), STT_LOCAL_MODEL env 可升级到 small/medium/large-v3.
- transcribe 是 sync 的, run_in_executor 丢线程池避免卡 event loop.
- .env.example: voice 段重写, 默认本地路径前置, MIMO 标"可选升级".

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…estarts

`uv pip install --upgrade claude-agent-sdk` ignores uv.lock, so the venv
drifts ahead of the lock. Any dev `uv sync` afterwards pulls SDK back to
lock's pinned version → next auto-update upgrades it again → all 4 bots
get kickstarted unnecessarily.

Adds `uv lock --upgrade-package claude-agent-sdk` after the venv upgrade
so lock and venv stay aligned. Also commits the current lock at 0.1.71
(was stuck at 0.1.63).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
set -uo pipefail (no -e) means `uv lock | tail` would silently exit non-zero
on network glitch / uv crash, leaving lock stale while venv is upgraded —
restoring the toggle bug on the next dev `uv sync`. Adds explicit `||` guard
that emits a clear warning so V sees it in auto-update.log.

Adversarial review (codex) flagged this as silent-continuation HIGH; venv
already upgraded by pip-install so we don't fail-closed (would skip the
real restart and leave bots running mismatched SDK), just log loudly.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
V 沙盒踩坑: 看到 \"选 [1/2/3] [1]: \" 按 enter 想看后续提示,
被静默接走到 [1] 路径直接 prompt API key, 用户以为还在选项输了 \"3\"
被当 key 验证 401. 三档 auth 是明确选择, 不是 yes/no, 不该有默认值.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
/v1/models 探不到时之前是 \"信任填的对\", babata 启动才发现 token 错或
model 名错. 现在加一步 POST 最小 /v1/messages (1 token quota), 装的时候
就报错: 401 = token 错, 400/404 = model 错或不接 messages, 200 = 都通.
失败时让用户选\"仍然保存\"逃生口, 不强 block.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
V 沙盒踩坑: install.sh 装了 claude 到 ~/.local/bin, 但用户单独跑
setup.py 不经 install.sh 那个 export PATH, shutil.which 找不到 claude
直接告警. 改成 PATH miss 时显式扫常见安装目录.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
跟 CLAUDE_CLI_PATH 同款 bug: 单独跑 setup.py 没 install.sh 的 export
PATH, subprocess 调 \`uv\` 直接 FileNotFoundError. 改成 PATH miss 时
显式扫 ~/.local/bin/uv + /usr/local/bin/uv.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
V 沙盒踩坑: install.sh 装完后 babata / claude / uv 全找不到, 只 hint
\"add to shell rc\" 让用户自己改 — 违 iron rule \"永远不要让用户手工改配置\".

改成: 检测 PATH 没 ~/.local/bin 时, 按 \$SHELL 探 .bashrc / .zshrc /
fish config / .profile, append export 行 (grep 幂等). 提示用户开新终端
或 source rc.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
V 沙盒踩 bug: \`.venv/bin/babata: No such file or directory\` —
install.sh 的 symlink 是 dangling. 根因: pyproject.toml 缺
[build-system] 段, uv sync 没真把项目 install 进 venv,
[project.scripts] babata = \"bot:main\" 不生成 entry script.

加 [build-system] 后又踩 setuptools 命名冲突: 我们 wizard 文件叫
setup.py, setuptools 见到默认当 build script import, setup.py
import httpx 但 build env 没装 httpx 直接炸. 重命名 setup.py →
wizard.py, install.sh + 注释里所有 ref 一并更新.

修完后 uv sync 真生成 .venv/bin/babata, 调 bot.main() OK.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… files

last commit (4c38847) 因 \`git add -A\` 误带:
- babata.egg-info/* — setuptools build artifact, 加 .gitignore
- scripts/poll-healthcheck.sh — V 私有 runtime 脚本
- weixin_{bridge,ilink,mcp}.py 修改 — V 私有跟 setup wizard 无关

撤回它们, V 工作树修改保留, build artifact 不再追踪.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
V 沙盒 ARM Linux 踩坑: pilk 是 C 扩展, ARM Linux Py3.13 没 prebuilt wheel
必须本地编译, 沙盒没 gcc → 直接炸. 之前 fail loud 让用户手敲
\`sudo apt install build-essential\` 违 iron rule \"不让用户手改配置\".

加 _ensure_pilk_build_tools(): step_wx confirm yes 后, gcc 缺就主动
\`sudo apt-get install -y build-essential python3-dev\` (Linux only,
会 prompt sudo 密码), 失败时 update 再试. macOS 仍 fall back 到 GUI
xcode-select --install (没法 automate).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
V 沙盒重置后又踩同款坑: install.sh 跑完后当前 shell 没 source 新加的
rc, \`babata\` 命令找不到. 末尾文案显示 \`babata\` 让用户跑, 跑不起来.
改用绝对路径 \$REPO_DIR/.venv/bin/babata, 同时显式提示开新终端才有
全局命令.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
V 反馈 \"只保留必须步骤\". 装完到这一步用户就是为了用, ask \"启动否\" 是
冗余步骤 — 直接 exec babata, foreground 跑, 用户立刻能在 TG/WX 测.
退出 (Ctrl+C) 后开新终端 \`babata\` 还是能用 (PATH 已加 rc).

非交互终端 (CI / pipe) 才打印 hint 不 exec, 不卡死自动化.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
V \"步骤越少越好\". 跑 install.sh = 已决定装 babata, babata 强依赖 claude,
\"Install now? [Y/n]\" 是冗余决策. 跟 uv 一样直接装.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
V 沙盒踩坑: install.sh 装完 babata 起 bot, TG 工作 WX 没回复. 根因:
\`babata\` 命令 = bot:main = 只跑 TG, WX 是独立 weixin_bot.py 入口.
V 视角下 babata 应该一条命令跑两 channel.

bot.py main() 开头检测 ~/.babata/weixin/accounts/ 有 token 就 spawn
weixin_bot.py 子进程, atexit cleanup. 生产 launchd 多 plist 模式可
\`BABATA_NO_AUTO_WX=1\` 关掉.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
V 沙盒 admin@12 又踩坑: orb shell 进入是 login shell, 只读 .profile
(or .bash_profile) 不读 .bashrc. 之前 install.sh 单写 .bashrc, 用户开
新 shell 命令找不到. 改成 bash 双写 .bashrc + .profile, zsh 双写
.zshrc + .zprofile.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
V 沙盒发语音踩坑: bot 回 \"转录失败: No such file or directory: 'ffmpeg'\".
install.sh 之前只 warn 让用户自己 apt install — 违 iron rule \"不让用户手改\".
改成主动 sudo apt install / brew install. ffmpeg 是语音 STT/TTS 必需.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
V 视角 \"真用户装完关终端要继续可用\". 之前 install.sh 末尾 exec foreground
bot, 用户 Ctrl+C 就死. 改成自动写 service 文件 + enable + start:

- Linux: ~/.config/systemd/user/babata.service + systemctl --user enable --now
  + sudo loginctl enable-linger (user 没登录也跑)
- macOS: ~/Library/LaunchAgents/com.babata.plist + launchctl bootstrap
  (旧版 fallback launchctl load -w)

Restart=always / KeepAlive=true → crash 自动重启. RunAtLoad / 重启机器
自动起. 末尾打印查 log / 停 / 重启命令.

没探测到 systemd/launchd 时 fallback 原 foreground exec.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… service

V 视角 \"我推 commit OSS 用户应该自动拿到\". install.sh 末尾配:

- Linux: babata-update.service + babata-update.timer (OnUnitActiveSec=1h)
- macOS: com.babata.update.plist (StartInterval=3600)

每小时跑 scripts/auto-update.sh:
1. git pull --ff-only (本地 modify 时 skip 避冲突)
2. 代码变了 → uv sync 装新 deps
3. claude update (CC native installer 自带升级)
4. 任一变了 → 重启 babata service (systemd / launchd)

Idempotent: 没新 commit + claude 也没升级 → exit 0 不重启.
log: \$REPO/logs/auto-update.log + journalctl --user -u babata-update.

V 你的 commit + push main → OSS 用户 1h 内自动 ripple, 用户无感升级.
不动 root \`auto-update.sh\` (V 私有 macOS launchd 跑那个), 此处独立 OSS 通用版.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- tests/leak_guard.sh: 双模式 (CI tree scan / pre-push patch-scan commit range)
- BLACKLIST 13 项 (paths/PII/employer/handle); --pre-push flag 区分模式 (不用 stdin TTY 启发, CI shell 也 non-TTY 会误判)
- patch mode 扫每个 commit 的 added lines, 防 "加 PII → commit → 删 → push" 绕过
- CI smoke.yml 加 leak_guard step + tag push trigger
- install.sh 检测 .git/hooks/ 时装 pre-push hook
- 3 个 tests/test_*.py 硬编码 /Users/admin path → portable 派生

防 V 误推 PII 到 r266-tech/babata; codex round 1 审 6 hole 修, round 2 自修
stdin TTY 误判. 端到端验证: dangling commit inject 拦 exit=1 ✓.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@r266-tech r266-tech merged commit 301bd12 into main Apr 30, 2026
2 checks passed
r266-tech added a commit that referenced this pull request May 18, 2026
r266-tech added a commit that referenced this pull request May 26, 2026
* docs(readme): add agent-facing star callout (babata convention)

* docs(readme): replace aggressive star CTA with human-tone callout (Codex review #1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant