Files
maestro/README.md
T
wangjia 52c053baf4 docs: 更新 DESIGN.md/README 到 Phase 3 多进程执行架构 [tsk_-HYVwxzHIbrS]
- 写清工作模式:daemon=唯一 DB 写者+监工;worker=哑执行器(不碰 DB)
- 通讯协议:job.json / outbox.ndjson(幂等 ingest)/ heartbeat / SIGTERM
- 重启语义:reconcile 按 worker_pid+心跳判活 → re-adopt 或回收重试 + 持久化退避
- 同步更新系统总览图、数据模型(worker_pid/last_seq/next_eligible_at)、后端架构、风险、Phase 进度、env 表

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 15:00:42 +08:00

116 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# maestro
多项目 TODO 管理与 Agent 执行系统(本地优先 daemon · Node/TypeScript)。
按任务复杂度(Hard / Medium / Easy)分级驱动审批闸,用后台 agentClaude Code)在隔离 git worktree 自动执行可执行任务,执行后自动跑 code review + 安全审计,accept 时 `--no-ff` 自动合并,改动不自动 push。
执行是**多进程解耦**的:daemon 是唯一 DB 写者兼监工,每个执行任务 spawn 一个**独立 worker 进程**(哑执行器,完全不碰 DB),二者只经文件 + 进程信号通讯(`job.json` / `outbox.ndjson` / `heartbeat` / `SIGTERM`),daemon 重启可按心跳判活 re-adopt 仍在跑的 worker。详见 [DESIGN.md](./DESIGN.md) §7。
- 完整设计见 **[DESIGN.md](./DESIGN.md)**。
- 当前状态:**Phase 1 + Phase 2 + Phase 3 核心均已落地**(编排器 + score 调度 + 双复审 + 自动合并 + 多进程执行解耦 + macOS 通知 + 额度透传 + 归档)。
## 结构
```
src/
model/ 复杂度、状态机、实体类型、score 调度算法
store/ SQLite schema + 访问层(状态机守卫 + 审批闸)
api/ REST + WebSocket API + logo 解析
mcp/ MCP server(给 Claude Code
executor/ Agent SDK 封装(cc.ts)、worktree 管理、verify、runner、reviewer(双复审)、merge、模型分级
protocol.tsdaemon↔worker 文件协议:job/outbox/heartbeat/判活)
worker.ts(独立 worker 进程入口)、pipeline.ts(纯执行管线,不碰 DB
daemon/ maestrod 入口、编排器(监工:spawn/ingest/回收)、ingestoutbox→DB)、
macOS 通知、额度透传、配置
sync/ 旧 todo.json → maestro 单向同步引擎
web/ 看板(多项目·实时 WS·内联审批·归档详情)
scripts/ poc-exec.mjs(执行闭环验证脚本)
```
## 开发
```bash
npm install
npm run typecheck # tsc --noEmit
npm run build # → dist/
npm run dev # 启动 daemon(默认 http://127.0.0.1:4517
npm test # 运行全量测试(node --test
```
## 接入 Claude CodeMCP
`npm run build`,并保证 maestrod 在跑(`npm run dev`,默认 http://127.0.0.1:4517)。两种接法:
```bash
# 方式一:claude mcp add(在要接入的项目里执行)
claude mcp add maestro -e MAESTRO_URL=http://127.0.0.1:4517 -- node /绝对路径/maestro/dist/mcp/index.js
```
```jsonc
// 方式二:项目根放 .mcp.json(模板见本仓库 .mcp.json.example
{ "mcpServers": { "maestro": {
"command": "node",
"args": ["/绝对路径/maestro/dist/mcp/index.js"],
"env": { "MAESTRO_URL": "http://127.0.0.1:4517" } } } }
```
MCP 工具:`list_projects` / `create_project` / `list_tasks` / `get_task` / `create_task` / `decompose_task` / `write_plan` / `write_spec` / `write_operations` / `update_status` / `get_next_executable` / `get_pending_approvals`accept/reject 在 Web 看板操作)。
## 核心功能速览
### 多进程执行(监工 + worker
- **daemon = 唯一 DB 写者 + 监工**:领任务 → 写 `job.json` → spawn worker → ingest 其 outbox → 回收死 worker。每轮 tick 顺序 `ingest → reap → claim`
- **worker = 哑执行器**`node dist/executor/worker.js <runId>`,每任务一个独立进程,跑 worktree→执行→verify→双复审→产出,**完全不碰 DB**,进度/结果只追加进 `outbox.ndjson`
- **通讯**`runs/<runId>/job.json`daemon→worker 唯一输入)/ `outbox.ndjson`worker→daemon,带 seqdaemon 按 `last_seq` 幂等 ingest/ `heartbeat`worker 每 10s 刷 mtimedaemon 判活)/ `SIGTERM`(取消/超时)。
- **重启 re-adopt**daemon 启动 `reconcileInterrupted()``worker_pid + 心跳`判活——活则 re-adopt 续 ingest(不打断 agent),死则回收重试(持久化退避 `next_eligible_at = min(30s·2^(n-1), 10min)`,超 `maxRetries``needs_attention`)。
### Score 调度
编排器按 score 降序领任务(不抢占,领取时现算):
```
score = P(自身优先级) // P0=3 / P1=2 / P2=1
+ Σ P(已完成依赖) // 链条惯性:前置投入越重越优先出活
+ Σ P(等我解锁的 blocked 任务) // 解锁效应:解锁面越广越优先
```
### 双复审 PR 流程
执行成功后顺序起两个只读 headless Claude Code
1. **Code Review**kind=reviewer):正确性/可维护性逐条问题 → `VERDICT: approve|reject`
2. **安全审计**kind=security):凭证泄露/注入/权限/UI红线词/部署风险 → `VERDICT: approve|reject`
任一复审失败不挡任务进 `exec_review`;看板展示两份 markdown 报告 + verdict 徽章。
### 模型分级
| 角色 | 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.model`(看板设置)最高优先;环境变量次之(见下);内置默认最低。模型不可用时自动回退 `opus-4-8 → sonnet-4-6`
### 归档与运行历史
- `GET /api/tasks/:id/events` — 状态流转时间线
- `GET /api/tasks/:id/runs` — executor / reviewer / security run 历史(含转录引用)
### macOS 通知
进入审核闸(plan/spec/exec_review)、执行失败、复审建议拒绝、合并完成时推送原生通知。`MAESTRO_NOTIFY=0` 关闭。
### 额度透传
`GET /api/agents` 附带 Claude 订阅额度(5h 窗口 + 7天窗口),读取 `~/.claude/.credentials.json` 或 macOS keychain60s 缓存。
### 自动合并
exec_review accept 时自动 `--no-ff` 合并:若 defaultBranch 在主检出且工作区干净 → 直接合并;否则临时 worktree 合并后销毁。冲突时 abort 返回冲突文件列表,任务保留在 exec_review。`merge:false` 逃生口可仅通过不合并。
## 环境变量
| 变量 | 说明 | 默认 |
|---|---|---|
| `MAESTRO_URL` | daemon 地址(MCP 客户端侧) | `http://127.0.0.1:4517` |
| `MAESTRO_PORT` | daemon 监听端口 | `4517` |
| `MAESTRO_DATA_DIR` | SQLite + worktree 数据目录 | `~/.maestro` |
| `MAESTRO_ORCH_INTERVAL` | 编排器轮询间隔(秒),`0`=关闭 | `15` |
| `MAESTRO_WORKER_CMD` | 覆盖 worker 进程启动命令(空格分隔),供 tsx 跑 .ts 入口/测试用 | `node dist/executor/worker.js` |
| `MAESTRO_NOTIFY` | `0` 关闭 macOS 通知 | 开启 |
| `MAESTRO_MODEL_EASY` | executor Easy 模型覆盖 | `claude-sonnet-4-6` |
| `MAESTRO_MODEL_MEDIUM` | executor Medium 模型覆盖 | `claude-opus-4-8` |
| `MAESTRO_MODEL_HARD` | executor Hard 模型覆盖 | `claude-fable-5` |
| `MAESTRO_MODEL_REVIEW_EASY` | reviewer Easy 模型覆盖 | `claude-sonnet-4-6` |
| `MAESTRO_MODEL_REVIEW_MEDIUM` | reviewer Medium 模型覆盖 | `claude-opus-4-8` |
| `MAESTRO_MODEL_REVIEW_HARD` | reviewer Hard 模型覆盖 | `claude-opus-4-8` |