This Project is currently in alpha, is free to use, and officially promises nothing yet!
-
LLM Tool Claude Codex Gemini CLI
-
Kanban Provider Jira Linear GitHub Projects
An orchestration tool for AI-assisted kanban-shaped git-versioned software development.
Install Operator! Terminals extension from Visual Studio Code Marketplace
Operator is for you if:
-
you do work assigned from tickets on a kanban board, such as Jira Cloud, Linear, or GitHub Projects
-
you use LLM assisted coding agent tools to accomplish work, such as Claude Code, OpenAI Codex, or Google Gemini CLI
-
your work is version controlled with a git repository provider like GitHub or GitLab
-
you are drowning in the AI software development soup.
and you are ready to start seriously automating your work.
operator is a TUI (terminal user interface) application that uses session wrappers (tmux, cmux, or Zellij) to manage multiple AI coding agents across multi-project workspaces of many codebases. It is designed to be ticket-first, launching LLM coding agents keyed off from markdown stories from a ticketing provider. It provides:
- Queue Management: ticket queue with priority-based work assignment, launchable from a dashboard
- Agent Orchestration: Launch, monitor, pause/resume LLM coding agents against kanban shaped work tickets, and track the ticket progress as it goes through your defined work implementation steps
- Notifications: macOS and linux notifications for agent events, keeping you the human in the loop.
- Dashboard: Real-time view of queue, active agents, completed work, and waiting instances seeking feedback or human review
Operator is designed to facilitate work from markdown tickets, tackling tasks across multiple code repositories by semi-autonomous agents. Operator should be started from the root of your collective work projects repository (eg, ~/Documents), so that it may start feature or fix work in the right part of the codebase.
When started for the first time, Operator will setup configuration to consume and process work tickets, and identify local projects by scanning for LLM tool marker files (CLAUDE.md, CODEX.md, GEMINI.md) and git repositories.
Operator comes with a separate web component, unneeded to do work but purpose built to give you a developer portal to expand their workflows and administrate Operator with ease.
Operator starts and runs it's own REST API, which can be reached by outside clients, including by the opr8r wrapper client. This is included to communicate with Operator api hosts outside of where it's hosted.
# Launch dashboard operator # Quick commands (without entering TUI) operator queue # Show queue status operator launch <ticket> # Launch agent for ticket (with confirmation) operator create # Create a new work ticket operator agents # List active agents operator pause # Pause queue processing operator resume # Resume queue processing operator stalled # Show stalled agents awaiting input operator alert # Create investigation from external alert operator docs # Generate documentation from source-of-truth files operator api # Start the REST API server operator setup # Initialize operator workspace
Download the latest release for your platform:
# macOS Apple Silicon curl -L https://github.com/untra/operator/releases/latest/download/operator-macos-arm64 -o operator chmod +x operator sudo mv operator /usr/local/bin/ # Linux x86_64 curl -L https://github.com/untra/operator/releases/latest/download/operator-linux-x86_64 -o operator chmod +x operator sudo mv operator /usr/local/bin/ # Linux ARM64 curl -L https://github.com/untra/operator/releases/latest/download/operator-linux-arm64 -o operator chmod +x operator sudo mv operator /usr/local/bin/
Or build from source:
git clone https://github.com/untra/operator.git
cd operator
cargo build --release
sudo cp target/release/operator /usr/local/bin/Workspace configuration lives in .tickets/operator/config.toml (created by operator setup). An optional global override can be placed at ~/.config/operator/config.toml.
[agents] max_parallel = 5 # Maximum concurrent agents cores_reserved = 1 # Cores to keep free (actual max = cores - reserved) health_check_interval = 30 [notifications] enabled = true [notifications.os] enabled = true sound = false events = [] # Empty = all events [queue] auto_assign = true # Automatically assign work when agents free priority_order = ["INV", "FIX", "FEAT", "SPIKE"] poll_interval_ms = 1000 [paths] tickets = ".tickets" # Relative to cwd projects = "." # cwd is projects root state = ".tickets/operator" [ui] refresh_rate_ms = 250 completed_history_hours = 24 summary_max_length = 40 [launch] confirm_autonomous = true confirm_paired = true launch_delay_ms = 2000 [sessions] wrapper = "tmux" # "tmux", "cmux", or "zellij"
Work is assigned in priority order (not strict FIFO):
- INV (Investigation) - Failures need immediate attention
- FIX - Bug fixes and follow-up work
- FEAT - New features
- SPIKE - Research (requires human pairing)
Within each priority level, tickets are processed FIFO by timestamp.
| Type | Mode | Parallelism | Human Required |
|---|---|---|---|
| Investigation | Paired | Single | Yes (urgent) |
| Spike | Paired | Single | Yes |
| Fix | Autonomous | Parallel OK | No (launch confirm only) |
| Feature | Autonomous | Parallel OK | No (launch confirm only) |
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β operator v0.1.28 βΆ RUNNING 5/7 β
ββββββββββββ¬βββββββββββββ¬βββββββββββββββββββ¬ββββββββββββββββββββ€
β STATUS β QUEUE (12) β IN PROGRESS (5) β DONE (8) β
ββββββββββββΌβββββββββββββΌβββββββββββββββββββΌββββββββββββββββββββ€
β βΎ Config β INV-003 !!οΈ β AβΆ backend β β FEAT-040 12:30 β
β β dir β FIX-089 β FEAT-042 5m β β FIX-088 12:15 β
β β cfg β FIX-090 β AβΆ frontend β β FEAT-041 11:45 β
β β tkts β FEAT-043 β FIX-091 3m β β FIX-087 11:30 β
β βΎ Conns β FEAT-044 β CβΈ api β β
β β API β FEAT-045 β SPIKE-015 12m β β
β β Web β β Awaiting input β β
β tmux β β AβΆ admin β β
β βΈ Kanban β β FEAT-047 1m β β
β βΈ LLM β β AβΆ infra β β
β βΈ Git β β FIX-092 8m β β
ββββββββββββ΄βββββββββββββ΄βββββββββββββββββββ΄ββββββββββββββββββββ€
β [Q]ueue [L]aunch [P]ause [R]esume [A]gents [?]Help [q]uit β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
See Keyboard Shortcuts Reference for the full list, auto-generated from src/ui/keybindings.rs. Press ? in the TUI to view shortcuts in-app.
Agents are launched in terminal sessions with the appropriate project folder and an initial prompt derived from the ticket.
Investigations can be triggered externally:
- Webhook endpoint for alerting systems
- File watch for alert drop files
- CLI for manual urgent tickets
# Create urgent investigation from external alert operator alert --source pagerduty --message "500 errors in backend" --severity S1
Operator launches LLM agents via CLI tools in terminal sessions. Each tool is configured via a JSON definition in src/llm/tools/.
| Tool | Detection | Models | Session Flag |
|---|---|---|---|
claude |
claude --version |
opus, sonnet, haiku | --session-id |
codex |
codex --version |
gpt-4o, o1, o3 | --resume |
gemini |
gemini --version |
pro, flash, ultra | --resume |
Each tool has a JSON config in src/llm/tools/ that defines argument mappings and a command template. Operator constructs the launch command from this config:
- Prompt file: Prompts are written to
.tickets/operator/prompts/<uuid>.txtto avoid shell escaping issues with multiline prompts - Session ID: A UUID v4 is generated per launch, enabling session resumption
- Model aliases: Operator uses short aliases (e.g., "opus", "sonnet") that resolve to latest model versions
Create a new JSON tool config following the schema in src/llm/tools/tool_config.schema.json. The config defines:
- Tool binary name and version detection command
- Model aliases and argument mappings
- Command template with placeholder variables
- Capability flags (sessions, headless, permission modes)
Requirements for the LLM tool:
- Must be installable as a CLI binary
- Must accept prompt via flag (not just stdin)
- Must support model selection
- Should support session/conversation ID for continuity
- Should run interactively in a terminal (for session wrapper integration)
Operator's agent-launch hierarchy has three layers:
ββ llm_tools ββββββββββ ββ model_servers βββββββ
β claude (detected) β β anthropic-api (impl.)β
β codex (detected) β β openai-api (impl.)β
β gemini (detected) β β google-api (impl.)β
β β β ollama-local (user) β
βββββββββββββββββββββββ ββββββββββββββββββββββββ
β²γγγγ β²γγγγ
β β
ββββββ delegators ββββββββ
name, llm_tool, model, model_server (optional)
llm_toolsare the agentic coding-agent CLIs (claude/codex/gemini). They're detected on PATH and drive the session.model_serversname the host that serves the model weights. Implicit builtins (anthropic-api,openai-api,google-api) exist without declaration. Users can declare additional servers for ollama, lmstudio, vllm, or any OpenAI-compatible endpoint.delegatorsare named(llm_tool, model, model_server?)triples used to launch a ticket. Whenmodel_serveris omitted, the llm_tool's implicit vendor default is used.
Example operator.toml:
[[model_servers]] name = "ollama-local" kind = "ollama" base_url = "http://localhost:11434" [[delegators]] name = "codex-local-qwen" llm_tool = "codex" model = "qwen2.5-coder" model_server = "ollama-local"
Ad-hoc launch flags:
# Named delegator (recommended) operator launch --delegator codex-local-qwen # Ad-hoc override operator launch --llm-tool codex --model qwen2.5-coder --model-server ollama-local
Protocol compatibility. Codex speaks the OpenAI API β pairing with ollama requires no bridge. Claude and Gemini use their own vendor protocols and require a translating proxy (e.g. claude-code-router, litellm-proxy) between the CLI and ollama; declare the bridge URL as your model_server.base_url.
Current release ships the infrastructure β ollama detection and automatic env-var injection on spawn land in the next release. See docs/getting-started/model-servers/ for the full walkthrough.
# Run in development cargo run # Run tests cargo test # Build release cargo build --release
Reference documentation is auto-generated from source-of-truth files to minimize maintenance.
| Generator | Source | Output |
|---|---|---|
| taxonomy | src/taxonomy/taxonomy.toml |
docs/taxonomy/index.md |
| issuetype-schema | src/schemas/issuetype_schema.json |
docs/schemas/issuetype.md |
| metadata-schema | src/schemas/ticket_metadata.schema.json |
docs/schemas/metadata.md |
| shortcuts | src/ui/keybindings.rs |
docs/shortcuts/index.md |
| cli | src/main.rs, src/env_vars.rs |
docs/cli/index.md |
| config | src/config.rs |
docs/configuration/index.md |
| OpenAPI | src/rest/ (utoipa annotations) |
docs/schemas/openapi.json |
| llm-tools | src/llm/tools/tool_config.schema.json |
docs/llm-tools/index.md |
| startup | src/startup/mod.rs |
docs/startup/index.md |
| config-schema | docs/schemas/config.json |
docs/schemas/config.md |
| state-schema | docs/schemas/state.json |
docs/schemas/state.md |
| schema-index | docs/schemas/ |
docs/schemas/index.md |
| jira-api | docs/schemas/jira-api.json |
docs/getting-started/kanban/jira-api.md |
# Serve docs locally with Jekyll cd docs && bundle install && bundle exec jekyll serve # Visit http://localhost:4000 # View OpenAPI spec with Swagger UI # After starting Jekyll, visit http://localhost:4000/schemas/api/
# Regenerate all auto-generated docs cargo run -- docs # Regenerate specific docs cargo run -- docs --only openapi cargo run -- docs --only config # Available generators: taxonomy, issuetype-schema, metadata-schema, shortcuts, # cli, config, OpenAPI, llm-tools, startup, config-schema, state-schema, # schema-index, jira-api