documentation

Supported agents

How each agent's limit stop is detected, where the reset time comes from, and how a session whose process is gone gets revived. Claude Code and Codex are on by default; the rest are experimental and enabled in unsnooze setup.

Agents

Claude Code

Two channels: the StopFailure hook (authoritative, carries the session id) plus pane scraping for banners and the interactive limit menu, which is always answered with "Stop and wait for limit to reset" — never a blind Enter. Dead sessions revive via claude --resume <id>.

OpenAI Codex CLI

Scrape-based, since Codex fires no event on limits, plus the rollout files under ~/.codex/sessions/. unsnooze matches the exact ■ You've hit your usage limit … banner strings from the Codex source and parses try again at 3:51 PM, Feb 23rd, 2026 9:01 PM and in 4 days 20 hours 9 minutes. Dead sessions revive via codex resume <id> "<message>" — the prompt travels in argv.

Grok Build (xAI) — experimental

The hook channel works (Grok reads Claude-compatible hooks, including StopFailure). Its limit banner is not publicly documented, so pane detection uses generic patterns with a safe fallback.

Qwen Code — experimental

A Claude-shaped StopFailure hook installed into ~/.qwen/settings.json (fires with error: rate_limit) plus scraping for the quota renders: Qwen OAuth quota exceeded, Coding Plan Allocated quota exceeded, and OpenRouter Rate limit exceeded: limit_… passthroughs. Qwen never shows a reset time, so waits use the 5-hour fallback and self-correct on verify. Dead sessions revive via qwen --resume <id>, with ids from the *.runtime.json sidecars qwen writes for exactly this.

Kimi CLI (Moonshot) — experimental

Kimi retries a 429 three times within seconds, then stops with a red LLM provider error: Error code: 429 … rate_limit_reached_error line — that is the detection anchor. The 429 carries no reset time (5-hour fallback plus verify). Dead sessions revive via kimi -r <id> -p "<message>"; because kimi silently starts a new session for an unknown id, the id is checked on disk first, with --continue otherwise. Membership expired (402) only notifies.

OpenCode — experimental

OpenCode retries rate limits itself, forever, honoring retry-after — it will sleep hours, showing Rate Limited [retrying in 2h5m attempt #4]. So unsnooze records the stop but never touches a live self-retrying pane; its job is reviving sessions whose process died mid-wait (laptop slept, tmux gone) via opencode -s <ses_id>, with the reset parsed from the countdown. Zen plan banners (5 hour/weekly/monthly usage limit reached…) and OpenRouter passthroughs are detected too; insufficient credits (402) only notifies.

Antigravity CLI (Google, agy) — experimental

The Gemini CLI successor. Scrapes the quota strings (Individual quota reached … Resets in 2h52m46s, Model quota limit exceeded, Refreshes in 6 days and 18 hours — a multi-day reset is the weekly cap, anything shorter the 5-hour window), rejoins a banner a narrow pane wrapped, and dates the countdown from the prompt that failed. It treats 503 MODEL_CAPACITY_EXHAUSTED as a transient overload, not a limit. Dead sessions revive via agy --conversation=<id>, with ids from ~/.gemini/antigravity-cli/history.jsonl. When a folder has more than one recent conversation, unsnooze does not guess: it wakes the live pane, and falls back to --continue if that pane is gone.

Cursor CLI (cursor-agent) — experimental

The only agent whose limit is not waitable: Cursor's included usage resets on your monthly billing cycle, not a rolling window. So unsnooze never schedules a wake for it. The stop is a model limit that probes every 15/30/60 minutes and resumes the moment the banner clears — you switch to Auto, enable on-demand, or the cycle rolls. Transport errors take the transient-overload path and Authentication required only notifies. Dead sessions revive via cursor-agent --resume=<id>, with ids from ~/.cursor/chats/<md5 of cwd>/<chatId>/meta.json (each checked against its recorded cwd), and --continue otherwise.

The wrapper shadows cursor-agent only. The bare cursor command is the IDE launcher and is never touched; the newer agent alias is too generic a name to shadow safely.

Missed a banner? The experimental adapters, Grok and Antigravity especially, are closed source. Run unsnooze report [agent] and paste the capture into an issue — that is how they get better.

OpenRouter and proxy launchers

OpenRouter is not a separate agent. Its 429 bodies (Rate limit exceeded: limit_rpd/…, free-models-per-day) are detected inside the CLIs that use it (OpenCode, Qwen Code). Credit exhaustion (402) is a notification — there is no reset to wait for, only a top-up.

Headroom and other proxy launchers. headroom wrap claude and headroom wrap codex launch the real executable directly, bypassing unsnooze's shell wrapper, so no same-pane monitor is attached. The Claude hook can still record stops, as can the session-file watcher while the daemon, guiWatch and that agent are enabled. For full pane monitoring, use Headroom's provider-scope routing and start claude / codex normally, so unsnooze stays the outer launcher. With Headroom v0.34:

headroom
$ headroom install apply --scope provider --providers manual --target claude --target codex

Claude Design

Claude Design shares your 5-hour and weekly limits with chat, Cowork and Claude Code, so a long design run stops the same way and unsnooze resumes it the same way. Of its three surfaces — the claude.ai/design canvas, the Claude Desktop sidebar, and an official MCP server driven by Claude Code — unsnooze supports the MCP server:

claude design
$ unsnooze design setup     # registers the claude-design MCP server
# then, inside Claude Code:
/design-login
$ unsnooze design           # confirms it is registered and signed in

# give long design runs room to compact rather than stall
$ unsnooze config set launchExtraArgs.claude "--autocompact 400000"

unsnooze does not automate the web canvas, and will not. Anthropic's Consumer Terms bar accessing Claude "through automated or non-human means", and accounts have been terminated for it. Claude Code is the documented exemption, and that is what unsnooze drives.

  • A signed-out /design-login is not a usage limit. Waiting never clears it, so unsnooze reports it separately.
  • Design no longer has its own weekly allowance — everything draws from one shared pool, which is why unsnooze usage already counts design work.