Metadata-Version: 2.4
Name: armada-ai
Version: 0.3.5
Summary: Terminal orchestration for Open Code and Claude Code agents
Author: Armada Contributors
License-Expression: MIT
Project-URL: Homepage, https://github.com/rguiu/armada
Project-URL: Repository, https://github.com/rguiu/armada
Project-URL: Issues, https://github.com/rguiu/armada/issues
Keywords: ai,agents,tmux,llm,orchestration,claude,opencode
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: User Interfaces
Classifier: Topic :: System :: Clustering
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastapi<1.0,>=0.100
Requires-Dist: uvicorn<1.0,>=0.20
Requires-Dist: websockets<15.0,>=10.0
Requires-Dist: qrcode<10.0,>=7.0
Requires-Dist: mcp<2.0,>=1.0
Requires-Dist: tomli>=1.0; python_version < "3.11"
Provides-Extra: test
Requires-Dist: pytest>=8.0; extra == "test"
Requires-Dist: httpx2>=0.1; extra == "test"
Requires-Dist: pytest-cov>=5.0; extra == "test"
Requires-Dist: pytest-timeout>=2.0; extra == "test"
Dynamic: license-file

```
   █████╗ ██████╗ ███╗   ███╗ █████╗ ██████╗  █████╗
  ██╔══██╗██╔══██╗████╗ ████║██╔══██╗██╔══██╗██╔══██╗
  ███████║██████╔╝██╔████╔██║███████║██║  ██║███████║
  ██╔══██║██╔══██╗██║╚██╔╝██║██╔══██║██║  ██║██╔══██║
  ██║  ██║██║  ██║██║ ╚═╝ ██║██║  ██║██████╔╝██║  ██║
  ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝     ╚═╝╚═╝  ╚═╝╚═════╝ ╚═╝  ╚═╝
```

> Persistent sessions and live supervision for coding agents.

[![PyPI](https://img.shields.io/pypi/v/armada-ai)](https://pypi.org/project/armada-ai/)
[![Test PyPI](https://img.shields.io/badge/testpypi-v0.2.2-blue.svg)](https://test.pypi.org/project/armada-ai/)
[![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://pypi.org/project/armada-ai/)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/rguiu/armada/blob/main/LICENSE)

## What is Armada?

Armada runs coding agents in persistent tmux sessions and lets you monitor and control them from a dashboard or CLI.

Each agent runs in its own session and maintains state across reconnects, restarts, and devices. You can start agents from your laptop, disconnect and reconnect later, monitor execution in real time, and manage multiple agents at once.

### Key Features

- **Persistent agent sessions** — every agent runs inside a tmux session and survives disconnects. No custom runtime.
- **Live status tracking** — see which agents are active, idle, pending, or error in real time.
- **Web + terminal control** — manage agents via the dashboard or `armada watch`.
- **Multi-agent workflows** — spawn workers and coordinate execution across a tree of agents.
- **Message system** — structured communication between nodes with event-driven delivery.
- **MCP integration** — agents interact with Armada through typed MCP tools instead of raw API calls.

## Installation

**Prerequisites:** Python 3.10+, tmux, and either OpenCode or Claude Code installed on your PATH.

```bash
pip install armada-ai
armada setup                # install agent skills for OpenCode and Claude Code
```

`armada` is now available. You can also install from source or run via Docker — see below.

<details>
<summary>Docker</summary>

```bash
docker build -t armada .
docker run -d -p 9100:9100 --name armada armada
```
</details>

<details>
<summary>From source</summary>

```bash
git clone https://github.com/rguiu/armada.git
cd armada
bash install.sh
```
</details>

<details>
<summary>Test PyPI (pre-release)</summary>

Test PyPI may contain typosquat packages that hijack dependency names. Install in two steps to keep dependencies on real PyPI:

```bash
pip install --index-url https://pypi.org/simple/ fastapi uvicorn websockets qrcode mcp 'tomli>=1.0'
pip install --index-url https://test.pypi.org/simple/ --no-deps armada-ai
armada setup
```
</details>

## Quick Start

```bash
armada                     # start server + open dashboard
```

Open `http://127.0.0.1:9100`.

1. **Register a project** — sidebar Projects → **+ Add**. Give it an ID, name, and directory path.
2. **Create a node** — click **+ Node**, pick a project, choose an agent type (OpenCode, Claude Code, or Bash), optionally add an initial prompt.
3. **Attach** — select the node and click **Attach**. Opens the agent session in iTerm2 (macOS) for full TUI, or xterm.js in-browser.
4. **Monitor** — the dashboard updates every 10 seconds. See status, activity logs, and task history.
5. **Connect other devices** — scan the QR code in the sidebar to open the dashboard on your phone or tablet.

![Armada Dashboard](img/armada.png)

![CLI Demo](img/armada1.gif)

## CLI Watch Dashboard

`armada watch` is a live terminal dashboard for managing agents without a browser:

```
$ armada watch

 Nodes   Projects   |  3 active  1 pending  12 idle  |  23 agents

 ● HOOK20           ▣ idle   PGLease            unknown needs external_directory
 ○ HOOK18             idle   PGLease            server restarted — reconnected
 ○ H1                 idle   Armada
 ○ Armada-006         idle   Armada
 ● Armada-005         active Armada             running bash

 ⚠ Pending: HOOK20

 ┃ [↑↓]nav [enter]attach [n]ew [k]kill [d]delete [tab]projects [q]quit ┃
```

<details>
<summary>Full keybindings and forms</summary>

| Key | Action |
|---|---|
| `↑` `↓` | Navigate agent list |
| `Enter` | Attach to selected node (focuses existing pane) |
| `a` | Split-attach (experimental — opens a new tmux pane for the node) |
| `n` | New node (interactive form) |
| `k` | Kill selected node |
| `d` | Delete selected node |
| `Tab` | Switch to Projects view |
| `q` | Quit |

> **Note:** `a` (split-attach) is experimental and may not work reliably in all terminal environments. It is not shown in the bottom bar but remains available as a hidden shortcut.

Forms for creating nodes and projects use keyboard navigation: `Tab`/`↑↓` to move between fields, `←→` to cycle options, type freely in text fields, `Enter` on `[Save]` to submit, `Esc` to cancel.
</details>

## Agent Types: Claude Code vs OpenCode

Armada supports both Claude Code and OpenCode as first-class agents. Each integrates differently:

### OpenCode

OpenCode is an open-source AI coding agent. Armada's OpenCode integration uses:

- **MCP Server** — an Armada MCP server provides typed tools (`spawn_node`, `send_message`, `report_status`, etc.) directly in the agent's tool palette. Auto-configured via `opencode.json`.
- **Plugin system** — an `armada-pending` plugin hooks into OpenCode's event loop (tool start/stop, permission requests). Agents automatically report status to Armada.
- **Skills** — `armada-node` and `armada-worker` skill files teach agents orchestration and messaging patterns.

To use OpenCode: install it, make sure `opencode` is on your PATH, and run `armada setup`. When creating a node, select "opencode" as the agent type.

### Claude Code

Claude Code is Anthropic's official CLI agent. Armada's Claude Code integration uses:

- **Hook system** — four shell hooks fire on tool use, idle transitions, and permission requests. These use the `armada report` CLI to report status.
- **Skills** — the same skill files are installed to `~/.claude/skills/` and auto-activate when `ARMADA_NODE_NAME` is set.

To use Claude Code: install it via `npm install -g @anthropic-ai/claude-code`, make sure `claude` is on your PATH, and run `armada setup`. When creating a node, select "claude" as the agent type.

### Bash

Bare shell nodes without an agent. Useful for running scripts or manual commands. Armada provides a bash wrapper (`armada-bash.sh`) with functions like `armada_report_active`, `armada_spawn`, and `armada_kill_child`. Status reporting uses the `armada report` CLI.

### Which one should you use?

| | OpenCode | Claude Code |
|---|---|---|
| **Install** | `pip install opencode` | `npm install -g @anthropic-ai/claude-code` |
| **Status reporting** | Plugin (TypeScript, event-driven) | Shell hooks (pre/post-tool, stop) |
| **Permissions** | Permission events in plugin | `claude-permission.sh` hook |
| **Cost tracking** | Token usage from step-finish events | Not built in |
| **Best for** | Open-source workflows, custom plugins | Anthropic ecosystem, official support |

Either works. Pick based on which agent you already have installed.

## Commands

| Command | Description |
|---|---|
| `armada` | Start daemon + open dashboard |
| `armada --no-browser` | Start server without opening browser |
| `armada start` | Start daemon in background |
| `armada stop` | Stop the daemon |
| `armada watch` | Interactive terminal dashboard (htop-style) |
| `armada create -p <project>` | Create a new agent node |
| `armada nodes` | List all agents in a table |
| `armada attach <name>` | Attach to a node by name (iTerm2) |
| `armada projects` | List projects |
| `armada projects add <id> <name> <path>` | Register a project |
| `armada projects rm <id>` | Remove a project |
| `armada setup` | Install skills and MCP config to user profile |
| `armada version` | Print the Armada version |
| `armada token` | Print the auth token |
| `armada token --qr` | Print token as scannable QR code |
| `armada config` | Show or set configuration |
| `armada config set <key> <val>` | Change a config value (`default_agent`, `port`, etc.) |
| `armada service install` | Install as system service (launchd/systemd) |
| `armada status` | Show server health and agent counts |
| `armada doctor` | Clean up stale tmux sessions and DB state |
| `armada mcp` | Start the Armada MCP server (stdio mode, for AI agents) |
| `armada report <status> <msg>` | Report node status (used by hooks and scripts) |
| `armada --lan` | Bind server to LAN IP (access from other devices) |

## Agent Delegation

Agents can delegate work to child nodes using MCP tools:

```
Orchestrator
├── Reviewer  — reviews the code
└── Tests     — writes and runs tests
                └── sends "job completed" message back to Orchestrator
```

1. Start Armada: `armada`
2. Register a project and create an orchestrator node (agent type: "opencode" or "claude")
3. The orchestrator uses `spawn_node("reviewer")` and `send_task(node_id, "review the auth module")` — agent type and project are inherited automatically
4. Workers send completion messages back to the parent via `send_message(to_node_id=parent_id, payload="job completed", msg_type="result")`
5. The orchestrator collects results via `read_inbox()` and cleans up with `kill_node()`

Skills (`armada-node`, `armada-worker`, `armada-orchestrator`) teach agents the full workflow including messaging patterns.

## MCP Server

Armada includes an MCP (Model Context Protocol) server that exposes all operations as typed tools for AI agents. Instead of constructing curl commands, agents call tools with automatic defaults:

| Tool | Purpose |
|------|---------|
| `spawn_node(name)` | Spawn a child node (inherits agent_type, project, parent) |
| `send_task(node_id, command)` | Send command to node (auto-waits for tmux init) |
| `kill_node(node_id)` | Kill node and descendants |
| `get_tree()` | Full node hierarchy with status |
| `get_node(node_id)` | Node details and reports |
| `report_status(status, message)` | Report own status |
| `send_message(to_node_id, payload)` | Send message to another node |
| `read_inbox()` | Read pending messages |
| `broadcast(payload)` | Send message to all children |
| `post_to_queue(payload)` | Post task to shared work queue |
| `claim_from_queue()` | Claim next available queue task |

The MCP server is auto-configured when nodes are created. Run manually with `armada mcp`.

## Inter-Node Messaging

Nodes communicate through a task mailbox system with event-driven delivery:

- **Direct messages** — any node can send structured messages to any other node
- **Broadcast** — fan-out a message to all children with one call
- **Work queue** — post tasks to a shared queue for any idle agent to claim
- **Event-driven delivery** — no polling; the server pushes messages via tmux when the recipient goes idle
- **ACK** — messages track `pending → delivered → done` lifecycle
- **Completion notifications** — workers automatically notify their parent when a task is done

## Architecture

Armada uses a FastAPI server with SQLite (WAL). Each node is backed by a tmux session — no custom agent runtime, just tmux providing persistence, reconnection, and multiplexing. Nodes report status via `POST /api/report`. The dashboard refreshes over a persistent WebSocket.

## API Endpoints

| Method | Path | Purpose |
|---|---|---|
| `GET` | `/api/tree` | Full node hierarchy |
| `POST` | `/api/nodes` | Create node |
| `GET` | `/api/nodes/:id` | Node detail + reports |
| `DELETE` | `/api/nodes/:id` | Kill node + cascades to children |
| `POST` | `/api/nodes/:id/send` | Send command to worker |
| `POST` | `/api/nodes/:id/attach` | Open terminal attached to node |
| `POST` | `/api/report` | Agent status report (`active`/`idle`/`pending`/`error`) |
| `POST` | `/api/nodes/:id/messages` | Send message to node |
| `GET` | `/api/nodes/:id/messages` | Read node inbox |
| `PATCH` | `/api/messages/:id` | Acknowledge message (mark done) |
| `POST` | `/api/nodes/:id/broadcast` | Broadcast to all children |
| `POST` | `/api/queue` | Post task to shared work queue |
| `GET` | `/api/queue` | List unclaimed queue tasks |
| `POST` | `/api/queue/:id/claim` | Claim a queue task |
| `GET/POST/DELETE` | `/api/project-labels` | CRUD project directories |
| `GET` | `/health` | Health check (no auth) |
| `GET` | `/metrics` | Prometheus metrics |

Full API docs at `http://127.0.0.1:9100/docs` (FastAPI Swagger UI).

## Development

```bash
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[test]"

pytest                          # run tests
pytest --cov=armada_ai          # with coverage
ruff check armada_ai/ tests/    # lint
```

CI runs ruff + pytest-cov on Python 3.10–3.13 on push to `main`.

## License

MIT
