Files
maestro/CLAUDE.md
T
2026-06-14 00:33:31 +08:00

4.7 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commands

npm install               # install dependencies
npm run typecheck         # tsc --noEmit (type check without build)
npm run build             # compile TypeScript → dist/ (also copies schema.sql)
npm run dev               # start daemon on http://127.0.0.1:4517
npm test                  # run all tests (node --test via tsx)
tsx --test test/<file>.test.ts  # run a single test file

Worker processes can be run against TypeScript source directly (for dev/testing) via:

MAESTRO_WORKER_CMD="tsx src/executor/worker.ts" npm run dev

Architecture

Maestro is a local-first daemon that manages tasks across multiple git projects. It drives tasks through a complexity-based approval pipeline and auto-executes approved tasks via headless Claude Code agents.

Process Model (critical to understand)

The system is split into two strictly separated process roles:

daemon (src/daemon/) — the only DB writer. Responsible for:

  • Serving REST + WebSocket API (src/api/)
  • Running the orchestrator loop (tick = ingest → reap → claim)
  • Spawning one worker OS process per task
  • Ingesting worker output from outbox.ndjson into SQLite
  • Reaping dead workers, managing retries/back-off, state transitions

worker (src/executor/worker.ts + src/executor/pipeline.ts) — a dumb executor that never touches the DB. Each task gets its own node dist/executor/worker.js <runId>. It reads only runs/<runId>/job.json and appends progress/results to runs/<runId>/outbox.ndjson. The daemon ingests this file idempotently via a lastSeq cursor.

Communication between daemon and worker is file + signal only (job.json, outbox.ndjson, heartbeat, SIGTERM). This makes execution survive daemon restarts.

Key Source Modules

Path Purpose
src/model/ Types (types.ts), state machine (status.ts), complexity levels (complexity.ts), score scheduling algorithm (scoring.ts)
src/store/ SQLite access layer (store.ts), schema (schema.sql), state-machine guards, mappers
src/daemon/orchestrator.ts Score-based task scheduling loop: ingest → reap → claim
src/daemon/ingest.ts Reads worker outbox.ndjson, writes DB events, triggers WS push
src/executor/protocol.ts File protocol definitions + heartbeat/liveness helpers
src/executor/pipeline.ts Worker execution pipeline: worktree setup → agent run → verify → dual review → output
src/executor/cc.ts Claude Agent SDK wrapper for headless CC runs
src/executor/reviewer.ts Code review + security audit agent runs
src/executor/merge.ts --no-ff auto-merge logic on exec_review accept
src/api/server.ts Fastify REST + WebSocket server
src/mcp/ MCP server tools exposed to Claude Code sessions
src/sync/ One-way sync from legacy todo.json files
web/ Dashboard SPA (multi-project, real-time WS, inline approve/reject)

Task Lifecycle

init → [Hard: analyzing → plan_review] → [Medium: speccing → spec_review] → ready
     → queued → executing → exec_review → done
  • Hard: planner agent produces analysis + task decomposition; requires plan_review approval
  • Medium: agent writes a spec (what + why); requires spec_review approval
  • Easy: agent writes operations record; goes directly to ready
  • All tasks with code changes pass through exec_review (dual review: code-review + security audit)
  • accept at exec_review triggers automatic --no-ff merge; merge:false skips merge

Score Scheduling

score = P(self) + Σ P(completed deps) + Σ P(tasks blocked by self)

P0=3, P1=2, P2=1. Higher score → picked first. No preemption.

Model Tier Assignment

Role Easy Medium Hard
executor claude-sonnet-4-6 claude-opus-4-8 claude-fable-5
reviewer claude-sonnet-4-6 claude-opus-4-8 claude-opus-4-8

Project-level model setting overrides env vars; env vars override built-in defaults.

Data Directory

Default ~/.maestro/ — contains SQLite DB, runs/<runId>/ directories (job.json, outbox.ndjson, heartbeat, sandbox.sb, transcripts), and git worktrees.

Key Env Vars

Var Default Note
MAESTRO_PORT 4517 daemon listen port
MAESTRO_DATA_DIR ~/.maestro SQLite + worktree root
MAESTRO_ORCH_INTERVAL 15 orchestrator tick seconds; 0 disables
MAESTRO_WORKER_CMD node dist/executor/worker.js override for tsx dev
MAESTRO_NOTIFY on set 0 to disable macOS notifications
MAESTRO_SANDBOX off set on for OS-level write fence + ulimits on workers