# Maestro **Repository Path**: momen_official/maestro ## Basic Information - **Project Name**: Maestro - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: feat/mvp - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-15 - **Last Updated**: 2026-11-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Maestro **一个 24/7 常驻的「总管 AI」+ 飞书式多账户 IM。** 你只给目标,它自己判断清晰度、拆解、分派、盯风险并定期汇报;拿不准的时候才停下来问你。 聊天层照飞书设计(ADR-0003):每个账户真实有效——真人(用户名+密码登录)或 AI(有人设、不可登录),可以拉人建账户、拉群、1对1 单聊;AI 在群里默认只记录消息(它自己的「记录」空间),被 @ 才组合上下文与自己的记录回复,回复里也可以 @ 别人(被 @ 的 AI 会接着回,最多级联 3 层);单聊里 AI 对每条消息都回复。 Maestro 不是执行器。具体干活的是既有的专业工具(当前是 [OpenCode](https://opencode.ai)),Maestro 负责的是「张罗、盯进度、催、汇报」——统领 AI → 部门 AI → 专业工具,三层分工。 状态:MVP 可运行,单项目、多账户。设计依据见 `2026-10-15-ai-orchestrator-design.md`,领域词汇见 `GLOSSARY.md`。 ## 它解决什么 - **事事都要人插手** → 清晰目标自动拆解、自动派发、自动跑到完成。 - **没人抬头看全局** → 周期心跳产出汇报,并把停滞与风险单独列出。 - **各部门成孤岛** → 统领统一派活、串依赖、裁决冲突。 - **拿不准还硬猜** → 目标不清晰就不动,先回来问;工具抛出的问题统领答不了,就挂起该任务,不阻塞其它任务。 一次工作循环: ``` 目标 → 清晰度判断 ─┬─ clear → 拆解为任务 → 部门 AI 派给 OpenCode 会话 → 完成 └─ unclear → 在该目标房间里追问,等你补充后再判断 心跳 tick(默认每 5 分钟)→ 恢复陈旧任务 → 派发就绪任务 → 产出汇报 / 停滞 / 风险 ``` 不可逆动作(提 PR、对外发言等)必须先经你批准;可逆的内部动作自主执行,并登记撤销路径。 ## 前置要求 | 依赖 | 说明 | | --- | --- | | Node.js 22 LTS | 已在 v22.18.0 验证;启动用到 `process.loadEnvFile`,需要 Node ≥ 20.12 | | npm | 安装依赖、构建、跑测试 | | 两个 OpenAI 兼容模型端点 | 一个「强」模型做统领,一个「便宜」模型做部门/汇总;任何兼容 `/v1/chat/completions` 的服务都行 | | OpenCode server | 部门 AI 通过它执行真实任务,默认地址 `http://127.0.0.1:4096`。**默认不连接**:可在「模型设置」页一键连接/断开(运行时生效),或设 `MAESTRO_OPENCODE_ENABLED=true` 作初始默认。断开时任务由部门模型直接执行 | | 编译器(可选) | `better-sqlite3` 有预编译包,缺失时才会用到 `python3` / `make` / `g++` | ## 安装 ```bash git clone https://gitee.com/momen_official/maestro.git cd maestro npm ci npm run build # 后端 tsc + 类型检查 + 构建 web 看板到 web/dist ``` ## 配置 配置全部来自环境变量。密钥**不要**写进仓库,放到进程外的 env 文件里。进程启动时会按下列顺序查找 env 文件,先命中的文件优先,真实环境变量永远优先于文件: 1. `MAESTRO_ENV_FILE` 指定的路径(必须存在,否则启动失败) 2. `~/.config/maestro/env` 3. `./.env.local`(已被 gitignore) ```bash mkdir -p ~/.config/maestro cat > ~/.config/maestro/env <<'EOF' MAESTRO_ORCH_BASE_URL=https://api.example.com/v1 MAESTRO_ORCH_API_KEY=sk-orchestrator-... MAESTRO_ORCH_MODEL=strong-model-id MAESTRO_WORKER_BASE_URL=https://api.example.com/v1 MAESTRO_WORKER_API_KEY=sk-worker-... MAESTRO_WORKER_MODEL=cheap-model-id MAESTRO_USER=admin MAESTRO_PASSWORD_HASH=scrypt$$ MAESTRO_PROVIDERS_FILE=/home/you/.config/maestro/providers.json MAESTRO_GATEWAY_TOKEN=<一段长随机串> EOF chmod 600 ~/.config/maestro/env ``` `config.example.json` 只是字段说明,进程**不会**读它。 ### 必填 | 变量 | 说明 | | --- | --- | | `MAESTRO_ORCH_BASE_URL` / `MAESTRO_ORCH_API_KEY` / `MAESTRO_ORCH_MODEL` | 统领(强)模型端点 | | `MAESTRO_WORKER_BASE_URL` / `MAESTRO_WORKER_API_KEY` / `MAESTRO_WORKER_MODEL` | 部门/汇总(便宜)模型端点 | | `MAESTRO_USER` | 单用户登录名 | | `MAESTRO_PASSWORD_HASH` | 密码的 scrypt 哈希,格式 `scrypt$$` | ### 常用可选 | 变量 | 默认值 | 说明 | | --- | --- | --- | | `PORT` | `8080` | HTTP 端口 | | `HOST` | `0.0.0.0` | 监听地址 | | `DB_PATH` | `./data/maestro.db` | SQLite 路径,父目录自动创建 | | `TICK_CRON` | `0 * * * *` | 心跳周期(cron);想每 5 分钟就设 `*/5 * * * *` | | `MAESTRO_OPENCODE_ENABLED` | 关闭 | 工具连接的**初始默认值**:`1`/`true`/`on`/`yes`(不分大小写)为开。运行时状态以界面按钮(settings 持久化)为准;断开时任务由部门模型直接执行,不依赖 OpenCode | | `ARCHIVE_MAX_CONTENT_CHARS` | `16000` | 单条归档内容的最大字符数 | | `RETENTION_DAYS` | `90` | 归档保留天数(当前仅解析配置,尚无自动裁剪作业) | | `MAESTRO_GATEWAY_TOKEN` | 无 | 启用对外 OpenAI 兼容网关的 Bearer 令牌;不设则网关返回 503 | | `MAESTRO_PROVIDERS_FILE` | 无 | 外部模型配置文件(推荐 `~/.config/maestro/providers.json`,密钥 AES-256-GCM 加密);不设则模型配置留在 SQLite | | `MAESTRO_ORCH_PROMPT_PRICE` / `MAESTRO_ORCH_COMPLETION_PRICE` | 无 | 每百万 token 的美元单价,两项都设才计费 | | `MAESTRO_WORKER_PROMPT_PRICE` / `MAESTRO_WORKER_COMPLETION_PRICE` | 无 | 同上,便宜模型 | | `MAESTRO_OPENCODE_BASE_URL` | `http://127.0.0.1:4096` | OpenCode server 地址 | | `MAESTRO_OPENCODE_PASSWORD` | 无 | 显式覆盖 OpenCode service 的 Basic 密码;不设则读 `$XDG_STATE_HOME/opencode/service.json` | | `MAESTRO_WORKING_DIR` | 当前目录 | 部门 AI 跑 OpenCode 会话的工作目录 | | `MAESTRO_DEFAULT_DEPARTMENT` / `MAESTRO_DEFAULT_CHARTER` | `engineering` / 通用工程部门 | 首次启动时自动建的默认部门 | | `MAESTRO_PROVIDER_SYNC=env` | 无 | 强制用环境变量覆盖已保存的模型配置 | ### 生成登录密码哈希 `npm run build` 之后: ```bash node -e "import('./dist/server/auth.js').then(m => console.log(m.hashPassword(process.argv[1])))" '你的密码' ``` 把输出整行填给 `MAESTRO_PASSWORD_HASH`。改密码只需重新生成并重启。 ## 启动 生产模式(先 `npm run build`,由 Fastify 同时提供 API 与 `web/dist` 看板): ```bash node dist/index.js ``` 开发模式(两个终端,前端热更新): ```bash npm run dev # tsx 直接跑 src/index.ts,监听 :8080 npm run web:dev # Vite 开发服务器,/api 代理到 :8080 ``` 正常启动的日志形如: ``` [maestro] loaded env from /home/you/.config/maestro/env [maestro] listening on http://0.0.0.0:8080 (tick: 0 * * * *) ``` 然后浏览器打开 `http://:8080`,用 `MAESTRO_USER` 与刚才的密码登录。 `sudo systemctl` / `pm2` / `docker` 均可常驻托管:进程收到 `SIGTERM` 或 `Ctrl-C` 会停调度器、关 HTTP、关数据库后退出;重启后未完成的任务与待你处理的问题仍在。 ## 使用说明 登录后是一个聊天式工作区,左侧导航按「频道 / 目标 / 群 / 成员 / 工作区」分组。 ### 1. 在 `#总管` 提目标 直接把目标当消息发出去,例如「给现有 API 增加 `/health` 接口」。 - **清晰目标**:立刻拆解成任务并派给部门 AI,你不需要再做任何事。 - **模糊目标**:先不动手,在这个目标自己的房间里追问澄清(每问都带推荐答案,也可自定义回复或拒答);你补充之后,清晰度门禁在原目标上重新判断,清晰了才建任务。 拿不准时 Maestro 会停下来问,这是设计的一部分,不是故障。 `#总管` 里的消息除了「提目标」,也会被当作管理指令解析(确定性正则,不花模型调用): | 这样说 | 效果 | | --- | --- | | `创建一个设计部门` | 新建部门,默认职责「负责『设计』方向的工作。」 | | `把设计部门改名为品牌部门` | 部门改名 | | `删除设计部门` | 归档部门(有在飞任务、或这是最后一个部门时会被拒绝) | | `把目标 3 标记为已完成` | 改目标状态(未开始 / 规划中 / 进行中 / 已完成 / 失败) | | `把目标 3 设为待澄清` | 改目标清晰度 | | `把目标 5 重命名为 上线 GXDE 商店` | 改目标标题 | | `删除目标 2` | 归档目标 | | `设置项目简介:这是一个开源软件商店的社区项目` | 写项目简介,之后做清晰度判断时会参考 | 不像指令的消息就当成新目标处理。 ### 2. 汇报、预警与待办 | 频道 | 里面是什么 | | --- | --- | | `#汇报` | 每次心跳的周期汇报:做了什么、哪里停滞、有什么风险 | | `#预警` | 停滞任务与风险点 | | `#待办` | 工具抛出、统领答不了的「待你处理」问题,以及需要你批准的不可逆动作 | 在 `#待办` 里回答或批准后,Maestro 会立刻尝试推进一次(不必等下一个 tick)。回答只解除它所挂住的那个任务,其它任务照常跑。 ### 3. 目标房间 点开某个目标进入它自己的房间:澄清问答、统领的拆解、每个任务的状态与产出物都在这里,也可以继续追问。任务详情里能实时看到部门 AI 的 OpenCode 会话输出。 ### 4. 群(多 AI 讨论) 新建群并拉入多个部门 AI。你发一句话,被拉进来的成员按顺序各自发言(每人都看得到前面的人说了什么),最后由总管总结。适合需要跨部门对齐的方案讨论;一次发言是「成员数 + 1」次模型调用。 ### 5. 成员与组织架构 「成员」看每个部门 AI 的职责、负载、当前任务,可直接私聊;「组织架构」看总管 → 部门的委派关系与实时状态。部门可在界面上增删改,也可以直接在 `#总管` 发管理指令。 ### 6. 归档 模型调用、工具会话、人类对话、决策的 append-only 记录,按目标/任务过滤,用于审计和复盘。 ### 7. 模型设置 在这里改运行时模型端点、模型名和 API key,并做连通性测试。配置写入 `MAESTRO_PROVIDERS_FILE`(密钥加密,权限 600),页面只回显 `hasApiKey`,永远不会把 key 返回给前端。 ### 8. 对外 OpenAI 兼容网关(可选) 设置 `MAESTRO_GATEWAY_TOKEN` 后,外部客户端(OpenCode、脚本)可以拿 Maestro 当模型代理,请求会转发到当前活跃的 provider、计量用量并归档: ```bash curl -s http://localhost:8080/v1/models \ -H "Authorization: Bearer $MAESTRO_GATEWAY_TOKEN" curl -s http://localhost:8080/v1/chat/completions \ -H "Authorization: Bearer $MAESTRO_GATEWAY_TOKEN" \ -H 'content-type: application/json' \ -d '{"model":"cheap-model-id","messages":[{"role":"user","content":"hi"}]}' ``` ### 9. 诊断(测试路径) 「模型设置」页的「运行诊断」按钮(或 `GET /api/diagnostics`)一次体检全部依赖,并检查**所有目标是否达成**: - 数据库是否可用; - 工具连接:开关状态(界面可一键切换,运行时生效);连接时探测 OpenCode server 可达性;断开时任务由模型直接执行; - 两级模型端点连通性(各 ping 一次 1 token 的补全); - 所有未归档目标的达成情况:未达成目标按任务状态分解,说明卡点(失败 / 等你回答 / 等批准 / 工具关闭排队 / 待派发 / 执行中)。 全程只读探测,单层失败不影响其它层的结论。 ## 开发 | 命令 | 作用 | | --- | --- | | `npm run dev` | 直接运行后端(tsx) | | `npm run build` | `tsc` + web 类型检查 + 构建看板到 `web/dist` | | `npm test` | 全量测试(后端 vitest + web jsdom) | | `npm run test:watch` | 监听模式 | | `npm run web:typecheck` | 只检查前端类型 | | `npm run web:build` / `npm run web:dev` | 只构建 / 只启动前端 | 目录: ``` src/ index.ts 常驻进程装配与启动 config.ts env.ts 环境变量校验、本地 env 文件加载 orchestrator/ 统领、部门 AI、门禁、运行时、心跳、汇报、群讨论 adapters/ 工具适配器(OpenCode) db/ SQLite schema、迁移与仓储 archive/ 会话归档 models/ 模型 provider 注册与加密文件 gateway/ 对外 OpenAI 兼容网关 server/ Fastify 路由与单用户鉴权 web/ 聊天式看板(React + Vite) tests/ unit/ 与 e2e/ docs/ 计划、验收、ADR、agent 约定 ``` 改动约定见 `AGENTS.md`、`docs/agents/`;交付前要跑的检查见 `docs/agents/delivery-gate.md`(类型检查 + 全量测试 + 构建 + 真实进程跑一遍)。 ## 数据与安全 - 运行数据在 `DB_PATH`(默认 `data/maestro.db`,整个 `data/` 已 gitignore)。 - provider 密钥在 `MAESTRO_PROVIDERS_FILE` 指向的文件里加密保存;`secret.key` 与密文放在一起,rotation 或丢失会导致启动失败,删掉两者后在「模型设置」页重填即可。 - 对外网关需要 `MAESTRO_GATEWAY_TOKEN`;登录用单个 scrypt 哈希 + HMAC 签名 cookie。 - Gitee token(`~/.config/maestro/gitee_token` 或 `GITEE_TOKEN`)只供 agent 读写 issue 使用,不要提交或粘贴到 issue、截图、聊天里。 - 提交前按 `docs/agents/secrets.md` 自查:`git status --short` 与 `git grep -l -E 'sk-[A-Za-z0-9]{10,}|Bearer [A-Za-z0-9._-]{20,}'`。 ## 现状与边界 - **单操作者、单项目**:首次启动自动创建默认项目与默认部门;没有多租户和权限体系。 - **issue 源导入未实现**:Gitee issue 触发部门 AI 仍是 Roadmap(见 `docs/plans/2026-10-15-mvp-acceptance.md` 的「未实现」条目)。 - **社区侦察 / helpdesk 知识库未实现**:同为 Roadmap。 - **归档保留期尚未自动裁剪**:`RETENTION_DAYS` 已解析但没有清理作业。 - **OpenCode 是当前唯一的工具适配器,且默认不连接**(界面按钮或 `MAESTRO_OPENCODE_ENABLED`);断开时任务由部门模型直接执行,连接后若 OpenCode server 没起,任务派发会失败,诊断里可见。 ## 更多文档 | 文件 | 内容 | | --- | --- | | `2026-10-15-ai-orchestrator-design.md` | 设计文档(目标、失败判据、验收) | | `GLOSSARY.md` | 领域词汇表,写代码/提 issue 时按这套叫法 | | `docs/GLOSSARY-QUICK.md` | 8 个核心领域词的速查表,先看这张再看全表 | | `docs/plans/2026-10-15-mvp-acceptance.md` | MVP 验收记录与人工冒烟步骤 | | `docs/TROUBLESHOOTING.md` | 起不来 / 进不去 / 任务不动——三类常见故障的排查步骤 | | `docs/adr/` | 架构决策记录 | | `docs/agents/` | 交付门禁(delivery-gate)、密钥(secrets)、issue 跟踪、标签约定 |