| name | bashkit-debug |
| description | Analyze BashKit agent debug traces. Use when debugging a BashKit-powered agent run — reading JSONL trace files, correlating tool calls, identifying errors, slow operations, and execution patterns. Triggers on "debug trace", "analyze trace", "bashkit debug", "what went wrong", or when reading .jsonl trace files from BASHKIT_DEBUG. |
BashKit Debug Trace Analyzer
You are analyzing execution traces from a BashKit-powered AI agent. These traces capture every tool call the agent made, with inputs, outputs, timing, errors, and parent/child relationships.
Trace Format
Traces are JSONL files (one JSON object per line) generated by BASHKIT_DEBUG=file:/path/to/trace.jsonl.
Each line is a DebugEvent:
interface DebugEvent {
id: string;
ts: number;
tool: string;
event: "start" | "end" | "error";
input?: unknown;
output?: unknown;
summary?: Record<string, unknown>;
duration_ms?: number;
parent?: string;
error?: string;
}
Event Lifecycle
Every tool call produces 2-3 events:
- start — Has
input with summarized parameters
- end — Has
output, summary, and duration_ms (success path)
- error — Has
error message (failure path, replaces end)
Correlate by id: a start event with id: "bash-3" pairs with the end or error event with the same id.
Parent/Child Relationships
The parent field links tool calls to their spawning Task tool. Example:
{"id":"task-1","tool":"task","event":"start","input":{"description":"Fix the tests"}}
{"id":"bash-5","tool":"bash","event":"start","input":{"command":"npm test"},"parent":"task-1"}
{"id":"bash-5","tool":"bash","event":"end","summary":{"exitCode":1},"duration_ms":3200,"parent":"task-1"}
{"id":"task-1","tool":"task","event":"end","summary":{"subagent":"sub-1"},"duration_ms":15000}
Events with the same parent ran inside the same sub-agent.
Tool-Specific Summary Fields
Each tool's end event includes a summary with tool-specific metrics:
| Tool | Summary Fields |
|---|
| bash | exitCode, stdoutLen, stderrLen, interrupted |
| read | type ("text"/"directory"), totalLines, returnedLines, offset (text) or count (directory) |
| write | bytes_written |
| edit | replacements |
| glob | count (number of matched files) |
| grep | Varies by mode: fileCount/total/matchCount, plus exitCode |
| task | subagent, tokens: { input, output } |
| web-search | resultCount |
| web-fetch | contentLength, responseLength |
| todo-write | total, in_progress, completed, pending (counts per status) |
| skill | skillName, instructionLength |
Tool-Specific Output Fields
The output field on end events contains the actual data the agent received:
| Tool | Output Content |
|---|
| bash | { stdout, stderr } — command output (truncated to ~4000 chars) |
| read | File content as string (text files) or directory entries |
| grep | Matched files, count entries, or content matches depending on mode |
| task | Sub-agent's final result text |
| glob | First 10 matched file paths |
| web-search | First 5 search results with titles and URLs |
Output is truncated: strings at 4000 chars, arrays at 20 items, objects at depth 5.
Analysis Playbook
When asked to analyze a trace, follow this process:
Step 1: Read the Trace File
cat /path/to/trace.jsonl
Or if large, start with a summary:
wc -l /path/to/trace.jsonl
grep '"event":"error"' /path/to/trace.jsonl
grep '"event":"end"' /path/to/trace.jsonl
Step 2: Build the Timeline
Correlate start/end pairs by id. For each tool call, extract:
- What: tool name + key input (command, file path, pattern)
- Result: success/error + key summary metric
- Time: duration_ms
- Context: parent (if inside a sub-agent)
Step 3: Identify Issues
Errors — Look for "event":"error" entries:
bash errors: check exit codes, stderr content, timeout
read errors: file not found, permission denied
edit errors: string not found, multiple occurrences
grep errors: invalid regex, ripgrep not installed
task errors: sub-agent failures, budget exceeded
Slow Operations — Flag tool calls over these thresholds:
bash: >10s (may indicate hanging command or large output)
read/write/edit: >1s (filesystem issue)
grep/glob: >5s (overly broad pattern)
task: depends on complexity, but >60s warrants investigation
web-search/web-fetch: >10s (API latency)
Patterns to Watch For:
- Repeated identical tool calls → agent is looping (check if caching is enabled)
bash with exit code != 0 followed by same command → agent retrying without fixing
edit errors "string not found" → agent has stale file content, needs to re-read
grep with 0 matches followed by broader grep → agent searching iteratively (normal)
task with high token usage → sub-agent doing too much work
- Orphaned
start events with no matching end/error → crash or timeout
- Many
read calls to the same file → missing cache, or agent re-reading after edits (normal)
Step 4: Report Findings
Structure your report as:
- Overview: Total calls, duration, error count
- Errors: Each error with context (what was attempted, why it failed)
- Performance: Slowest calls, total time breakdown by tool
- Patterns: Any concerning patterns (loops, retries, excessive calls)
- Recommendations: Specific fixes (enable caching, adjust timeouts, fix tool inputs)
Helper Script
The summarize-trace.sh script in this skill directory can pre-process large trace files:
./skills/bashkit-debug/summarize-trace.sh /path/to/trace.jsonl
This outputs a condensed timeline that's more token-efficient to analyze than the raw JSONL.
Enabling Debug Traces
Tell users to run their BashKit agent with:
BASHKIT_DEBUG=file:./trace.jsonl node my-agent.js
Other modes (less useful for post-mortem analysis):
BASHKIT_DEBUG=json — JSON lines to stderr (pipe to file: 2>trace.jsonl)
BASHKIT_DEBUG=stderr or BASHKIT_DEBUG=1 — Human-readable to stderr
BASHKIT_DEBUG=memory — In-memory only (programmatic access via getDebugLogs())