Production AI coding agent
Project description
Attocode
Production AI coding agent built in Python. Features a Textual-based TUI, multi-agent swarm orchestration, intelligent budget management, and a safety sandbox system.
Features
- Interactive TUI --- Rich terminal interface with live tool status, streaming, plan/task panels, and keyboard shortcuts (powered by Textual)
- Single-turn mode --- Run one-shot prompts from the command line for scripting and automation
- Swarm mode --- Multi-agent orchestration with a standalone Python hybrid coordinator (
attoswarm) and heterogeneous backends - Budget management --- Token-based economics with doom-loop detection, phase tracking, and budget extension dialogs
- Safety sandbox --- Platform-aware command isolation (Seatbelt on macOS, Landlock on Linux, Docker, or allowlist fallback)
- Session persistence --- SQLite-backed sessions, checkpoints, goals, audit logs, and permission grants that persist across prompts
- MCP support --- Connect external tools via the Model Context Protocol
- Multi-provider --- Anthropic, OpenRouter, and OpenAI adapters
- Skills & agents --- Extensible skill and agent system with project-level and user-level customization
Requirements
- Python 3.12+
- An API key for at least one LLM provider (e.g.
ANTHROPIC_API_KEY)
Installation
Development install (recommended)
git clone https://github.com/eren23/attocode.git
cd attocode/attocode_py
uv sync --all-extras # creates .venv, installs everything
Global install (recommended for end users)
# From the repo root (or use ./attocode_py from parent)
cd attocode/attocode_py
uv tool install --force . --with anthropic --with openai
This installs three commands globally: attocode, attocodepy, and attoswarm.
To update after pulling new code:
uv tool install --force . --with anthropic --with openai
Optional provider extras
uv sync --extra anthropic # Anthropic SDK (recommended)
uv sync --extra openai # OpenAI SDK
uv sync --extra tree-sitter # AST parsing for code analysis
uv sync --extra dev # Development tools (pytest, mypy, ruff)
uv sync --all-extras # All of the above
Fallback: pip / pipx (if uv is not available)
# Dev install
python -m venv .venv
source .venv/bin/activate # or .venv/Scripts/activate on Windows
pip install -e ".[dev]"
# Global install with pipx (installs attocode, attocodepy, attoswarm)
pipx install --force .
# Provider extras
pip install -e ".[anthropic]"
pip install -e ".[openai]"
Set your API key:
export ANTHROPIC_API_KEY="sk-ant-..."
# Or for OpenRouter:
export OPENROUTER_API_KEY="sk-or-..."
Quick Start
Single-turn --- ask a question and get one response:
attocode "List all Python files in this project"
Interactive TUI --- launch the full terminal interface:
attocode
Swarm mode --- decompose a task across multiple parallel agents:
attocode --swarm "Build a REST API for a todo app with tests"
Hybrid swarm mode (recommended) --- process-boundary orchestration via attoswarm:
attocode --swarm .attocode/swarm.yaml --hybrid "Build a REST API for a todo app with tests"
# or directly
attoswarm run .attocode/swarm.yaml "Build a REST API for a todo app with tests"
Run the standalone dashboard for a run directory:
attoswarm tui .agent/hybrid-swarm
Running from Anywhere
The attocode command always operates on the current working directory --- it reads .attocode/config.json from where you run it, so the install location doesn't matter.
uv tool install (recommended): Already on PATH after install --- attocode, attocodepy, and attoswarm all work from any directory. Rebuild after code changes with uv tool install --force . --with anthropic --with openai.
uv run (from the project directory):
cd /path/to/attocode_py
uv run attocode "your prompt"
Other options: venv activation, shell alias, symlink
Activate the venv:
source /absolute/path/to/attocode_py/.venv/bin/activate
attocode "your prompt"
Shell alias: Add to ~/.bashrc, ~/.zshrc, or ~/.config/fish/config.fish:
# bash / zsh
alias attocode="/absolute/path/to/attocode_py/.venv/bin/attocode"
# fish
alias attocode /absolute/path/to/attocode_py/.venv/bin/attocode
Symlink:
ln -s /absolute/path/to/attocode_py/.venv/bin/attocode ~/.local/bin/attocode
CLI Reference
| Flag | Short | Description |
|---|---|---|
PROMPT |
Positional --- run single-turn with this prompt | |
--model |
-m |
LLM model to use |
--provider |
LLM provider (anthropic, openrouter, openai) |
|
--permission |
-p |
Permission mode: strict, interactive, auto-safe, yolo |
--yolo |
Shorthand for --permission yolo (auto-approve all) |
|
--task |
-t |
Task description (alternative to positional prompt) |
--max-tokens |
Maximum response tokens | |
--temperature |
LLM temperature (0.0--1.0) | |
--max-iterations |
-i |
Maximum agent iterations |
--timeout |
Request timeout in seconds | |
--resume |
Resume a previous session by ID | |
--tui / --no-tui |
Force TUI or plain REPL mode | |
--theme |
TUI theme (dark, light, auto) |
|
--trace |
Save JSONL execution traces to .attocode/traces/ |
|
--swarm |
Enable swarm mode (optional: path to config YAML) | |
--swarm-resume |
Resume a previous swarm session by ID | |
--hybrid |
Route swarm execution to standalone attoswarm orchestrator |
|
--paid-only |
Only use paid models (no free tier) | |
--debug |
Enable debug logging | |
--non-interactive |
Run in non-interactive mode | |
--version |
Show version and exit |
Keyboard Shortcuts
| Key | Action |
|---|---|
Ctrl+C |
Exit (press twice to force quit during execution) |
Ctrl+L |
Clear message log |
Ctrl+P |
Open command palette / help |
Ctrl+Y |
Copy last agent response to clipboard |
Ctrl+T |
Toggle tool call details |
Ctrl+W |
Toggle swarm panel |
ESC |
Cancel current operation |
Slash Commands
The TUI provides ~48 slash commands. Type /help in the TUI to see the full list. Here are the most commonly used:
Core
| Command | Description |
|---|---|
/help |
Show all available commands |
/status |
Show agent status and metrics |
/budget |
Show budget usage details |
/extend [amount] |
Request budget extension |
/model [name] |
Show or switch the LLM model |
/compact |
Force context compaction |
/save |
Save current session checkpoint |
/clear |
Clear message log |
/quit |
Exit the application |
Session Persistence
Session data (goals, audit logs, permissions, checkpoints) is stored in SQLite and persists across prompts within the same TUI session.
| Command | Description |
|---|---|
/sessions |
List recent sessions |
/load <id> |
Load a previous session |
/resume [id] |
Resume most recent (or specific) session |
/checkpoint |
Create a named checkpoint |
/checkpoints [id] |
List checkpoints for a session |
/reset |
Reset conversation (clear messages & metrics) |
/handoff [fmt] |
Export session handoff summary |
Goals
Track high-level objectives across prompts:
| Command | Description |
|---|---|
/goals |
List current goals |
/goals add "..." |
Add a new goal |
/goals done <n> |
Mark goal N as complete |
/goals all |
Show all goals including completed |
Debug & Audit
| Command | Description |
|---|---|
/audit |
Show recent tool call audit log |
/grants |
Show remembered permission grants |
/trace [subcmd] |
Trace inspection (summary/analyze/issues/export) |
/undo [path] |
Undo last file change (or specific file) |
/diff |
Show file changes made in this session |
/context [breakdown] |
Show context window token details |
Skills & Agents
| Command | Description |
|---|---|
/skills |
List available skills |
/skills info <name> |
Show detailed skill info |
/skills new <name> |
Create a new skill scaffold |
/agents |
List available agents |
/agents info <name> |
Show detailed agent info |
/spawn <task> |
Spawn a subagent for a task |
MCP (Model Context Protocol)
| Command | Description |
|---|---|
/mcp |
List connected MCP servers |
/mcp tools |
Show tools from MCP servers |
/mcp connect <cmd> |
Connect a new MCP server |
/mcp disconnect <name> |
Disconnect an MCP server |
Configuration
| Command | Description |
|---|---|
/init |
Initialize .attocode/ directory structure |
/config |
Show current config (provider, model, key) |
/config provider <name> |
Switch provider (persists globally) |
/config model <name> |
Switch model (persists globally) |
/config api-key |
Re-enter API key (TUI dialog) |
/setup |
Run the first-time setup wizard |
/theme [name] |
Show or switch theme |
Swarm Mode
Swarm mode decomposes complex tasks into subtasks, schedules them in dependency-aware waves, and dispatches them to parallel worker agents. In hybrid mode (--hybrid), orchestration is handled by the standalone Python attoswarm package over a filesystem protocol, with workers running as subprocesses.
See docs/swarm-guide.md for a detailed walkthrough with examples. For day-to-day hybrid execution and observability, see docs/hybrid-swarm-operations.md.
For a complete example project using hybrid swarm orchestration, see attocodepy_swarmtester_3.
Quick setup:
# Copy the example config
cp .attocode/swarm.yaml.example .attocode/swarm.yaml
# Run swarm mode
attocode --swarm "Build a REST API for a todo app with tests"
Configuration
Attocode reads configuration from a hierarchy of locations:
~/.attocode/ # User-level (global defaults)
config.json
rules.md
skills/
agents/
.attocode/ # Project-level (overrides user-level)
config.json
swarm.yaml
rules.md
skills/
agents/
Priority: built-in defaults < ~/.attocode/ < .attocode/
Key config options (config.json)
{
"model": "claude-sonnet-4-20250514",
"provider": "anthropic",
"max_tokens": 8192,
"temperature": 0.0,
"max_iterations": 25,
"sandbox": { "mode": "auto" }
}
Swarm config (swarm.yaml)
See .attocode/swarm.yaml.example for a fully annotated template.
Architecture
src/attocode/
types/ Type definitions (messages, agent, config)
agent/ Core agent orchestrator and builders
core/ Execution loop, subagent spawner, tool executor
providers/ LLM provider adapters (Anthropic, OpenRouter, OpenAI)
tools/ Built-in tool implementations (file ops, bash, search)
integrations/ Feature modules organized by domain:
budget/ Economics, budget pools, doom-loop detection
context/ Context engineering, compaction, codebase analysis
safety/ Policy engine, sandbox (seatbelt/landlock/docker)
persistence/ SQLite session store, checkpoints, goals
agents/ Shared blackboard, delegation protocol
tasks/ Task decomposition, planning, verification
skills/ Skill loading and execution
mcp/ MCP client and tool integration
quality/ Learning store, self-improvement, health checks
utilities/ Hooks, rules, routing, logging, retry
swarm/ Multi-agent orchestrator (18 modules, 10k+ lines)
streaming/ Streaming and PTY shell
lsp/ Language server protocol integration
tricks/ Context engineering techniques
tracing/ Trace collector, event types, cache boundary tracking
tui/ Textual TUI (app, widgets, dialogs, bridges, styles)
Testing
# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=attocode --cov-report=term-missing
# Run a specific test file
uv run pytest tests/unit/tui/test_swarm_panel.py -v
# Linting and type checking
uv run ruff check src/ tests/
uv run mypy src/
Project Stats
| Metric | Count |
|---|---|
| Source files | 318 |
| Source lines | ~75,000 |
| Test files | 116 |
| Test lines | ~29,300 |
| Total tests | 2,778+ |
Known Issues
snapshot_report.htmlin git history: Commit207feeecontains asnapshot_report.htmlthat exposes a (now-rotated) OpenRouter API key. The file has been untracked and added to.gitignore. The key in the history is no longer valid. Before making this repository public, a history rewrite (git filter-repo) must be run to permanently remove the file from all commits.
TODO
Incremental codebase context updates
The codebase context system (integrations/context/) currently does a full os.walk + re-parse on every discover_files() call and caches _repo_map / _dep_graph with no invalidation. When the agent edits or creates files mid-session, the cached data goes stale silently — symbols, dep graph, and importance scores all reflect the state at discovery time.
What's needed:
- Hook into tool results. After
write_file,edit_file, orbash(when it creates/deletes files), mark affected entries in_filesas dirty instead of re-walking the entire tree. - Mtime-based staleness. Store
mtimeperFileInfo. On the nextget_repo_map()/select_context(), stat only dirty files and re-parse them. TheCodeAnalyzercontent-hash cache already handles re-analysis correctly — the gap is that nothing triggers it. - Incremental dep graph. When a file changes, remove its old edges from
DependencyGraph.forward/.reverse, re-parse its imports, and add new edges. No need to rebuild the entire graph. - Invalidate
_repo_mapon any file mutation. The tree text and language stats are cheap to regenerate, so just nulling_repo_mapis fine. - New/deleted file handling.
discover_files()is the only way to pick up new files or notice deletions. A lightweight incremental scan (check parent dirs of changed paths) would avoid full re-walks.
The CodeAnalyzer._cache (djb2 content hash) already does per-file invalidation correctly — the problem is one layer up in CodebaseContextManager which has no change-awareness at all.
Documentation
- Architecture --- Module relationships and data flow
- Providers --- LLM provider adapter reference
- Sandbox --- Platform-aware command isolation
- Budget --- Token economics and doom-loop detection
- MCP --- Model Context Protocol integration
- Testing --- Test patterns and conventions
- Contributing --- How to contribute
License
See LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file attocode-0.1.10.tar.gz.
File metadata
- Download URL: attocode-0.1.10.tar.gz
- Upload date:
- Size: 1.1 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
83358778a991cc5dc0b27de1337a64a3d3930652b5f55f25f8a3dc17dfe1658e
|
|
| MD5 |
bdf37cb0d6dc09c67eb5ef815c5b657e
|
|
| BLAKE2b-256 |
a15a5c77fc50330e6cf25675aa99c4c12d8719485f3b1d53f8f8fa2c08c0abe8
|
Provenance
The following attestation bundles were made for attocode-0.1.10.tar.gz:
Publisher:
release-py.yml on eren23/attocode
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
attocode-0.1.10.tar.gz -
Subject digest:
83358778a991cc5dc0b27de1337a64a3d3930652b5f55f25f8a3dc17dfe1658e - Sigstore transparency entry: 1017554638
- Sigstore integration time:
-
Permalink:
eren23/attocode@64a6403532b3d109431c51c5ea1409853a0cba4a -
Branch / Tag:
refs/tags/v0.1.10 - Owner: https://github.com/eren23
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-py.yml@64a6403532b3d109431c51c5ea1409853a0cba4a -
Trigger Event:
push
-
Statement type:
File details
Details for the file attocode-0.1.10-py3-none-any.whl.
File metadata
- Download URL: attocode-0.1.10-py3-none-any.whl
- Upload date:
- Size: 824.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6cb83fc61328e64bd19c372bc3e027b9cafe2305d374fc252aecf5e459d47694
|
|
| MD5 |
2df4468e8b467bc1bf9ea69fa653998e
|
|
| BLAKE2b-256 |
5f6df540de9b397defe47a9d2a62aad7dba4db3aecd96df59775f54fb20b199c
|
Provenance
The following attestation bundles were made for attocode-0.1.10-py3-none-any.whl:
Publisher:
release-py.yml on eren23/attocode
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
attocode-0.1.10-py3-none-any.whl -
Subject digest:
6cb83fc61328e64bd19c372bc3e027b9cafe2305d374fc252aecf5e459d47694 - Sigstore transparency entry: 1017554704
- Sigstore integration time:
-
Permalink:
eren23/attocode@64a6403532b3d109431c51c5ea1409853a0cba4a -
Branch / Tag:
refs/tags/v0.1.10 - Owner: https://github.com/eren23
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-py.yml@64a6403532b3d109431c51c5ea1409853a0cba4a -
Trigger Event:
push
-
Statement type: