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:
| key | default | meaning |
|---|---|---|
multiplexer | auto | auto, tmux, or zellij. Auto prefers the multiplexer you're inside, then the only installed backend, tmux as tie-breaker. |
autoResume | true | Master switch. Off = stops are still tracked, but nothing resumes until resume-now or turning it back on. |
menuAutoAnswer | true | May unsnooze answer Claude's limit menu (send keys in your pane)? Off = watch-only. |
notifications | true | Master switch for all notifications. Off silences every channel. |
notifyChannel | auto | auto, native, osc, or bell — see Notifications. |
guiWatch | true | May 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.codex | true | Which CLIs are guarded. |
agents.grok … agents.agy | false | Experimental adapters — off by default; enable in setup or e.g. config set agents.qwen on. |
workspaceGuard | inform | Repo changed while a session slept? inform wakes it with a heads-up; pause holds it; off disables. See Guards. |
contextGuard | inform | Big cold context at wake? inform resumes and notifies; pause holds sessions above the threshold; off disables. Claude Code only for now. |
contextGuardTokens | 100000 | Context-size threshold (tokens) for contextGuard. |
usageWarn | notify | Pre-wall usage warnings from the daemon: notify or off. |
usageWarnAt | 80,95 | Percent thresholds for usage warnings. Non-numeric values fall back to the default — never silently disable. |
mouse | true | Mouse support in the dashboard; toggle live with m. Hold Shift (Option in iTerm2) to select text. |
reapResumed | false | Opt-in: auto-close resumed panes idle longer than reapIdleAfter. |
reapIdleAfter | 604800000 (7d) | Idle age (ms) before an opt-in auto-reap closes a resumed pane. |
updateCheck | true | Daily new-version check — a plain GET to the npm registry, nothing identifying. |
ntfyTopic / ntfyServer / ntfyToken / ntfyPrivacy | "" / ntfy.sh / "" / full | Phone push via ntfy — off until a topic is set. See Notifications. |
remoteQueue | true | Set 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:
| channel | behavior |
|---|---|
auto | OSC (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. |
native | OS toast — macOS osascript, Linux notify-send, WSL/Windows PowerShell toast. |
osc | Force OSC to attached client ttys; native if zero deliveries. |
bell | BEL 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
$ 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.