documentation

Settings and guards

Every key in ~/.unsnooze/config.json, the guards that decide when not to wake a session, and how you get told about it.

Settings

unsnooze setup writes ~/.unsnooze/config.json; change anything later with unsnooze config set <key> <value>. The full surface, with defaults:

keydefaultmeaning
multiplexerautoauto, tmux, or zellij. Auto prefers the multiplexer you're inside, then the only installed backend, tmux as tie-breaker.
autoResumetrueMaster switch. Off = stops are still tracked, but nothing resumes until resume-now or turning it back on.
menuAutoAnswertrueMay unsnooze answer Claude's limit menu (send keys in your pane)? Off = watch-only.
notificationstrueMaster switch for all notifications. Off silences every channel.
notifyChannelautoauto, native, osc, or bell — see Notifications.
guiWatchtrueMay the daemon watch session files for GUI-surface stops? Needs the daemon running.
resumeMessage"Continue where you left off…"The message typed to wake a session. Override per session with unsnooze message <id>.
resumeMessages.<agent>""Per-agent override of resumeMessage (.claude, .codex, .grok, .qwen, .kimi, .opencode, .agy). Empty = global message.
agents.claude / agents.codextrueWhich CLIs are guarded.
agents.grokagents.agyfalseExperimental adapters — off by default; enable in setup or e.g. config set agents.qwen on.
workspaceGuardinformRepo changed while a session slept? inform wakes it with a heads-up; pause holds it; off disables. See Guards.
contextGuardinformBig cold context at wake? inform resumes and notifies; pause holds sessions above the threshold; off disables. Claude Code only for now.
contextGuardTokens100000Context-size threshold (tokens) for contextGuard.
usageWarnnotifyPre-wall usage warnings from the daemon: notify or off.
usageWarnAt80,95Percent thresholds for usage warnings. Non-numeric values fall back to the default — never silently disable.
mousetrueMouse support in the dashboard; toggle live with m. Hold Shift (Option in iTerm2) to select text.
reapResumedfalseOpt-in: auto-close resumed panes idle longer than reapIdleAfter.
reapIdleAfter604800000 (7d)Idle age (ms) before an opt-in auto-reap closes a resumed pane.
updateChecktrueDaily new-version check — a plain GET to the npm registry, nothing identifying.
ntfyTopic / ntfyServer / ntfyToken / ntfyPrivacy"" / ntfy.sh / "" / fullPhone push via ntfy — off until a topic is set. See Notifications.
remoteQueuetrueSet on the host being controlled: may other hosts queue prompts on this one (prompt add --host <this>)? Off = the queue verbs answer a typed disabled instead of silently dropping. See Queued prompts.

Every setting also has an UNSNOOZE_* environment override (src/settings.js), and timings/paths are tunable via UNSNOOZE_* vars (src/config.js).

Multiplexer session names

Interactive launches own the base session name (default unsnooze); a second concurrent terminal takes unsnooze-2, and so on. The resumer daemon may join a live session but only ever creates unsnooze-resumed — a revived agent never steals the interactive name. Override with UNSNOOZE_SESSION_NAME and UNSNOOZE_RESUME_SESSION; attach with e.g. tmux attach -t unsnooze-resumed.

Guards

workspaceGuard — the repo changed while it slept

The repo's HEAD and dirty state are fingerprinted at stop time and re-checked at wake. inform (default) resumes with a heads-up appended to the wake message — "Heads up: this workspace changed while the session was stopped (HEAD abc1234 → def5678). Re-read the current state of the repo before continuing." — while pause holds the session and resume-now shows the diff stat first; off disables.

contextGuard — the cold-cache wake tax

Providers cache your session's context, but that cache lives minutes, not hours. After a long limit stop, the first wake message — unsnooze's or a hand-typed "continue", identical cost — re-reads the entire conversation at full uncached price. A ~150k-token session can eat a real slice of the fresh window the moment it wakes.

unsnooze estimates the size from the session transcript (shown as ctx ~152k tok in status). inform resumes and notifies you of the price; pause holds sessions above contextGuardTokens (default 100k) for a manual resume-now. What actually helps: /compact before the wall, and lean overnight sessions.

Overload is not a limit

Transient 5xx/529/429 errors take a seconds-scale backoff path ([30, 60, 120, 240, 300]s ± jitter) and never enter the ledger.

Notifications

On limit-hit, resumed, and gave-up, unsnooze alerts you via the channel set in notifyChannel:

channelbehavior
autoOSC (when the terminal supports it) plus BEL on the pane tty; falls back to native only if OSC delivered nothing. No pane / non-tmux mux → native.
nativeOS toast — macOS osascript, Linux notify-send, WSL/Windows PowerShell toast.
oscForce OSC to attached client ttys; native if zero deliveries.
bellBEL to the pane tty; native if undeliverable.

OSC support: iTerm2, kitty, WezTerm, Ghostty, and Warp get OSC 9; rxvt gets OSC 777; Apple Terminal, VS Code, Alacritty, and Zed are denylisted (native is used instead). OSC/BEL need tmux's client/pane tty APIs — under Zellij, notifications fall back to native.

Phone push via ntfy

ntfy
$ unsnooze config set ntfyTopic "unsnooze-$(openssl rand -hex 8)"
$ unsnooze config set ntfyPrivacy terse   # keep paths out of push bodies

⚠ ntfy.sh topics are public — the name is the password. Use an unguessable topic like the generated one above, a tk_… access token (ntfyToken), or a self-hosted server (ntfyServer). Pushes fire alongside the local channel.