operator is a Rust TUI application for orchestrating Claude Code agents across multi-project codebases. It manages ticket queues, launches agents, tracks progress, and provides notifications.
- Language: Rust
- TUI Framework: ratatui (with crossterm backend)
- Async Runtime: tokio
- Notifications: mac-notification-sys (macOS)
- Config: config crate (TOML)
- File Watching: notify crate
All changes MUST pass these checks before committing:
cargo fmt # Format code
cargo clippy -- -D warnings # Lint (warnings are errors)
cargo test # Run all testsIf any of these fail, fix the issues before proceeding. Do NOT use #[allow(...)] attributes to silence warnings unless there's a documented reason (e.g., code used only in tests).
When changes touch subprojects, those must also pass validation:
opr8r (Rust/cargo):
cargo run vscode-extension (TypeScript/npm):
cd vscode-extension && npm run lint && npm run compilebackstage-server (TypeScript/Bun):
cd backstage-server && bun run lint && bun run typecheck && bun testThis project follows TDD practices:
- Write tests first - Before implementing a feature or fix, write a failing test that defines the expected behavior
- Run the test - Verify it fails for the right reason
- Implement the minimum code - Write just enough code to make the test pass
- Refactor - Clean up while keeping tests green
- Repeat - Add more tests to cover edge cases
Example workflow:
# 1. Write a new test in the appropriate module
# 2. Run tests to see it fail
cargo test test_new_feature -- --nocapture
# 3. Implement the feature
# 4. Run tests to see it pass
cargo test
# 5. Run full validation before committing
cargo fmt && cargo clippy -- -D warnings && cargo test- Unit tests go in the same file as the code, in a
#[cfg(test)] mod testsblock - Integration tests go in
tests/directory - Use descriptive test names:
test_<function>_<scenario>_<expected_behavior>
cargo fmt # Format code
cargo clippy -- -D warnings # Lint (warnings as errors)
cargo test # Run all tests
cargo test <name> # Run specific test
cargo run # Run TUI
cargo run -- queue # CLI: show queue
cargo run -- launch # CLI: launch next ticketsrc/
├── main.rs # Entry point, CLI parsing
├── app.rs # Application state and event loop
├── ui/ # TUI rendering
│ ├── mod.rs
│ ├── dashboard.rs # Main dashboard layout
│ ├── queue.rs # Queue panel
│ ├── agents.rs # Agents panel
│ └── dialogs.rs # Confirmation dialogs
├── queue/ # Queue management
│ ├── mod.rs
│ ├── ticket.rs # Ticket parsing
│ ├── watcher.rs # File system watcher
│ └── assigner.rs # Work assignment logic
├── agents/ # Agent lifecycle
│ ├── mod.rs
│ ├── launcher.rs # Claude Desktop integration
│ ├── tracker.rs # Agent state tracking
│ └── session.rs # Session persistence
├── notifications/ # Notification system
│ ├── mod.rs
│ └── macos.rs # macOS notifications
├── config.rs # Configuration management
└── state.rs # Persistent state store
- INV (Investigation) - Failures, highest priority
- FIX - Bug fixes
- FEAT - Features
- SPIKE - Research (requires pairing)
- Autonomous (FEAT, FIX): Launch and forget, monitor progress
- Paired (SPIKE, INV): Require human interaction, track "awaiting input"
- Max agents = min(configured_max, cpu_cores - reserved_cores)
- Autonomous agents can run in parallel across non-intersecting projects
- Paired agents run one at a time per operator attention
- Same project = sequential (to avoid conflicts)
Operator state persists in .operator/:
.operator/
├── state.json # Current queue/agent state
├── sessions/ # Agent session logs
│ └── {agent-id}.json
└── history.json # Completed work log
- Watch: Monitor
.tickets/queue/for new tickets - Sort: Order by priority, then FIFO timestamp
- Assign: When agent slot available, select next ticket
- Confirm: Prompt operator for launch confirmation
- Launch: Open Claude Desktop with project + ticket prompt
- Track: Monitor agent progress, watch for completion
- Complete: Move ticket, notify, update stats
Launch command (macOS):
open -a "Claude" --args --project "/path/to/project"Initial prompt injected via:
- Clipboard + paste simulation, OR
- Project-specific
.claude/initial-prompt.md, OR - AppleScript automation
macOS notifications via mac-notification-sys:
Notification::new()
.title("Agent Complete")
.subtitle("backend")
.message("FEAT-042: Add pagination")
.send()?;On startup, operator scans the configured projects directory for subdirectories containing a CLAUDE.md file. These are presented as available projects when creating tickets.
- Check
.tickets/queue/for tickets matching your project - Look for
*-{project}-*.mdfiles, take the oldest (FIFO) - Move claimed ticket to
.tickets/in-progress/ - Create feature branch:
git checkout -b {branch-from-ticket}
- Run full validation:
cargo fmt && cargo clippy -- -D warnings && cargo test - Ensure all tests pass and no clippy warnings
- Commit with message:
{type}({project}): {summary}\n\nTicket: {ID}\n
Operator uses a schema-driven, code-derived documentation strategy to reduce maintenance burden. Documentation is auto-generated from structured source-of-truth files, ensuring docs stay in sync with code.
| File | Generates | Purpose |
|---|---|---|
src/backstage/taxonomy.toml |
docs/backstage/taxonomy.md |
25 project Kinds across 5 tiers |
src/schemas/issuetype_schema.json |
docs/schemas/issuetype.md |
Issue type structure (key, mode, fields, steps) |
src/schemas/ticket_metadata.schema.json |
docs/schemas/metadata.md |
Ticket YAML frontmatter format |
src/ui/keybindings.rs |
docs/shortcuts/index.md |
Keyboard shortcuts by context |
src/main.rs + src/env_vars.rs |
docs/cli/index.md |
CLI commands and env vars |
src/config.rs |
docs/configuration/index.md |
Config structure (via schemars) |
src/rest/ |
docs/schemas/openapi.json |
REST API spec (via utoipa) |
# Generate all documentation
cargo run -- docs
# Generate specific docs only
cargo run -- docs --only taxonomy
cargo run -- docs --only openapi
cargo run -- docs --only config
# Available generators: taxonomy, issuetype, metadata, shortcuts, cli, config, openapiAll generated files include a header warning:
<!-- AUTO-GENERATED FROM {source} - DO NOT EDIT MANUALLY -->
<!-- Regenerate with: cargo run -- docs -->- Create a struct implementing
DocGeneratortrait insrc/docs_gen/ - Implement
name(),source(),output_path(), andgenerate() - Register in
src/docs_gen/mod.rsgenerate_all()function - Add to CLI match in
src/main.rscmd_docs()