How Athena Works

How Athena Works

Athena Flow is a runtime that wraps Claude Code. It does not modify Claude Code's binary or intercept network traffic — it uses Claude Code's official hooks system to observe and influence agent behavior.

The Three-Layer Architecture

┌────────────────────────────────────────────────────────────┐
│                      Claude Code                           │
│   (the agent — reads files, runs bash, writes code)        │
└──────────────────────────┬─────────────────────────────────┘
                           │ fires hooks at each lifecycle point
                           ▼
┌────────────────────────────────────────────────────────────┐
│                   athena-hook-forwarder                    │
│   (thin binary — receives hook stdin, sends NDJSON         │
│    over Unix Domain Socket to Athena runtime)              │
└──────────────────────────┬─────────────────────────────────┘
                           │ NDJSON event stream over UDS
                           ▼
┌────────────────────────────────────────────────────────────┐
│                  Athena Flow Runtime                       │
│  ┌──────────────┐  ┌─────────────┐  ┌──────────────────┐  │
│  │  Workflow    │  │  Plugins    │  │ Isolation Policy │  │
│  │  Engine      │  │  System     │  │ (controller)     │  │
│  └──────────────┘  └─────────────┘  └──────────────────┘  │
│  ┌──────────────────────────────────────────────────────┐  │
│  │            Session Store (SQLite)                    │  │
│  └──────────────────────────────────────────────────────┘  │
│  ┌──────────────────────────────────────────────────────┐  │
│  │          Terminal UI (React 19 + Ink 6)              │  │
│  └──────────────────────────────────────────────────────┘  │
└────────────────────────────────────────────────────────────┘

Startup Sequence

When you run athena-flow:

  1. Config loading — Global config (~/.config/athena/config.json) and project config (.athena/config.json) are merged with CLI flags
  2. Plugin resolution — Plugin dirs from config + --plugin flags + workflow plugins[] are loaded. For marketplace refs, the repo is cloned/updated in ~/.config/athena/marketplaces/
  3. Workflow activation — If a workflow is specified, it is loaded from ~/.config/athena/workflows/<n>/workflow.json. Its declared plugins are merged into the plugin set. Its isolation preset may upgrade the session preset (with a warning)
  4. Hook registration — Athena generates a temporary settings file (athena-hooks-<PID>-<timestamp>.json) that registers athena-hook-forwarder as the handler for all Claude Code hook events. The file is passed to Claude Code via --setting-sources and deleted on exit
  5. Socket open — The Unix Domain Socket listener starts at <projectDir>/.claude/run/ink-<PID>.sock
  6. TUI render — The terminal UI (React 19 + Ink 6) initializes and displays the session header
  7. Ready — Athena waits for Claude Code to start and send hook events

Hook Registration

Claude Code supports hooks — binaries that Claude Code calls at specific lifecycle points. Athena registers the athena-hook-forwarder binary for all 13+ hook event types. Hook events that require a tool matcher use "*" to receive all tool calls.

Claude Code calls the forwarder synchronously — the agent pauses briefly while the forwarder runs. The forwarder is intentionally minimal: read stdin, write to socket, exit. It completes in single-digit milliseconds.

Event Processing

When an event arrives at the Athena runtime via the socket:

  1. Parse — The NDJSON envelope is decoded and mapped to a RuntimeEvent with a canonical RuntimeEventKind
  2. Store — The event is persisted to SQLite in the current session database
  3. Policy evaluation — If the event is a tool.pre or permission.request, the isolation policy (controller) evaluates it and produces a RuntimeDecision. Decisions with source: 'rule' are auto-applied; decisions requiring user input pause the feed
  4. Feed mapping — The runtime event is transformed into one or more FeedEvent objects by the feed mapper, then appended to the timeline
  5. Workflow step — If a workflow is active and running a loop, the event is checked against completion and blocked markers
  6. UI update — The Ink/React tree re-renders with the new feed events

This pipeline runs in Node.js event loop order — each step completes before the next. SQLite writes are synchronous (better-sqlite3), which is fast enough that async adds no benefit.