npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

aoaoe

v7.5.0

Published

Autonomous supervisor for agent-of-empires sessions using OpenCode or Claude Code

Readme

An autonomous supervisor for Agent of Empires sessions. Uses OpenCode or Claude Code as the reasoning engine.

This project is a companion to Agent of Empires (AoE) by Nate Brake. AoE is the foundation -- it manages multiple AI coding agents in tmux sessions with git worktrees. aoaoe adds an autonomous supervisor layer on top. You need AoE running first; aoaoe plugs into it.

Self-improvement mode: make self starts aoaoe supervising its own AoE session — reading the roadmap from aoaoe.tasks.json, implementing features, committing, and pushing. It updates itself in real time.

What is this?

AoE is great at spawning and organizing agents, but someone still needs to watch the tmux panes and intervene when agents get stuck, ask questions, or finish their work.

aoaoe is that someone -- except it is an LLM. It polls your AoE sessions, reads agent output, decides when to act, and executes without you needing to be there.

This is the conductor, not the orchestra. AoE manages the sessions. The agents inside do the coding. aoaoe watches everything and steps in when needed.

Prerequisites

You need these installed first:

| Tool | What it does | Install | |------|-------------|---------| | tmux | Terminal multiplexer (AoE uses it) | brew install tmux | | Agent of Empires | Manages AI agent sessions | See AoE README | | OpenCode or Claude Code | LLM reasoning backend | npm i -g @anthropic-ai/claude-code or see OpenCode docs |

Verify they're on your PATH:

aoe --version       # agent-of-empires
tmux -V             # tmux
opencode --version  # if using OpenCode backend
claude --version    # if using Claude Code backend

Install

Pick one:

# npm (recommended)
npm install -g aoaoe

# Homebrew
brew install Talador12/tap/aoaoe

# curl
curl -fsSL https://raw.githubusercontent.com/Talador12/agent-of-agent-of-empires/main/scripts/install.sh | bash

# from source
git clone https://github.com/Talador12/agent-of-agent-of-empires
cd agent-of-agent-of-empires && npm install && npm run build && npm link

Verify:

aoaoe --version

Try It Alongside Running Sessions

Already have AoE sessions running? aoaoe is designed to run safely alongside them. Start with zero-risk commands and work your way up:

1. See what aoaoe sees (read-only, no LLM)

aoaoe test-context

Lists all your AoE sessions, resolves project directories, discovers context files (AGENTS.md, claude.md, etc.), and reports sizes. No LLM calls, no tmux writes, no side effects. This is just a diagnostic scan.

2. Full loop, actions only logged (costs LLM tokens)

aoaoe --dry-run

Runs the complete observe-reason-execute pipeline -- polls sessions, captures tmux output, calls the LLM for decisions -- but never executes actions. Instead of typing into your agents' tmux panes, it logs what it would do. Use this to verify the supervisor makes reasonable decisions before letting it act.

3. Full autonomous mode

aoaoe

The real deal. Polls, reasons, and executes -- sending keystrokes to agents, restarting crashed sessions, etc. You can still interrupt at any time with ESC ESC in the chat UI.

| Mode | Reads sessions? | Calls LLM? | Touches agents? | |------|:-:|:-:|:-:| | test-context | Yes | No | No | | --observe | Yes | No | No | | --dry-run | Yes | Yes | No | | --confirm | Yes | Yes | You approve each action | | aoaoe | Yes | Yes | Yes |

Self-improvement

aoaoe can supervise its own development. With an aoaoe AoE session open on this repo:

make setup   # install deps, build, create AoE session if missing (one-time)
make self    # aoaoe supervises itself: reads roadmap, implements, commits, pushes
make self-dry  # watch-only — see what it would do without letting it act

The goal in aoaoe.tasks.json drives the session: pick backlog items, implement with tests, commit atomically, push, tag releases. The daemon watches its own tmux pane and nudges the agent when it stalls or needs direction.

Quick Start

aoaoe has two parts: a daemon (the brain) and a chat UI (your window into it). Here's how to get both running.

Step 1: Have AoE sessions running

You need at least one AoE session for aoaoe to supervise. If you don't have any yet:

aoe add ./my-project -t my-agent -c "opencode"   # add an agent
aoe session start my-agent                         # start it
aoe                                                # enter AoE TUI to verify

Step 2: Register aoaoe as an AoE session (one-time)

This adds aoaoe's chat UI as a session inside AoE, so you can access it alongside your agents:

aoaoe register

This creates a session called "aoaoe" that runs the interactive chat UI. You only need to do this once.

Step 3: Start the daemon

In a separate terminal (or tmux pane, or backgrounded):

aoaoe

The daemon starts polling your AoE sessions, reasoning about what it sees, and executing actions. It logs to stderr so you can watch it work.

Step 4: Enter the chat UI

aoe session start aoaoe    # start the aoaoe session (if not already running)
aoe                        # enter AoE TUI, then select "aoaoe"

You're now in the chat UI. Type messages to the reasoner, run /overview to see what all agents are doing, or press ESC ESC to interrupt the current reasoning cycle.

Minimal example (all steps)

# Terminal 1: start the daemon
aoaoe

# Terminal 2: register + start + enter
aoaoe register
aoe session start aoaoe
aoe    # select "aoaoe" in the TUI

Using a different reasoning backend

# Use Claude Code instead of OpenCode
aoaoe --reasoner claude-code

# Use a specific model
aoaoe --reasoner opencode --model anthropic/claude-sonnet-4-20250514
aoaoe --reasoner claude-code --model claude-sonnet-4-20250514

Task System

aoaoe can automatically create and manage AoE sessions from a task list. Define repos you want to work on in aoaoe.tasks.json (next to your config file):

[
  {
    "repo": "github/adventure",
    "sessionTitle": "adventure",
    "sessionMode": "existing",
    "goal": "Process queued TODOs in this existing AoE session"
  },
  {
    "repo": "github/agent-of-agent-of-empires",
    "sessionTitle": "aoaoe-roadmap",
    "sessionMode": "new",
    "tool": "opencode",
    "goal": "Ship next roadmap item with tests"
  },
  {
    "repo": "github/cloud-hypervisor",
    "sessionMode": "auto",
    "goal": "Address PR review feedback"
  }
]

| Field | Required | Description | |-------|:--------:|-------------| | repo | Yes | Path to the project directory (relative to cwd or absolute) | | sessionTitle | No | AoE session title to target. Default: derived from repo basename | | sessionMode | No | Session allocation strategy: existing (link only), new (create), auto (link or create). Default: auto | | tool | No | Agent tool to use (opencode, claude-code, etc.). Default: opencode | | goal | No | Goal text injected into the supervisor's context for this task |

When the daemon starts, it now auto-imports any currently visible AoE sessions into the task list (mode=existing) so active and inactive sessions are immediately schedulable. Then it reconciles tasks: creates new AoE sessions when needed, links existing sessions by title, and starts linked sessions as needed. Progress is tracked persistently in ~/.aoaoe/task-state.json and survives session cleanup.

Interactive task updates (aoaoe task new/edit/rm or /task ...) also sync back to aoaoe.tasks.json, so your list evolves as you go.

The supervisor can report progress milestones and mark tasks complete via two special actions:

  • report_progress — logs a milestone summary to persistent state
  • complete_task — marks the task done and cleans up the session

View task status:

aoaoe tasks    # show task progress table

Daemon TUI Commands

The daemon runs an interactive TUI with a rich command set. These commands are available when the daemon is running (started with aoaoe).

Talking to the AI

| Command | What it does | |---------|-------------| | (any text) | Send a message -- queued for the next reasoning cycle | | !message | Insist -- interrupt + deliver message immediately | | /insist <msg> | Same as !message | | /explain | Ask the AI to explain what's happening right now |

Controls

| Command | What it does | |---------|-------------| | /pause | Pause the supervisor (stops reasoning) | | /resume | Resume after pause | | /mode [name] | Switch mode at runtime: observe, dry-run, confirm, autopilot (no arg = show current) | | /interrupt | Interrupt the AI mid-thought | | ESC ESC | Same as /interrupt (shortcut) |

Navigation

| Command | What it does | |---------|-------------| | 1-9 | Quick-switch: jump to session N | | /view [N\|name] | Drill into a session's live output (default: 1) | | /back | Return to overview from drill-down | | /sort [mode] | Sort sessions: status, name, activity, health, default (no arg = cycle) | | /compact | Toggle compact mode (dense session panel) | | /pin [N\|name] | Pin/unpin a session to the top | | /bell | Toggle terminal bell on errors/completions | | /focus | Toggle focus mode (show only pinned sessions) | | /mute [N\|name] | Mute/unmute a session's activity entries | | /unmute-all | Unmute all sessions at once | | /filter [tag] | Filter activity by tag -- presets: errors, actions, system (no arg = clear) | | /who | Show fleet status: status, uptime, idle-since, context, errors, group, note | | /uptime | Show session uptimes | | /top [mode] | Rank sessions by errors (default), burn, or idle | | /auto-pin | Toggle auto-pin on error | | /note N\|name text | Attach a note to a session (no text = clear) | | /notes | List all session notes | | /group N\|name tag | Assign session to a group (lowercase, max 16 chars; no tag = clear) | | /groups | List all groups and their members | | /group-filter [tag] | Show only sessions in a group (no arg = clear) | | /rename N\|name [display] | Set custom TUI display name (no display = clear); persisted | | /watchdog [N] | Alert if session stalls N minutes (default 10); /watchdog off to disable | | /quiet-hours [H-H] | Suppress watchdog+burn alerts during hours (e.g. 22-06); no arg = clear | | /broadcast <msg> | Send message to all sessions; /broadcast group:<tag> <msg> for group | | /duplicate N [t] | Clone a session (same tool/path) with optional new title | | /tag N tag1,tag2 | Set freeform tags on a session (no tags = clear); /tags to list | | /tag-filter [tag] | Show only sessions with given freeform tag (no arg = clear) | | /color N [c] | Set accent dot color: lime amber rose teal sky slate (no color = clear) | | /color-all [c] | Set accent color for all sessions at once | | /mute-errors | Toggle suppression of error/! action entries in activity log | | /pin-all-errors | Pin every session currently in error state | | /pin-draining | Pin all draining sessions to the top | | /labels | List all active session labels | | /sort-by-health | Sort sessions by health score (worst first) | | /icon N [emoji] | Set or clear a single emoji shown in the session row | | /timeline N [n] | Show last n activity entries for a session (default 30) | | /find <text> | Search all session pane outputs for text | | /reset-health N | Clear error counts + context history to reset a session's health score | | /prev-goal N [n] | Restore nth-most-recent goal for a session (default 1 = latest) | | g1-g99 | Quick-switch to session 10+ (e.g. g12 jumps to session 12) | | /clip [N] | Copy last N activity entries to clipboard (default 20) | | /diff N | Show activity since bookmark N | | /mark | Bookmark current activity position | | /jump N | Jump to bookmark N | | /marks | List all bookmarks | | /search <pattern> | Filter activity entries by substring (no arg = clear) | | Click session | Click an agent card to drill down (click again to go back) | | Mouse wheel | Scroll activity (overview) or session output (drill-down) | | PgUp / PgDn | Scroll through activity or session output | | Home / End | Jump to oldest / return to live |

Info

| Command | What it does | |---------|-------------| | /status | Show daemon state (mode, reasoner, poll counts, last cycle) | | /dashboard | Show full dashboard | | /tasks | Show task progress table | | /t ... /todo ... /idea ... | Aliases for /task ... | | /task [sub] [args] | Task management (list, start, stop, edit, new, rm) | | /task <session> :: <goal> | Fast path: update/create task for an existing session and set its goal | | :<goal> | Fastest path in drill-down: set goal for that session | | just type (in drill-down) | Default behavior: update goal for the focused session | | /burn-rate | Show context token burn rates (tokens/min) for all sessions | | /ceiling | Show context token usage vs limit for all sessions | | /stats | Per-session health, errors (+trend), burn rate, context %, cost, uptime | | /top [mode] | Rank sessions by errors (default), burn, or idle | | /who | Fleet status: status, uptime, idle-since, cost, errors+trend, group, note | | /snapshot [md] | Export session state snapshot to ~/.aoaoe/snapshot-<ts>.json (or .md) | | /export-stats | Export /stats output to ~/.aoaoe/stats-<ts>.json | | /session-report N | Full markdown report for one session → ~/.aoaoe/report-<name>-<ts>.md | | /cost-summary | Show total estimated spend across all sessions | | /recall <kw> [N] | Search 7-day persisted history for keyword | | /history-stats | Aggregate stats from history: entry counts, top tags, span | | /clear-history | Truncate ~/.aoaoe/tui-history.jsonl | | /copy [N] | Copy session's current pane output to clipboard (default: current drill-down) | | /alias /x /cmd | Create command alias (/x expands to /cmd); no args = list | | /ctx-budget | Show context budget allocation across sessions (activity-weighted) | | /profile [name] | Show active AoE profiles; optionally switch focus to a named profile | | /replay <N\|name> [lps] | Play back a session's stored pane output line by line (default 10 lps; run again to stop) | | /notify-filter <session> <events...> | Set per-session webhook event filter (session_error, session_done, etc.); no args = list; clear = remove all |

Other

| Command | What it does | |---------|-------------| | /verbose | Toggle detailed logging | | /clear | Clear the screen | | /help | Show all commands |

TUI Features

  • Activity sparkline -- 10-minute activity rate chart in the separator bar (Unicode blocks with color gradient)
  • Activity sparkline -- 10-minute activity rate chart in the separator bar (Unicode blocks with color gradient)
  • Session cards -- per-session status with pin , mute , note , group ⊹tag, health ⬡N, color , tags [tag1,tag2], and activity rate 3/m indicators
  • Health score -- composite 0–100 badge (errors, burn rate, context ceiling, stall time); LIME ≥80, AMBER ≥60, ROSE <60; also in compact mode
  • Error sparklines -- ROSE 5-bucket mini-chart of recent error frequency in each card (last 5 min)
  • Error trend -- ↑/→/↓ arrows in /stats and /who showing error direction
  • Idle-since -- time since last output change in idle/done cards and /who output
  • Cost tracking -- $N.NN spent parsed from pane output; shown in /stats, /who, /cost-summary
  • Session grouping -- /group//group-filter for named group organization; ⊹tag badge in cards
  • Session tagging -- /tag for multi-freeform-tag sets; /tag-filter panel filter; [tag1,tag2] badge
  • Session rename -- /rename custom TUI display name (bold + original dim); persisted
  • Session color -- /color accent dot per card (8 colors); /color-all for bulk set; persisted
  • Watchdog -- /watchdog N fires on stall; suppressed during /quiet-hours; ⊛Nm header badge
  • Burn-rate alerts -- auto "status" alert > 5k tokens/min; suppressed during quiet hours
  • Context ceiling warning -- auto alert at 90% context when "X / Y tokens" format available
  • Quiet hours -- /quiet-hours HH-HH suppresses watchdog + burn-rate alerts during set hours
  • Session timeline -- /timeline N [n] shows last n activity entries filtered by session
  • Session report -- /session-report N writes full markdown report to ~/.aoaoe/
  • Snapshot export -- /snapshot [md] exports all session state to ~/.aoaoe/
  • History search -- /recall <kw> searches 7-day persisted history; /history-stats shows aggregates
  • Broadcast -- /broadcast [group:<tag>] <msg> sends to all or group-filtered sessions via tmux
  • Duplicate -- /duplicate N [title] clones a session (same tool + path) with new title
  • Ranked view -- /top [errors|burn|idle] composite attention ranking; /stats full per-session table
  • Sticky preferences -- sort, compact, focus, bell, auto-pin, tag filter, aliases, groups, renames, colors, tags, quiet hours persist across restarts
  • Filter pipeline -- mute → suppress (/mute-errors) → tag → search all compose
  • Aliases -- /alias /x /cmd shortcuts; up to 50, persisted
  • Activity heatmap -- 24-hour colored block chart via aoaoe stats
  • Bookmarks -- mark positions, jump back, diff since a bookmark
  • Clipboard export -- /clip and /copy copy activity or session pane output to clipboard
  • Automatic context compaction -- when a session hits 80% context usage, daemon sends a compaction nudge via tmux; 10-min cooldown per session
  • Multi-profile polling -- daemon polls all configured AoE profiles simultaneously; sessions deduped by ID across profiles
  • Session replay -- /replay <N|name> [lps] plays back stored pane output in the activity log at configurable speed

Chat UI Commands

The chat UI (aoaoe-chat) runs inside an AoE tmux pane. Register it with aoaoe register, then access via aoe -> select "aoaoe".

| Command | What it does | |---------|-------------| | /overview | Show all AoE sessions with tasks, model, tokens, cost. Works without the daemon. | | /tasks | Alias for /overview | | /status | Daemon connection status + countdown to next reasoning cycle | | /progress [--since --json] | What each session accomplished recently | | /health | Per-session health scores (0-100) with fleet average | | /incident [opts] | Incident quick view: response-flow runbook + recent events (--since, --limit, --json, --ndjson, --follow) | | /runbook [section] [--json] | Print operator playbook slice (quickstart, response-flow/incident, all) | | /supervisor [opts] | Judge/orchestrator status across tasks/sessions (--all, --since, --limit, --json) | | /prompt-template [name] | Set/show reasoner strategy (default, hands-off, aggressive, review-focused, shipping) | | /pin-save <name> | Save current pinned sessions as a named preset | | /pin-load <name> | Restore a saved pin preset | | /pin-presets | List saved pin presets | | /interrupt | Interrupt the current reasoner call | | /dashboard | Request full dashboard output from daemon | | /pause | Pause the daemon (stops reasoning) | | /resume | Resume after pause | | /sessions | Instant session list from daemon state (no tmux capture needed) | | /explain | Ask the AI to explain what's happening right now in plain English | | /verbose | Toggle verbose logging | | /clear | Clear the screen | | /help | Show all commands | | ESC ESC | Interrupt the reasoner (same as /interrupt) | | (any text) | Send a message to the reasoner -- included in the next reasoning cycle |

How /overview works

/overview captures every AoE pane directly via tmux and parses:

  • Tasks: OpenCode TODO items ([*] done, [.] in progress, [o] pending)
  • Model: Which LLM the agent is using (e.g. "Claude Opus 4.6")
  • Context: Token count and cost
  • Last line: Most recent meaningful output

This works standalone -- you don't need the daemon running.

How interrupt works

When the daemon is reasoning, press ESC ESC (or type /interrupt) to stop the current LLM call. The daemon will pause and wait for your input. Type a message and it will be included in the next reasoning cycle. This is useful when you want to redirect the supervisor's attention.

Daemon CLI

aoaoe [command] [options]

commands:
  (none)         start the supervisor daemon (interactive TUI)
  init           detect tools + sessions, import history, generate config
  status         quick daemon health check (is it running? what's it doing?)
  runbook        print operator quickstart for day-2 supervision
  runbook --json machine-readable runbook output for tooling
  runbook --section <quickstart|response-flow|incident|all> print only one runbook section
  incident       one-shot incident quick view (response-flow + recent activity)
  incident --since <duration>      filter incident event window (30m, 2h, 1d)
  incident --limit <N>             cap incident events shown (default: 5)
  incident --json                  machine-readable incident output
  incident --ndjson                emit compact one-line JSON snapshots
  incident --watch                 stream incident snapshots continuously
  incident --follow                shortcut for --watch --changes-only --heartbeat 30
  incident --changes-only          emit only when incident state changes (implies --watch)
  incident --heartbeat <sec>       keepalive interval (implies --changes-only + --watch)
  incident --interval <ms>         watch refresh interval (default: 5000, min: 500)
  supervisor     one-shot supervisor/task/session orchestration status
  supervisor --all                 show full recent supervisor event buffer
  supervisor --since <duration>    filter events to a time window (30m, 2h, 7d)
  supervisor --limit <N>           cap number of events shown (default: 5)
  supervisor --json                machine-readable output for automation
  supervisor --ndjson              emit compact one-line JSON snapshots
  supervisor --watch               stream supervisor snapshots continuously
  supervisor --changes-only        emit only when state changes (implies --watch)
  supervisor --heartbeat <sec>     keepalive interval (implies --changes-only + --watch)
  supervisor --interval <ms>       watch refresh interval (default: 5000, min: 500)
  config         show the effective resolved config (defaults + file)
  config --validate  validate config + check tool availability
  config --diff  show only fields that differ from defaults
  notify-test    send a test notification to configured webhooks
  doctor         comprehensive health check (config, tools, daemon, disk)
  logs           show recent conversation log entries
  logs --actions show action log entries (from ~/.aoaoe/actions.log)
  logs --grep <pattern>  filter log entries by substring or regex
  logs -n <count>        number of entries to show (default: 50)
  export         export session timeline as JSON or Markdown for post-mortems
  export --format <json|markdown>  output format (default: json)
  export --output <file>           write to file (default: stdout)
  export --last <duration>         time window: 1h, 6h, 24h, 7d (default: 24h)
  task           manage tasks and sessions (list, reconcile, start, stop, new, rm, edit, help)
  task templates show available task templates (roadmap, pr-review, bugfix, etc.)
  task new <t> <p> --template roadmap  create task with template goal
  task start-all|stop-all|pause-all|resume-all  batch fleet management
  tasks          show task progress (from aoaoe.tasks.json)
  tasks --json   machine-readable task state with live session status
  progress       per-session accomplishment digest (last 24h)
  progress --since <dur> --json  filter window + machine-readable output
  health         per-session health scores (0-100, fleet average)
  health --json  machine-readable health output
  adopt          import all untracked live AoE sessions as tasks
  adopt --template roadmap  apply a template goal to adopted sessions
  backup [path]  backup ~/.aoaoe/ state + config to tarball
  restore <path> restore from backup tarball or directory
  sync init <url> set up git-based state sharing with remote repo
  sync push       push local state to sync remote
  sync pull       pull remote state and restore locally
  sync diff       show changes since last push
  sync status     show sync repo status
  export --tasks  export task history as JSON or markdown
  export --tasks --format md  markdown format with progress timelines
  history        review recent actions (from ~/.aoaoe/actions.log)
  test-context   scan sessions + context files (read-only, no LLM, safe)
  test           run integration tests (requires aoe, opencode, tmux)
  register       register aoaoe as an AoE session (one-time setup)

options:
  --reasoner <opencode|claude-code>  reasoning backend (default: opencode)
  --poll-interval <ms>               poll interval in ms (default: 10000)
  --port <number>                    opencode server port (default: 4097)
  --health-port <number>             start HTTP health check server on this port
  --model <model>                    model to use
  --profile <name>                   aoe profile (default: default)
  --dry-run                          run full loop but only log actions (costs
                                     LLM tokens, but never touches sessions)
  --observe                          observe only — no LLM calls, no execution,
                                      zero cost. shows what the daemon sees.
  --confirm                          ask before each action — the AI proposes,
                                      you approve with y/n before it runs.
  --verbose, -v                      verbose logging
  --help, -h                         show help
  --version                          show version

init options:
  --force, -f                        overwrite existing config

register options:
  --title, -t <name>                 session title in AoE (default: aoaoe)

Supervisor Streaming Examples

# Human-readable watch output (change-only)
aoaoe supervisor --watch --changes-only --heartbeat 60

# NDJSON stream for pipes/collectors
aoaoe supervisor --watch --ndjson --changes-only --heartbeat 30

# Filter to the last 2 hours and show only 20 events
aoaoe supervisor --since 2h --limit 20

JSON/NDJSON payloads include emitReason with one of:

  • snapshot (one-shot invocation)
  • interval (periodic watch tick)
  • change (watch emission caused by state change)
  • heartbeat (keepalive emission from --heartbeat)

Incident Streaming Examples

# One-shot incident snapshot (human readable)
aoaoe incident --since 30m --limit 10

# Fast follow mode (alias for --watch --changes-only)
aoaoe incident --follow --heartbeat 30 --ndjson

# NDJSON incident stream for monitors (change-only + keepalive)
aoaoe incident --watch --ndjson --changes-only --heartbeat 30

# JSON watch stream (compact one object per tick in watch mode)
aoaoe incident --watch --json --interval 5000

Operator Playbook

Use this when running aoaoe as a long-lived judge over many AoE sessions.

# 1) Start low-noise supervision stream in a side pane
aoaoe supervisor --watch --ndjson --changes-only --heartbeat 30

# 2) If sessions/tasks drift, force immediate reconciliation
aoaoe task reconcile

# 3) If a specific session needs new direction, inject a goal quickly
aoaoe-chat
# then type: /task <session> :: <new goal>

Recommended response flow:

  • emitReason=change spikes: inspect /supervisor --since 30m --limit 20
  • stalled task (pending/paused too long): run aoaoe task reconcile, then nudge via /task ... :: ...
  • noisy but unchanged systems: keep --changes-only --heartbeat 30 so monitors still get liveness

Task Templates

Create tasks with built-in goal presets instead of writing JSON by hand:

aoaoe task templates                       # list available templates
aoaoe task new my-project ./path --template roadmap
aoaoe task new bugfix-auth ./path --template bugfix

Built-in templates: roadmap, roadmap-strict, pr-review, bugfix, explore, ci-fix

Custom templates: add to ~/.aoaoe/templates.json

Prompt Templates

Switch the reasoner's supervision strategy at runtime:

/prompt-template hands-off    # minimal intervention
/prompt-template aggressive   # proactive nudging
/prompt-template shipping     # focus on commits and pushes

Or set in config: "promptTemplate": "hands-off"

Pin Presets

Save and restore named sets of pinned sessions:

/pin-save work              # save current pins
/pin-load work              # restore later
/pin-presets                # list all saved presets

Configuration

Config lives at ~/.aoaoe/aoaoe.config.json (canonical, written by aoaoe init). A local aoaoe.config.json in cwd overrides for development. Defaults work fine without a config file:

{
  "reasoner": "opencode",
  "pollIntervalMs": 10000,
  "opencode": {
    "port": 4097,
    "model": "anthropic/claude-sonnet-4-20250514"
  },
  "claudeCode": {
    "model": "claude-sonnet-4-20250514",
    "yolo": true,
    "resume": true
  },
  "aoe": {
    "profile": "default"
  },
  "policies": {
    "maxIdleBeforeNudgeMs": 120000,
    "maxErrorsBeforeRestart": 3,
    "autoAnswerPermissions": true
  },
  "sessionDirs": {
    "adventure": "github/adventure",
    "cloudchamber": "cc/cloudchamber"
  },
  "contextFiles": [],
  "notifications": {
    "webhookUrl": "https://example.com/webhook",
    "slackWebhookUrl": "https://hooks.slack.com/services/T.../B.../xxx",
    "events": ["session_error", "session_done", "daemon_started", "daemon_stopped"]
  }
}

| Field | Description | Default | |-------|-------------|---------| | reasoner | "opencode" or "claude-code" | "opencode" | | pollIntervalMs | How often to check AoE sessions (ms) | 10000 | | opencode.port | Port for opencode serve | 4097 | | opencode.model | Model in provider/model format | (OpenCode default) | | claudeCode.model | Anthropic model name | (Claude Code default) | | claudeCode.yolo | Skip permissions in Claude Code | true | | claudeCode.resume | Maintain session across calls | true | | aoe.profile | AoE profile to monitor | "default" | | policies.maxIdleBeforeNudgeMs | Nudge idle agents after this long | 120000 | | policies.maxErrorsBeforeRestart | Restart after N consecutive errors | 3 | | policies.autoAnswerPermissions | Auto-approve permission prompts | true | | policies.allowDestructive | Allow remove_agent and stop_session actions | false | | policies.maxStuckNudgesBeforePause | Auto-pause task after N nudges with no progress (0 = disabled) | 0 | | policies.quietHours | Skip reasoning during these hours, e.g. "01:00-06:00" (polling continues) | (none) | | promptTemplate | Reasoner prompt strategy: default, hands-off, aggressive, review-focused, shipping | "default" | | policies.userActivityThresholdMs | Ignore sessions with recent human keystrokes | 30000 | | policies.actionCooldownMs | Minimum ms between actions on the same session | 30000 | | protectedSessions | Session titles that are observe-only (no actions) | [] | | sessionDirs | Map session titles to project directories (relative to cwd or absolute). Bypasses heuristic directory search. | {} | | contextFiles | Extra AI instruction file paths to load from each project root | [] | | captureLinesCount | Number of tmux lines to capture per session (-S flag) | 100 | | healthPort | Start HTTP health check server on this port (e.g. 4098). GET /health returns JSON status. | (none) | | notifications.webhookUrl | Generic webhook URL (POST JSON) | (none) | | notifications.slackWebhookUrl | Slack incoming webhook URL (block kit format) | (none) | | notifications.events | Filter which events fire (omit to send all). Valid: session_error, session_done, action_executed, action_failed, daemon_started, daemon_stopped | (all) | | notifications.maxRetries | Retry failed webhook deliveries with exponential backoff (1s, 2s, 4s, ...) | 0 (no retry) | | tuiHistoryRetentionDays | How many days of TUI history to replay on startup (1-365) | 7 |

Also reads .aoaoe.json as an alternative config filename.

sessionDirs — explicit project directory mapping

By default, aoaoe resolves project directories by searching subdirectories (up to 2 levels deep) for a folder name matching each session title. This works great for standard layouts like repos/github/adventure/.

For non-standard layouts or when the session title doesn't match the directory name, use sessionDirs to provide explicit mappings:

{
  "sessionDirs": {
    "adventure": "github/adventure",
    "cloudchamber": "cc/cloudchamber",
    "my-agent": "/absolute/path/to/project"
  }
}

Paths can be relative (resolved from the directory where you run aoaoe) or absolute. Case-insensitive matching is used for session title lookup. If a mapped path doesn't exist on disk, aoaoe falls back to heuristic search.

Use aoaoe test-context to verify resolution.

notifications — webhook alerts for daemon events

aoaoe can send webhook notifications when significant events occur (session errors, task completions, daemon start/stop). Supports generic JSON webhooks and Slack incoming webhooks with block kit formatting.

{
  "notifications": {
    "webhookUrl": "https://example.com/webhook",
    "slackWebhookUrl": "https://hooks.slack.com/services/T.../B.../xxx",
    "events": ["session_error", "session_done", "daemon_started", "daemon_stopped"]
  }
}

Both webhook URLs are optional — configure one or both. The events array filters which event types fire (omit it to receive all events). Notifications are fire-and-forget with a 5s timeout and 60s rate limiting per event+session combo to prevent spam.

Run aoaoe notify-test to verify your webhook configuration.

How It Works

┌──────────────────────────────────────────────────────┐
│                    aoaoe daemon                      │
│                                                      │
│  ┌───────────┐   ┌─────��────────┐   ┌───────────┐    │
│  │  Poller   │──▶│   Reasoner   │──▶│ Executor  │    │
│  │           │   │ ┌──────────┐ │   │           │    │
│  │ aoe CLI + │   │ │ OpenCode │ │   │ tmux send │    │
│  │ tmux cap  │   │ │  server  │ │   │ keys, aoe │    │
│  │           │   │ ├──────────┤ │   │ CLI cmds  │    │
│  │           │   │ │  Claude  │ │   │           │    │
│  │           │   │ │   Code   │ │   │           │    │
│  │           │   │ └──────────┘ │   │           │    │
│  └───────────��   └──────────────┘   └───────────┘    │
│                                                      │
│  ┌────────────────────────────────────────────────┐  │
│  │           Chat UI (aoaoe-chat)                 │  │
│  │    runs inside AoE tmux pane, reads state      │  │
│  │    from ~/.aoaoe/ via file-based IPC           │  │
│  └────────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────────┘
         │                              │
         ▼                              ▼
    AoE sessions                  LLM Provider
    (tmux panes)              (local or remote)

Three loops

Poller (every N seconds, configurable):

  • Calls aoe list --json to get all session IDs, statuses, and tools
  • For each active session: tmux capture-pane -t <session> -p -S -100
  • Diffs against previous capture to detect new output
  • Builds an observation payload

Reasoner (on new observations):

  • Sends observation to the configured LLM backend
  • System prompt defines the supervisor role, policies, and available actions
  • Receives back a structured JSON action decision

Executor (on decisions):

  • tmux send-keys -- inject a prompt into an agent
  • aoe session start/stop/restart -- lifecycle management
  • aoe add / aoe remove -- spawn or tear down agents

Supervisor behavior

The LLM supervisor follows these policies:

  • If an agent is stuck or idle too long, nudge it with context or a rephrased task
  • If an agent asks a question and is waiting for input, answer it
  • If an agent finishes its task, acknowledge and optionally assign follow-up work
  • If a session crashes, restart it
  • Do NOT micromanage -- only intervene when there is a clear problem or decision needed

Available actions

The reasoner returns structured JSON decisions:

{ "action": "send_input", "session": "<id>", "text": "<prompt>" }
{ "action": "start_session", "session": "<id>" }
{ "action": "stop_session", "session": "<id>" }
{ "action": "create_agent", "path": "<dir>", "title": "<name>", "tool": "<agent>" }
{ "action": "remove_agent", "session": "<id>" }
{ "action": "report_progress", "session": "<id>", "summary": "<milestone>" }
{ "action": "complete_task", "session": "<id>", "summary": "<final status>" }
{ "action": "wait" }

Reasoning Backends

| Backend | Interface | Stateful | Model Flexibility | |---------|-----------|----------|-------------------| | OpenCode | opencode serve + SDK | Yes (long-running session) | Any provider via OpenCode config | | Claude Code | claude --print subprocess | Via --resume | Anthropic models |

OpenCode backend

Runs opencode serve as a headless HTTP server. Uses the OpenCode JS SDK to maintain a long-running session with full context. Works with any model provider configured in OpenCode (Anthropic, OpenAI, Ollama, etc.).

Claude Code backend

Calls claude --print --output-format json as a subprocess. System prompt injected via --append-system-prompt. Session continuity via --resume <session_id>.

IPC and State Files

The daemon and chat UI communicate via files in ~/.aoaoe/:

| File | Written by | Read by | Purpose | |------|-----------|---------|---------| | daemon-state.json | daemon | chat UI | Current phase, countdown, per-session state | | conversation.log | daemon | chat UI | Observations, reasoning, actions log | | pending-input.txt | chat UI | daemon | User messages queued for next reasoning cycle | | interrupt | chat UI | daemon | Flag file -- presence triggers interrupt | | chat.pid | chat UI | daemon | Chat process PID for detection | | actions.log | daemon | -- | Persistent action history (JSONL) |

Intelligence Modules

aoaoe includes 196 intelligence modules that run every daemon tick without LLM calls — pure computation, zero runtime dependencies. They cover fleet observability, cost management, goal tracking, scheduling, health monitoring, and operator tooling.

Reasoning Pipeline (8 gates, runs before every LLM call):

  • Token quota → fleet rate limiter → observation cache → priority filter → context compressor → LLM call → approval workflow → cost tracker

Core Per-Tick Autonomous Systems:

  • Session summarizer, conflict detector + auto-resolver, goal completion detector, cost budget enforcer
  • Adaptive poll controller, fleet SLA monitor, progress velocity tracker, recovery playbook
  • Dependency scheduler, session graduation (trust ladder), workflow engine

Fleet Intelligence (on-demand via 197 TUI /commands):

  • Cost tracking: budgets, forecasts, trends, anomalies, chargebacks, optimization recommendations
  • Goal management: auto-priority, cascading, decomposition, NL parsing, confidence estimation, burndown charts
  • Observability: incident timeline, event bus, health scoring, diagnostics, structured logs, pattern evolution
  • Operations: shift handoff, compliance, runbooks, auto-scaler, canary mode, graceful shutdown
  • API: REST server with OpenAPI spec, SSE events, webhooks, bearer auth, rate limiting, pagination

See AGENTS.md for the full module list with descriptions.

Project Structure

src/
  # ── core daemon (the 15 files that make it go) ──
  index.ts            # daemon entry point, main loop, subcommands
  loop.ts             # extracted tick logic (poll->reason->execute), testable with mocks
  config.ts           # config loader, CLI arg parser, validation
  types.ts            # shared types (SessionSnapshot, Action, DaemonState, etc.)
  poller.ts           # aoe CLI + tmux capture-pane wrapper
  executor.ts         # maps action decisions to shell commands
  tui.ts              # in-place terminal UI (alternate screen, scroll, sparklines)
  input.ts            # stdin readline + keypress handlers (/commands)
  init.ts             # `aoaoe init`: auto-discover tools, generate config
  context.ts          # discoverContextFiles, resolveProjectDir, loadSessionContext
  health.ts           # HTTP health check endpoint
  daemon-state.ts     # IPC state file + interrupt flag
  task-manager.ts     # task orchestration: definitions, persistent state

  # ── reasoner backends ──
  reasoner/
    index.ts          # common Reasoner interface + factory
    prompt.ts         # system prompt + observation formatting
    parse.ts          # response parsing, JSON extraction, action validation
    opencode.ts       # OpenCode HTTP backend (native fetch to opencode serve)
    claude-code.ts    # Claude Code subprocess backend (claude --print)

  # ── CLI tools ──
  chat.ts             # interactive chat UI (aoaoe-chat binary)
  tail.ts             # live-stream daemon activity to another terminal
  stats.ts            # aggregate statistics + activity heatmap
  replay.ts           # play back tui-history.jsonl with timing
  export.ts           # timeline export (JSON/Markdown)

  # ── 196 intelligence modules (*.ts + *.test.ts pairs) ──
  # fleet observability, cost management, goal tracking, scheduling,
  # health monitoring, operator tooling — see AGENTS.md for full list

Related Projects

  • Agent of Empires -- the session manager this project controls
  • OpenCode -- AI coding agent, used as a reasoning backend
  • Claude Code -- Anthropic's CLI agent, used as a reasoning backend

License

MIT License -- see LICENSE for details.