Create authoritative documentation suite for Claude Code JSONL session log processing, synthesized from codebase analysis, official Anthropic documentation, and community tooling research. Documentation structure (docs/claude-jsonl-reference/): 01-format-specification.md (214 lines): - Complete message envelope structure with all fields - Content block types (text, thinking, tool_use, tool_result) - Usage object for token reporting - Model identifiers and version history - Conversation DAG structure via parentUuid 02-message-types.md (346 lines): - Every message type with concrete JSON examples - User messages (string content vs array for tool results) - Assistant messages with all content block variants - Progress events (hooks, bash, MCP) - System, summary, and file-history-snapshot types - Codex format differences (response_item, function_call) 03-tool-lifecycle.md (341 lines): - Complete tool invocation to result flow - Hook input/output formats (PreToolUse, PostToolUse) - Parallel tool call handling - Tool-to-result pairing algorithm - Missing result edge cases - Codex tool format differences 04-subagent-teams.md (363 lines): - Task tool invocation and input fields - Subagent transcript locations and format - Team coordination (TeamCreate, SendMessage) - Hook events (SubagentStart, SubagentStop) - AMC spawn tracking with pending spawn registry - Worktree isolation for subagents 05-edge-cases.md (475 lines): - Parsing edge cases (invalid JSON, type ambiguity) - Type coercion gotchas (bool vs int in Python) - Session state edge cases (orphans, dead detection) - Tool call edge cases (missing results, parallel ordering) - Codex-specific quirks (content injection, buffering) - File system safety (path traversal, permissions) - Cache invalidation strategies 06-quick-reference.md (238 lines): - File locations cheat sheet - jq recipes for common queries - Python parsing snippets - Common gotchas table - Useful constants - Debugging commands Also adds CLAUDE.md at project root linking to documentation and providing project overview for agents working on AMC. Sources include Claude Code hooks.md, headless.md, Anthropic Messages API reference, and community tools (claude-code-log, claude-JSONL-browser). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
AMC — Agent Mission Control
A real-time dashboard for monitoring and interacting with Claude Code sessions.
Overview
AMC provides a unified view of all running Claude Code sessions across projects. It displays session status, conversation history, and pending questions — and allows you to respond directly from the dashboard without switching terminal tabs.
Features
- Real-time monitoring — Sessions are grouped by status (needs attention, active, starting, done) with 3-second polling
- Conversation history — View the full chat history for any session, pulled from Claude Code's JSONL logs
- Response injection — Send responses to agents directly via Zellij pane integration
- Question detection — Detects both structured
AskUserQuestionprompts and prose questions (messages ending with "?") - Session lifecycle — Automatically cleans up orphaned sessions and stale event logs
Installation
- Clone this repository
- Symlink the launcher to your PATH:
ln -s /path/to/amc/bin/amc ~/.local/bin/amc
- Configure Claude Code hooks (see Hook Setup)
Usage
amc start # Start the server and open the dashboard
amc stop # Stop the server
amc status # Check if the server is running
The dashboard opens at http://127.0.0.1:7400.
Hook Setup
AMC requires Claude Code hooks to report session state. Add this to your ~/.claude/settings.json:
{
"hooks": {
"SessionStart": [
{ "command": "/path/to/amc/bin/amc-hook" }
],
"UserPromptSubmit": [
{ "command": "/path/to/amc/bin/amc-hook" }
],
"Stop": [
{ "command": "/path/to/amc/bin/amc-hook" }
],
"SessionEnd": [
{ "command": "/path/to/amc/bin/amc-hook" }
],
"PreToolUse": [
{ "matcher": "AskUserQuestion", "command": "/path/to/amc/bin/amc-hook" }
],
"PostToolUse": [
{ "matcher": "AskUserQuestion", "command": "/path/to/amc/bin/amc-hook" }
]
}
}
Architecture
┌─────────────────────┐ ┌─────────────────────┐
│ Claude Code │────▶│ amc-hook │
│ (hooks) │ │ (writes state) │
└─────────────────────┘ └──────────┬──────────┘
│
▼
┌─────────────────────┐
│ ~/.local/share/ │
│ amc/sessions/ │
│ amc/events/ │
└──────────┬──────────┘
│
▼
┌─────────────────────┐ ┌─────────────────────┐
│ Dashboard │◀────│ amc-server │
│ (Preact UI) │ │ (Python HTTP) │
└─────────────────────┘ └─────────────────────┘
Components
| Component | Description |
|---|---|
bin/amc |
Launcher script — start/stop/status commands |
bin/amc-server |
Python HTTP server serving the API and dashboard |
bin/amc-hook |
Hook script called by Claude Code to write session state |
dashboard/ |
Modular Preact dashboard (index.html, components/, lib/, utils/) |
Data Storage
All runtime data lives in ~/.local/share/amc/:
| Path | Contents |
|---|---|
sessions/*.json |
Current session state (one file per session) |
events/*.jsonl |
Event log for each session (append-only) |
server.pid |
PID file for the running server |
server.log |
Server stdout/stderr |
API Reference
| Method | Endpoint | Description |
|---|---|---|
| GET | / |
Dashboard HTML |
| GET | /api/state |
All sessions as JSON |
| GET | /api/events/{id} |
Event timeline for a session |
| GET | /api/conversation/{id}?project_dir=... |
Conversation history (from Claude Code logs) |
| POST | /api/dismiss/{id} |
Dismiss (delete) a completed session |
| POST | /api/respond/{id} |
Send a response to a session |
Response Injection
The /api/respond/{id} endpoint injects text into a session's Zellij pane. Request body:
{
"text": "your response here",
"freeform": true,
"optionCount": 3
}
text— The response to sendfreeform— If true, treats as freeform text (selects "Other" option first)optionCount— Number of options in the current question (used for freeform)
Response injection works via:
- Zellij plugin (
~/.config/zellij/plugins/zellij-send-keys.wasm) — Required for pane-targeted sends and Enter submission - Optional unsafe fallback (
AMC_ALLOW_UNSAFE_WRITE_CHARS_FALLBACK=1) — Uses focused-panewrite-charsonly when explicitly enabled
AMC resolves the Zellij binary from PATH plus common Homebrew locations (/opt/homebrew/bin/zellij, /usr/local/bin/zellij) so response injection still works when started via launchctl.
Session Statuses
| Status | Meaning |
|---|---|
starting |
Session started, no prompt submitted yet |
active |
Session is processing work |
needs_attention |
Agent is waiting for user input (question or AskUserQuestion) |
done |
Session stopped (can be dismissed) |
Cleanup Behavior
- Orphan sessions: Sessions with missing Zellij sessions in "starting" status are auto-deleted
- Stale "starting" sessions: Sessions stuck in "starting" for >1 hour are removed
- Stale event logs: Event logs without matching sessions are deleted after 24 hours
- SessionEnd: Deletes the session file immediately
Requirements
- Python 3.8+
- Zellij (for response injection)
- Claude Code with hooks support
Testing
Run the server test suite:
python3 -m unittest discover -s tests -v
Zellij Plugin
For pane-targeted response injection (including reliable Enter submission), install the zellij-send-keys plugin:
# Build and install the plugin
# (See zellij-send-keys repository for instructions)
Place the compiled WASM at ~/.config/zellij/plugins/zellij-send-keys.wasm.
License
MIT