grep "rm -rf" src/
Searching for a string isn't running it. Search tools without an action flag are suppressed.
ranwhat watch
ranwhat watch reads what Claude Code and twenty-nine other coding agents have already written to disk, the audit trail they keep anyway, and reports the sixteen kinds of action worth a second look. It changes nothing.
This isn't antivirus. There's no adversary and no signature, because you asked the agent to do things. So it doesn't guess whether an action was allowed. It raises the ones you'd want to know about either way.
| Rule | Severity | Why it's on the list |
|---|---|---|
Credential access.env · ~/.aws/credentials · id_rsa |
Critical | Read a file whose only purpose is holding secrets. The contents are now in a context you don't control, and in the transcript too: find and mask them with ranwhat clean. Then block the next read. |
Secret-shaped string in a tool callsk_live_… · ghp_… · AKIA… |
Critical | A credential-shaped value appeared verbatim in a tool call. Even if the call was benign, the value is now in the transcript. |
Package or release publishednpm publish · twine upload · docker push |
Critical | Something reached a registry other people install from. Supply-chain reach, usually irreversible. |
Cloud resource destroyed or modifiedterraform destroy · kubectl delete · aws iam attach-… |
Critical | A write or delete against live infrastructure, including IAM changes, terraform apply -auto-approve and DROP TABLE. |
Financial API calledstripe charges · refunds |
Critical | With a live key, each of these moves real money. |
Log or history tamperinghistory -c · cloudtrail stop |
Critical | An action whose effect is removing the record of other actions. |
Cloud instance credentials requested169.254.169.254/…/security-credentials · …/service-accounts/default/token |
Critical | A request to a cloud metadata service for the role the machine runs as, on AWS, GCP, Azure, Alibaba or Oracle. The short-lived token that comes back is in the transcript, ready to use, and grants whatever the role can. A plain metadata read, an instance id or a region, is not reported. |
Destructive gitpush --force · reset --hard |
High | History rewriting. The class of action that destroys the record of what else happened. |
Recursive deletionrm -rf · find -delete |
High | Recoverable only if something else was backing it up. Severity follows the target: rm -rf build is not reported, rm -rf ~/Documents is high, rm -rf "$HOME" is critical. |
Local file sent to the networkcurl -d @file · curl -F file=@… |
High | File contents sent outbound in one command. That shape, whatever the intent. |
Downloaded script run unreadcurl … | sh · bash <(curl …) |
High | A script fetched from the network and handed straight to a shell or interpreter. Whatever the server sent at that moment ran with your permissions, and nothing on disk shows what it was. Saving it to a file and running it in a later call is two calls, and is not reported. |
Files made writable by every userchmod -R 777 · chmod o+w |
High | Severity follows the reach: chmod -R 777 / or ~ is critical, a recursive change is high, one file or directory is medium, and a scratch path under /tmp is not reported. chmod 755 and +x never are. |
Container data wipeddocker system prune -a · docker volume rm |
High | Volumes, or every container, removed: docker system prune --all or --volumes, volume rm or prune, compose down -v. A plain prune, or one named container, is not reported. |
Decoded command runbase64 -d | sh · eval "$(… | base64 -d)" |
High | A command hidden in base64, hex or printf escapes and handed straight to a shell, eval or an interpreter, so the agent's own text shows only the encoding. watch decodes what it can without running it and judges the result by the other rules: an encoded rm -rf ~ is reported as that deletion too. Decoding to a file or to read it (base64 -d > key.pem, | jq) is not reported. |
Startup or scheduled job installedcrontab - · launchctl load · schtasks /create |
High | Something set to run again on its own, at login, at boot or on a schedule, with your permissions, after the session has ended: a crontab, a launch agent, a systemd unit, a Windows service, a Run key. A change to a shell startup file is medium: an export PATH line appended to ~/.zshrc is medium, one that runs curl … | sh in every new shell is high. A packaged service enabled by name (systemctl enable docker) is medium. |
Agent guardrails loosened--dangerously-skip-permissions · bypassPermissions · ranwhat hook uninstall |
High | An agent changed what it, or another agent, may do without asking you: one launched with its approvals off, a broad allow rule added, a deny rule taken out. Critical when it switches off the hook itself, every hook, or every prompt in your user settings, so the hook asks before a call that shows its own removal. A settings file rewritten whole with other settings, by a call that does not show what it replaced, is medium. So is an MCP server or a hook added. |
watch looks back over history after the fact, so it is not live monitoring of Claude Code or any other agent, and it blocks nothing. To have a call these rules rate high or critical wait for your yes before Claude Code runs it, install the opt-in hook. For a record kept while the agent works, add a hook or OpenTelemetry, as the Claude Code audit log guide shows.
So three things that look dangerous are not treated as actions. The first watch build, run on a real machine's history, flagged 6 findings, and these were the 3 false positives among them.
Searching for a string isn't running it. Search tools without an action flag are suppressed.
The payload is Python source. bash -c is the exception: that really is shell, so it recurses in.
A heredoc body is data being written. Writing a script that contains a command isn't running it.
No wrapper, no proxy, nothing in your critical path unless you install the hook. It reads what each agent already wrote to disk, all of them by default.
| Agent | Location | Format | Status |
|---|---|---|---|
| Claude Code | ~/.claude/projects/*/*.jsonl, and each session's subagents/ ($CLAUDE_CONFIG_DIR) |
JSONL | Shipped |
| Codex | ~/.codex/sessions/ and archived_sessions/ ($CODEX_HOME); its prompt history, shell snapshots and thread index searched for secrets |
JSONL; SQLite read only; .jsonl.zst read only, on Python 3.14 or with the zstd command |
Shipped |
| Gemini CLI | ~/.gemini/tmp/<project>/chats/ ($GEMINI_CLI_HOME) |
JSONL, JSON | Shipped |
| Antigravity | ~/.gemini/antigravity-cli/brain/, and the same under antigravity and antigravity-ide |
JSONL | Shipped |
| GitHub Copilot CLI | ~/.copilot/session-state/<session>/events.jsonl ($COPILOT_HOME) |
JSONL | Shipped |
| GitHub Copilot in VS Code | <editor>/User/workspaceStorage/<workspace>/chatSessions/ and globalStorage/emptyWindowChatSessions/ ($VSCODE_PORTABLE, $VSCODE_APPDATA) |
JSONL, JSON | Shipped |
| Cursor | The editor's Cursor/User/globalStorage/state.vscdb, and ~/.cursor/chats/ for cursor-agent |
SQLite | Shipped, secrets read-only |
| Windsurf | ~/.windsurf/transcripts/, written when Windsurf's post_cascade_response_with_transcript hook is on |
JSONL; Cascade's own history is encrypted and not read | Shipped |
| Cline | The editor's globalStorage/saoudrizwan.claude-dev/tasks/, and ~/.cline/data ($CLINE_DATA_DIR) |
JSON | Shipped |
| Roo Code | The editor's globalStorage/rooveterinaryinc.roo-cline/tasks/ |
JSON, text | Shipped |
| Kilo Code | ~/.local/share/kilo/kilo.db and the older storage/ JSON files ($XDG_DATA_HOME/kilo, $KILO_DB) |
SQLite, read only; JSON | Shipped |
| OpenCode | ~/.local/share/opencode/ ($XDG_DATA_HOME/opencode, $OPENCODE_DB) |
SQLite, read only; older JSON files | Shipped |
| Continue | ~/.continue/sessions/ ($CONTINUE_GLOBAL_DIR) |
JSON | Shipped |
| Aider | .aider.chat.history.md in the repository ranwhat runs in, and in your home folder ($AIDER_CHAT_HISTORY_FILE) |
Text | Shipped |
| Goose | ~/.local/share/goose/sessions/ ($GOOSE_PATH_ROOT) |
SQLite, read only; older JSONL | Shipped |
| Zed | ~/.local/share/zed/threads/threads.db ($XDG_DATA_HOME/zed) |
SQLite, read only | Shipped, secrets read-only |
| Warp | ~/.local/state/warp-terminal/warp.sqlite ($XDG_STATE_HOME) |
SQLite | Shipped, secrets read-only |
| Amazon Q | ~/.aws/amazonq/history/chat-history-*.json for the IDE plugins, and the CLI's data.sqlite3 under ~/.local/share/amazon-q ($XDG_DATA_HOME) |
JSON, read only; SQLite, read only | Shipped, secrets read-only |
| Qwen Code | ~/.qwen/projects/<project>/chats/, and older tmp/<hash>/chats/ ($QWEN_RUNTIME_DIR, $QWEN_HOME) |
JSONL, JSON | Shipped |
| CodeBuddy | ~/.codebuddy/projects/ ($CODEBUDDY_CONFIG_DIR) |
JSONL | Shipped |
| Grok Build | ~/.grok/sessions/<folder>/<session>/updates.jsonl ($GROK_HOME) |
JSONL | Shipped |
| Droid | ~/.factory/sessions/ ($FACTORY_HOME_OVERRIDE) |
JSONL | Shipped |
| Kimi Code | ~/.kimi-code/sessions/ ($KIMI_CODE_HOME) |
JSONL | Shipped |
| Kimi CLI | ~/.kimi/sessions/ ($KIMI_SHARE_DIR) |
JSONL | Shipped |
| Pi | ~/.pi/agent/sessions/ ($PI_CODING_AGENT_DIR) |
JSONL | Shipped |
| Oh My Pi | ~/.omp/agent/sessions/ ($PI_CODING_AGENT_DIR, $PI_CONFIG_DIR, $XDG_DATA_HOME/omp) |
JSONL | Shipped |
| Muse Code | ~/.local/share/muse/sessions/ ($XDG_DATA_HOME/muse) |
JSONL | Shipped |
| Mistral Vibe | ~/.vibe/logs/session/ ($VIBE_HOME) |
JSON, JSONL; unified sessions read only | Shipped |
| DeepSeek Harness | ~/.dsh/sessions/ ($DSH_HOME) |
JSONL, compressed ones read only | Shipped |
| OpenClaw | $OPENCLAW_STATE_DIR/agents/*/agent/openclaw-agent.sqlite (default ~/.openclaw) |
SQLite, tool calls found by shape; compressed events and cold archives not read yet | Shipped, secrets read-only |
| Meta Muse | Meta's cloud | Nothing on your machine | Cloud only |
| Grok Bot | xAI's cloud | Nothing on your machine | Cloud only |
| Amp | ampcode.com, for the current Amp |
Nothing on your machine | Cloud only |
Each agent is read from where it keeps its history, and the variable in brackets moves it for ranwhat as it moves it for the agent. --source ID reads one agent, --path ID=PATH reads one from elsewhere, and ranwhat sources lists where it looked and what it found.
Databases and compressed files are only ever read. Cursor, Zed, Warp and OpenClaw keep their history in SQLite, so clean finds their secrets but cannot mask them there; the same goes for both of Amazon Q's stores, the databases Kilo Code, OpenCode and Goose keep, and Mistral Vibe's unified sessions and DeepSeek Harness's compressed ones. Windsurf keeps Cascade's own history encrypted, so ranwhat counts those files and reads the plaintext transcripts Windsurf's hook writes instead. Not read yet: the large tool outputs Claude Code stores in <session>/tool-results/, and ~/.claude/history.jsonl. Where Claude Code keeps your history lists the files a session leaves behind.
Meta Muse, Grok Bot and the current Amp keep their history in their vendor's cloud, so there is nothing on your machine to read. Muse Code and Grok Build, Meta's and xAI's coding CLIs, are read.
ranwhat watch --json prints one record per flagged call.