# anima

CLI agent runner with lifecycle management. Spawn, monitor, interact with, and collect LLM agents from your terminal.

Each agent runs its own PydanticAI loop and exposes an MCP server interface for status, interaction, and interruption.

## Install

```bash
pip install anima
```

## Development Setup

For development and verification:

```bash
# 1. Clone repository
git clone https://github.com/yourorg/anima.git
cd anima

# 2. Install uv (if not already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh

# 3. Install dependencies (including dev tools)
uv sync --extra dev

# 4. Run verification
uvx invar-tools guard --all
```

**Environment requirements**:
- Python 3.11+
- `uv` package manager (handles all dependency resolution)
- Dependencies in `pyproject.toml` are automatically installed by `uv sync`

**Guard/Doctest reproducibility**: All dependencies (including `fastmcp>=2.0.0` and dev tools) are declared in `pyproject.toml`. Use `uvx invar-tools guard` for reproducible verification in fresh worktrees.

**Development workflow**:
- **Install dev dependencies first**: `uv sync --extra dev` (required for pytest, doctest execution)
- **Run guard with all checks**: `uvx invar-tools guard --all` (contract + static + doctest)
- **Guard runs doctests by default**: No separate configuration needed — contracts and doctests are verified automatically

## Quick start

Run a one-off task:

```bash
anima run --persona-file researcher.json \
          --llm-base-url http://localhost:4000/v1 \
          --mcp "npx -y @anthropic/mcp-server-web" \
          "Summarize today's top HN posts"
```

Spawn a background agent:

```bash
anima spawn --persona-file monitor.json \
            --job-file watch-job.json \
            --lifecycle daemon
```

List running agents:

```bash
anima list
```

Talk to an agent interactively:

```bash
anima talk abc123
```

The `talk` command automatically detects if the agent supports SSE streaming (progressive
output). New agents emit text chunks in real-time via Server-Sent Events; older agents
(<0.1.0) return 404 and fall back to blocking mode (wait for complete response).

Streaming behavior:
- Detects SSE support once per session, caches result
- Progressive output with chunk/done/error events
- `/stop` cancels current turn, agent continues running
- `/quit` or Ctrl-C detaches session, agent continues running

Collect a daemon's result:

```bash
anima collect abc123
```

Kill an agent:

```bash
anima kill abc123
```

## CLI reference

### Launch (run, spawn, chat)

| Command | Description |
| ------- | ----------- |
| `anima run` | Run one-off agent task |
| `anima spawn` | Spawn background agent |
| `anima chat` | Spawn an ephemeral agent and attach interactive chat |

### Observe (list, status, inspect, logs, tree)

| Command | Description |
| ------- | ----------- |
| `anima list` | List agents |
| `anima status <id>` | Agent details |
| `anima inspect <id>` | Full agent snapshot |
| `anima logs <id>` | View agent event logs |
| `anima tree` | Show agent hierarchy tree |

### Control (approve, reject, resume, kill)

| Command | Description |
| ------- | ----------- |
| `anima approve <id>` | Approve agent's approval request |
| `anima reject <id>` | Reject agent's approval request |
| `anima resume <id>` | Resume suspended agent |
| `anima kill <id>` | Kill agent |

### Monitor (monitor, serve, talk)

| Command | Description |
| ------- | ----------- |
| `anima monitor` | TUI dashboard |
| `anima serve --port <n>` | Remote node mode (MCP server) |
| `anima talk <id>` | Interactive session with agent |

### Cleanup (rm, prune)

| Command | Description |
| ------- | ----------- |
| `anima rm <id>` | Remove agent state |
| `anima prune` | Batch-clean terminal agents |

All commands support `--json` for machine-readable output.

## Agent lifecycle

**Ephemeral** agents run to completion and exit. Use `anima run` for non-interactive one-off execution, or `anima chat` to launch and attach an interactive session.

`anima chat` preserves the spawned instance only when you pass `--keep` or detach with `/detach`; otherwise it performs cleanup after the session exits.

**Daemon** agents run in the background until collected or killed. Use `anima spawn --lifecycle daemon`.

Agents can be in these states: `pending`, `running`, `suspended`, `awaiting_approval`, `completed`, `failed`, `killed`.

## How it works

- Each agent process is an MCP server exposing `anima.status()`, `anima.interact()`, and `anima.interrupt()`.
- Agents get built-in `ctl.*` tools for lifecycle control: finish, fail, suspend, request approval, spawn sub-agents.
- Budget enforcement with grace finalization when token limits are reached.
- State stored in `$ANIMA_STATE` (default `~/.anima/`).

## License

MIT
