bmad-auto-copilot 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/README.md +189 -0
- package/bin/cli.js +144 -0
- package/lib/install.js +221 -0
- package/lib/run.js +79 -0
- package/lib/status.js +120 -0
- package/lib/uninstall.js +56 -0
- package/lib/utils.js +105 -0
- package/package.json +31 -0
- package/templates/bmad-loop.ps1 +390 -0
- package/templates/bmad-loop.sh +384 -0
- package/templates/prompts/code-review.md +41 -0
- package/templates/prompts/create-story.md +36 -0
- package/templates/prompts/dev-story.md +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# bmad-auto-copilot
|
|
2
|
+
|
|
3
|
+
Automated BMAD sprint development loop using **GitHub Copilot CLI**.
|
|
4
|
+
|
|
5
|
+
Install into any BMAD project — runs the full story cycle automatically:
|
|
6
|
+
**create-story** → **dev-story** → **code-review** → **auto-commit** → repeat.
|
|
7
|
+
|
|
8
|
+
## Quick Start
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
# In any BMAD project directory:
|
|
12
|
+
npx bmad-auto-copilot install
|
|
13
|
+
|
|
14
|
+
# Run the automation:
|
|
15
|
+
npx bmad-auto-copilot run
|
|
16
|
+
|
|
17
|
+
# Or directly:
|
|
18
|
+
./.scripts/bmad-auto/copilot/bmad-loop.sh
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## What It Does
|
|
22
|
+
|
|
23
|
+
The automation loop continuously:
|
|
24
|
+
|
|
25
|
+
1. Reads `sprint-status.yaml` to determine story states
|
|
26
|
+
2. Opens a **NEW Copilot CLI session** for each action (fresh context window):
|
|
27
|
+
- `backlog` stories → **SM agent** runs create-story
|
|
28
|
+
- `ready-for-dev` stories → **Dev agent** runs dev-story
|
|
29
|
+
- `review` stories → **Dev agent** runs code-review
|
|
30
|
+
3. Auto-commits code after successful code reviews
|
|
31
|
+
4. Repeats until all stories reach `done`
|
|
32
|
+
|
|
33
|
+
Each session uses **Claude Opus 4.6** by default (configurable).
|
|
34
|
+
|
|
35
|
+
## Prerequisites
|
|
36
|
+
|
|
37
|
+
### 1. GitHub Copilot CLI
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# macOS
|
|
41
|
+
brew install copilot-cli
|
|
42
|
+
|
|
43
|
+
# npm (all platforms)
|
|
44
|
+
npm install -g @github/copilot
|
|
45
|
+
|
|
46
|
+
# Windows
|
|
47
|
+
winget install GitHub.Copilot
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Then authenticate: `copilot` → `/login`
|
|
51
|
+
|
|
52
|
+
### 2. BMAD Method
|
|
53
|
+
|
|
54
|
+
Your project must have BMAD installed:
|
|
55
|
+
```bash
|
|
56
|
+
npx bmad-method install
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Required files:
|
|
60
|
+
- `_bmad/` directory
|
|
61
|
+
- `.github/agents/bmad-agent-bmm-sm.md`
|
|
62
|
+
- `.github/agents/bmad-agent-bmm-dev.md`
|
|
63
|
+
- `sprint-status.yaml` (from sprint planning)
|
|
64
|
+
|
|
65
|
+
## Commands
|
|
66
|
+
|
|
67
|
+
### `install`
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npx bmad-auto-copilot install # Install in current directory
|
|
71
|
+
npx bmad-auto-copilot install ~/my-project # Install in specific project
|
|
72
|
+
npx bmad-auto-copilot install --force # Overwrite existing installation
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Auto-detects your BMAD output folder from `_bmad/bmm/config.yaml`.
|
|
76
|
+
|
|
77
|
+
Installs to: `.scripts/bmad-auto/copilot/`
|
|
78
|
+
|
|
79
|
+
### `run`
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npx bmad-auto-copilot run # Run with defaults
|
|
83
|
+
npx bmad-auto-copilot run --max 100 # Limit to 100 iterations
|
|
84
|
+
npx bmad-auto-copilot run --model gpt-4.1 # Use different model
|
|
85
|
+
npx bmad-auto-copilot run --verbose --dry # Dry run with debug output
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### `status`
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npx bmad-auto-copilot status # Check prerequisites and sprint progress
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### `uninstall`
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
npx bmad-auto-copilot uninstall # Remove from current project
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Direct Script Usage
|
|
101
|
+
|
|
102
|
+
After installation, you can run the scripts directly:
|
|
103
|
+
|
|
104
|
+
### macOS / Linux
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
./.scripts/bmad-auto/copilot/bmad-loop.sh # Default
|
|
108
|
+
./.scripts/bmad-auto/copilot/bmad-loop.sh 100 # 100 iterations
|
|
109
|
+
./.scripts/bmad-auto/copilot/bmad-loop.sh 250 --verbose # Verbose
|
|
110
|
+
./.scripts/bmad-auto/copilot/bmad-loop.sh 250 --dry # Dry run
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Windows
|
|
114
|
+
|
|
115
|
+
```powershell
|
|
116
|
+
.\.scripts\bmad-auto\copilot\bmad-loop.ps1
|
|
117
|
+
.\.scripts\bmad-auto\copilot\bmad-loop.ps1 -MaxIterations 100 -Verbose
|
|
118
|
+
.\.scripts\bmad-auto\copilot\bmad-loop.ps1 -DryRun
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Configuration
|
|
122
|
+
|
|
123
|
+
### Environment Variables
|
|
124
|
+
|
|
125
|
+
| Variable | Default | Description |
|
|
126
|
+
|----------|---------|-------------|
|
|
127
|
+
| `COPILOT_MODEL` | `claude-opus-4.6` | AI model for all sessions |
|
|
128
|
+
| `ITERATION_DELAY` | `10` | Seconds between iterations |
|
|
129
|
+
|
|
130
|
+
### bmad-auto-config.yaml
|
|
131
|
+
|
|
132
|
+
Auto-generated during install. Contains project-specific paths:
|
|
133
|
+
|
|
134
|
+
```yaml
|
|
135
|
+
project_root: "/path/to/your/project"
|
|
136
|
+
output_folder: "_bmad-output"
|
|
137
|
+
implementation_artifacts: "_bmad-output/implementation-artifacts"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## How Sessions Work
|
|
141
|
+
|
|
142
|
+
Each step creates a **completely isolated Copilot CLI session**:
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
copilot --agent sm --model claude-opus-4.6 -p <prompt> --allow-all --no-ask-user
|
|
146
|
+
copilot --agent dev --model claude-opus-4.6 -p <prompt> --allow-all --no-ask-user
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
This ensures:
|
|
150
|
+
- **Fresh context window** per action (no context pollution between steps)
|
|
151
|
+
- **Correct agent persona** (SM for story creation, Dev for implementation/review)
|
|
152
|
+
- **Consistent model** across all sessions
|
|
153
|
+
|
|
154
|
+
## Installed Files
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
.scripts/bmad-auto/copilot/
|
|
158
|
+
├── bmad-loop.sh # macOS/Linux automation script
|
|
159
|
+
├── bmad-loop.ps1 # Windows PowerShell script
|
|
160
|
+
├── bmad-auto-config.yaml # Project paths (auto-generated, gitignored)
|
|
161
|
+
├── bmad-progress.log # Execution log (gitignored)
|
|
162
|
+
└── prompts/
|
|
163
|
+
├── create-story.md # SM agent prompt
|
|
164
|
+
├── dev-story.md # Dev agent prompt
|
|
165
|
+
└── code-review.md # Dev agent review prompt
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Global Installation
|
|
169
|
+
|
|
170
|
+
For frequent use across many projects:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
npm install -g bmad-auto-copilot
|
|
174
|
+
bmad-auto-copilot install
|
|
175
|
+
bmad-auto-copilot run
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Safety Features
|
|
179
|
+
|
|
180
|
+
- **Max iterations**: Default 250, prevents infinite loops
|
|
181
|
+
- **Session isolation**: Each step = new Copilot CLI session
|
|
182
|
+
- **Git check**: Only commits when there are actual changes
|
|
183
|
+
- **Dry run mode**: Preview without executing
|
|
184
|
+
- **Progress log**: All actions logged to `bmad-progress.log`
|
|
185
|
+
- **Progress tracking**: Shows done/total story percentage
|
|
186
|
+
|
|
187
|
+
## License
|
|
188
|
+
|
|
189
|
+
MIT
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// ============================================================
|
|
4
|
+
// bmad-auto-copilot CLI
|
|
5
|
+
// ============================================================
|
|
6
|
+
// Usage:
|
|
7
|
+
// npx bmad-auto-copilot install Install into current BMAD project
|
|
8
|
+
// npx bmad-auto-copilot install /path Install into specified project
|
|
9
|
+
// npx bmad-auto-copilot uninstall Remove from current project
|
|
10
|
+
// npx bmad-auto-copilot status Show install status
|
|
11
|
+
// npx bmad-auto-copilot run Run the automation loop directly
|
|
12
|
+
// ============================================================
|
|
13
|
+
|
|
14
|
+
const { install } = require('../lib/install');
|
|
15
|
+
const { uninstall } = require('../lib/uninstall');
|
|
16
|
+
const { status } = require('../lib/status');
|
|
17
|
+
const { run } = require('../lib/run');
|
|
18
|
+
|
|
19
|
+
const HELP = `
|
|
20
|
+
bmad-auto-copilot — Automated BMAD sprint loop via GitHub Copilot CLI
|
|
21
|
+
|
|
22
|
+
USAGE:
|
|
23
|
+
npx bmad-auto-copilot <command> [options]
|
|
24
|
+
|
|
25
|
+
COMMANDS:
|
|
26
|
+
install [path] Install automation scripts into a BMAD project
|
|
27
|
+
Defaults to current directory if path not given
|
|
28
|
+
uninstall [path] Remove automation scripts from a BMAD project
|
|
29
|
+
status [path] Check installation status and prerequisites
|
|
30
|
+
run [path] Run the automation loop (shortcut for bmad-loop.sh)
|
|
31
|
+
|
|
32
|
+
OPTIONS:
|
|
33
|
+
--model <model> AI model (default: claude-opus-4.6)
|
|
34
|
+
--max <n> Max iterations (default: 250)
|
|
35
|
+
--output <folder> BMAD output folder (default: auto-detect from config)
|
|
36
|
+
--force Overwrite existing installation
|
|
37
|
+
--help, -h Show this help
|
|
38
|
+
|
|
39
|
+
EXAMPLES:
|
|
40
|
+
npx bmad-auto-copilot install
|
|
41
|
+
npx bmad-auto-copilot install ~/projects/my-app
|
|
42
|
+
npx bmad-auto-copilot install --model claude-sonnet-4.5
|
|
43
|
+
npx bmad-auto-copilot run --max 100
|
|
44
|
+
npx bmad-auto-copilot status
|
|
45
|
+
npx bmad-auto-copilot uninstall
|
|
46
|
+
|
|
47
|
+
PREREQUISITES:
|
|
48
|
+
- GitHub Copilot CLI: npm install -g @github/copilot
|
|
49
|
+
- BMAD Method installed in the target project (npx bmad-method install)
|
|
50
|
+
- Sprint planning completed (sprint-status.yaml exists)
|
|
51
|
+
`;
|
|
52
|
+
|
|
53
|
+
function parseArgs(args) {
|
|
54
|
+
const parsed = {
|
|
55
|
+
command: null,
|
|
56
|
+
projectPath: null,
|
|
57
|
+
model: 'claude-opus-4.6',
|
|
58
|
+
maxIterations: 250,
|
|
59
|
+
outputFolder: null,
|
|
60
|
+
force: false,
|
|
61
|
+
verbose: false,
|
|
62
|
+
dryRun: false,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
let i = 0;
|
|
66
|
+
while (i < args.length) {
|
|
67
|
+
const arg = args[i];
|
|
68
|
+
|
|
69
|
+
if (!parsed.command && !arg.startsWith('-')) {
|
|
70
|
+
parsed.command = arg;
|
|
71
|
+
i++;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (!parsed.projectPath && !arg.startsWith('-') && parsed.command) {
|
|
76
|
+
parsed.projectPath = arg;
|
|
77
|
+
i++;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
switch (arg) {
|
|
82
|
+
case '--model':
|
|
83
|
+
parsed.model = args[++i];
|
|
84
|
+
break;
|
|
85
|
+
case '--max':
|
|
86
|
+
parsed.maxIterations = parseInt(args[++i], 10);
|
|
87
|
+
break;
|
|
88
|
+
case '--output':
|
|
89
|
+
parsed.outputFolder = args[++i];
|
|
90
|
+
break;
|
|
91
|
+
case '--force':
|
|
92
|
+
parsed.force = true;
|
|
93
|
+
break;
|
|
94
|
+
case '--verbose':
|
|
95
|
+
case '-v':
|
|
96
|
+
parsed.verbose = true;
|
|
97
|
+
break;
|
|
98
|
+
case '--dry':
|
|
99
|
+
case '-d':
|
|
100
|
+
parsed.dryRun = true;
|
|
101
|
+
break;
|
|
102
|
+
case '--help':
|
|
103
|
+
case '-h':
|
|
104
|
+
parsed.command = 'help';
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
i++;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return parsed;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async function main() {
|
|
114
|
+
const args = parseArgs(process.argv.slice(2));
|
|
115
|
+
|
|
116
|
+
switch (args.command) {
|
|
117
|
+
case 'install':
|
|
118
|
+
await install(args);
|
|
119
|
+
break;
|
|
120
|
+
case 'uninstall':
|
|
121
|
+
await uninstall(args);
|
|
122
|
+
break;
|
|
123
|
+
case 'status':
|
|
124
|
+
await status(args);
|
|
125
|
+
break;
|
|
126
|
+
case 'run':
|
|
127
|
+
await run(args);
|
|
128
|
+
break;
|
|
129
|
+
case 'help':
|
|
130
|
+
case null:
|
|
131
|
+
case undefined:
|
|
132
|
+
console.log(HELP);
|
|
133
|
+
break;
|
|
134
|
+
default:
|
|
135
|
+
console.error(`Unknown command: ${args.command}`);
|
|
136
|
+
console.log(HELP);
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
main().catch((err) => {
|
|
142
|
+
console.error(`\n[ERROR] ${err.message}`);
|
|
143
|
+
process.exit(1);
|
|
144
|
+
});
|
package/lib/install.js
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// bmad-auto-copilot — install command
|
|
3
|
+
// ============================================================
|
|
4
|
+
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const {
|
|
8
|
+
resolveProject,
|
|
9
|
+
isBmadProject,
|
|
10
|
+
detectOutputFolder,
|
|
11
|
+
getInstallPath,
|
|
12
|
+
isInstalled,
|
|
13
|
+
colors,
|
|
14
|
+
} = require('./utils');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Recursively copy a directory.
|
|
18
|
+
*/
|
|
19
|
+
function copyDir(src, dest) {
|
|
20
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
21
|
+
|
|
22
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
23
|
+
const srcPath = path.join(src, entry.name);
|
|
24
|
+
const destPath = path.join(dest, entry.name);
|
|
25
|
+
|
|
26
|
+
if (entry.isDirectory()) {
|
|
27
|
+
copyDir(srcPath, destPath);
|
|
28
|
+
} else {
|
|
29
|
+
fs.copyFileSync(srcPath, destPath);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Install automation scripts into a BMAD project.
|
|
36
|
+
*/
|
|
37
|
+
async function install(args) {
|
|
38
|
+
const root = resolveProject(args.projectPath);
|
|
39
|
+
const installPath = getInstallPath(root);
|
|
40
|
+
|
|
41
|
+
console.log('');
|
|
42
|
+
console.log(
|
|
43
|
+
colors.cyan('╔══════════════════════════════════════════════════════╗')
|
|
44
|
+
);
|
|
45
|
+
console.log(
|
|
46
|
+
colors.cyan('║ bmad-auto-copilot — Install ║')
|
|
47
|
+
);
|
|
48
|
+
console.log(
|
|
49
|
+
colors.cyan('╚══════════════════════════════════════════════════════╝')
|
|
50
|
+
);
|
|
51
|
+
console.log('');
|
|
52
|
+
|
|
53
|
+
// Validate BMAD project
|
|
54
|
+
if (!isBmadProject(root)) {
|
|
55
|
+
console.log(colors.red('[ERROR] Not a BMAD project (no _bmad/ directory)'));
|
|
56
|
+
console.log('');
|
|
57
|
+
console.log('Make sure you run this from a BMAD project root, or specify the path:');
|
|
58
|
+
console.log(colors.gray(' npx bmad-auto-copilot install /path/to/project'));
|
|
59
|
+
console.log('');
|
|
60
|
+
console.log('To set up BMAD first:');
|
|
61
|
+
console.log(colors.gray(' npx bmad-method install'));
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
console.log(colors.green(`[OK] BMAD project found: ${root}`));
|
|
66
|
+
|
|
67
|
+
// Check existing installation
|
|
68
|
+
if (isInstalled(root) && !args.force) {
|
|
69
|
+
console.log(
|
|
70
|
+
colors.yellow(
|
|
71
|
+
'[WARNING] Already installed. Use --force to overwrite.'
|
|
72
|
+
)
|
|
73
|
+
);
|
|
74
|
+
console.log(colors.gray(` Installed at: ${installPath}`));
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Auto-detect output folder
|
|
79
|
+
const detected = detectOutputFolder(root);
|
|
80
|
+
const outputFolder = args.outputFolder || detected.outputFolder;
|
|
81
|
+
const implArtifacts = detected.implArtifacts;
|
|
82
|
+
|
|
83
|
+
console.log(colors.green(`[OK] Output folder: ${outputFolder}`));
|
|
84
|
+
console.log(colors.green(`[OK] Impl artifacts: ${implArtifacts}`));
|
|
85
|
+
|
|
86
|
+
// Copy template files
|
|
87
|
+
const templatesDir = path.join(__dirname, '..', 'templates');
|
|
88
|
+
console.log(colors.gray(`[COPY] Templates → ${installPath}`));
|
|
89
|
+
|
|
90
|
+
copyDir(templatesDir, installPath);
|
|
91
|
+
|
|
92
|
+
// Generate bmad-auto-config.yaml with correct paths
|
|
93
|
+
const configContent = `# Auto-generated by bmad-auto-copilot installer
|
|
94
|
+
# Project-specific paths — update if you change your BMAD output folder
|
|
95
|
+
|
|
96
|
+
project_root: "${root}"
|
|
97
|
+
output_folder: "${outputFolder}"
|
|
98
|
+
implementation_artifacts: "${implArtifacts}"
|
|
99
|
+
`;
|
|
100
|
+
|
|
101
|
+
fs.writeFileSync(path.join(installPath, 'bmad-auto-config.yaml'), configContent);
|
|
102
|
+
console.log(colors.green('[OK] Generated bmad-auto-config.yaml'));
|
|
103
|
+
|
|
104
|
+
// Make shell script executable (Unix)
|
|
105
|
+
const shScript = path.join(installPath, 'bmad-loop.sh');
|
|
106
|
+
if (fs.existsSync(shScript)) {
|
|
107
|
+
try {
|
|
108
|
+
fs.chmodSync(shScript, 0o755);
|
|
109
|
+
console.log(colors.green('[OK] bmad-loop.sh marked executable'));
|
|
110
|
+
} catch (e) {
|
|
111
|
+
// Windows — chmod may not work
|
|
112
|
+
console.log(colors.gray('[SKIP] chmod not available (Windows)'));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Check for .github/agents
|
|
117
|
+
const agentsDir = path.join(root, '.github', 'agents');
|
|
118
|
+
if (!fs.existsSync(agentsDir)) {
|
|
119
|
+
console.log(
|
|
120
|
+
colors.yellow(
|
|
121
|
+
'[WARNING] .github/agents/ not found — Copilot CLI agents may not work'
|
|
122
|
+
)
|
|
123
|
+
);
|
|
124
|
+
console.log(
|
|
125
|
+
colors.gray(
|
|
126
|
+
' BMAD agent files (bmad-agent-bmm-sm.md, bmad-agent-bmm-dev.md) are needed'
|
|
127
|
+
)
|
|
128
|
+
);
|
|
129
|
+
} else {
|
|
130
|
+
const smAgent = path.join(agentsDir, 'bmad-agent-bmm-sm.md');
|
|
131
|
+
const devAgent = path.join(agentsDir, 'bmad-agent-bmm-dev.md');
|
|
132
|
+
if (fs.existsSync(smAgent) && fs.existsSync(devAgent)) {
|
|
133
|
+
console.log(colors.green('[OK] BMAD agents found (sm, dev)'));
|
|
134
|
+
} else {
|
|
135
|
+
console.log(
|
|
136
|
+
colors.yellow('[WARNING] Missing agent files in .github/agents/')
|
|
137
|
+
);
|
|
138
|
+
if (!fs.existsSync(smAgent))
|
|
139
|
+
console.log(colors.gray(' Missing: bmad-agent-bmm-sm.md'));
|
|
140
|
+
if (!fs.existsSync(devAgent))
|
|
141
|
+
console.log(colors.gray(' Missing: bmad-agent-bmm-dev.md'));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Check sprint-status.yaml
|
|
146
|
+
const sprintPath = path.join(root, implArtifacts, 'sprint-status.yaml');
|
|
147
|
+
if (fs.existsSync(sprintPath)) {
|
|
148
|
+
console.log(colors.green('[OK] sprint-status.yaml found'));
|
|
149
|
+
} else {
|
|
150
|
+
console.log(
|
|
151
|
+
colors.yellow('[WARNING] sprint-status.yaml not found — run sprint planning first')
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Add to .gitignore
|
|
156
|
+
addToGitignore(root, installPath);
|
|
157
|
+
|
|
158
|
+
// Print summary
|
|
159
|
+
console.log('');
|
|
160
|
+
console.log(colors.cyan('═══════════════════════════════════════════'));
|
|
161
|
+
console.log(colors.bold(' Installation Complete!'));
|
|
162
|
+
console.log(colors.cyan('═══════════════════════════════════════════'));
|
|
163
|
+
console.log('');
|
|
164
|
+
console.log(' Installed to:');
|
|
165
|
+
console.log(colors.gray(` ${installPath}`));
|
|
166
|
+
console.log('');
|
|
167
|
+
console.log(' Model: ' + colors.bold(args.model));
|
|
168
|
+
console.log(' Max iterations: ' + colors.bold(String(args.maxIterations)));
|
|
169
|
+
console.log('');
|
|
170
|
+
console.log(colors.bold(' Quick Start:'));
|
|
171
|
+
console.log('');
|
|
172
|
+
|
|
173
|
+
if (process.platform === 'win32') {
|
|
174
|
+
console.log(colors.gray(` cd ${root}`));
|
|
175
|
+
console.log(
|
|
176
|
+
colors.gray(' .\\.scripts\\bmad-auto\\copilot\\bmad-loop.ps1')
|
|
177
|
+
);
|
|
178
|
+
} else {
|
|
179
|
+
console.log(colors.gray(` cd ${root}`));
|
|
180
|
+
console.log(
|
|
181
|
+
colors.gray(' ./.scripts/bmad-auto/copilot/bmad-loop.sh')
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
console.log('');
|
|
186
|
+
console.log(' Or run directly:');
|
|
187
|
+
console.log(colors.gray(' npx bmad-auto-copilot run'));
|
|
188
|
+
console.log('');
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Add log/config to .gitignore if needed
|
|
193
|
+
*/
|
|
194
|
+
function addToGitignore(root, installPath) {
|
|
195
|
+
const gitignorePath = path.join(root, '.gitignore');
|
|
196
|
+
const relPath = path.relative(root, installPath);
|
|
197
|
+
const entries = [
|
|
198
|
+
`${relPath}/bmad-progress.log`,
|
|
199
|
+
`${relPath}/bmad-auto-config.yaml`,
|
|
200
|
+
];
|
|
201
|
+
|
|
202
|
+
if (!fs.existsSync(gitignorePath)) return;
|
|
203
|
+
|
|
204
|
+
let content = fs.readFileSync(gitignorePath, 'utf8');
|
|
205
|
+
let added = false;
|
|
206
|
+
|
|
207
|
+
for (const entry of entries) {
|
|
208
|
+
if (!content.includes(entry)) {
|
|
209
|
+
if (!content.endsWith('\n')) content += '\n';
|
|
210
|
+
content += `${entry}\n`;
|
|
211
|
+
added = true;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (added) {
|
|
216
|
+
fs.writeFileSync(gitignorePath, content);
|
|
217
|
+
console.log(colors.green('[OK] Updated .gitignore (log + config)'));
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
module.exports = { install };
|
package/lib/run.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// bmad-auto-copilot — run command
|
|
3
|
+
// ============================================================
|
|
4
|
+
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const { execSync, spawn } = require('child_process');
|
|
7
|
+
const {
|
|
8
|
+
resolveProject,
|
|
9
|
+
getInstallPath,
|
|
10
|
+
isInstalled,
|
|
11
|
+
colors,
|
|
12
|
+
} = require('./utils');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Run the automation loop directly.
|
|
16
|
+
*/
|
|
17
|
+
async function run(args) {
|
|
18
|
+
const root = resolveProject(args.projectPath);
|
|
19
|
+
const installPath = getInstallPath(root);
|
|
20
|
+
|
|
21
|
+
if (!isInstalled(root)) {
|
|
22
|
+
console.log(colors.red('[ERROR] Not installed. Run first:'));
|
|
23
|
+
console.log(colors.gray(' npx bmad-auto-copilot install'));
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const isWindows = process.platform === 'win32';
|
|
28
|
+
const scriptArgs = [];
|
|
29
|
+
|
|
30
|
+
if (isWindows) {
|
|
31
|
+
const script = path.join(installPath, 'bmad-loop.ps1');
|
|
32
|
+
scriptArgs.push(
|
|
33
|
+
'powershell',
|
|
34
|
+
[
|
|
35
|
+
'-ExecutionPolicy',
|
|
36
|
+
'Bypass',
|
|
37
|
+
'-File',
|
|
38
|
+
script,
|
|
39
|
+
'-MaxIterations',
|
|
40
|
+
String(args.maxIterations),
|
|
41
|
+
...(args.verbose ? ['-Verbose'] : []),
|
|
42
|
+
...(args.dryRun ? ['-DryRun'] : []),
|
|
43
|
+
...(args.model !== 'claude-opus-4.6'
|
|
44
|
+
? ['-Model', args.model]
|
|
45
|
+
: []),
|
|
46
|
+
]
|
|
47
|
+
);
|
|
48
|
+
} else {
|
|
49
|
+
const script = path.join(installPath, 'bmad-loop.sh');
|
|
50
|
+
scriptArgs.push(script, [
|
|
51
|
+
String(args.maxIterations),
|
|
52
|
+
...(args.verbose ? ['--verbose'] : []),
|
|
53
|
+
...(args.dryRun ? ['--dry'] : []),
|
|
54
|
+
]);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
console.log(colors.cyan('[RUN] Starting BMAD auto loop...'));
|
|
58
|
+
console.log(colors.gray(` Script: ${scriptArgs[0]}`));
|
|
59
|
+
console.log('');
|
|
60
|
+
|
|
61
|
+
// Set model env var
|
|
62
|
+
const env = { ...process.env };
|
|
63
|
+
if (args.model) {
|
|
64
|
+
env.COPILOT_MODEL = args.model;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Spawn the loop script as a child process with inherited stdio
|
|
68
|
+
const child = spawn(scriptArgs[0], scriptArgs[1], {
|
|
69
|
+
cwd: root,
|
|
70
|
+
stdio: 'inherit',
|
|
71
|
+
env,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
child.on('exit', (code) => {
|
|
75
|
+
process.exit(code || 0);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
module.exports = { run };
|