# See the risky commands Claude Code already ran.

> Sixteen rules over the audit trail Claude Code, Codex, Gemini CLI and twenty-seven more coding agents keep: credential reads, rm -rf, force pushes, npm publish.

Canonical: https://ranwhat.com/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.

```
$ ranwhat watch --days 30
```

[Install](https://ranwhat.com/install)

## Sixteen things worth interrupting you for.

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](https://ranwhat.com/clean). Then [block the next read](https://ranwhat.com/guides/claude-code-env-secrets). |
| **Secret-shaped string in a tool call** `sk_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 published** `npm publish · twine upload · docker push` | Critical | Something reached a registry other people install from. Supply-chain reach, usually irreversible. |
| **Cloud resource destroyed or modified** `terraform 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 called** `stripe charges · refunds` | Critical | With a live key, each of these moves real money. |
| **Log or history tampering** `history -c · cloudtrail stop` | Critical | An action whose effect is removing the record of other actions. |
| **Cloud instance credentials requested** `169.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 git** `push --force · reset --hard` | High | History rewriting. The class of action that destroys the record of what else happened. |
| **Recursive deletion** `rm -rf · find -delete` | High | [Recoverable only if something else was backing it up](https://ranwhat.com/guides/claude-code-deleted-files). 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 network** `curl -d @file · curl -F file=@…` | High | File contents sent outbound in one command. That shape, whatever the intent. |
| **Downloaded script run unread** `curl … \| 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 user** `chmod -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 wiped** `docker 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 run** `base64 -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 installed** `crontab - · 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](https://ranwhat.com/commands#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](https://ranwhat.com/commands#hook). For a record kept while the agent works, add a hook or OpenTelemetry, as the [Claude Code audit log guide](https://ranwhat.com/guides/claude-code-audit-log) shows.

## A watcher that cries wolf gets muted in a day.

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.

### grep "rm -rf" src/

Searching for a string isn't running it. Search tools without an action flag are suppressed.

### python3 -c "…rm -rf…"

The payload is Python source. `bash -c` is the exception: that really is shell, so it recurses in.

### cat > f.sh <<'EOF'

A heredoc body is data being written. Writing a script that contains a command isn't running it.

- **On real history**: **A later release reported 15 findings on one machine's 90-day history.** Eleven were true deletions of build and temp directories that nobody would want to read, so deletions are now ranked by target. After that change the same history gave 4, and all four were real.
- **Evidence**: Every finding carries surrounding context. `rm -rf` on its own tells you nothing. The target is the point. A secret in it is masked: every value [clean](https://ranwhat.com/clean) finds anywhere in your history, known by an index of salted fingerprints in `~/.ranwhat/known`.
- **Test suite**: Written as invariants rather than expected output.

## Reads the agents already on your machine.

No wrapper, no proxy, nothing in your critical path unless you install the [hook](https://ranwhat.com/commands#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](https://docs.openclaw.ai/reference/database-schemas/layout) 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](https://ranwhat.com/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](https://ranwhat.com/guides/claude-code-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.

## Machine-readable, and one command for both halves.

`ranwhat watch --json` prints one record per flagged call.

- **Record**: `id`, `source`, `session`, `project`, `cwd` when the agent wrote one down, `timestamp`, `tool_name`, `tool_call_id`, `payload_hash`, `severity`, and every rule the call tripped, each with its evidence.
- **Its id**: 16 characters, the same on every run over the same history, and new for a call run again or flagged for something more. A call read twice with no time of its own is one record, with each copy's id in `ids`. The report prints it at the end of each action's line.
- **What you expected**: [`ranwhat ignore ID`](https://ranwhat.com/commands#ignore) stops listing an action you expected, and `ranwhat ignore all` every action listed now, so later runs list only what is new. Each report says how many it left out and by which line of `~/.ranwhat/ignore`, and `--no-ignore` lists them again. A secret is never left out, a critical action only by its id or a narrow entry that expires, and a change an agent makes to what ranwhat reports only once you acknowledge it.
- **Once each**: A call replayed by a resumed session is reported once, not once per transcript that carries it.
- **Both halves**: `ranwhat check` runs watch and [clean](https://ranwhat.com/clean) in one pass, and changes nothing.

## Related guides

- [Claude Code audit logthese records as a log, and a hook or OpenTelemetry from now on](https://ranwhat.com/guides/claude-code-audit-log)
- [Claude Code deleted my filesfiltering for deletions, and what rewind cannot restore](https://ranwhat.com/guides/claude-code-deleted-files)
- [AI coding agent securitythe full checklist](https://ranwhat.com/guides/ai-coding-agent-security)
