vibe-coding-auto-resume

Auto-resume claude after rate-limit resets.

English · 中文 · Français · Русский

The problem

Claude Code's 5-hour and weekly limits interrupt long agentic loops. SSH disconnects kill the session. You wake up to find a half-finished task and a stale terminal.

What it does

Install (one time)

git clone https://github.com/zhihuiyuze/vibe-coding-auto-resume.git ~/vibe
cd ~/vibe
./install.sh
source ~/.bashrc

Idempotent. Symlinks tools to ~/.local/bin/, adds a vibe shell function, appends a tmux snippet. Never touches ~/.claude/; never runs sudo on your behalf.

Three scenarios — pick the one that matches you

1. I'm starting a new Claude task

cd ~/dev/<your-project>
vibe work                  # cd here + open a named tmux session
vibe run                   # replaces `claude` — same flags, same UI

Use Claude normally. When the 5-hour block is exhausted, vibe run sleeps until the reset and relaunches the same session UUID automatically. Anthropic's new interactive limit modal (What do you want to do? 1. Stop and wait …) is auto-handled — only the safe "Stop and wait" option is ever picked.

Detach: Ctrl+b d. Come back: vibe work.

2. I want to resume a session I started earlier

If you remember the session UUID:

cd ~/dev/<your-project>
vibe work
vibe run --resume <session-uuid>

If you don't, but it's the most recent in that project:

vibe run --mode continue                    # like `claude --continue`, with auto-resume

List candidates from JSONL filenames:

ls -t ~/.claude/projects/$(pwd | sed 's|/|-|g')/*.jsonl | head -5
# filename minus `.jsonl` = session UUID

3. SSH dropped — how do I check it's still running and reconnect?

tmux owns the process, your shell does not. SSH dies, the session lives. Step-by-step:

ssh you@server                              # 1. reconnect
tmux ls                                     # 2. is the vibe-* session still there?
                                            #    expected: e.g. "vibe-default: 1 windows (...)"
vibe work                                   # 3. re-attach (or `vibe work <name>` if you named it)
                                            #    you land exactly where you left off

Once back in, scroll up to see what happened while you were gone: Ctrl+b [, then PageUp / arrows, q to exit. If a rate limit hit, the wrapper already handled it — you'll see [vibe-run] Sleeping … until … and the resume in scrollback.

Peek without attaching (e.g. from another machine, just checking status):

ssh you@server "tmux ls"
ssh you@server "tmux capture-pane -t vibe-default -p | tail -50"
ssh you@server "vibe status"

If tmux ls says no server running, the host rebooted or tmux was OOM-killed. The tmux session is gone but Claude's JSONL log isn't — use Scenario 2 above to resume.

Discover & juggle sessions

vibe ls shows every vibe-* tmux session with its cwd, attached state, and a ← here mark when the cwd matches yours:

$ 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 without arguments now uses this discovery before defaulting to the cwd-hash name:

Explicit vibe work <name> skips discovery — the name always wins. For projects you'll revisit often, give an explicit name (vibe work projectA) so the session survives path renames and is recognizable in vibe ls.

Optional: smarter detection via LLM

L1 (JSONL parsing) and L2 (tmux pane regex) cover common rate-limit shapes with zero external calls. To handle TUI wording changes and extract reset times the regex misses, opt into L3:

echo 'DEEPSEEK_API_KEY=sk-...' >> ~/.config/vibe/env   # chmod 600, created by installer
chmod 600 ~/.config/vibe/env
source ~/.bashrc

Providers: DeepSeek (~$0.05/block), Anthropic Claude Haiku, OpenAI gpt-4o-mini, Ollama (local, [untested]). With L3 off (default until you add a key), nothing leaves your machine.

How detection works

When claude exits, three signals decide what happened:

LayerReadsWhen it shines
L1~/.claude/projects/<cwd>/*.jsonl — Claude's own logAlways on. Tracks token usage and block start/end.
L2tmux capture-pane + scrollbackVisible rate-limit message in the main pane.
L2.5JSONL tail text scanSubagent rate-limit messages that scrolled out of the visible pane.
L3LLM classifier (DeepSeek / Claude Haiku / OpenAI / Ollama)Opt-in. Robust to wording changes; extracts reset time semantically.

L1 and L2/L2.5 cost zero externally. L3 is opt-in and costs about $0.05/block with DeepSeek.

CLI flags

vibe run [...args]
  --resume <uuid>        resume a specific session (passed once, used for all cycles)
  --threshold <0..1>     opt-in soft cap (default off — burn the block)
  --max-cycles <n>       resume cycles per invocation (0 = unlimited, default 1)
  --mode auto|session-id|continue
  --provider deepseek|claude|openai|ollama
  --no-l3                force L1+L2 only
  --dangerously-skip-permissions
  -p "prompt"
  ... any other flag passes straight to claude

Configuration

WhereWhat
~/.config/vibe/envLLM keys + tunables (chmod 600). Sourced by the bashrc marker block with set -a.
~/.local/state/vibe/<name>/Per-session UUID cache. Isolated between vibe work foo and vibe work bar.
<your-project>/HANDOFF.mdCross-session continuity file. Created only when you run vibe setup-workspace from inside that project.

What it never does

Docs