agent-orchestration-standard
Health Pass
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Community trust — 61 GitHub stars
Code Fail
- exec() — Shell command execution in cli/dash.mjs
- process.env — Environment variable access in cli/dash.mjs
- network request — Outbound network request in cli/dash.mjs
- spawnSync — Synchronous process spawning in cli/test.mjs
- process.env — Environment variable access in cli/test.mjs
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
A live, local-first dashboard for Claude Code sessions: project graph of agents, tokens, tool feed, replay, alerts. Plugin + terminal UI + MCP server. Includes the AOS-1 agent orchestration spec.
AOS-1: Agent Orchestration Standard
AOS-1 is a minimal, runtime-agnostic contract for orchestrating several AI agents toward one standing Goal. A periodic Heartbeat re-evaluates the Goal, reaps stalled work, plans, dispatches ready Tasks, and enforces budgets until the Goal is achieved, blocked, or cancelled. All state lives in plain files, and an append-only event log is the source of truth. The normative text is in SPEC.md.
This repository holds the spec, JSON Schemas, a zero-dependency conformance validator, and a reference server, dashboard and heartbeat runner.

The live dashboard watching three projects and 19 agents. All screenshots use a synthetic demo dataset (no real projects or paths).
Screenshots
Regenerate with make screenshots (needs playwright-core and the monitor running; ffmpeg for the GIF). The data comes from scripts/demo-state.mjs, served to the real UI through request interception.
How it works
flowchart LR
S["Claude Code sessions<br/>terminal / IDE / desktop"] --> H["Hooks<br/>aos-hook.mjs, 16 events"]
H --> L[("Sanitized event log<br/>local")]
L --> M["Monitor<br/>folds events: projects, models, tokens,<br/>conflicts, stuck / errored rules"]
M --> W["Web UI"]
M --> T["Terminal UI"]
M --> P["MCP server"]
M --> SL["Status line"]
M --> N["Notifier"]
NOTE["localhost only, read-only,<br/>no prompts or file contents stored"] -.- M
Highlights
- Privacy-first local telemetry: hooks log event and tool names, counts and short labels only, never prompts, command lines, file contents, tool output or error messages.
- Project-graph layout (heart, project hubs, agents) with node and label overlaps ruled out by construction; the terminal layout's no-overlap rules are covered by automated tests.
- Canvas particle streams (adaptive to frame time, paused in background tabs, crisp on high-DPI screens), tried in Safari and Chromium.
- Per-model stuck thresholds, plus errored-agent and file-conflict detection.
- Pan and zoom (wheel, trackpad, pinch, drag, keyboard) with the particle streams staying aligned to the graph.
- Replay: scrub the recorded timeline and see the graph as it was.
- Light and dark themes with checked contrast tokens.
- One plugin ships the hooks, the web UI, a terminal dashboard (
aos-dash), a read-only MCP server and a macOS notifier. - Automated test suites for the spec validator, terminal UI, MCP server, notifier and theme contrast (
make test).
Quickstart
Requires Node 18+. There are no dependencies to install.
node server.mjs # dashboard + API at http://127.0.0.1:4317
node conformance/validate.mjs # validate ./state against schemas and the spec's MUSTs
node conformance/validate.mjs path/to/state # validate another state directory
node conformance/validate.mjs --selftest # prove the validator catches the negative fixtures
The validator exits 0 when the state conforms and 1 when it does not. Each violation is printed as FAIL: <file>: <message>. Warnings, such as a stale heartbeat, do not affect the exit code.
Directory map
SPEC.md AOS-1 normative specification
README.md this file
ROADMAP.md what exists, known limitations, ideas
server.mjs reference HTTP server (serves ui/ and the state API)
ui/ dashboard (goal, heartbeat, task board, agents, events, pause/resume/cancel)
heartbeat/ heartbeat runner and config.json
state/ runtime state (the file-based binding)
goal.json Goal
tasks.json Task[]
agents.json Agent[]
heartbeat.json Heartbeat
events.ndjson append-only Events, one JSON object per line
schemas/ JSON Schema (draft 2020-12): goal, task, agent, heartbeat, event
conformance/
validate.mjs validator with a built-in schema-subset checker
fixtures/valid/ state directories that must pass
fixtures/invalid/ state directories that must each fail, one violation per directory
What the validator checks
Schema checks use type, required, enum, properties, items, pattern, minimum and minItems. The semantic checks are:
- Goal, task, agent and goal-terminal statuses are valid lifecycle values.
- The Goal has a budget (SPEC section 7).
- Every Task has a non-empty
output_contractand at least oneacceptancecheck (section 6). - Task ids are unique, every
depends_onreference exists, and there are no dependency cycles. assignee,current_taskandgoal_idreferences resolve, andattemptsdoes not exceedmax_attempts.events.ndjsonhas parseable lines, valid Event shapes, and strictly increasingseq.- Heartbeat liveness is consistent with the age of
ts(alive under 1.5x, late under 3x, dead at 3x or more ofinterval_s). A terminal Goal must not have arunningheartbeat.
The validator cannot see past writes, so append-only is checked structurally (monotonic seq, parseable lines). Appending only is up to the writer.
Configuring dispatch
The heartbeat runner starts each ready Task by running a shell command. Set it in heartbeat/config.json under dispatch_command:
{
"interval_s": 60,
"dispatch_command": "claude -p \"$AOS_TASK_PROMPT\""
}
Keep the exact key names and the variables available to the command in sync with heartbeat/config.json and the runner's header comment, which are the authority. The command is the only place a real agent runtime is plugged in. Anything that can be launched from a shell works: the Claude CLI, a script, or an HTTP client. Per SPEC section 7, a command that deploys, sends messages, spends money, or deletes things MUST be gated on human approval recorded as a human.* Event.
Keeping it running
Run the server and the heartbeat as long-lived processes. The heartbeat file is the liveness signal, so a crashed runner shows up as late and then dead in the dashboard.
Quick, with nohup:
cd /path/to/agent-orchestration-standard
nohup node server.mjs > server.log 2>&1 &
Durable, with launchd on macOS. Save this as ~/Library/LaunchAgents/dev.aos.server.plist, adjust the paths, then run launchctl load ~/Library/LaunchAgents/dev.aos.server.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
<key>Label</key><string>dev.aos.server</string>
<key>ProgramArguments</key><array>
<string>/usr/local/bin/node</string>
<string>/path/to/agent-orchestration-standard/server.mjs</string>
</array>
<key>WorkingDirectory</key><string>/path/to/agent-orchestration-standard</string>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
<key>StandardOutPath</key><string>/tmp/aos-server.log</string>
<key>StandardErrorPath</key><string>/tmp/aos-server.log</string>
</dict></plist>
Use the same pattern, with a different label and the heartbeat entry point, for the heartbeat runner if it is a separate process. Stop with launchctl unload <plist>. On Linux, an equivalent systemd unit with Restart=always works.
Claude Code live dashboard (plugin)
Beyond the spec and the reference runner, this repo contains a read-only live monitor for Claude Code sessions: it shows every session, project and subagent as a graph (heart -> project hubs -> agents) with live streams, per-agent model, tokens, run time, tool feed, file conflicts, errors and alerts. It is local-only (binds 127.0.0.1) and stores only event and tool names, short labels, counts, and the local folder/file paths it needs for project grouping and file-conflict detection: never prompts, command lines (only a Bash command's first word), file contents, tool output or error messages. Full paths stay in the local log and are never shown in the dashboard, terminal view or MCP output (see plugin/README.md for the exact list).
| Part | Where | What |
|---|---|---|
| Hooks | hooks/aos-hook.mjs, plugin/hooks/hooks.json |
Claude Code hooks write sanitized one-line events |
| Monitor | monitor.mjs |
Folds events into /api/state, /api/history, replay (?at=), alerts, notifications |
| Web UI | ui/ |
The graph, drawers, replay, cost readout, light/dark toggle |
| Terminal UI | cli/dash.mjs (aos-dash) |
The same graph in the terminal (--once for a snapshot) |
| MCP server | plugin/mcp/server.mjs |
Read-only tools so Claude can query the monitor |
| Notifier | plugin/notify/ |
Branded macOS notifications with an app icon |
| Plugin | plugin/, .claude-plugin/marketplace.json |
Packages all of the above; node plugin/build.mjs regenerates the copies |
Install (needs Node 18+ and the Claude Code CLI):
make install # builds, registers + installs the local plugin, links `aos-dash`, builds the notifier, starts the monitor
make doctor # checks the whole setup and tells you what to fix
make # lists every target (test, build, start/stop, statusline, uninstall, ...)
Then open http://127.0.0.1:4318 (the monitor starts automatically with a session; set AOS_NO_AUTOSTART=1 to disable). New sessions pick up the hooks; existing ones need /reload-plugins. Project grouping, alerts and the stuck/errored rules can be tuned in the monitor's live/config.json (see plugin/README.md). Status: personal project, macOS-first. Licensed under the MIT License.
Debugging
Open http://127.0.0.1:4318/?debug=1 to show a small on-screen recorder (ui/debug.js) that logs layout, canvas, visibility and frame-rate changes with Copy/Clear buttons. It is inert without the flag and never changes the page.
Security
- Threat model. The monitor is a local, read-only observer. It binds
127.0.0.1only, rejects requests whoseHostorOriginis notlocalhost/127.0.0.1(DNS-rebinding and cross-site protection), sends no CORS headers, has no write endpoints, and serves only the files underui/(dotfiles, traversal and symlinks out ofui/are refused). Anyone who can run code as your user can read the log anyway; the design goal is that nothing leaves the machine and no other site or user can reach it. - What is stored. See the exact field list under Privacy in plugin/README.md. Agent names and task labels come from Claude Code tool calls, so the UI and terminal view treat them as untrusted text (never rendered as HTML or terminal escape codes). New log files are created owner-only (
0600, directory0700). - How to erase. Delete the data folder:
~/.claude/plugins/data/aos-dashboard-aos-local/live(or yourAOS_LIVE_DIR);make uninstallremoves the plugin but keeps the data. - Reporting. Please open a GitHub issue. For anything sensitive, open an issue asking for a private contact rather than posting details.
Contributing
Issues and small pull requests are welcome. Edit the sources in the repo root (monitor.mjs, hooks/, ui/, cli/), then run make build (regenerates the plugin/ copies) and make test; keep it zero-dependency and Node 18 compatible.
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found







