Lightweight, git-native multi-agent orchestration framework for autonomous project execution
Project description
lindy-orchestrator
Lightweight, git-native multi-agent orchestration framework for autonomous project execution.
lindy-orchestrator decomposes natural-language goals into dependency-ordered tasks, dispatches them to Claude Code agents working in isolated module directories, validates results through pluggable QA gates, and coordinates everything through markdown files and git.
No database. No shared memory. No infrastructure. Just git, markdown, and your existing project.
Why
Multi-module projects need coordination. Telling an LLM agent to "add user authentication" across a backend and frontend requires decomposing the goal, ordering dependencies, dispatching work to the right directory, and verifying the result. lindy-orchestrator automates this entire loop:
Goal (natural language)
→ LLM decomposes into task DAG
→ Parallel dispatch to module agents
→ QA gates validate each result
→ Retry with feedback on failure
→ Final report
Each module stays isolated (its own CLAUDE.md, STATUS.md, working directory). The orchestrator is the only thing that sees the whole picture.
Install
# From PyPI
pip install lindy-orchestrator
# With Anthropic API support (optional)
pip install lindy-orchestrator[api]
# From source
git clone https://github.com/eddieran/lindy-orchestrator.git
cd lindy-orchestrator
pip install -e ".[dev]"
Requirements: Python 3.11+ and Claude Code CLI in PATH.
Quick Start
cd my-project
# Option A: quick scaffold (auto-detects modules)
lindy-orchestrate init
# Option B: deep onboard (generates CLAUDE.md, CONTRACTS.md, STATUS.md)
lindy-orchestrate onboard
# Preview the task plan
lindy-orchestrate plan "Add user authentication with JWT"
# Execute
lindy-orchestrate run "Add user authentication with JWT"
See docs/USAGE.md for the full usage guide.
How It Works
1. Read all module STATUS.md files (current state)
2. Send goal + context to LLM → JSON task plan with dependency DAG
3. Scheduler dispatches ready tasks in parallel (respecting dependencies)
4. Each task: Claude Code agent works in module directory → commits → pushes
5. QA gates validate each result (CI status, shell commands, agent review)
6. On QA failure: augment prompt with feedback, retry (up to N times)
7. On dependency failure: skip downstream tasks, continue independent ones
8. Generate execution report
CLI Reference
| Command | Description |
|---|---|
init |
Quick scaffold — detect modules, generate orchestrator.yaml and STATUS.md |
onboard |
Deep onboard — static analysis, interactive Q&A, full artifact generation |
run <goal> |
Decompose and execute a goal with parallel dispatch and QA gates |
plan <goal> |
Generate a task plan without executing (use -o plan.json to save) |
status |
Show module health, active tasks, and blockers (--json for machine output) |
logs |
Show recent action logs (-n 50 for count, --json for raw JSONL) |
resume |
Resume a previous session (latest or by session ID) |
validate |
Validate config, module paths, STATUS.md, and Claude CLI availability |
All commands accept -c path/to/orchestrator.yaml to specify a config file.
Configuration
orchestrator.yaml in your project root:
project:
name: "my-project"
branch_prefix: "af" # task branches: af/task-1, af/task-2, ...
modules:
- name: backend
path: backend/
repo: myorg/my-backend # GitHub slug (required for ci_check gate)
ci_workflow: ci.yml
- name: frontend
path: frontend/
repo: myorg/my-frontend
planner:
mode: cli # "cli" uses claude -p; "api" uses Anthropic SDK
dispatcher:
timeout_seconds: 1800 # hard timeout per task dispatch (30 min)
stall_timeout_seconds: 600 # no-output stall detection (10 min)
permission_mode: bypassPermissions
qa_gates:
custom:
- name: pytest
command: "pytest --tb=short -q"
cwd: "{module_path}" # resolved to module's absolute path
safety:
dry_run: false
max_retries_per_task: 2
max_parallel: 3
Key Concepts
Modules
Independent directories in your project (services, packages, microservices). Each module gets its own STATUS.md, CLAUDE.md, and isolated agent workspace. Auto-detected by marker files: pyproject.toml, package.json, Cargo.toml, go.mod, pom.xml, etc.
STATUS.md
Human-readable, git-diffable state file per module. Tracks active work, completed tasks, backlogs, cross-module requests, key metrics, and blockers. The orchestrator reads these programmatically; agents and humans read and write them in natural language.
CONTRACTS.md
Single source of truth for cross-module interfaces. Generated by onboard when module coupling is moderate or higher. Defines API contracts, shared schemas, task ID conventions, and the CI delivery protocol.
QA Gates
Pluggable validation that runs after each task dispatch:
| Gate | Description |
|---|---|
ci_check |
Polls GitHub Actions workflow status via gh CLI |
command_check |
Runs arbitrary shell commands (exit code 0 = pass) |
agent_check |
Dispatches a separate QA agent for semantic validation |
| Custom YAML | User-defined command gates in orchestrator.yaml |
On failure, the orchestrator augments the original prompt with QA feedback and retries up to max_retries_per_task times.
Dispatch Modes
| Mode | Function | Use Case |
|---|---|---|
| Streaming | dispatch_agent() |
Long tasks — real-time heartbeat, stall detection, event callbacks |
| Blocking | dispatch_agent_simple() |
Short tasks — plan generation, reports, no thread overhead |
The streaming dispatcher monitors agent output with a 10-minute stall floor (never kills before 10 min of silence, regardless of config) and a configurable hard timeout as a safety net.
Sessions
Persistent execution state stored as JSON in .orchestrator/sessions/. Supports pause and resume across terminal sessions via lindy-orchestrate resume.
Architecture
src/lindy_orchestrator/
├── cli.py # Typer CLI entry point
├── config.py # YAML config loading + Pydantic validation
├── models.py # Core data models (TaskPlan, TaskItem, QACheck, ...)
├── dispatcher.py # Claude CLI subprocess management (streaming + blocking)
├── planner.py # Goal → TaskPlan decomposition via LLM
├── scheduler.py # DAG-based parallel execution with retry logic
├── prompts.py # LLM prompt templates (Jinja2)
├── session.py # Session state persistence and resume
├── logger.py # Append-only JSONL audit trail
├── reporter.py # Rich console output formatting
├── qa/
│ ├── __init__.py # Gate registry and runner
│ ├── ci_check.py # GitHub Actions CI polling
│ ├── command_check.py # Shell command execution
│ └── agent_check.py # Agent-based semantic validation
├── status/
│ ├── parser.py # STATUS.md → structured data
│ ├── templates.py # STATUS.md generation
│ └── writer.py # Surgical markdown table updates
└── discovery/
├── analyzer.py # Static project analysis (tech stack, dependencies)
├── interview.py # Interactive and non-interactive onboarding Q&A
├── generator.py # Artifact generation (CLAUDE.md, CONTRACTS.md, ...)
└── templates/ # Jinja2 template renderers
Development
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest tests/ -v
# Lint and format
ruff check src/ tests/
ruff format src/ tests/
See CONTRIBUTING.md for contribution guidelines.
License
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 lindy_orchestrator-0.6.1.tar.gz.
File metadata
- Download URL: lindy_orchestrator-0.6.1.tar.gz
- Upload date:
- Size: 214.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca4cb7c7eb3e04f88f45c7e35433e88bac42e7e5bb52d4ef487733ee51bc3d62
|
|
| MD5 |
b07fd43b62e63102a5cd48a8b5133470
|
|
| BLAKE2b-256 |
702d2debc3f669102893d7490c23f46c70f617273c897d980caf50abc1b38f13
|
File details
Details for the file lindy_orchestrator-0.6.1-py3-none-any.whl.
File metadata
- Download URL: lindy_orchestrator-0.6.1-py3-none-any.whl
- Upload date:
- Size: 126.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
374abc6cad2b918bd08df4cdbdce4ca110bd0713756db1f7c0b09c00e613d6d3
|
|
| MD5 |
dfba63b425cb8553e6aafb770cae341a
|
|
| BLAKE2b-256 |
049703937ae4320e843012d2c8669dadcdb45c6bb1a71a331e85ba3f80c179b4
|