Session & History

Every superclaw run is recorded to a JSONL file. Sessions are inspectable, auditable, and queryable with standard tools like jq.

Where sessions are stored

Sessions are appended to .superclaw/runs.jsonl in the working directory (or /data/.superclaw/runs.jsonl in Docker). One JSON object per line, one line per run.

📁.superclaw/
📄runs.jsonl — append-only run history
📄config.lock — resolved config for the last run

The .superclaw/ directory is created automatically on the first run. Add it to .gitignore if you do not want session history committed.

Session schema

Each line in runs.jsonl is a complete JSON object with the following structure:

json
1{2  "id": "01HZ3K8XQVN5YWBR4PSTJ7MEA",3  "version": "0.3.0",4  "started_at": "2025-11-14T09:31:02Z",5  "finished_at": "2025-11-14T09:31:09Z",6  "duration_ms": 7142,7  "status": "done",8  "task": "read the README and write a summary to summary.md",9  "model": "claude-opus-4-5",10  "skills": ["summarize"],11  "steps": 2,12  "steps_limit": 20,13  "tokens_used": 1284,14  "tool_calls": [15    {16      "step": 1,17      "tool": "read_file",18      "input": { "path": "README.md" },19      "output_bytes": 2142,20      "duration_ms": 3,21      "error": null22    },23    {24      "step": 2,25      "tool": "write_file",26      "input": { "path": "summary.md" },27      "output_bytes": 847,28      "duration_ms": 2,29      "error": null30    }31  ],32  "result": "Summary written to summary.md (847 bytes, 3 sections).",33  "error": null34}
FieldTypeDescription
idstringULID — lexicographically sortable by creation time.
versionstringsuperclaw version that produced this run.
started_atRFC3339Run start time (UTC).
finished_atRFC3339Run end time (UTC).
duration_msintegerTotal wall-clock duration in milliseconds.
statusstringOne of: done, error, timeout, budget_exceeded.
taskstringThe task string passed at invocation.
modelstringThe model ID used.
skills[]stringSkills that were active during the run.
stepsintegerNumber of tool-call rounds executed.
steps_limitintegerThe max_steps value in effect.
tokens_usedintegerTotal output tokens consumed.
tool_calls[]objectOrdered list of tool calls with input, output size, duration, and error.
resultstring|nullThe final text response from the model, or null if aborted.
errorstring|nullError message if status != done, otherwise null.

Status values

done

The model returned a final response with no pending tool calls. The task completed normally.

error

The run terminated due to an unrecoverable error — API failure after retries, filesystem permission error, or invalid tool call.

timeout

The run exceeded timeout_seconds. The current tool call was interrupted and the session was closed.

budget_exceeded

The run hit max_steps or max_fetch_calls before the model returned a final response.

Timeout run example

json
{
  "id": "01HZ3K9YQVN5YWBR4PSTJ8MEA",
  "version": "0.3.0",
  "started_at": "2025-11-14T10:02:11Z",
  "finished_at": "2025-11-14T10:04:11Z",
  "duration_ms": 120003,
  "status": "timeout",
  "task": "scan all files and generate a full test suite",
  "model": "claude-opus-4-5",
  "skills": ["coding"],
  "steps": 14,
  "steps_limit": 20,
  "tokens_used": 18432,
  "tool_calls": [...],
  "result": null,
  "error": "run exceeded timeout of 120s"
}

Querying history with jq

Because runs.jsonl is standard JSONL, you can use jq to slice and inspect it:

bash
# Show all run IDs and statuses
jq -r '[.id, .status] | @tsv' .superclaw/runs.jsonl

# Count runs by status
jq -r '.status' .superclaw/runs.jsonl | sort | uniq -c

# Show only failed runs
jq 'select(.status != "done")' .superclaw/runs.jsonl

# Show tool usage frequency across all runs
jq -r '.tool_calls[].tool' .superclaw/runs.jsonl | sort | uniq -c | sort -rn

# Show average steps per run
jq '.steps' .superclaw/runs.jsonl | awk '{s+=$1; n++} END {print s/n " avg steps"}'

# Get the last 5 runs
tail -n 5 .superclaw/runs.jsonl | jq '{id, status, task, steps, duration_ms}'

Retention policy

By default, superclaw retains all runs indefinitely. You can configure automatic pruning in superclaw.json:

superclaw.jsonjson
{
  "history": {
    "max_runs": 500,
    "max_age_days": 30
  }
}
FieldDefaultDescription
history.max_runsunlimitedPrune oldest runs when this count is exceeded.
history.max_age_daysunlimitedRemove runs older than this many days.

Pruning runs at the start of each new run. It compacts the runs.jsonl file in-place, so the file size stays bounded over long-running deployments.