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 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 };