teernisse 8578a19330 feat(dashboard): add smooth modal entrance/exit animations
Implements animated modal open/close with accessibility support:

- Add closing state with 200ms exit animation before unmount
- Refactor to React hooks-compliant structure (guards after hooks)
- Add CSS keyframes for backdrop fade and panel scale+translate
- Include prefers-reduced-motion media query to disable animations
  for users with vestibular sensitivities
- Use handleClose callback wrapper for consistent animation behavior
  across Escape key, backdrop click, and close button

The animations provide visual continuity without being distracting,
and gracefully degrade to instant transitions when reduced motion
is preferred.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-25 16:32:00 -05:00

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 AskUserQuestion prompts and prose questions (messages ending with "?")
  • Session lifecycle — Automatically cleans up orphaned sessions and stale event logs

Installation

  1. Clone this repository
  2. Symlink the launcher to your PATH:
ln -s /path/to/amc/bin/amc ~/.local/bin/amc
  1. 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 send
  • freeform — 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:

  1. Zellij plugin (~/.config/zellij/plugins/zellij-send-keys.wasm) — Required for pane-targeted sends and Enter submission
  2. Optional unsafe fallback (AMC_ALLOW_UNSAFE_WRITE_CHARS_FALLBACK=1) — Uses focused-pane write-chars only 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

Description
No description provided
Readme 2.3 MiB
Languages
Python 70%
JavaScript 22.9%
Shell 4.9%
CSS 1.5%
HTML 0.7%