bmad-auto-copilot 1.1.1 → 1.1.3
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/README.md +6 -4
- package/bin/cli.js +9 -3
- package/lib/run.js +7 -3
- package/package.json +1 -1
- package/templates/bmad-loop.ps1 +26 -11
- package/templates/bmad-loop.sh +12 -8
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@ The automation loop continuously:
|
|
|
30
30
|
3. Auto-commits code after successful code reviews
|
|
31
31
|
4. Repeats until all stories reach `done`
|
|
32
32
|
|
|
33
|
-
Each session uses **
|
|
33
|
+
Each session uses **GPT-5.3-Codex** with **xhigh reasoning effort** by default (configurable).
|
|
34
34
|
|
|
35
35
|
## Prerequisites
|
|
36
36
|
|
|
@@ -82,6 +82,7 @@ Installs to: `.scripts/bmad-auto/copilot/`
|
|
|
82
82
|
npx bmad-auto-copilot run # Run with defaults
|
|
83
83
|
npx bmad-auto-copilot run --max 100 # Limit to 100 iterations
|
|
84
84
|
npx bmad-auto-copilot run --model gpt-4.1 # Use different model
|
|
85
|
+
npx bmad-auto-copilot run --reasoning-effort high # Use different reasoning effort
|
|
85
86
|
npx bmad-auto-copilot run --verbose --dry # Dry run with debug output
|
|
86
87
|
```
|
|
87
88
|
|
|
@@ -124,7 +125,8 @@ After installation, you can run the scripts directly:
|
|
|
124
125
|
|
|
125
126
|
| Variable | Default | Description |
|
|
126
127
|
|----------|---------|-------------|
|
|
127
|
-
| `COPILOT_MODEL` | `
|
|
128
|
+
| `COPILOT_MODEL` | `gpt-5.3-codex` | AI model for all sessions |
|
|
129
|
+
| `COPILOT_REASONING_EFFORT` | `xhigh` | Reasoning effort for all sessions |
|
|
128
130
|
| `ITERATION_DELAY` | `10` | Seconds between iterations |
|
|
129
131
|
|
|
130
132
|
### bmad-auto-config.yaml
|
|
@@ -142,8 +144,8 @@ implementation_artifacts: "_bmad-output/implementation-artifacts"
|
|
|
142
144
|
Each step creates a **completely isolated Copilot CLI session**:
|
|
143
145
|
|
|
144
146
|
```
|
|
145
|
-
copilot --
|
|
146
|
-
copilot --
|
|
147
|
+
copilot --model gpt-5.3-codex --reasoning-effort xhigh -p <prompt> --allow-all --no-ask-user
|
|
148
|
+
copilot --model gpt-5.3-codex --reasoning-effort xhigh -p <prompt> --allow-all --no-ask-user
|
|
147
149
|
```
|
|
148
150
|
|
|
149
151
|
This ensures:
|
package/bin/cli.js
CHANGED
|
@@ -30,7 +30,8 @@ COMMANDS:
|
|
|
30
30
|
run [path] Run the automation loop (shortcut for bmad-loop.sh)
|
|
31
31
|
|
|
32
32
|
OPTIONS:
|
|
33
|
-
--model <model> AI model (default:
|
|
33
|
+
--model <model> AI model (default: gpt-5.3-codex)
|
|
34
|
+
--reasoning-effort Reasoning effort (default: xhigh)
|
|
34
35
|
--max <n> Max iterations (default: 250)
|
|
35
36
|
--output <folder> BMAD output folder (default: auto-detect from config)
|
|
36
37
|
--force Overwrite existing installation
|
|
@@ -39,7 +40,8 @@ OPTIONS:
|
|
|
39
40
|
EXAMPLES:
|
|
40
41
|
npx bmad-auto-copilot install
|
|
41
42
|
npx bmad-auto-copilot install ~/projects/my-app
|
|
42
|
-
npx bmad-auto-copilot install --model
|
|
43
|
+
npx bmad-auto-copilot install --model gpt-5.3-codex
|
|
44
|
+
npx bmad-auto-copilot run --reasoning-effort xhigh
|
|
43
45
|
npx bmad-auto-copilot run --max 100
|
|
44
46
|
npx bmad-auto-copilot status
|
|
45
47
|
npx bmad-auto-copilot uninstall
|
|
@@ -54,7 +56,8 @@ function parseArgs(args) {
|
|
|
54
56
|
const parsed = {
|
|
55
57
|
command: null,
|
|
56
58
|
projectPath: null,
|
|
57
|
-
model: '
|
|
59
|
+
model: 'gpt-5.3-codex',
|
|
60
|
+
reasoningEffort: 'xhigh',
|
|
58
61
|
maxIterations: 250,
|
|
59
62
|
outputFolder: null,
|
|
60
63
|
force: false,
|
|
@@ -82,6 +85,9 @@ function parseArgs(args) {
|
|
|
82
85
|
case '--model':
|
|
83
86
|
parsed.model = args[++i];
|
|
84
87
|
break;
|
|
88
|
+
case '--reasoning-effort':
|
|
89
|
+
parsed.reasoningEffort = args[++i];
|
|
90
|
+
break;
|
|
85
91
|
case '--max':
|
|
86
92
|
parsed.maxIterations = parseInt(args[++i], 10);
|
|
87
93
|
break;
|
package/lib/run.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// ============================================================
|
|
4
4
|
|
|
5
5
|
const path = require('path');
|
|
6
|
-
const {
|
|
6
|
+
const { spawn } = require('child_process');
|
|
7
7
|
const {
|
|
8
8
|
resolveProject,
|
|
9
9
|
getInstallPath,
|
|
@@ -40,8 +40,9 @@ async function run(args) {
|
|
|
40
40
|
String(args.maxIterations),
|
|
41
41
|
...(args.verbose ? ['-Verbose'] : []),
|
|
42
42
|
...(args.dryRun ? ['-DryRun'] : []),
|
|
43
|
-
...(args.model
|
|
44
|
-
|
|
43
|
+
...(args.model ? ['-Model', args.model] : []),
|
|
44
|
+
...(args.reasoningEffort
|
|
45
|
+
? ['-ReasoningEffort', args.reasoningEffort]
|
|
45
46
|
: []),
|
|
46
47
|
]
|
|
47
48
|
);
|
|
@@ -63,6 +64,9 @@ async function run(args) {
|
|
|
63
64
|
if (args.model) {
|
|
64
65
|
env.COPILOT_MODEL = args.model;
|
|
65
66
|
}
|
|
67
|
+
if (args.reasoningEffort) {
|
|
68
|
+
env.COPILOT_REASONING_EFFORT = args.reasoningEffort;
|
|
69
|
+
}
|
|
66
70
|
|
|
67
71
|
// Spawn the loop script as a child process with inherited stdio
|
|
68
72
|
const child = spawn(scriptArgs[0], scriptArgs[1], {
|
package/package.json
CHANGED
package/templates/bmad-loop.ps1
CHANGED
|
@@ -7,11 +7,13 @@
|
|
|
7
7
|
Each step runs as a NEW Copilot CLI session (fresh context window).
|
|
8
8
|
Continues until all stories reach 'done' state in sprint-status.yaml.
|
|
9
9
|
|
|
10
|
-
Model:
|
|
10
|
+
Model: GPT-5.3-Codex with xhigh reasoning (configurable via params or env vars)
|
|
11
11
|
.PARAMETER MaxIterations
|
|
12
12
|
Safety limit for maximum loop iterations (default: 250)
|
|
13
13
|
.PARAMETER Model
|
|
14
|
-
AI model to use (default:
|
|
14
|
+
AI model to use (default: gpt-5.3-codex)
|
|
15
|
+
.PARAMETER ReasoningEffort
|
|
16
|
+
Reasoning effort to use (default: xhigh)
|
|
15
17
|
.PARAMETER Verbose
|
|
16
18
|
Enable detailed debug logging
|
|
17
19
|
.PARAMETER DryRun
|
|
@@ -31,6 +33,7 @@
|
|
|
31
33
|
param(
|
|
32
34
|
[int]$MaxIterations = 250,
|
|
33
35
|
[string]$Model = "",
|
|
36
|
+
[string]$ReasoningEffort = "",
|
|
34
37
|
[switch]$Verbose,
|
|
35
38
|
[switch]$DryRun
|
|
36
39
|
)
|
|
@@ -51,7 +54,15 @@ if (-not $Model) {
|
|
|
51
54
|
$Model = $env:COPILOT_MODEL
|
|
52
55
|
}
|
|
53
56
|
if (-not $Model) {
|
|
54
|
-
$Model = "
|
|
57
|
+
$Model = "gpt-5.3-codex"
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# Reasoning effort: prefer parameter > env var > default
|
|
61
|
+
if (-not $ReasoningEffort) {
|
|
62
|
+
$ReasoningEffort = $env:COPILOT_REASONING_EFFORT
|
|
63
|
+
}
|
|
64
|
+
if (-not $ReasoningEffort) {
|
|
65
|
+
$ReasoningEffort = "xhigh"
|
|
55
66
|
}
|
|
56
67
|
|
|
57
68
|
# Delay between iterations (seconds)
|
|
@@ -164,6 +175,8 @@ function Get-NextAction {
|
|
|
164
175
|
Write-Log "[DEBUG] Found $($storyLines.Count) story lines" "Gray"
|
|
165
176
|
}
|
|
166
177
|
|
|
178
|
+
# Strip inline YAML comments so status matching works with annotated lines
|
|
179
|
+
$storyLines = $storyLines | ForEach-Object { $_ -replace '\s*#.*$', '' }
|
|
167
180
|
$reviewCount = ($storyLines | Where-Object { $_ -match ':\s*review\s*$' }).Count
|
|
168
181
|
$readyCount = ($storyLines | Where-Object { $_ -match ':\s*ready-for-dev\s*$' }).Count
|
|
169
182
|
$backlogCount = ($storyLines | Where-Object { $_ -match ':\s*backlog\s*$' }).Count
|
|
@@ -179,6 +192,10 @@ function Get-NextAction {
|
|
|
179
192
|
Write-Log "[NEXT] Found story in REVIEW state -> code-review (Dev agent)" "Green"
|
|
180
193
|
return "code-review"
|
|
181
194
|
}
|
|
195
|
+
if ($inProgressCount -gt 0) {
|
|
196
|
+
Write-Log "[NEXT] Found story in IN-PROGRESS state -> dev-story resume (Dev agent)" "Green"
|
|
197
|
+
return "dev-story"
|
|
198
|
+
}
|
|
182
199
|
if ($readyCount -gt 0) {
|
|
183
200
|
Write-Log "[NEXT] Found story in READY-FOR-DEV state -> dev-story (Dev agent)" "Green"
|
|
184
201
|
return "dev-story"
|
|
@@ -192,10 +209,6 @@ function Get-NextAction {
|
|
|
192
209
|
return "complete"
|
|
193
210
|
}
|
|
194
211
|
|
|
195
|
-
if ($inProgressCount -gt 0) {
|
|
196
|
-
Write-Log "[WAIT] Found $inProgressCount story(ies) in-progress" "Yellow"
|
|
197
|
-
}
|
|
198
|
-
|
|
199
212
|
return "wait"
|
|
200
213
|
}
|
|
201
214
|
|
|
@@ -218,10 +231,10 @@ function Invoke-CopilotSession {
|
|
|
218
231
|
$prompt = Get-Content $PromptFile -Raw
|
|
219
232
|
$prompt = $prompt -replace '\{TIMESTAMP\}', (Get-Date -Format "yyyy-MM-dd HH:mm:ss")
|
|
220
233
|
|
|
221
|
-
Write-Log "[SESSION] New Copilot CLI session -> Agent: $Agent | Model: $Model | Action: $ActionLabel" "Magenta"
|
|
234
|
+
Write-Log "[SESSION] New Copilot CLI session -> Agent: $Agent | Model: $Model | Reasoning: $ReasoningEffort | Action: $ActionLabel" "Magenta"
|
|
222
235
|
|
|
223
236
|
if ($DryRun) {
|
|
224
|
-
Write-Log "[DRY RUN] Would execute: copilot --
|
|
237
|
+
Write-Log "[DRY RUN] Would execute: copilot --model $Model --reasoning-effort $ReasoningEffort -p '...' --allow-all --no-ask-user" "Yellow"
|
|
225
238
|
return $true
|
|
226
239
|
}
|
|
227
240
|
|
|
@@ -233,6 +246,7 @@ function Invoke-CopilotSession {
|
|
|
233
246
|
# The prompt itself contains all workflow instructions.
|
|
234
247
|
copilot `
|
|
235
248
|
--model $Model `
|
|
249
|
+
--reasoning-effort $ReasoningEffort `
|
|
236
250
|
--allow-all `
|
|
237
251
|
--no-ask-user `
|
|
238
252
|
-p $prompt
|
|
@@ -258,7 +272,7 @@ function Invoke-CopilotSession {
|
|
|
258
272
|
|
|
259
273
|
function Get-StoryKeyForState {
|
|
260
274
|
param([string]$State)
|
|
261
|
-
$lines = Get-Content $SprintStatusPath | Where-Object { $_ -match '^\s*\d+-\d+-' -and $_ -notmatch 'retrospective' -and $_ -match ": *${State} *$" }
|
|
275
|
+
$lines = Get-Content $SprintStatusPath | ForEach-Object { $_ -replace '\s*#.*$', '' } | Where-Object { $_ -match '^\s*\d+-\d+-' -and $_ -notmatch 'retrospective' -and $_ -match ": *${State} *$" }
|
|
262
276
|
if ($lines) {
|
|
263
277
|
$first = ($lines | Select-Object -First 1).Trim()
|
|
264
278
|
return ($first -split ':')[0]
|
|
@@ -318,7 +332,7 @@ function Write-Summary {
|
|
|
318
332
|
$lines = $content -split "`n"
|
|
319
333
|
$storyLines = $lines | Where-Object {
|
|
320
334
|
$_ -match '^\s*[0-9]+-[0-9]+-' -and $_ -notmatch 'retrospective'
|
|
321
|
-
}
|
|
335
|
+
} | ForEach-Object { $_ -replace '\s*#.*$', '' }
|
|
322
336
|
$done = ($storyLines | Where-Object { $_ -match ':\s*done\s*$' }).Count
|
|
323
337
|
$total = $storyLines.Count
|
|
324
338
|
$pct = if ($total -gt 0) { [math]::Round($done * 100 / $total) } else { 0 }
|
|
@@ -341,6 +355,7 @@ Write-Host ""
|
|
|
341
355
|
Write-Log "[START] BMAD Auto Loop Started" "Green"
|
|
342
356
|
Write-Log "Max iterations: $MaxIterations" "Gray"
|
|
343
357
|
Write-Log "Model: $Model" "Gray"
|
|
358
|
+
Write-Log "Reasoning effort: $ReasoningEffort" "Gray"
|
|
344
359
|
Write-Log "Project root: $ProjectRoot" "Gray"
|
|
345
360
|
Write-Log "Sprint status: $SprintStatusPath" "Gray"
|
|
346
361
|
if ($DryRun) {
|
package/templates/bmad-loop.sh
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
# - BMAD installed with .github/agents/ directory (sm, dev agents)
|
|
23
23
|
# - Sprint planning completed (sprint-status.yaml exists)
|
|
24
24
|
#
|
|
25
|
-
# MODEL:
|
|
25
|
+
# MODEL: GPT-5.3-Codex with xhigh reasoning (configurable via env vars)
|
|
26
26
|
#
|
|
27
27
|
# ============================================================
|
|
28
28
|
|
|
@@ -52,8 +52,9 @@ CONFIG_PATH="$SCRIPT_DIR/bmad-auto-config.yaml"
|
|
|
52
52
|
PROGRESS_LOG="$SCRIPT_DIR/bmad-progress.log"
|
|
53
53
|
PROMPT_DIR="$SCRIPT_DIR/prompts"
|
|
54
54
|
|
|
55
|
-
# Model configuration -
|
|
56
|
-
COPILOT_MODEL="${COPILOT_MODEL:-
|
|
55
|
+
# Model configuration - GPT-5.3-Codex + xhigh reasoning effort
|
|
56
|
+
COPILOT_MODEL="${COPILOT_MODEL:-gpt-5.3-codex}"
|
|
57
|
+
COPILOT_REASONING_EFFORT="${COPILOT_REASONING_EFFORT:-xhigh}"
|
|
57
58
|
|
|
58
59
|
# Delay between iterations (seconds)
|
|
59
60
|
ITERATION_DELAY="${ITERATION_DELAY:-10}"
|
|
@@ -159,7 +160,8 @@ get_next_action() {
|
|
|
159
160
|
fi
|
|
160
161
|
|
|
161
162
|
# Filter story lines (pattern: digits-digits-*) excluding retrospectives
|
|
162
|
-
|
|
163
|
+
# Strip inline YAML comments (# ...) so status matching works with annotated lines
|
|
164
|
+
local story_lines=$(grep -E '^\s*[0-9]+-[0-9]+-' "$SPRINT_STATUS_PATH" | grep -v "retrospective" | sed 's/ *#.*//')
|
|
163
165
|
|
|
164
166
|
if $VERBOSE; then
|
|
165
167
|
local count=$(echo "$story_lines" | wc -l | tr -d ' ')
|
|
@@ -230,10 +232,10 @@ invoke_copilot() {
|
|
|
230
232
|
local prompt=$(cat "$prompt_file")
|
|
231
233
|
prompt="${prompt//\{TIMESTAMP\}/$(date "+%Y-%m-%d %H:%M:%S")}"
|
|
232
234
|
|
|
233
|
-
log "[SESSION] New Copilot CLI session → Model: $COPILOT_MODEL | Action: $action_label" "magenta"
|
|
235
|
+
log "[SESSION] New Copilot CLI session → Model: $COPILOT_MODEL | Reasoning: $COPILOT_REASONING_EFFORT | Action: $action_label" "magenta"
|
|
234
236
|
|
|
235
237
|
if $DRY_RUN; then
|
|
236
|
-
log "[DRY RUN] Would execute: copilot --model $COPILOT_MODEL -p '...' --allow-all --no-ask-user" "yellow"
|
|
238
|
+
log "[DRY RUN] Would execute: copilot --model $COPILOT_MODEL --reasoning-effort $COPILOT_REASONING_EFFORT -p '...' --allow-all --no-ask-user" "yellow"
|
|
237
239
|
return 0
|
|
238
240
|
fi
|
|
239
241
|
|
|
@@ -242,6 +244,7 @@ invoke_copilot() {
|
|
|
242
244
|
# The prompt itself contains all workflow instructions.
|
|
243
245
|
if copilot \
|
|
244
246
|
--model "$COPILOT_MODEL" \
|
|
247
|
+
--reasoning-effort "$COPILOT_REASONING_EFFORT" \
|
|
245
248
|
--allow-all \
|
|
246
249
|
--no-ask-user \
|
|
247
250
|
-p "$prompt" \
|
|
@@ -261,7 +264,7 @@ invoke_copilot() {
|
|
|
261
264
|
|
|
262
265
|
get_story_key_for_state() {
|
|
263
266
|
local state="$1"
|
|
264
|
-
grep -E '^\s*[0-9]+-[0-9]+-' "$SPRINT_STATUS_PATH" | grep -v "retrospective" | grep ": *${state} *$" | head -1 | sed 's/^[[:space:]]*//' | cut -d: -f1
|
|
267
|
+
grep -E '^\s*[0-9]+-[0-9]+-' "$SPRINT_STATUS_PATH" | grep -v "retrospective" | sed 's/ *#.*//' | grep ": *${state} *$" | head -1 | sed 's/^[[:space:]]*//' | cut -d: -f1
|
|
265
268
|
}
|
|
266
269
|
|
|
267
270
|
# ============================================================
|
|
@@ -306,7 +309,7 @@ print_summary() {
|
|
|
306
309
|
return
|
|
307
310
|
fi
|
|
308
311
|
|
|
309
|
-
local story_lines=$(grep -E '^\s*[0-9]+-[0-9]+-' "$SPRINT_STATUS_PATH" | grep -v "retrospective")
|
|
312
|
+
local story_lines=$(grep -E '^\s*[0-9]+-[0-9]+-' "$SPRINT_STATUS_PATH" | grep -v "retrospective" | sed 's/ *#.*//')
|
|
310
313
|
local done=$(echo "$story_lines" | grep -c ': *done *$' || true)
|
|
311
314
|
local total=$(echo "$story_lines" | grep -c '.' || true)
|
|
312
315
|
local pct=0
|
|
@@ -332,6 +335,7 @@ log "" "white"
|
|
|
332
335
|
log "[START] BMAD Auto Loop Started" "green"
|
|
333
336
|
log "Max iterations: $MAX_ITERATIONS" "gray"
|
|
334
337
|
log "Model: $COPILOT_MODEL" "gray"
|
|
338
|
+
log "Reasoning effort: $COPILOT_REASONING_EFFORT" "gray"
|
|
335
339
|
log "Project root: $PROJECT_ROOT" "gray"
|
|
336
340
|
log "Sprint status: $SPRINT_STATUS_PATH" "gray"
|
|
337
341
|
if $DRY_RUN; then
|