Terraform-style agent operations for AI coding tools. Define your agent team, run repeatable workflows, track every artifact and gate, and move from messy terminal sessions to versioned engineering operations.
cargo install tuttiTutti is the operations layer above Claude Code, Codex, Aider, OpenClaw, and API-direct agents. It gives each agent a role, worktree, workflow, audit trail, and dashboard so issue intake, implementation, review, CI, and merge gates happen as repeatable "org code" in tutti.toml.
Agent SDKs help you build agents. Tutti helps you run agent work.
Factory floor: 3 agents working simultaneously, work-item dots flowing through the pipeline, dispatch panel to trigger runs from the browser.
Agent Focus Mode: live terminal output, token usage stats (985K input, 41.6M cache read), prompt bar to send instructions.
cargo install tutti # install the CLI (requires Rust)
cd your-project
tt init --template rust-cli # generate a Rust CLI agent-ops config
tt run --list # see workflows generated for this repo
tt run verify --strict # first successful workflow: cargo test + clippy
tt up # launch your persistent agent team
tt serve --port 4040 # inspect runs, agents, logs, and handoffsOr pick a template explicitly:
tt init --template gstack-startup # 5-agent interactive SDLC team
tt init --template rust-cli # 3-agent Rust project team
tt init --template minimal # 2-agent starterPrerequisites: Rust toolchain, tmux, and at least one AI coding CLI installed for agent sessions (Claude Code, Codex, or Aider). Command-only workflows such as the Rust template's verify can run before you launch agents. For non-Rust repos, start with tt init or tt init --template minimal, then add the smallest verification command your project already trusts.
Tutti models the engineering loop as pluggable operational stages:
- Intake: GitHub issue, Linear ticket, Jira ticket, local queue, or webhook event.
- Execution: Claude Code, Codex, Aider, OpenClaw, or API-direct model providers.
- Review: CodeRabbit, Claude/Codex reviewer packets, human approval, CI, or policy checks.
- Gate: required checks, resolved review threads, approval state, cost/policy limits.
- Record: run ledger, artifacts, logs, dashboard events, and replayable state.
The built-in Tutti-for-Tutti workflow uses GitHub issue intake and CodeRabbit review because that is the first concrete adapter pair. It is not the product boundary. The product boundary is the loop.
- Defines agent operations as code in
tutti.toml: roles, runtimes, workflows, hooks, gates, and policies - Spawns and manages multiple AI coding agent sessions (Claude Code, Codex, Aider) in tmux
- Isolates each agent in its own git worktree to prevent merge conflicts
- Orchestrates workflows — chain prompt steps, shell commands, and agent coordination into repeatable pipelines defined in
tutti.toml - Web dashboard at
:4040— factory-floor view of all agents with real-time SSE updates, state-driven visuals (working/idle/stopped/blocked), and workflow run tracking - Agent Focus Mode — click any agent to zoom into full-screen view with live terminal output, token usage, git diff, context health, and a prompt input bar
- Automated SDLC — claim work, plan, implement, test, open PRs, collect reviews, resolve feedback, and enforce merge gates
- API-direct agent loop — optional ModelProvider path with built-in tools, policy gates, SQLite event log, and cost tracking
- Resilience — detects auth failures, rate limits, and provider outages; auto-recovers sessions based on configured strategies
- Issue claim leases — exclusive locks on GitHub issues for autonomous workflow runs
- Not another generic agent framework. Tutti is the operations layer around agent work: lifecycle, workflow, state, review, policy, and observability.
- Not tied to one provider. It can orchestrate terminal agents and, where configured, run API-direct model providers through the same operational controls.
- No API keys required for CLI-agent mode. Existing Claude Code, Codex, Aider, or OpenClaw authentication keeps working. API-direct runs opt into provider credentials explicitly.
- No vendor lock-in. Your agent operations live in a versioned
tutti.tomlfile you can review, fork, and move.
Tutti is strongest when coordination is the bottleneck, not raw model quality:
- You already run multiple agent sessions and the human is doing the routing, tracking, and merge management by hand
- Work splits cleanly into separable lanes: implementation, testing, docs, review
- You want persistent specialists working through a backlog, not five agents crowding one change
- The work contains waiting states that parallel agents can hide: test runs, review loops, CI, retries
A single agent is often the better choice when the repo is small, the task is tightly coupled, or the coordination tax would outweigh any throughput gain.
Your agent team topology is defined in tutti.toml — who does what, which runtime, what workflows:
[workspace]
name = "my-project"
[roles]
implementer = "claude-code"
tester = "claude-code"
reviewer = "codex"
[[agent]]
name = "implementer"
role = "implementer"
[[agent]]
name = "tester"
role = "tester"
[[workflow]]
name = "verify"
[[workflow.step]]
type = "prompt"
agent = "tester"
text = "Run the test suite and report results."
wait_for_idle = trueSwap claude-code for codex in [roles] and every agent using that role switches runtime — no per-agent edits. Version it. Share it. Fork someone else's.
# Install from crates.io
cargo install tutti
# Or install from source
git clone https://github.com/nutthouse/tutti.git
cd tutti
cargo install --path . --locked
# Initialize in your project
cd your-project
tt init
# Edit your team config
$EDITOR tutti.toml
# Launch
tt upIf tt is not found after install, add Cargo bin to your shell PATH:
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc- Core CLI commands:
init,up,down,status,voices,watch,switch,diff,detect,land,review,send,handoff,attach,peek,logs,usage,run,verify,doctor,permissions,workspaces,issue-claim - Runtime adapters: Claude Code, Codex CLI, Aider, OpenClaw
- API-direct spine:
ModelProvider, OpenAI-compatible provider, tool execution loop, policy gate, SQLite event log - Template packs:
tt init --template gstack-startupgenerates a fully configured team from built-in or custom templates, with repo auto-detection - Role mapping:
[roles]table maps logical roles to runtimes — swap providers without editing every agent - Artifact pipeline: prompt steps capture and pass typed artifacts between workflow stages via
artifact_glob/artifact_name - Artifact-polling mode: interactive skills (e.g.
/office-hours) wait for artifact files instead of idle detection, enabling human-in-the-loop workflows - Dependency-aware startup order (
depends_on) - Per-agent git worktree isolation
- Cross-workspace registry (
tt workspaces,tt up --all,tt down --all) - Token/capacity reporting via
tt usagefor API profiles (plan = "api") from local Claude Code + Codex session logs max_concurrentlaunch guardrails per profile (tt uprefuses launches above limit)- Workspace
[[tool_pack]]declarations +tt doctorprerequisite checks (commands/env/profile/runtime) - API-profile budget guardrails (
[budget]) with pre-exec checks ontt up/send/run/verify - Issue claim leases with
tt issue-claim acquire|heartbeat|release|sweepfor autonomous SDLC loops tt permissions suggest <workflow>for batch command pre-approval- Permission block errors include actionable fix hints
tt run --dry-run --jsonincludes literal command strings for pre-validation- Resume intent log + compensator preflight for safe workflow replay
- SDLC automation framework with 6-agent topology (planner, conductor, implementer, tester, docs-release, reviewer)
- Orchestration state machine + run ledger for deterministic recovery
- Session replacement flow (
tt handoff apply) hardening and richer packet templates - CLI wiring for API-direct workflow runs (
tt run --direct) - Replay UX for API-direct run event logs
- Pluggable intake and review adapters beyond GitHub + CodeRabbit
- Image upload to remote agents (bridging files to agent context from the browser)
- Provider-level failover/rate-limit rotation
- Richer cost attribution and context-health telemetry
- OpenClaw integration hardening (packaging templates + external registry examples)
- Community phrase/arrangement registry
- Why Tutti exists:
docs/WHY_TUTTI.md - External agent/orchestrator contract:
docs/AGENT_INTEGRATION_CONTRACT.md - OpenClaw skill contract:
docs/OPENCLAW_SKILL_CONTRACT.md - OpenClaw skill starter:
skills/openclaw/SKILL.md - OpenClaw integration bundle:
integrations/openclaw/README.md - PR reproducibility loop (CodeRabbit + checks + merge gate):
docs/pr-review-loop.md - Versioning and release automation:
VERSIONING.md
The team topology file. This is the "org code" — it defines your agent team as a versionable, forkable configuration.
[workspace]
name = "my-project"
description = "My project workspace"
[workspace.auth]
default_profile = "claude-personal" # profile from ~/.config/tutti/config.toml
[defaults]
worktree = true
runtime = "claude-code"
[launch]
mode = "auto" # safe | auto | unattended
policy = "constrained" # constrained | bypass
[budget]
mode = "warn" # warn | enforce
warn_threshold_pct = 80
workspace_weekly_tokens = 5000000
[budget.agent_weekly_tokens]
backend = 2000000
frontend = 1500000
[[agent]]
name = "backend"
runtime = "claude-code" # or "codex", "aider", "gemini-cli", etc.
scope = "src/api/**"
prompt = "You own the API layer. Use existing patterns. Track work in bd."
fresh_worktree = true # optional: reset this agent worktree on each tt up
[[agent]]
name = "frontend"
runtime = "claude-code"
scope = "src/app/**"
prompt = "You own the UI. Follow existing component patterns."
[[agent]]
name = "tests"
runtime = "codex"
scope = "tests/**"
prompt = "Write and maintain tests. Run the test suite after changes."
depends_on = ["backend", "frontend"]
[[workflow]]
name = "verify-app"
schedule = "*/30 * * * *"
[[workflow.step]]
id = "verify"
type = "command"
run = "cargo test --quiet"
cwd = "workspace"
subdir = "backend" # optional workspace-relative command directory
fail_mode = "closed"
output_json = ".tutti/state/verify.json"
[[workflow.step]]
type = "ensure_running"
agent = "backend"
[[workflow.step]]
type = "prompt"
agent = "conductor"
text = "Summarize anomalies from latest snapshot and propose dispatch actions."
inject_files = [".tutti/state/snapshot.json"]
[[workflow.step]]
type = "workflow"
workflow = "verify-app"
strict = true
fail_mode = "closed"
[[workflow.step]]
type = "review"
agent = "backend"
reviewer = "reviewer"
depends_on = [4]
[[workflow.step]]
type = "land"
agent = "backend"
force = true
depends_on = [5]
[[hook]]
event = "workflow_complete"
workflow_source = "observe_cycle"
workflow_name = "verify-app"
run = "echo scheduled verify completed"Profiles are configured globally in ~/.config/tutti/config.toml:
[[profile]]
name = "claude-personal"
provider = "anthropic"
command = "claude"
max_concurrent = 5
plan = "max"
reset_day = "monday"
weekly_hours = 45.0tt usage scans and aggregates usage only for profiles with plan = "api".
tt permissions is opt-in and reads [permissions] from ~/.config/tutti/config.toml.
With default launch mode (auto), constrained non-interactive runs require [permissions] allow rules.
For prompt steps that need workspace artifacts, use inject_files = ["relative/path.json"] to copy files into the target agent's working tree before the prompt is sent.
Prompt steps can capture artifacts with artifact_glob and artifact_name — after the prompt step completes, tutti globs for new files and registers them as step outputs. Downstream steps reference artifacts via inject_files = ["{{output.artifact_name.path}}"] or {{output.artifact_name.path}} in prompt text. Glob patterns support ~, {slug}, {workspace}, and {agent} interpolation.
For command steps that should run under a workspace subpath, use subdir = "relative/path" instead of shell cd ... &&.
Use depends_on = [<step-number>, ...] on workflow steps to unlock dependency-aware execution; independent ensure_running/review/land steps run in parallel waves.
Budget guardrails are API-only: when [budget] is configured and the workspace profile has plan = "api", Tutti checks budget caps before up/send/run/verify, emits budget.threshold / budget.blocked control events, and either warns or blocks based on budget.mode.
Optional tool packs can be declared per workspace and validated with tt doctor:
[[tool_pack]]
name = "analytics"
required_commands = ["bq", "jq"]
required_env = ["GCP_PROJECT"]Each running agent instance is a voice — the musical term for an individual part in an ensemble. tt voices lists what's playing.
A tutti.toml file is an arrangement — the configuration that tells each voice what to play and when. Share arrangements, fork them, adapt them to your project.
A movement is a phase of work — a logical grouping of tasks across agents. "Build the auth system" might be one movement containing work across backend, frontend, and test voices.
Reusable prompt components and skills are phrases. A phrase might be a CLAUDE.md snippet, a testing methodology, a code style guide, or an architectural pattern. Publish and share phrases through the community registry.
- Spawn and manage agents from any supported runtime
- Git worktree isolation per agent (configurable)
- Session persistence across restarts
- Start and terminate individual agents (
tt up/tt down) - Inspect worktree + branch changes (
tt diff <agent>) - Land agent commits into current branch (
tt land <agent>) - Override local cleanliness guard when needed (
tt land <agent> --force, with temporary stash/restore) - Push/open PRs from agent branches (
tt land <agent> --pr) - Dispatch review packets to reviewer agent (
tt review <agent>) - Ad-hoc prompt dispatch with optional auto-start + wait + captured output (
tt send --auto_up --wait --output)
tt init --template <name>generatestutti.tomlfrom built-in or custom templates- Three starter templates:
gstack-startup(5-agent interactive SDLC),rust-cli(3-agent with verify workflow),minimal(2-agent fallback) - Repo auto-detection: templates declare
detect(any-match) anddetect_all(all-match) file patterns;tt initwithout--templatescans the repo and suggests the best match - Role mapping via
[roles]table — agents declarerole = "planner"instead of hardcoding runtimes; resolution order: explicit runtime > role lookup > defaults {{project_name}}variable substitution in template config body- Template tag (
# template: name version) in generated config, propagated toAutomationRunRecord
- Prompt steps capture output artifacts via
artifact_globandartifact_name— after a step completes, tutti globs for new files matching the pattern - Downstream steps reference artifacts via
inject_files = ["{{output.artifact_name.path}}"]— files are copied into the target agent's worktree - Artifact-polling mode: when
artifact_globis set withoutwait_for_idle, tutti polls for the artifact file every 5s instead of idle-detecting, enabling interactive skills (e.g./office-hours) where the agent waits for human input - Pre-step snapshot prevents race conditions with concurrent runs
- Glob patterns support
~,{slug},{workspace}, and{agent}interpolation
tt run/tt verifyreusable workflow execution with persisted run records- Run checkpoints persisted at
.tutti/state/workflow-checkpoints/<run_id>.json+tt run --resume <run_id> - Workflow step types:
prompt,command,ensure_running,workflow(nested),review,land - Workflow
review/landsteps auto-start required sessions when they are not already running - Workflow
landsteps enforce a merge gate. Today the built-in gate targets GitHub PRs, required checks, and resolved review threads; the stage model is designed for other review systems. workflow_completehooks for deterministic chaining- Auto-reclaim of newly-started
persistent = falsesessions at workflow end tt servelocal control API endpoints:- Reads:
/v1/health,/v1/status,/v1/voices,/v1/workflows,/v1/runs,/v1/ops,/v1/logs,/v1/handoffs,/v1/policy-decisions,/v1/events - Event cursor/list filter:
/v1/events?cursor=<RFC3339 timestamp>&workspace=<name> - SSE stream:
/v1/events/stream?cursor=<RFC3339 timestamp>&workspace=<name> - Stream emits lifecycle/control events (
agent.started,agent.stopped,agent.working,agent.idle,agent.auth_failed,workflow.started,workflow.completed,workflow.failed, handoff events) - Actions (POST):
/v1/actions/up|down|send|run|verify|review|land - Envelope shape:
ok/action/error/data sendaction returns structured send result (waited,completion_source,captured_output)- Mutating actions support
Idempotency-Keyheader (oridempotency_keyrequest field)
- Reads:
- Real-time status for all running agents
- Profile/workspace token usage and capacity estimates (
tt usage, API profiles only) - Interactive terminal watch mode with
PLAN+ liveCTXplus quick attach/peek flow - Per-agent log capture and tailing (
tt logs) - Workflow run telemetry at
.tutti/state/run-telemetry.jsonl
- OpenAI-compatible
ModelProvideradapter (built) - Provider-neutral message/content model with tool-use blocks (built)
- Built-in tools for file reads, writes, patches, shell commands, and grep/glob (built)
- Policy gate before tool execution (built)
- SQLite event log for model calls, tool calls, policy decisions, and costs (built)
tt run --directworkflow wiring (planned)tt replayfor API-direct run inspection (planned)
tt handoff generate <agent>creates markdown packets in.tutti/handoffs/tt handoff apply <agent>injects latest packet into a running agent sessiontt handoff list [--agent ...] [--json]for packet discovery- Auto packet generation in
tt watch(and post-tt up) whenCTXcrosses configured handoff threshold - Configurable packet templates and richer handoff content (planned)
- One-command session replacement polish/hardening (planned)
- Factory-floor web dashboard at
:4040with real-time SSE updates - Pipeline stages with state-driven visuals (working/idle/stopped/blocked)
- Work-item dots flowing through stages during workflow runs
- Agent Focus Mode: click any stage card → full-screen drill-down with:
- Live terminal output (polled every 2s)
- Token usage stats (input, output, cache read/write)
- Git diff of agent's worktree changes
- Context health % with color-coded fill bar
- Prompt input bar to send instructions to the agent
- Dispatch panel: trigger workflow runs from the browser
- Mobile-responsive layout with swipeable tabs on phone
- Cost breakdown by agent (planned: by provider, by time period)
- Provider health panel (auth status, rate limit state)
- Auth failure detection (OAuth expiry, provider outages)
- Rate-limit/provider outage signal detection in health probes
- Emergency state capture on auth failures
- Workflow command retry/backoff (
[resilience].retry_*) - Launch-time profile rotation/fallback (
[resilience].provider_down_strategy = "rotate_profile"orrate_limit_strategy) - Runtime auth/rate-limit/provider-down recovery in
tt serve(cooldown-throttled restart + strategy-aware profile rotation) - Runtime auth/rate-limit/provider-down recovery in
tt watch(cooldown-throttled restart + strategy-aware profile rotation) - Correlated failure detection (provider-level vs individual agent) (planned)
- Runtime/session pause-resume orchestration (planned)
- Multiple profiles per provider (personal, work, team accounts)
- Per-profile capacity settings (
plan,reset_day,weekly_hours) - Per-profile concurrency limits (
max_concurrent) enforced bytt up - Automatic launch-time profile rotation/fallback (built)
tt profilescommand (planned)
- Team-shared command allowlist in
~/.config/tutti/config.tomlunder[permissions] - Policy entries may be shell command prefixes (
git status,cargo test) and/or Claude tool names (Read,Edit,Write) tt permissions check <command...>evaluates command prefixes against policytt permissions export --runtime claudeemits a Claude settings scaffoldtt upauto-wires constrained non-interactive policy for Claude sessions- Codex/OpenClaw/Aider constrained mode is hard-enforced via Tutti shell-policy shims plus runtime flags/prompt guidance
- If constrained non-interactive launch is selected without policy,
tt upfails with guidance - Launch policy decisions are persisted to
.tutti/state/policy-decisions.jsonland exposed via/v1/policy-decisions
- Declarative
[[tool_pack]]blocks intutti.toml(required_commands,required_env) tt doctorreports pass/warn/fail for tmux, profile wiring, runtime binaries, and tool-pack prerequisitestt doctoralso probes running agents for auth health (auth/<agent>checks)tt doctorvalidates serve readiness (serve/state_dir,serve/events_log,serve/scheduler,serve/port)- CI smoke profile (
.github/workflows/ci.yml) runs headlesstt doctor --strict+tt run smoke-check --strict
- Share and discover arrangements (team configs)
- Publish and install phrases (reusable prompts/skills)
tt browseto explore what others are running
┌──────────────────────────────────────────┐
│ tt (CLI) │
│ init · run · up · serve · review · land │
├──────────────────────────────────────────┤
│ Agent Ops Core │
│ topology · workflows · gates · policies │
├─────────────────────┬────────────────────┤
│ CLI-Agent Path │ API-Direct Path │
│ Claude/Codex/Aider │ ModelProvider │
│ tmux · worktrees │ tools · policy │
├─────────────────────┴────────────────────┤
│ State + Artifacts │
│ ledgers · checkpoints · outputs · events │
├──────────────────────────────────────────┤
│ Observability │
│ logs · run telemetry · status · replay │
├──────────────────────────────────────────┤
│ Dashboard / Control API │
│ Web UI · REST API · SSE event stream │
└──────────────────────────────────────────┘
| Runtime | Status | Notes |
|---|---|---|
| Claude Code | ✅ Primary | Full support including context monitoring |
| Codex CLI | ✅ Supported | Token tracking via local Codex session logs |
| Aider | ✅ Supported | Model-agnostic |
| OpenClaw | ✅ Supported | Native runtime adapter (runtime = "openclaw") |
| Gemini CLI | 🔜 Planned | |
| Custom | 🔜 Planned | Any CLI agent via adapter interface |
BYOS: Bring Your Own Subscription. In CLI-agent mode, Tutti uses whatever tools you already have installed and authenticated. If you can run claude in your terminal, Tutti can orchestrate it. API-direct mode is explicit and configured separately.
Org code is real code. How you structure your agent team is as important as the code they write. It should be versioned, reviewed, and iterable — just like infrastructure-as-code or CI/CD pipelines.
Operations beat demos. A good agent demo writes code once. A good agent operation can be rerun, inspected, reviewed, resumed, and trusted.
Adapters, not a walled garden. GitHub and CodeRabbit are useful first integrations. The model is intake, execution, review, gate, record. Other issue trackers, agent tools, and review systems should fit the same loop.
Start simple, scale up. One agent in a tutti.toml is fine. You don't need five agents and a complex topology on day one. Tutti should make even a single agent session better through observability and handoff support, then earn the right to add more agents when the work naturally separates.
Tutti is early. If this resonates with how you work, we want to hear from you.
- Issues: Bug reports, feature requests, questions
- Discussions: Share your arrangements, talk about workflows
- PRs: See CONTRIBUTING.md for guidelines
- Debugging: See docs/OPERATOR_DEBUGGING.md for the operator failure-debugging loop
- Core CLI (
tt init,tt up,tt down,tt status,tt voices,tt watch,tt switch,tt diff,tt detect,tt land,tt review,tt send,tt handoff,tt attach,tt peek,tt logs,tt usage,tt run,tt verify,tt doctor,tt permissions,tt workspaces) - Claude Code runtime adapter
- Codex runtime adapter
- Aider runtime adapter
-
tt usageprofile/workspace capacity reporting - Context health monitoring
- Automatic handoff packet generation
- Web dashboard (factory floor + Agent Focus Mode)
- Cost tracking and attribution (provider-accurate)
- OpenClaw skill for Tutti orchestration workflows
- Issue claim leases for autonomous SDLC loops
-
tt permissions suggestfor batch workflow pre-approval - SDLC automation framework (issue → implement → test → PR → review → merge)
- Published on crates.io (
cargo install tutti) - API-direct agentic spine (provider trait, tools, agent loop, event log)
-
tt run --directCLI wiring - Pluggable intake and review adapters beyond GitHub + CodeRabbit
- Agent-to-agent message bus
- Phrase registry (community prompts/skills)
- Arrangement sharing (community team configs)
- Web dashboard (factory floor + Agent Focus Mode)
MIT
In music, tutti means "all together" — the moment every voice in the ensemble plays as one. That's what your agents should feel like.

