ai-maestro 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/LICENSE +15 -0
- package/README.md +727 -0
- package/bin/maestro.mjs +246 -0
- package/package.json +29 -0
- package/src/checkpoint.mjs +102 -0
- package/src/codex-diagnostics.mjs +682 -0
- package/src/codex-home-inspect.mjs +252 -0
- package/src/codex-home.mjs +258 -0
- package/src/commands.mjs +809 -0
- package/src/config.mjs +11 -0
- package/src/debug.mjs +164 -0
- package/src/encoding-guard.mjs +125 -0
- package/src/engines/ai-router-engine.mjs +37 -0
- package/src/engines/codex-engine.mjs +21 -0
- package/src/engines/engine.mjs +21 -0
- package/src/engines/registry.mjs +29 -0
- package/src/files.mjs +65 -0
- package/src/format.mjs +132 -0
- package/src/lock.mjs +439 -0
- package/src/memory-log.mjs +18 -0
- package/src/memory.mjs +1 -0
- package/src/orchestration/attempt-chain-runtime.mjs +627 -0
- package/src/orchestration/budget-manager.mjs +121 -0
- package/src/orchestration/capability-registry.mjs +108 -0
- package/src/orchestration/consolidator.mjs +772 -0
- package/src/orchestration/delegation-executor.mjs +262 -0
- package/src/orchestration/delegation-manager.mjs +116 -0
- package/src/orchestration/deployment-intent.mjs +36 -0
- package/src/orchestration/engine-history.mjs +110 -0
- package/src/orchestration/engine-policy.mjs +73 -0
- package/src/orchestration/engine-selector.mjs +187 -0
- package/src/orchestration/execution-context.mjs +45 -0
- package/src/orchestration/failure-classifier.mjs +136 -0
- package/src/orchestration/failure-evidence.mjs +237 -0
- package/src/orchestration/fallback-chain-lock.mjs +217 -0
- package/src/orchestration/fallback-chain-trail.mjs +218 -0
- package/src/orchestration/fallback-executor.mjs +146 -0
- package/src/orchestration/fallback-graph.mjs +106 -0
- package/src/orchestration/fallback-recommendation.mjs +73 -0
- package/src/orchestration/file-conflict-detector.mjs +126 -0
- package/src/orchestration/host-validation.mjs +241 -0
- package/src/orchestration/orchestration-loop.mjs +1971 -0
- package/src/orchestration/orchestration-runtime.mjs +1019 -0
- package/src/orchestration/orchestration-scheduler.mjs +135 -0
- package/src/orchestration/orchestration-trail.mjs +192 -0
- package/src/orchestration/preflight.mjs +212 -0
- package/src/orchestration/provider-health.mjs +566 -0
- package/src/orchestration/provider-router.mjs +352 -0
- package/src/orchestration/rc-check-adapters.mjs +817 -0
- package/src/orchestration/rc-check.mjs +544 -0
- package/src/orchestration/rc-policy.mjs +200 -0
- package/src/orchestration/runtime-gate.mjs +146 -0
- package/src/orchestration/sector-managers.mjs +215 -0
- package/src/orchestration/self-hosting-canary.mjs +231 -0
- package/src/orchestration/self-hosting-readiness.mjs +244 -0
- package/src/orchestration/spec-planner.mjs +877 -0
- package/src/orchestration/subtask-planner.mjs +176 -0
- package/src/orchestration/task-classifier.mjs +241 -0
- package/src/orchestration/verifier.mjs +1608 -0
- package/src/orchestration-commands.mjs +279 -0
- package/src/planner.mjs +38 -0
- package/src/project.mjs +1 -0
- package/src/run-diagnostics.mjs +641 -0
- package/src/runner.mjs +243 -0
- package/src/safety.mjs +116 -0
- package/src/schema.mjs +371 -0
- package/src/session-commands.mjs +521 -0
- package/src/shell.mjs +93 -0
- package/src/smart-planner.mjs +249 -0
- package/src/task-commands.mjs +1182 -0
- package/src/tasks.mjs +134 -0
- package/src/ui/commands.mjs +76 -0
- package/src/ui/events.mjs +45 -0
- package/src/ui/public/app.js +600 -0
- package/src/ui/public/index.html +88 -0
- package/src/ui/public/style.css +460 -0
- package/src/ui/server.mjs +112 -0
- package/src/ui/state.mjs +504 -0
- package/src/usage.mjs +178 -0
- package/src/workspace-diff.mjs +228 -0
package/README.md
ADDED
|
@@ -0,0 +1,727 @@
|
|
|
1
|
+
# AI Maestro CLI
|
|
2
|
+
|
|
3
|
+
AI Maestro is a global-friendly Node.js CLI named `maestro` for orchestrating AI coding work across project-local memory, plans, tasks, runs, checkpoints, and handoffs.
|
|
4
|
+
|
|
5
|
+
The design goal is simple: the project remembers, not the AI session.
|
|
6
|
+
|
|
7
|
+
## Status
|
|
8
|
+
|
|
9
|
+
Current version: 1.0.0 (first public release).
|
|
10
|
+
|
|
11
|
+
AI-MAESTRO already implements, and validates through its own test suite:
|
|
12
|
+
|
|
13
|
+
- A deterministic planner (`maestro plan`/`maestro start`) that classifies a
|
|
14
|
+
request and generates a scoped task list instead of one generic template.
|
|
15
|
+
- A worker discipline layer: a stricter Codex worker prompt, post-execution
|
|
16
|
+
verification (workspace diff, syntax validation per changed file, deletion
|
|
17
|
+
guard, analysis-only guard), so a task can only be marked `completed` when
|
|
18
|
+
its actual file changes were verified.
|
|
19
|
+
- An orchestration pipeline (task classifier, preflight, engine selector,
|
|
20
|
+
sector managers, budget manager, verifier, fallback graph, provider health,
|
|
21
|
+
circuit breaker, and a real provider router) that a real `run-task`/
|
|
22
|
+
`run-one` consults before dispatching a worker.
|
|
23
|
+
- `--dry-run` on the planning and execution commands to preview the full
|
|
24
|
+
decision (classification, selected engine, preflight, budget, fallback)
|
|
25
|
+
without ever calling a worker or mutating task/run state.
|
|
26
|
+
- Delegation and subtask planning (splitting a complex task into subtasks)
|
|
27
|
+
is implemented as **planning only** — AI-MAESTRO does not auto-execute
|
|
28
|
+
subagents yet. Parallel subagent execution, worktree isolation, and
|
|
29
|
+
automatic fallback re-dispatch are not implemented in this release.
|
|
30
|
+
- A release-candidate classifier (`maestro release-check`, `rc-check`) for
|
|
31
|
+
judging whether an orchestration run is safe to treat as a release
|
|
32
|
+
candidate.
|
|
33
|
+
|
|
34
|
+
See `CHANGELOG.md` for the release history.
|
|
35
|
+
|
|
36
|
+
## Project Model
|
|
37
|
+
|
|
38
|
+
- `.memory/` is the official portable memory for state, decisions, risks, facts, events, and handoff. It is managed by `ai-universal-memory`.
|
|
39
|
+
- `.maestro/` is the operational layer for plans, tasks, worker runs, checkpoints, and local handoff reports.
|
|
40
|
+
- Codex CLI with `codex exec --profile 9router` is the default non-interactive worker.
|
|
41
|
+
- Premium/Claude-style review is reserved for future critical architecture or final review work, not default task execution.
|
|
42
|
+
|
|
43
|
+
AI-Router and AI-MAESTRO are separate tools:
|
|
44
|
+
|
|
45
|
+
- AI-Router is a fast CLI router for interactive engine dispatch through `ai`.
|
|
46
|
+
- AI-MAESTRO is a persistent project orchestrator with `.memory/`, `.maestro/`, task state, worker runs, checkpoints, handoffs, safety checks, and usage stats.
|
|
47
|
+
|
|
48
|
+
AI-MAESTRO borrows practical patterns from AI-Router, such as command detection, safety guard ideas, status-style diagnostics, and usage summaries, but it does not depend on AI-Router at runtime, and does not modify any local AI-Router installation. A future worker backend may call `ai simples` or `ai fcc` as an optional alternative, but the default worker remains Codex through the isolated `CODEX_HOME`.
|
|
49
|
+
|
|
50
|
+
## Requirements
|
|
51
|
+
|
|
52
|
+
- Node.js 18 or newer (this release was tested with Node.js 24.18.0).
|
|
53
|
+
- `ai-universal-memory` available for project memory.
|
|
54
|
+
- Codex CLI installed and configured.
|
|
55
|
+
- A Codex profile named `9router`.
|
|
56
|
+
- 9Router running if your `9router` profile depends on localhost, commonly port `20128`.
|
|
57
|
+
|
|
58
|
+
Install memory tooling if needed:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npm install -g ai-universal-memory
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Install
|
|
65
|
+
|
|
66
|
+
### Global install (recommended)
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm install -g ai-maestro
|
|
70
|
+
maestro --help
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
This exposes the `maestro` command globally, backed by `bin/maestro.mjs`.
|
|
74
|
+
|
|
75
|
+
### Development install (from a clone of this repository)
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npm link
|
|
79
|
+
maestro status
|
|
80
|
+
maestro doctor
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## First Safe Use
|
|
84
|
+
|
|
85
|
+
Inside the project you want AI-MAESTRO to manage:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
maestro init
|
|
89
|
+
maestro doctor
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`maestro init` only sets up local project state (`.memory/`, `.maestro/`); it
|
|
93
|
+
does not call a worker or change any files outside the project. `maestro
|
|
94
|
+
doctor` is fully read-only and reports what is configured, missing, or
|
|
95
|
+
misconfigured (Node version, Codex discovery, `9router` profile, memory
|
|
96
|
+
tooling, safety config) before you run anything that touches real files.
|
|
97
|
+
|
|
98
|
+
Once `doctor` is clean, preview a task before executing it:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
maestro plan "describe what you want to build"
|
|
102
|
+
maestro run-one --dry-run
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
`--dry-run` shows the full orchestration decision (classification, selected
|
|
106
|
+
engine, preflight, budget, fallback) without ever calling a worker or
|
|
107
|
+
mutating task/run state — see "Dry-run vs real execution" below. Only drop
|
|
108
|
+
`--dry-run` once you are comfortable with what a real run will do.
|
|
109
|
+
|
|
110
|
+
## Recommended Flow
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
maestro init
|
|
114
|
+
maestro doctor
|
|
115
|
+
maestro codex-home
|
|
116
|
+
maestro codex-home-diff
|
|
117
|
+
maestro codex-home-inventory
|
|
118
|
+
maestro codex-home-probe
|
|
119
|
+
maestro codex-home-repair
|
|
120
|
+
maestro codex-compare
|
|
121
|
+
maestro codex-test
|
|
122
|
+
maestro plan "criar app de teste com tela inicial, formulario e lista"
|
|
123
|
+
maestro run-one
|
|
124
|
+
maestro run-task 8
|
|
125
|
+
maestro stats
|
|
126
|
+
maestro checkpoint
|
|
127
|
+
maestro handoff
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Basic Flow
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
maestro start "descreva o que quer construir"
|
|
134
|
+
maestro continue
|
|
135
|
+
maestro task list
|
|
136
|
+
maestro task next
|
|
137
|
+
maestro run-one
|
|
138
|
+
maestro run-all --limit 3
|
|
139
|
+
maestro release-check
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
`maestro start` initializes project state, validates Codex, runs a smoke test
|
|
143
|
+
when needed, creates a plan, and checkpoints. It does not execute tasks.
|
|
144
|
+
|
|
145
|
+
`maestro plan` uses a deterministic, keyword-based planner (`smart-heuristic-v1`),
|
|
146
|
+
not an LLM. It classifies the request text and generates a task list shaped for
|
|
147
|
+
that intent; unrecognized requests fall back to a generic template. Before
|
|
148
|
+
replacing an active backlog, it archives active tasks to
|
|
149
|
+
`.maestro/archive/tasks-before-plan-YYYYMMDD-HHMMSS.json`.
|
|
150
|
+
|
|
151
|
+
`maestro continue` summarizes memory, handoff state, pending tasks, and the next
|
|
152
|
+
safe command.
|
|
153
|
+
|
|
154
|
+
## Dry-run vs Real Execution
|
|
155
|
+
|
|
156
|
+
Every command that can call a worker supports `--dry-run`:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
maestro run-one --dry-run
|
|
160
|
+
maestro run-task <id> --dry-run
|
|
161
|
+
maestro orchestra-plan [<id>] --dry-run
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
`--dry-run` runs the full orchestration pipeline (classification, sector
|
|
165
|
+
manager, engine selection, preflight, budget, policy, fallback graph) and
|
|
166
|
+
prints the resulting decision, but never calls a worker and never mutates
|
|
167
|
+
task or run state. Drop `--dry-run` only once you have reviewed that output
|
|
168
|
+
and are ready for AI-MAESTRO to actually dispatch a worker and write files.
|
|
169
|
+
|
|
170
|
+
## Failover and Canary Are Opt-in
|
|
171
|
+
|
|
172
|
+
`maestro run-task <id> --failover` and `maestro canary <path>` are explicit,
|
|
173
|
+
opt-in commands — they are never triggered automatically by `run-one`,
|
|
174
|
+
`run-task`, or `run-all`. Automatic fallback re-dispatch to an alternative
|
|
175
|
+
engine, and parallel/self-hosting canary execution, only happen when you
|
|
176
|
+
invoke these commands yourself.
|
|
177
|
+
|
|
178
|
+
## Maestro Console
|
|
179
|
+
|
|
180
|
+
Run the local dashboard with:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
maestro ui
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
It serves `http://127.0.0.1:4317` by default and tries the next ports if that
|
|
187
|
+
one is already in use. The command prints the selected URL and keeps running; it
|
|
188
|
+
does not open a browser automatically.
|
|
189
|
+
|
|
190
|
+
The console shows status cards for Maestro, Codex, Memory, Safety, Engine
|
|
191
|
+
Router, and Project state. It reads `.memory/` and `.maestro/`, refreshes through
|
|
192
|
+
Server-Sent Events, and keeps raw logs collapsed by default.
|
|
193
|
+
|
|
194
|
+
Current UX:
|
|
195
|
+
|
|
196
|
+
- `Run Task` appears on each `pending`, `failed`, or `in_progress` task.
|
|
197
|
+
- `Reabrir` appears on blocked tasks and maps to the existing `task pending` CLI path.
|
|
198
|
+
- The timeline merges recent events from memory, runs, usage, and UI command logs.
|
|
199
|
+
- Filters cover `Todos`, `Maestro`, `Codex`, `Memory`, `Safety`, `Engine`, `UI`, and `Erros/Bloqueios`.
|
|
200
|
+
- `Copiar Handoff` copies the current handoff text from memory or the Maestro fallback.
|
|
201
|
+
- Each card and timeline item can reveal its raw log on demand and copy it locally.
|
|
202
|
+
|
|
203
|
+
The UI can run only this allowlist of operational commands:
|
|
204
|
+
|
|
205
|
+
```text
|
|
206
|
+
doctor, codex-home, codex-test, task-list, task-next, run-one,
|
|
207
|
+
run-all-limit-3, run-task, task-pending, checkpoint, handoff, stats,
|
|
208
|
+
release-check, schema-check
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
There is no arbitrary terminal in the dashboard. Command execution uses fixed
|
|
212
|
+
`spawn()` argument arrays and records summaries in `.maestro/ui-runs.jsonl`.
|
|
213
|
+
The server binds only to `127.0.0.1`; do not expose it through a public tunnel,
|
|
214
|
+
reverse proxy, or shared interface.
|
|
215
|
+
|
|
216
|
+
Limitations currently remain:
|
|
217
|
+
|
|
218
|
+
- The timeline is a recent-event view, not a full historical explorer.
|
|
219
|
+
- Raw logs are still stored in the project files; the UI only controls visibility.
|
|
220
|
+
- The console does not replace the CLI for direct task maintenance or archive flows.
|
|
221
|
+
|
|
222
|
+
Current validated MVP state:
|
|
223
|
+
|
|
224
|
+
- The default worker is Codex through `codex-js-isolated`.
|
|
225
|
+
- Maestro sets `CODEX_HOME=%USERPROFILE%\.codex-maestro` only for spawned worker processes.
|
|
226
|
+
- The isolated Codex home has been validated with `workspace-write`.
|
|
227
|
+
- `maestro codex-test` creates `MAESTRO_CODEX_TEST.md` through 9Router.
|
|
228
|
+
- `api.openai.com` was not observed in the validated Codex smoke test.
|
|
229
|
+
- `blocked by policy` was not observed in the validated Codex smoke test.
|
|
230
|
+
- Normal Codex home `%USERPROFILE%\.codex` is not modified by Maestro.
|
|
231
|
+
- `your local AI-Router installation, if any,` is reference-only and is not modified by Maestro.
|
|
232
|
+
|
|
233
|
+
## Commands
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
maestro help
|
|
237
|
+
maestro init
|
|
238
|
+
maestro status
|
|
239
|
+
maestro start "pedido"
|
|
240
|
+
maestro start "pedido" --validate-worker
|
|
241
|
+
maestro continue
|
|
242
|
+
maestro doctor
|
|
243
|
+
maestro codex-home
|
|
244
|
+
maestro codex-test
|
|
245
|
+
maestro codex-compare
|
|
246
|
+
maestro stats
|
|
247
|
+
maestro release-check
|
|
248
|
+
maestro schema-check
|
|
249
|
+
maestro plan "..."
|
|
250
|
+
maestro run-one
|
|
251
|
+
maestro run-one --quiet
|
|
252
|
+
maestro run-one --dry-run
|
|
253
|
+
maestro run-one --force
|
|
254
|
+
maestro run-task 8
|
|
255
|
+
maestro run-task 8 --quiet
|
|
256
|
+
maestro run-task 8 --dry-run
|
|
257
|
+
maestro run-task 8 --force
|
|
258
|
+
maestro run-all
|
|
259
|
+
maestro run-all --limit 3
|
|
260
|
+
maestro retry <id>
|
|
261
|
+
maestro task list
|
|
262
|
+
maestro task next
|
|
263
|
+
maestro task show <id>
|
|
264
|
+
maestro task add "descricao"
|
|
265
|
+
maestro task complete <id>
|
|
266
|
+
maestro task fail <id>
|
|
267
|
+
maestro task pending <id>
|
|
268
|
+
maestro task archive-failed
|
|
269
|
+
maestro task archive-completed
|
|
270
|
+
maestro task clean-test
|
|
271
|
+
maestro checkpoint
|
|
272
|
+
maestro handoff
|
|
273
|
+
maestro ui
|
|
274
|
+
maestro engines list
|
|
275
|
+
maestro engines show <id>
|
|
276
|
+
maestro engines health
|
|
277
|
+
maestro engines validate <id>
|
|
278
|
+
maestro engines research
|
|
279
|
+
maestro route-task [<id>]
|
|
280
|
+
maestro preflight [<id>]
|
|
281
|
+
maestro orchestra-plan [<id>] [--dry-run]
|
|
282
|
+
maestro budget
|
|
283
|
+
maestro stats --by-engine
|
|
284
|
+
maestro stats --by-run-kind
|
|
285
|
+
maestro stats --cost
|
|
286
|
+
maestro stats --by-gate-decision
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## Task Maintenance
|
|
290
|
+
|
|
291
|
+
`maestro task list` prints task totals by status, priority, engine, title, short
|
|
292
|
+
date, and the next task selected by `run-one`.
|
|
293
|
+
|
|
294
|
+
`maestro task next` shows the exact pending task that `run-one` would execute.
|
|
295
|
+
`blocked` and `needs_human` tasks are ignored by `run-one` and `run-all`;
|
|
296
|
+
`run-all` also stops its batch when a task lands on `needs_human`, the same
|
|
297
|
+
as `failed`/`blocked`. Use `maestro task pending <id>` to reopen a `blocked`
|
|
298
|
+
or `needs_human` task after review; the next execution may block again if
|
|
299
|
+
the same condition still applies. For a `needs_human` task specifically,
|
|
300
|
+
`maestro run-task <id> --force` is available once a human has reviewed the
|
|
301
|
+
risk — `--force` can only promote a `needs_human` decision to execution; it
|
|
302
|
+
can never bypass the safety guard, `.env`/deletion protections, an engine
|
|
303
|
+
policy violation, or a budget hard limit, all of which resolve to `blocked`
|
|
304
|
+
before `--force` is even considered.
|
|
305
|
+
|
|
306
|
+
Archive commands preserve history under `.maestro/archive/` instead of deleting
|
|
307
|
+
tasks:
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
maestro task archive-failed
|
|
311
|
+
maestro task archive-completed
|
|
312
|
+
maestro task clean-test
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
`archive-failed` moves failed tasks out of active `TASKS.json`.
|
|
316
|
+
`archive-completed` does the same for completed tasks. `clean-test` archives
|
|
317
|
+
obvious infrastructure smoke-test tasks such as `MAESTRO_CODEX_TEST.md`,
|
|
318
|
+
`MAESTRO_WORKER_TEST.md`, `WORKING_*`, and `PROBE_*`.
|
|
319
|
+
|
|
320
|
+
## Codex Worker
|
|
321
|
+
|
|
322
|
+
`maestro run-one`, `maestro run-task <id>`, and `maestro run-all` use non-interactive Codex execution:
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
codex exec --profile 9router --sandbox workspace-write --skip-git-repo-check "<prompt>"
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
The worker prompt instructs Codex to read:
|
|
329
|
+
|
|
330
|
+
- `.memory/BRIEF.md`
|
|
331
|
+
- `.maestro/PLAN.md`
|
|
332
|
+
- `.maestro/TASKS.json`
|
|
333
|
+
- `.maestro/worker-policy.md`
|
|
334
|
+
|
|
335
|
+
The worker policy forbids editing `.env`, deploys, file deletion, modifying the
|
|
336
|
+
normal Codex home, and modifying any local AI-Router installation. Workers
|
|
337
|
+
should record changed files, run relevant validations, and log meaningful
|
|
338
|
+
work to `.memory/` when possible.
|
|
339
|
+
|
|
340
|
+
`maestro run-one` executes the next `pending` task by priority. `maestro
|
|
341
|
+
run-task <id>` executes a specific task when its status is `pending` or
|
|
342
|
+
`in_progress`. Archived, completed, and failed tasks are not executed directly;
|
|
343
|
+
use `maestro retry <id>` for failed tasks.
|
|
344
|
+
|
|
345
|
+
`maestro run-all --limit 3` executes pending tasks in priority order, stops on
|
|
346
|
+
the first error, records usage, and writes a checkpoint at the end.
|
|
347
|
+
|
|
348
|
+
Before any Codex worker is called, AI-MAESTRO runs `checkTaskSafety()` against
|
|
349
|
+
the task title and description. If a dangerous pattern or protected file is
|
|
350
|
+
detected, the task is marked `blocked`, Codex is not called, `.maestro/RUNS.jsonl`
|
|
351
|
+
and `.maestro/usage.jsonl` are updated, and the finding is logged to memory.
|
|
352
|
+
|
|
353
|
+
## Isolated Codex Home
|
|
354
|
+
|
|
355
|
+
Normal Codex usage should continue using the user's regular Codex home, typically:
|
|
356
|
+
|
|
357
|
+
```text
|
|
358
|
+
%USERPROFILE%\.codex
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
AI-MAESTRO uses a separate Codex home only for child worker processes:
|
|
362
|
+
|
|
363
|
+
```text
|
|
364
|
+
%USERPROFILE%\.codex-maestro
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
It sets `CODEX_HOME` only in the spawned Codex process. It does not set `CODEX_HOME` globally and does not edit the normal Codex config.
|
|
368
|
+
|
|
369
|
+
Create or validate the isolated config:
|
|
370
|
+
|
|
371
|
+
```powershell
|
|
372
|
+
maestro codex-home
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
The default Maestro Codex config uses profile `9router`, provider `9router`, and `wire_api = "responses"` pointing at `http://localhost:20128/v1`.
|
|
376
|
+
|
|
377
|
+
Run a direct worker smoke test:
|
|
378
|
+
|
|
379
|
+
```powershell
|
|
380
|
+
maestro codex-test
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
This attempts to create `MAESTRO_CODEX_TEST.md` through Codex using the isolated `CODEX_HOME`.
|
|
384
|
+
|
|
385
|
+
Run an invocation comparison when Codex works manually but fails through Maestro:
|
|
386
|
+
|
|
387
|
+
```powershell
|
|
388
|
+
maestro codex-compare
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
This creates four diagnostic files with different invocations and stores the
|
|
392
|
+
result in `.maestro/codex-compare.json`:
|
|
393
|
+
|
|
394
|
+
- `codex.cmd` with the normal Codex home.
|
|
395
|
+
- `codex.cmd` with `CODEX_HOME=%USERPROFILE%\.codex-maestro`.
|
|
396
|
+
- `node.exe codex.js` with the normal Codex home.
|
|
397
|
+
- `node.exe codex.js` with `CODEX_HOME=%USERPROFILE%\.codex-maestro`.
|
|
398
|
+
|
|
399
|
+
`codex.cmd` is the Windows command shim. `node.exe codex.js` runs the Codex
|
|
400
|
+
JavaScript entrypoint directly, which usually handles long prompts better. Some
|
|
401
|
+
Codex builds can behave differently between the two, so Maestro records the
|
|
402
|
+
working invocation instead of assuming they are equivalent.
|
|
403
|
+
|
|
404
|
+
`MAESTRO_CODEX_INVOCATION` controls the selected invocation:
|
|
405
|
+
|
|
406
|
+
- `auto` (default): use `.maestro/codex-compare.json` and choose the safest working invocation.
|
|
407
|
+
- `codex-js-isolated`: `node.exe codex.js` with the isolated Maestro Codex home.
|
|
408
|
+
- `codex-cmd-isolated`: `codex.cmd` with the isolated Maestro Codex home.
|
|
409
|
+
- `codex-js-normal-home`: `node.exe codex.js` without forcing `CODEX_HOME`.
|
|
410
|
+
- `codex-cmd`: `codex.cmd` without forcing `CODEX_HOME`.
|
|
411
|
+
|
|
412
|
+
The safest order is isolated first: `codex-js-isolated`, then
|
|
413
|
+
`codex-cmd-isolated`, then normal-home compatibility modes. If only `codex.cmd`
|
|
414
|
+
with the normal home works, Maestro reports it as compatibility mode and does
|
|
415
|
+
not edit the normal Codex config.
|
|
416
|
+
|
|
417
|
+
Compare the normal and isolated Codex homes without printing secrets:
|
|
418
|
+
|
|
419
|
+
```powershell
|
|
420
|
+
maestro codex-home-diff
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
This writes `.maestro/codex-home-diff.json` with file names, TOML sections,
|
|
424
|
+
non-sensitive config values, policy/trust-like files, and sensitive files by
|
|
425
|
+
existence/type only. Token, auth, session, cookie, and credential contents are
|
|
426
|
+
never copied into the report.
|
|
427
|
+
|
|
428
|
+
Generate a deeper redacted inventory:
|
|
429
|
+
|
|
430
|
+
```powershell
|
|
431
|
+
maestro codex-home-inventory
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
This writes `.maestro/codex-home-inventory.json`. Each relative path is
|
|
435
|
+
classified as config, trust, policy, sandbox runtime, rule, cache,
|
|
436
|
+
auth-sensitive, session-sensitive, unknown-sensitive, or safe-copy-candidate.
|
|
437
|
+
Hashes are included only for non-sensitive files. Sensitive contents are never
|
|
438
|
+
written to the report.
|
|
439
|
+
|
|
440
|
+
Probe safe candidates incrementally:
|
|
441
|
+
|
|
442
|
+
```powershell
|
|
443
|
+
maestro codex-home-probe
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
The probe confirms the current `codex-js-isolated` baseline, then tests safe
|
|
447
|
+
copy candidates one at a time. It backs up `.codex-maestro`, copies only the
|
|
448
|
+
candidate file, runs an isolated write test, and restores the backup if the
|
|
449
|
+
candidate does not unlock `workspace-write`. It never copies auth, token,
|
|
450
|
+
session, cookie, credential, cache, or unknown-sensitive files.
|
|
451
|
+
|
|
452
|
+
Repair the isolated home:
|
|
453
|
+
|
|
454
|
+
```powershell
|
|
455
|
+
maestro codex-home-repair
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
The repair first backs up `%USERPROFILE%\.codex-maestro` to
|
|
459
|
+
`%USERPROFILE%\.codex-maestro.backup-YYYYMMDD-HHMMSS`, then rewrites
|
|
460
|
+
`9router.config.toml` in the isolated home using the format expected by the
|
|
461
|
+
current Codex build: provider, model, `approval_policy = "never"`, and
|
|
462
|
+
`sandbox_mode = "workspace-write"` in the profile file. It does not copy auth,
|
|
463
|
+
session, token, cookie, credential, or cache files from the normal Codex home.
|
|
464
|
+
|
|
465
|
+
The target final state is `codex-js-isolated`. If the isolated home still enters
|
|
466
|
+
`read-only`, Maestro keeps `codex-js-normal-home` as a compatibility fallback.
|
|
467
|
+
That fallback uses the normal Codex configuration only at runtime; Maestro does
|
|
468
|
+
not edit the normal Codex config.
|
|
469
|
+
|
|
470
|
+
## Codex Sandbox Strategies
|
|
471
|
+
|
|
472
|
+
AI-MAESTRO resolves Codex sandbox execution with `MAESTRO_CODEX_STRATEGY`.
|
|
473
|
+
Valid values are:
|
|
474
|
+
|
|
475
|
+
- `auto` (default): use the first safe strategy proven by `maestro codex-test`.
|
|
476
|
+
- `basic`: `codex exec --profile 9router --sandbox workspace-write --skip-git-repo-check`.
|
|
477
|
+
- `global-approval`: pass approval globally before `exec`, for Codex builds where `--ask-for-approval` or `-a` is a global flag.
|
|
478
|
+
- `config-override`: pass `-c approval_policy="never"` and `-c sandbox_mode="workspace-write"` to `exec`.
|
|
479
|
+
- `ignore-rules`: add `--ignore-rules` for diagnosis when the exec help supports it.
|
|
480
|
+
- `workspace-permissions`: use an isolated `workspace-permissions.config.toml` with `default_permissions = ":workspace"`.
|
|
481
|
+
- `dangerous-yolo`: diagnostic only. It is never selected by `auto` and is only tested when `MAESTRO_ALLOW_DANGEROUS_CODEX_TEST=1`.
|
|
482
|
+
|
|
483
|
+
`maestro codex-test` tries the safe strategies in order and stores the first
|
|
484
|
+
working result in `.maestro/codex-strategy.json`. `runCodex` uses that validated
|
|
485
|
+
strategy in `auto` mode. If no strategy has been validated yet, it falls back to
|
|
486
|
+
`basic`.
|
|
487
|
+
|
|
488
|
+
Some Codex versions expose approval control only in `codex --help`, not in
|
|
489
|
+
`codex exec --help`. In that case the correct order is:
|
|
490
|
+
|
|
491
|
+
```powershell
|
|
492
|
+
codex --ask-for-approval never exec ...
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
or:
|
|
496
|
+
|
|
497
|
+
```powershell
|
|
498
|
+
codex -a never exec ...
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
not `codex exec --ask-for-approval never ...`.
|
|
502
|
+
|
|
503
|
+
Codex has two sandbox configuration styles. The older style uses
|
|
504
|
+
`sandbox_mode = "workspace-write"`. The newer permission style can use
|
|
505
|
+
`default_permissions = ":workspace"`. AI-MAESTRO keeps these in separate config
|
|
506
|
+
files and does not mix `default_permissions` with `sandbox_mode` in the
|
|
507
|
+
`workspace-permissions` diagnostic config.
|
|
508
|
+
|
|
509
|
+
Supported environment variables:
|
|
510
|
+
|
|
511
|
+
- `MAESTRO_CODEX_HOME`
|
|
512
|
+
- `MAESTRO_CODEX_PROFILE`
|
|
513
|
+
- `MAESTRO_CODEX_INVOCATION`
|
|
514
|
+
- `MAESTRO_CODEX_STRATEGY`
|
|
515
|
+
- `MAESTRO_CODEX_JS`
|
|
516
|
+
- `MAESTRO_CODEX_PATH`
|
|
517
|
+
- `MAESTRO_NPX_PATH`
|
|
518
|
+
- `NINEROUTER_API_KEY`
|
|
519
|
+
- `MAESTRO_ALLOW_LOCAL_TEST_KEY`
|
|
520
|
+
|
|
521
|
+
`NINEROUTER_API_KEY` is not silently replaced. If it is missing, `doctor` reports
|
|
522
|
+
an error. For explicit local diagnostics only, set
|
|
523
|
+
`MAESTRO_ALLOW_LOCAL_TEST_KEY=1` to allow the `local-test` fallback.
|
|
524
|
+
|
|
525
|
+
## Safety And Stats
|
|
526
|
+
|
|
527
|
+
AI-MAESTRO creates `.maestro/safety.json` and checks task text before dispatching a worker. If a task mentions protected files or dangerous actions, Maestro blocks the run, records it in `.maestro/RUNS.jsonl`, logs it to `.memory/`, and does not call Codex.
|
|
528
|
+
|
|
529
|
+
Usage is recorded in:
|
|
530
|
+
|
|
531
|
+
- `.maestro/usage.jsonl`
|
|
532
|
+
- `.maestro/usage-summary.json`
|
|
533
|
+
|
|
534
|
+
Show stats with:
|
|
535
|
+
|
|
536
|
+
```powershell
|
|
537
|
+
maestro stats
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
Stats include task runs, completed/failed/blocked counts, estimated tokens, estimated Claude tokens avoided, engines, recent runs, Codex home, expected provider, and whether `api.openai.com` appeared in output.
|
|
541
|
+
|
|
542
|
+
## Release Check
|
|
543
|
+
|
|
544
|
+
Run the MVP release gate with:
|
|
545
|
+
|
|
546
|
+
```powershell
|
|
547
|
+
maestro release-check
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
It runs syntax checks for the main modules, then runs doctor, Codex smoke test,
|
|
551
|
+
stats, checkpoint, and handoff. It also verifies that README exists,
|
|
552
|
+
`package.json` exposes the `maestro` bin, and the main commands are documented.
|
|
553
|
+
The report is written to `.maestro/RELEASE_CHECK.md`.
|
|
554
|
+
|
|
555
|
+
## Doctor
|
|
556
|
+
|
|
557
|
+
Run:
|
|
558
|
+
|
|
559
|
+
```bash
|
|
560
|
+
maestro doctor
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
The doctor checks:
|
|
564
|
+
|
|
565
|
+
- Node version.
|
|
566
|
+
- `.memory/` and `.memory/tools/cli.mjs`.
|
|
567
|
+
- `.maestro/`.
|
|
568
|
+
- `9router` on PATH.
|
|
569
|
+
- port `20128`.
|
|
570
|
+
- Codex command discovery.
|
|
571
|
+
- Codex normal and Maestro Codex home.
|
|
572
|
+
- `MAESTRO_CODEX_PATH`.
|
|
573
|
+
- `MAESTRO_CODEX_HOME`.
|
|
574
|
+
- `MAESTRO_CODEX_JS`.
|
|
575
|
+
- `MAESTRO_CODEX_PROFILE`.
|
|
576
|
+
- `NINEROUTER_API_KEY`.
|
|
577
|
+
- npx/npm discovery.
|
|
578
|
+
- `.maestro/safety.json`.
|
|
579
|
+
- `codex exec --profile 9router --help`.
|
|
580
|
+
- `package.json` global CLI fields.
|
|
581
|
+
- Git repository status and whether `--skip-git-repo-check` is needed.
|
|
582
|
+
|
|
583
|
+
Doctor output uses:
|
|
584
|
+
|
|
585
|
+
- `OK`
|
|
586
|
+
- `AVISO`
|
|
587
|
+
- `ERRO`
|
|
588
|
+
- `COMO CORRIGIR`
|
|
589
|
+
|
|
590
|
+
## Windows: spawn codex ENOENT
|
|
591
|
+
|
|
592
|
+
On Windows, PowerShell can sometimes find `codex`, while Node's `spawn(..., { shell: false })` cannot. AI Maestro tries, in order:
|
|
593
|
+
|
|
594
|
+
1. `MAESTRO_CODEX_JS`
|
|
595
|
+
2. `MAESTRO_CODEX_PATH` pointing to a `.js` file
|
|
596
|
+
3. the real `codex.js` behind `codex.cmd`
|
|
597
|
+
4. common npm global install paths under `%APPDATA%\npm\node_modules`
|
|
598
|
+
5. `MAESTRO_CODEX_PATH`
|
|
599
|
+
6. `where.exe codex.exe`
|
|
600
|
+
7. `where.exe codex.cmd`
|
|
601
|
+
8. `where.exe codex`
|
|
602
|
+
|
|
603
|
+
Prefer the real JS entrypoint for Codex on Windows because long prompts can be split incorrectly by `codex.cmd` wrappers:
|
|
604
|
+
|
|
605
|
+
```powershell
|
|
606
|
+
setx MAESTRO_CODEX_JS "%APPDATA%\npm\node_modules\@openai\codex\bin\codex.js"
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
AI Maestro will then execute:
|
|
610
|
+
|
|
611
|
+
```powershell
|
|
612
|
+
node "...\codex.js" exec --profile 9router --sandbox workspace-write --skip-git-repo-check "<prompt>"
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
with the prompt as one array argument.
|
|
616
|
+
|
|
617
|
+
If no JS entrypoint is configured or discoverable, AI Maestro falls back to:
|
|
618
|
+
|
|
619
|
+
1. `MAESTRO_CODEX_PATH`
|
|
620
|
+
2. `where.exe codex.exe`
|
|
621
|
+
3. `where.exe codex.cmd`
|
|
622
|
+
4. `where.exe codex`
|
|
623
|
+
|
|
624
|
+
If `maestro run-one` fails with `spawn codex ENOENT` or the doctor reports that Codex is missing, inspect the installed command:
|
|
625
|
+
|
|
626
|
+
```powershell
|
|
627
|
+
Get-Command codex -All | Format-List CommandType,Source,Definition
|
|
628
|
+
where.exe codex
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
Then configure the full executable path:
|
|
632
|
+
|
|
633
|
+
```powershell
|
|
634
|
+
setx MAESTRO_CODEX_PATH "CAMINHO_COMPLETO_DO_CODEX"
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
Open a new terminal after running `setx`, then run:
|
|
638
|
+
|
|
639
|
+
```powershell
|
|
640
|
+
maestro doctor
|
|
641
|
+
maestro run-one
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
If the path points to `codex.exe`, AI Maestro uses direct `spawn` with `shell:false`. If the path points to `codex.cmd` or `.bat`, AI Maestro uses a controlled `cmd.exe /d /s /c` fallback shaped like:
|
|
645
|
+
|
|
646
|
+
```powershell
|
|
647
|
+
cmd.exe /d /s /c ""%APPDATA%\npm\codex.cmd" exec --profile 9router --sandbox workspace-write --skip-git-repo-check "<prompt>""
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
Arguments are quoted individually before being passed to `cmd.exe`.
|
|
651
|
+
|
|
652
|
+
## Windows: spawn npx ENOENT
|
|
653
|
+
|
|
654
|
+
On Windows, Node may not find `npx` even when PowerShell can. AI Maestro resolves npx with:
|
|
655
|
+
|
|
656
|
+
1. `MAESTRO_NPX_PATH`
|
|
657
|
+
2. `where.exe npx.cmd`
|
|
658
|
+
3. `where.exe npx`
|
|
659
|
+
|
|
660
|
+
If `maestro init` fails with `spawn npx ENOENT`, inspect npx:
|
|
661
|
+
|
|
662
|
+
```powershell
|
|
663
|
+
where.exe npx
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
Then configure the full `.cmd` path:
|
|
667
|
+
|
|
668
|
+
```powershell
|
|
669
|
+
setx MAESTRO_NPX_PATH "C:\Program Files\nodejs\npx.cmd"
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
Open a new terminal and run:
|
|
673
|
+
|
|
674
|
+
```powershell
|
|
675
|
+
maestro doctor
|
|
676
|
+
maestro init
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
## Security
|
|
680
|
+
|
|
681
|
+
AI-MAESTRO itself never asks for, stores, or transmits API credentials. It
|
|
682
|
+
delegates model calls entirely to the Codex CLI, which you install and
|
|
683
|
+
authenticate separately; AI-MAESTRO only sets `CODEX_HOME` for the spawned
|
|
684
|
+
worker process and checks (never prints the value of) `NINEROUTER_API_KEY`.
|
|
685
|
+
Diagnostic commands (`codex-home-diff`, `codex-home-inventory`,
|
|
686
|
+
`codex-home-probe`) classify config files as auth/session/token/cookie/
|
|
687
|
+
credential-sensitive and never copy or print their contents — only
|
|
688
|
+
non-sensitive values, file existence, and file type are recorded.
|
|
689
|
+
|
|
690
|
+
Safety rules enforced at runtime:
|
|
691
|
+
|
|
692
|
+
- No `shell:true` for free-form user prompts; worker prompts are always
|
|
693
|
+
passed as array arguments, never interpolated into a shell string.
|
|
694
|
+
- No deploy command is run by Maestro.
|
|
695
|
+
- `.env` files are not edited by Maestro.
|
|
696
|
+
- `.memory/` and `.maestro/` are not deleted automatically.
|
|
697
|
+
- Before dispatching any worker, `checkTaskSafety()` scans the task text for
|
|
698
|
+
dangerous patterns or protected files; a match blocks the task instead of
|
|
699
|
+
calling Codex.
|
|
700
|
+
- Critical files are backed up before overwrite where practical:
|
|
701
|
+
- `.maestro/TASKS.json`
|
|
702
|
+
- `.maestro/RUNS.jsonl`
|
|
703
|
+
- `.maestro/PLAN.md`
|
|
704
|
+
- The Maestro Console (`maestro ui`) binds only to `127.0.0.1`, exposes no
|
|
705
|
+
arbitrary terminal, and can only run a fixed allowlist of operational
|
|
706
|
+
commands (see "Maestro Console" above). Do not expose it through a public
|
|
707
|
+
tunnel or reverse proxy.
|
|
708
|
+
|
|
709
|
+
If you find a security issue, please open an issue on the project repository
|
|
710
|
+
rather than filing a public task with sensitive details.
|
|
711
|
+
|
|
712
|
+
## Future Work
|
|
713
|
+
|
|
714
|
+
- Wire the fallback graph's hints into `run-task`'s actual failure handling
|
|
715
|
+
(today's release adds the classification/policy, not the automatic retry loop).
|
|
716
|
+
- Parallel subagent execution with per-subagent worktree/branch isolation (serial-only by design in this release).
|
|
717
|
+
- Populate engine `health` fields from a real `maestro engines health --refresh`-style
|
|
718
|
+
live check, instead of staying `null` until something else writes engine history.
|
|
719
|
+
- Register more of the models 9Router exposes as real, runnable engines
|
|
720
|
+
(today only `codex9` and `ai-router` have invocation modules).
|
|
721
|
+
- Premium/Claude review as an explicit opt-in command, still never a
|
|
722
|
+
default worker.
|
|
723
|
+
|
|
724
|
+
## License
|
|
725
|
+
|
|
726
|
+
AI-MAESTRO is released under the ISC License. See the `LICENSE` file for the
|
|
727
|
+
full text.
|