claude-wake was written to be safe to run unattended and was adversarially reviewed (security / cross-platform / correctness) before its first release. This document states the trust model plainly, including the residual risks the code does not try to defend against, so you can make an informed decision.
- No network. It makes zero network requests, contains no
eval/new Function, and every process it spawns is a fixed system binary (open,osacompile,launchctl,xdotool,xclip,powershell.exe, …). Nothing attacker-named is ever executed. - Zero runtime dependencies. The published package is the code you read.
The text it pastes is always the static message from your config — it can
never be derived from transcript or web content. A limit event is detected
only from top-level fields of a transcript line (isApiErrorMessage,
error/apiErrorStatus, sessionId); conversation content (including a
webpage you summarize) lives in a nested JSON string and cannot forge those
fields or fabricate a new transcript line. So a malicious page cannot make
claude-wake paste attacker-controlled text into your agent.
claude-wake trusts two directories as belonging to you:
~/.claude/projects/**— Claude Code's own transcripts (the detection input)~/.claude-wake/**— its own state, logs, config, and (macOS)KeySender.app
Anything that can already write files as your user is out of scope — it can
tamper with your shell, your editor, and your credentials regardless of this
tool. Keep both directories owner-only (~/.claude-wake is created 0700).
Two residual amplifications worth naming, for a local same-user attacker (i.e. already past the boundary above):
- Planted transcript → forced submit. Someone who can write a
<uuid>.jsonlunder~/.claude/projectscan name a real open panel's session id and a reset time of "now", causing claude-wake to focus that panel and pastemessage+ Enter — i.e. force-submit that panel's current input at a chosen time. The pasted text is still your staticmessage(unless they also rewrite yourconfig.json). - KeySender.app is a TCC-privileged helper (macOS). It holds the
Accessibility grant so the background daemon can paste. A same-user process
that writes
~/.claude-wake/send-request.txtand launches the app could borrow that grant to paste clipboard text + Enter into VS Code (only — the target editor's bundle id is compiled into the app and verified). The real containment is the0700directory; treat its contents as security-sensitive.
Neither is remotely exploitable and neither grants arbitrary-app or arbitrary-keystroke control — they are honest notes about what a local attacker who is already inside the boundary could amplify.
- Session ids are validated against a strict UUID pattern before any use; the
message crosses process boundaries via stdin / a
0600request file, never a shell string; URIs are built from validated ids + a scheme allow-shape (dangerous schemes likefile/javascriptare refused). - A resume message with a leading
/or@is neutralized so it can never be submitted as a slash-command or file-mention; message length is capped. - Keystrokes are sent only after verifying the target is frontmost (macOS
bundle id / X11 title suffix / Windows foreground PID). Wayland can't be
verified and is refused unless you set
allowUnverifiedPaste: true. - The clipboard is written only after that verification passes.
Found something? Please open a GitHub issue (or, for anything sensitive, mark it as such and we'll coordinate privately).