CloudCodeTree LogoCloudCodeTree
AI NewsTutorialsAbout
CloudCodeTree Logo
CloudCodeTree
  • AI News
  • Tutorials
  • About
← Back to AI News
What Did Claude Actually Do? Auditing Unattended Runs With JSONL Session Logs

What Did Claude Actually Do? Auditing Unattended Runs With JSONL Session Logs

Chris Harper

2 min read

Aug 6, 2026 · 20:04 UTC

AI
Workflow
Claude Code
Best Practices

Claude Code writes every tool call to JSONL logs in ~/.claude/projects/. One PostToolUse hook or three open-source tools turn those logs into a full audit trail for any background run.

When Claude Code finishes a background task — a cron-triggered publish run, a CI pipeline, an overnight refactor — you want to know: which files did it touch? Which commands did it run? The answer lives in ~/.claude/.

Where the logs are

Claude Code writes session transcripts to:

~/.claude/projects/<url-encoded-project-path>/<session-id>.jsonl

Each .jsonl file is one session, one JSON object per line, appended as the session runs. Crash-safe: a mid-session abort leaves a valid truncated file.

Each line is one event. Tool events look like:

{"type":"tool_use","id":"toolu_01XYZ","name":"Write","input":{"file_path":"/project/src/foo.ts","content":"..."}}
{"type":"tool_result","tool_use_id":"toolu_01XYZ","content":[{"type":"text","text":"File written"}]}

Quick audit with jq

# All files written in the last session
cd ~/.claude/projects
LATEST=$(ls -t */*.jsonl | head -1)
jq -r 'select(.type == "tool_use" and .name == "Write") | .input.file_path' "$LATEST"

# All bash commands run
jq -r 'select(.type == "tool_use" and .name == "Bash") | .input.command' "$LATEST"

# Token spend per turn
jq 'select(.usage != null) | .usage' "$LATEST"

Real-time audit hook (PostToolUse)

Add this to .claude/settings.json to log every tool call as it happens — no after-the-fact parsing:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": ".*",
        "hooks": [{
          "type": "command",
          "command": "jq -c '{ts: now|todate, tool: .tool_name, input: .tool_input}' >> ~/.claude/session-logs/$(date +%Y-%m-%d).jsonl"
        }]
      }
    ]
  }
}

This produces one JSON line per tool call in ~/.claude/session-logs/YYYY-MM-DD.jsonl:

{"ts":"2026-08-06T20:00:00Z","tool":"Write","input":{"file_path":"/project/content/feed.xml"}}
{"ts":"2026-08-06T20:00:01Z","tool":"Bash","input":{"command":"node scripts/ingest-feed.mjs"}}

Graphical viewers

  • claude-code-trace — TUI/web/desktop viewer. Browse sessions, inspect tool call trees, live-tail an active session. npx @delexw/claude-code-trace
  • cc-audit-log — scans all sessions under ~/.claude/projects/, classifies actions (file writes, edits, git, bash), outputs a human-readable timeline. npx cc-audit-log
  • claude-code-log — converts a JSONL transcript to readable HTML or Markdown for sharing a session trace with your team.

For teams running Claude Code in CI or as a scheduled background agent, the PostToolUse hook is a five-minute change that pays off the first time something unexpected happens.

Sources: How to See Everything Claude Code Does — DEV Community · claude-code-trace — GitHub · cc-audit-log — GitHub · Claude Code JSONL format — claude-dev.tools