痛点
Claude Code 的 5 小时和周限额会打断长 agentic 任务,SSH 断开会把会话整个杀掉。醒来一看任务半成品,终端也丢了。
它做什么
- 把
claude包一层,hit 5 小时块就 sleep 到 reset,用同一个 session UUID 自动续。 - 跑在命名的 tmux session 里,SSH 断了不影响。
- 三层检测:本地确定性优先,LLM 可选 opt-in。
- 自动接住新的交互式限额 modal(只选安全的 "Stop and wait")。
- 多会话:
vibe work feature-a和vibe work bugfix并行隔离。 - 核心只依赖
bash、jq、curl、tmux,没有 npm 没有 pip。
安装(一次性)
git clone https://github.com/zhihuiyuze/vibe-coding-auto-resume.git ~/vibe
cd ~/vibe
./install.sh
source ~/.bashrc
幂等。把工具软链到 ~/.local/bin/,往 ~/.bashrc 写一个 vibe shell 函数,往 ~/.tmux.conf 追加 snippet。不动 ~/.claude/,也不替你跑 sudo。
三个场景,对号入座
1. 起一个新的 Claude 任务
cd ~/dev/<your-project>
vibe work # cd 到这里,开命名 tmux session
vibe run # 替代 claude,参数和 UI 一致
正常用 Claude。5 小时 block 烧光时,vibe run 自己 sleep 到 reset,再用同一个 session UUID 重启。Anthropic 新的交互式 modal(What do you want to do? 1. Stop and wait …)也会被接住,只选安全的 "Stop and wait",绝不碰花钱那两个。
暂时离开:Ctrl+b d。回来:vibe work。
2. 接着之前开过的会话继续
记得 session UUID 的话:
cd ~/dev/<your-project>
vibe work
vibe run --resume <session-uuid>
不记得,但是这个项目最近一个 session:
vibe run --mode continue # 等价 claude --continue,外加 hit limit 自动续
列出候选 UUID:
ls -t ~/.claude/projects/$(pwd | sed 's|/|-|g')/*.jsonl | head -5
# 文件名去掉 .jsonl 就是 session UUID
3. SSH 断了,怎么确认还在跑、怎么重连回去
tmux 才是 claude 的真正归属,跟你的 shell 无关。SSH 死了 session 不会死。三步走:
ssh you@server # 1. 重连
tmux ls # 2. vibe-* session 还在不在
# 正常会输出类似 "vibe-default: 1 windows (...)"
vibe work # 3. 重新 attach(用了名字就 `vibe work <name>`)
# 一进去就是离开时的现场
attach 后想看走开期间发生了什么,Ctrl+b [ 进翻页模式,PageUp 或方向键往上翻,q 退出。如果中间 hit 了 limit,wrapper 已经处理过了,scrollback 里能看到 [vibe-run] Sleeping … until … 和恢复运行的日志。
不想 attach,只想瞄一眼(换台机器看状态):
ssh you@server "tmux ls"
ssh you@server "tmux capture-pane -t vibe-default -p | tail -50"
ssh you@server "vibe status"
如果 tmux ls 输出 no server running,通常是机器重启了,或者 tmux 被 OOM kill 了。tmux session 没了,但 Claude 的 JSONL 历史还在,走上面场景 2 就能从原 session 续。
发现 & 管理会话
vibe ls 列出所有 vibe-* tmux session,附 cwd、是否 attached、← here 标记(cwd 跟你当前一致就标):
$ vibe ls
vibe-boldfox /home/u/dev/projectA ← here [attached]
vibe-feature-x /home/u/dev/projectA ← here
vibe-quietowl /home/u/dev/scratch
vibe work 不带参数时,现在会先看 cwd 有没有匹配的 session 再决定:
- 0 个匹配,新建(cwd 哈希命名)
- 1 个匹配,直接 attach 不问
- N 个匹配,弹交互式 picker(输
1..N选,n新建)
显式 vibe work <name> 跳过 discovery,名字永远赢。经常用的项目,建议给个显式名字(vibe work projectA)而不是依赖 cwd 哈希。这样路径改名或换符号链不会漂到别的 session,vibe ls 里也好认。
可选:开 L3 LLM 检测
L1(JSONL 解析)和 L2(tmux pane regex)在常见 rate limit 场景下零外发够用。想更稳地应对 TUI 文案变化、想抓 L2 regex 漏掉的 reset 时间,可以 opt-in L3:
echo 'DEEPSEEK_API_KEY=sk-...' >> ~/.config/vibe/env # chmod 600,installer 已建文件
chmod 600 ~/.config/vibe/env
source ~/.bashrc
支持的 provider:DeepSeek(约 $0.05/block)、Anthropic Claude Haiku、OpenAI gpt-4o-mini、Ollama(本地,[untested])。L3 关掉时(默认,加 key 前一直是关)任何数据都不出本机。
检测原理
claude 退出时,三层信号判断刚才发生了什么:
| 层 | 读取来源 | 什么时候有用 |
|---|---|---|
| L1 | ~/.claude/projects/<cwd>/*.jsonl,Claude 自己的日志 | 常开。算 token 用量、block 开始和结束。 |
| L2 | tmux capture-pane + 滚动缓冲 | 主窗口能看到的限额提示。 |
| L2.5 | JSONL 尾部文本扫描 | 子 agent 的限额提示被滚出窗口外时兜底。 |
| L3 | LLM 分类器(DeepSeek / Claude Haiku / OpenAI / Ollama) | Opt-in。对措辞变化鲁棒,能语义提取 reset 时间。 |
L1 和 L2/L2.5 完全本地、零外发。L3 是 opt-in,DeepSeek 大概 $0.05/block。
CLI 参数
vibe run [...args]
--resume <uuid> 恢复指定会话(传一次,所有续接 cycle 都用)
--threshold <0..1> opt-in 软上限(默认关,榨干当前 block)
--max-cycles <n> 本次调用最多续接几次(0 = 无限,默认 1)
--mode auto|session-id|continue
--provider deepseek|claude|openai|ollama
--no-l3 强制只用 L1+L2
--dangerously-skip-permissions
-p "prompt"
... 其它任何参数都透传给 claude
配置
| 位置 | 内容 |
|---|---|
~/.config/vibe/env | LLM keys 加可调参数(chmod 600)。bashrc 里的标记块用 set -a 导出。 |
~/.local/state/vibe/<name>/ | 各 session 的 UUID 缓存。vibe work foo 和 vibe work bar 互相隔离。 |
<your-project>/HANDOFF.md | 跨会话续接文件。只在你从该项目内运行 vibe setup-workspace 时才创建。 |
它永远不做的事
- 不动其他项目目录,除非你从那个项目内显式跑
vibe setup-workspace。 - 不读你项目的
.env或.env.local。工具凭证在~/.config/vibe/env,项目环境是你的。 - 不跑
sudo。安装器只打印需要 sudo 的一两条命令然后停下。 - L3 关掉时(默认)任何数据都不外发。
- 限额 modal 永不自动选付费选项,只选 "Stop and wait",绝不碰 "Switch to usage credits" 或 "Upgrade your plan"。
文档
- AGENTS.md:架构、贡献指南、spec-first 工作流。
- docs/architecture.md:完整数据流图。
- docs/design/:每个 feature 一个已接受的设计文档。