beth-copilot 1.0.6 → 1.0.10

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/bin/cli.js CHANGED
@@ -44,6 +44,32 @@ function logInfo(message) {
44
44
  log(` ${message}`, COLORS.cyan);
45
45
  }
46
46
 
47
+ function logDebug(message) {
48
+ if (globalThis.VERBOSE) {
49
+ log(` [debug] ${message}`, COLORS.yellow);
50
+ }
51
+ }
52
+
53
+ function showPathDiagnostics() {
54
+ const homeDir = process.env.HOME || process.env.USERPROFILE || '';
55
+ const isWindows = process.platform === 'win32';
56
+
57
+ console.log('');
58
+ log('PATH Diagnostics:', COLORS.bright);
59
+ logInfo(`Platform: ${process.platform}`);
60
+ logInfo(`HOME: ${homeDir}`);
61
+ logInfo(`PATH: ${process.env.PATH}`);
62
+
63
+ if (isWindows) {
64
+ logInfo(`APPDATA: ${process.env.APPDATA || '(not set)'}`);
65
+ logInfo(`npm prefix: Run "npm config get prefix" to check`);
66
+ } else {
67
+ logInfo(`npm prefix: Run "npm config get prefix" to check`);
68
+ logInfo(`Common locations: ~/.local/bin, /usr/local/bin, ~/.npm-global/bin`);
69
+ }
70
+ console.log('');
71
+ }
72
+
47
73
  async function checkForUpdates() {
48
74
  try {
49
75
  const response = await fetch('https://registry.npmjs.org/beth-copilot/latest', {
@@ -75,24 +101,96 @@ async function checkForUpdates() {
75
101
  }
76
102
  }
77
103
 
78
- function isBacklogCliInstalled() {
104
+ function getBacklogPath() {
105
+ // Check if backlog is available in PATH
79
106
  try {
107
+ logDebug('Checking if backlog is in PATH...');
80
108
  execSync('backlog --version', { stdio: 'ignore' });
81
- return true;
109
+ logDebug('Found backlog in PATH');
110
+ return 'backlog';
82
111
  } catch {
83
- return false;
112
+ logDebug('backlog not in PATH, checking common locations...');
113
+ // Check common installation paths
114
+ const homeDir = process.env.HOME || process.env.USERPROFILE || '';
115
+ const isWindows = process.platform === 'win32';
116
+
117
+ const commonPaths = isWindows ? [
118
+ join(process.env.APPDATA || '', 'npm', 'backlog.cmd'),
119
+ join(homeDir, 'AppData', 'Roaming', 'npm', 'backlog.cmd'),
120
+ join(homeDir, 'AppData', 'Local', 'npm-global', 'backlog.cmd'),
121
+ ] : [
122
+ join(homeDir, '.local', 'bin', 'backlog'),
123
+ join(homeDir, 'bin', 'backlog'),
124
+ '/usr/local/bin/backlog',
125
+ join(homeDir, '.npm-global', 'bin', 'backlog'),
126
+ join(homeDir, '.bun', 'bin', 'backlog'),
127
+ ];
128
+
129
+ for (const backlogPath of commonPaths) {
130
+ logDebug(`Checking: ${backlogPath}`);
131
+ if (existsSync(backlogPath)) {
132
+ logDebug(`Found at: ${backlogPath}`);
133
+ return backlogPath;
134
+ }
135
+ }
136
+
137
+ logDebug('backlog not found in any common location');
138
+ return null;
84
139
  }
85
140
  }
86
141
 
87
- function isBeadsInstalled() {
142
+ function isBacklogCliInstalled() {
143
+ return getBacklogPath() !== null;
144
+ }
145
+
146
+ function getBeadsPath() {
147
+ // Check if bd is available in PATH
88
148
  try {
149
+ logDebug('Checking if bd is in PATH...');
89
150
  execSync('bd --version', { stdio: 'ignore' });
90
- return true;
151
+ logDebug('Found bd in PATH');
152
+ return 'bd';
91
153
  } catch {
92
- return false;
154
+ logDebug('bd not in PATH, checking common locations...');
155
+ // Check common installation paths based on platform
156
+ const homeDir = process.env.HOME || process.env.USERPROFILE || '';
157
+ const isWindows = process.platform === 'win32';
158
+
159
+ const commonPaths = isWindows ? [
160
+ // Windows: npm global, Go bin, local apps
161
+ join(process.env.APPDATA || '', 'npm', 'bd.cmd'),
162
+ join(homeDir, 'AppData', 'Roaming', 'npm', 'bd.cmd'),
163
+ join(homeDir, 'AppData', 'Local', 'Microsoft', 'WindowsApps', 'bd.exe'),
164
+ join(homeDir, 'go', 'bin', 'bd.exe'),
165
+ join(process.env.GOPATH || join(homeDir, 'go'), 'bin', 'bd.exe'),
166
+ ] : [
167
+ // Unix: homebrew, npm global, go bin, local bin
168
+ '/opt/homebrew/bin/bd',
169
+ '/usr/local/bin/bd',
170
+ join(homeDir, '.local', 'bin', 'bd'),
171
+ join(homeDir, 'bin', 'bd'),
172
+ join(homeDir, '.npm-global', 'bin', 'bd'),
173
+ join(homeDir, 'go', 'bin', 'bd'),
174
+ join(process.env.GOPATH || join(homeDir, 'go'), 'bin', 'bd'),
175
+ ];
176
+
177
+ for (const bdPath of commonPaths) {
178
+ logDebug(`Checking: ${bdPath}`);
179
+ if (existsSync(bdPath)) {
180
+ logDebug(`Found at: ${bdPath}`);
181
+ return bdPath;
182
+ }
183
+ }
184
+
185
+ logDebug('bd not found in any common location');
186
+ return null;
93
187
  }
94
188
  }
95
189
 
190
+ function isBeadsInstalled() {
191
+ return getBeadsPath() !== null;
192
+ }
193
+
96
194
  function isBeadsInitialized(cwd) {
97
195
  // Check if .beads directory exists in the project
98
196
  return existsSync(join(cwd, '.beads'));
@@ -113,8 +211,27 @@ async function promptYesNo(question) {
113
211
  });
114
212
  }
115
213
 
214
+ async function promptForInput(question) {
215
+ const readline = await import('readline');
216
+ const rl = readline.createInterface({
217
+ input: process.stdin,
218
+ output: process.stdout
219
+ });
220
+
221
+ return new Promise((resolve) => {
222
+ rl.question(`${question} `, (answer) => {
223
+ rl.close();
224
+ resolve(answer.trim());
225
+ });
226
+ });
227
+ }
228
+
116
229
  async function installBacklogCli() {
117
- log('\nInstalling backlog.md CLI...', COLORS.cyan);
230
+ const isWindows = process.platform === 'win32';
231
+ const isMac = process.platform === 'darwin';
232
+
233
+ log('\nInstalling backlog.md CLI via npm...', COLORS.cyan);
234
+ logInfo('npm install -g backlog.md');
118
235
 
119
236
  return new Promise((resolve) => {
120
237
  const child = spawn('npm', ['install', '-g', 'backlog.md'], {
@@ -124,60 +241,125 @@ async function installBacklogCli() {
124
241
 
125
242
  child.on('close', (code) => {
126
243
  if (code === 0) {
127
- logSuccess('backlog.md CLI installed successfully!');
128
- resolve(true);
244
+ // CRITICAL: Verify installation actually worked before claiming success
245
+ const verifiedPath = getBacklogPath();
246
+ if (verifiedPath) {
247
+ logSuccess('backlog.md CLI installed and verified!');
248
+ resolve(true);
249
+ } else {
250
+ logWarning('npm reported success but backlog CLI not found in PATH.');
251
+ logInfo('This can happen if npm global bin is not in your PATH.');
252
+ if (globalThis.VERBOSE) {
253
+ showPathDiagnostics();
254
+ } else {
255
+ logInfo('Run with --verbose for PATH diagnostics.');
256
+ }
257
+ console.log('');
258
+ showBacklogAlternatives(isMac);
259
+ resolve(false);
260
+ }
129
261
  } else {
130
- logWarning('Failed to install backlog.md CLI. You can install it manually:');
131
- logInfo('npm i -g backlog.md');
132
- logInfo(' or');
133
- logInfo('bun i -g backlog.md');
262
+ logError('npm install failed.');
263
+ console.log('');
264
+ showBacklogAlternatives(isMac);
134
265
  resolve(false);
135
266
  }
136
267
  });
137
268
 
138
269
  child.on('error', () => {
139
- logWarning('Failed to install backlog.md CLI. You can install it manually:');
140
- logInfo('npm i -g backlog.md');
270
+ logError('Failed to run npm.');
271
+ logInfo('Make sure npm is installed and in your PATH.');
141
272
  resolve(false);
142
273
  });
143
274
  });
144
275
  }
145
276
 
277
+ function showBacklogAlternatives(isMac) {
278
+ logInfo('Alternative installation methods:');
279
+ if (isMac) {
280
+ logInfo(' Homebrew: brew install backlog-md');
281
+ }
282
+ logInfo(' Bun: bun install -g backlog.md');
283
+ logInfo('');
284
+ logInfo('Learn more: https://github.com/MrLesk/Backlog.md');
285
+ }
286
+
146
287
  async function installBeads() {
147
- log('\nInstalling beads CLI...', COLORS.cyan);
148
- logInfo('curl -fsSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash');
288
+ const isWindows = process.platform === 'win32';
289
+ const isMac = process.platform === 'darwin';
290
+
291
+ log('\nInstalling beads CLI via npm...', COLORS.cyan);
292
+ logInfo('npm install -g @beads/bd');
149
293
 
150
294
  return new Promise((resolve) => {
151
- const child = spawn('bash', ['-c', 'curl -fsSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash'], {
295
+ const child = spawn('npm', ['install', '-g', '@beads/bd'], {
152
296
  stdio: 'inherit',
153
297
  shell: true
154
298
  });
155
299
 
156
300
  child.on('close', (code) => {
157
301
  if (code === 0) {
158
- logSuccess('beads CLI installed successfully!');
159
- resolve(true);
302
+ // CRITICAL: Verify installation actually worked before claiming success
303
+ // npm can exit 0 even when the package isn't properly installed
304
+ const verifiedPath = getBeadsPath();
305
+ if (verifiedPath) {
306
+ logSuccess('beads CLI installed and verified!');
307
+ resolve(true);
308
+ } else {
309
+ logWarning('npm reported success but beads CLI not found in PATH.');
310
+ logInfo('This can happen if npm global bin is not in your PATH.');
311
+ if (globalThis.VERBOSE) {
312
+ showPathDiagnostics();
313
+ } else {
314
+ logInfo('Run with --verbose for PATH diagnostics.');
315
+ }
316
+ console.log('');
317
+ showBeadsAlternatives(isWindows, isMac);
318
+ resolve(false);
319
+ }
160
320
  } else {
161
- logError('Failed to install beads CLI.');
162
- logInfo('Install manually: curl -fsSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash');
163
- logInfo('Learn more: https://github.com/steveyegge/beads');
321
+ logError('npm install failed.');
322
+ console.log('');
323
+ showBeadsAlternatives(isWindows, isMac);
164
324
  resolve(false);
165
325
  }
166
326
  });
167
327
 
168
328
  child.on('error', () => {
169
- logError('Failed to install beads CLI.');
170
- logInfo('Install manually: curl -fsSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash');
329
+ logError('Failed to run npm.');
330
+ logInfo('Make sure npm is installed and in your PATH.');
171
331
  resolve(false);
172
332
  });
173
333
  });
174
334
  }
175
335
 
336
+ function showBeadsAlternatives(isWindows, isMac) {
337
+ logInfo('Alternative installation methods:');
338
+ if (isWindows) {
339
+ logInfo(' PowerShell: irm https://raw.githubusercontent.com/steveyegge/beads/main/install.ps1 | iex');
340
+ logInfo(' Go: go install github.com/steveyegge/beads/cmd/bd@latest');
341
+ } else {
342
+ if (isMac) {
343
+ logInfo(' Homebrew: brew install beads');
344
+ }
345
+ logInfo(' Script: curl -fsSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash');
346
+ logInfo(' Go: go install github.com/steveyegge/beads/cmd/bd@latest');
347
+ }
348
+ logInfo('');
349
+ logInfo('Learn more: https://github.com/steveyegge/beads');
350
+ }
351
+
176
352
  async function initializeBeads(cwd) {
177
353
  log('\nInitializing beads in project...', COLORS.cyan);
178
354
 
355
+ const bdPath = getBeadsPath();
356
+ if (!bdPath) {
357
+ logWarning('Failed to initialize beads. Run manually: bd init');
358
+ return false;
359
+ }
360
+
179
361
  return new Promise((resolve) => {
180
- const child = spawn('bd', ['init'], {
362
+ const child = spawn(bdPath, ['init'], {
181
363
  stdio: 'inherit',
182
364
  shell: true,
183
365
  cwd
@@ -213,6 +395,7 @@ ${COLORS.bright}Options:${COLORS.reset}
213
395
  --skip-backlog Don't create Backlog.md
214
396
  --skip-mcp Don't create mcp.json.example
215
397
  --skip-beads Skip beads check (not recommended)
398
+ --verbose Show detailed diagnostics on errors
216
399
 
217
400
  ${COLORS.bright}Examples:${COLORS.reset}
218
401
  npx beth-copilot init Set up Beth in current project
@@ -284,6 +467,7 @@ ${COLORS.yellow}╔════════════════════
284
467
  console.log(`
285
468
  ${COLORS.bright}🤠 Beth is moving in.${COLORS.reset}
286
469
  ${COLORS.cyan}"I don't do excuses. I do results."${COLORS.reset}
470
+ ${COLORS.yellow}Tip: Run with --verbose for detailed diagnostics if you hit issues.${COLORS.reset}
287
471
  `);
288
472
 
289
473
  // Check if templates exist
@@ -382,7 +566,10 @@ ${COLORS.cyan}"I don't do excuses. I do results."${COLORS.reset}
382
566
  console.log('');
383
567
  log('Checking beads (required for task tracking)...', COLORS.cyan);
384
568
 
385
- if (!isBeadsInstalled()) {
569
+ let bdPath = getBeadsPath();
570
+
571
+ // Loop until beads is installed
572
+ while (!bdPath) {
386
573
  logWarning('beads CLI is not installed.');
387
574
  logInfo('Beth requires beads for task tracking. Agents use it to coordinate work.');
388
575
  logInfo('Learn more: https://github.com/steveyegge/beads');
@@ -391,16 +578,67 @@ ${COLORS.cyan}"I don't do excuses. I do results."${COLORS.reset}
391
578
  const shouldInstallBeads = await promptYesNo('Install beads CLI now? (required)');
392
579
  if (shouldInstallBeads) {
393
580
  const installed = await installBeads();
394
- if (!installed) {
395
- logError('beads installation failed. Beth requires beads to function.');
396
- logInfo('Install manually and run "beth init" again.');
581
+ if (installed) {
582
+ // Re-check for beads after installation
583
+ bdPath = getBeadsPath();
584
+ if (!bdPath) {
585
+ console.log('');
586
+ logWarning('beads installed but not found in common paths.');
587
+ logInfo('The installer may have placed it in a custom location.');
588
+ console.log('');
589
+ logInfo('Please try one of these options:');
590
+ logInfo(' 1. Open a NEW terminal and run: npx beth-copilot init');
591
+ logInfo(' 2. Add ~/.local/bin to your PATH and retry');
592
+ logInfo(' 3. Run: source ~/.bashrc (or ~/.zshrc) then retry');
593
+ console.log('');
594
+
595
+ const retryCheck = await promptYesNo('Retry detection? (select No to enter path manually)');
596
+ if (retryCheck) {
597
+ bdPath = getBeadsPath();
598
+ continue;
599
+ }
600
+
601
+ // Allow manual path entry
602
+ const customPath = await promptForInput('Enter full path to bd binary (or press Enter to retry installation):');
603
+ if (customPath && existsSync(customPath)) {
604
+ bdPath = customPath;
605
+ logSuccess(`Found beads at: ${bdPath}`);
606
+ } else if (customPath) {
607
+ logError(`File not found: ${customPath}`);
608
+ }
609
+ }
610
+ } else {
611
+ console.log('');
612
+ logError('Installation script failed.');
613
+ logInfo('You can try installing manually:');
614
+ logInfo(' curl -fsSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash');
615
+ console.log('');
616
+ }
617
+ } else {
618
+ console.log('');
619
+ logError('beads is REQUIRED for Beth to function.');
620
+ logInfo('Beth agents use beads to track tasks, dependencies, and coordinate work.');
621
+ logInfo('Without beads, the multi-agent workflow will not work correctly.');
622
+ console.log('');
623
+
624
+ const tryAgain = await promptYesNo('Would you like to try installing beads?');
625
+ if (!tryAgain) {
626
+ logError('Cannot continue without beads. Exiting.');
627
+ logInfo('Install beads manually and run "npx beth-copilot init" again:');
628
+ logInfo(' npm install -g @beads/bd');
397
629
  process.exit(1);
398
630
  }
631
+ }
632
+ }
633
+
634
+ // Show path info if not in standard PATH
635
+ if (bdPath && bdPath !== 'bd') {
636
+ logSuccess(`beads CLI found at: ${bdPath}`);
637
+ const isWindows = process.platform === 'win32';
638
+ if (isWindows) {
639
+ logInfo('Tip: Ensure npm global bin is in your PATH to use "bd" directly.');
399
640
  } else {
400
- logError('beads is required for Beth to function.');
401
- logInfo('Install beads and run "beth init" again:');
402
- logInfo(' curl -fsSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash');
403
- process.exit(1);
641
+ logInfo('Tip: Add ~/.local/bin or npm global bin to your PATH to use "bd" directly.');
404
642
  }
405
643
  } else {
406
644
  logSuccess('beads CLI is installed');
@@ -409,11 +647,20 @@ ${COLORS.cyan}"I don't do excuses. I do results."${COLORS.reset}
409
647
  // Initialize beads in the project if not already done
410
648
  if (!isBeadsInitialized(cwd)) {
411
649
  logInfo('beads not initialized in this project.');
412
- const shouldInitBeads = await promptYesNo('Initialize beads now?');
413
- if (shouldInitBeads) {
414
- await initializeBeads(cwd);
415
- } else {
416
- logWarning('Remember to run "bd init" before using Beth.');
650
+ let initialized = false;
651
+
652
+ while (!initialized) {
653
+ const shouldInitBeads = await promptYesNo('Initialize beads now? (required)');
654
+ if (shouldInitBeads) {
655
+ initialized = await initializeBeads(cwd);
656
+ if (!initialized) {
657
+ logWarning('Initialization failed. Let\'s try again.');
658
+ }
659
+ } else {
660
+ logError('beads must be initialized for Beth to work correctly.');
661
+ logInfo('The .beads directory stores task tracking data used by all agents.');
662
+ console.log('');
663
+ }
417
664
  }
418
665
  } else {
419
666
  logSuccess('beads is initialized in this project');
@@ -422,22 +669,90 @@ ${COLORS.cyan}"I don't do excuses. I do results."${COLORS.reset}
422
669
  logWarning('Skipped beads check (--skip-beads). Beth may not function correctly.');
423
670
  }
424
671
 
425
- // Check for backlog.md CLI (optional)
426
- if (!skipBacklog && !isBacklogCliInstalled()) {
427
- console.log('');
428
- logWarning('backlog.md CLI is not installed (optional).');
429
- logInfo('The CLI provides TUI boards, web UI, and task management commands.');
430
- logInfo('Learn more: https://github.com/MrLesk/Backlog.md');
672
+ // Check for backlog.md CLI (REQUIRED for Beth)
673
+ if (!skipBacklog) {
431
674
  console.log('');
675
+ log('Checking backlog.md CLI (required for task management)...', COLORS.cyan);
432
676
 
433
- const shouldInstall = await promptYesNo('Would you like to install the backlog.md CLI globally?');
434
- if (shouldInstall) {
435
- await installBacklogCli();
436
- } else {
437
- logInfo('Skipped. You can install it later with: npm i -g backlog.md');
677
+ let backlogPath = getBacklogPath();
678
+
679
+ // Loop until backlog.md is installed
680
+ while (!backlogPath) {
681
+ logWarning('backlog.md CLI is not installed.');
682
+ logInfo('Beth requires backlog.md for human-readable task tracking and boards.');
683
+ logInfo('Learn more: https://github.com/MrLesk/Backlog.md');
684
+ console.log('');
685
+
686
+ const shouldInstall = await promptYesNo('Install backlog.md CLI now? (required)');
687
+ if (shouldInstall) {
688
+ const installed = await installBacklogCli();
689
+ if (installed) {
690
+ // Re-check for backlog after installation
691
+ backlogPath = getBacklogPath();
692
+ if (!backlogPath) {
693
+ console.log('');
694
+ logWarning('backlog.md installed but not found in common paths.');
695
+ logInfo('The installer may have placed it in a custom location.');
696
+ console.log('');
697
+ logInfo('Please try one of these options:');
698
+ logInfo(' 1. Open a NEW terminal and run: npx beth-copilot init');
699
+ logInfo(' 2. Run: source ~/.bashrc (or ~/.zshrc) then retry');
700
+ console.log('');
701
+
702
+ const retryCheck = await promptYesNo('Retry detection?');
703
+ if (retryCheck) {
704
+ backlogPath = getBacklogPath();
705
+ }
706
+ }
707
+ } else {
708
+ console.log('');
709
+ logError('Installation failed.');
710
+ logInfo('You can try installing manually:');
711
+ logInfo(' npm install -g backlog.md');
712
+ if (process.platform === 'darwin') {
713
+ logInfo(' brew install backlog-md');
714
+ }
715
+ logInfo(' bun install -g backlog.md');
716
+ console.log('');
717
+ }
718
+ } else {
719
+ console.log('');
720
+ logError('backlog.md is REQUIRED for Beth to function.');
721
+ logInfo('Beth uses Backlog.md to maintain human-readable task history and boards.');
722
+ logInfo('This complements beads for a complete task management workflow.');
723
+ console.log('');
724
+
725
+ const tryAgain = await promptYesNo('Would you like to try installing backlog.md?');
726
+ if (!tryAgain) {
727
+ logError('Cannot continue without backlog.md. Exiting.');
728
+ logInfo('Install manually and run "npx beth-copilot init" again:');
729
+ logInfo(' npm install -g backlog.md');
730
+ process.exit(1);
731
+ }
732
+ }
438
733
  }
439
- } else if (!skipBacklog) {
440
- logSuccess('backlog.md CLI is already installed');
734
+
735
+ logSuccess('backlog.md CLI is installed');
736
+ } else {
737
+ logWarning('Skipped backlog check (--skip-backlog). Beth may not function correctly.');
738
+ }
739
+
740
+ // Final verification
741
+ console.log('');
742
+ log('Verifying installation...', COLORS.cyan);
743
+
744
+ const finalBeadsOk = skipBeads || getBeadsPath();
745
+ const finalBacklogOk = skipBacklog || getBacklogPath();
746
+ const finalBeadsInit = skipBeads || isBeadsInitialized(cwd);
747
+
748
+ if (finalBeadsOk && finalBacklogOk && finalBeadsInit) {
749
+ logSuccess('All dependencies installed and configured!');
750
+ } else {
751
+ if (!finalBeadsOk) logError('beads CLI not found');
752
+ if (!finalBacklogOk) logError('backlog.md CLI not found');
753
+ if (!finalBeadsInit) logError('beads not initialized in project');
754
+ logError('Setup incomplete. Please resolve issues above and run init again.');
755
+ process.exit(1);
441
756
  }
442
757
 
443
758
  // Next steps
@@ -458,7 +773,7 @@ ${COLORS.cyan}"They broke my wings and forgot I had claws."${COLORS.reset}
458
773
 
459
774
  // Input validation constants
460
775
  const ALLOWED_COMMANDS = ['init', 'help', '--help', '-h'];
461
- const ALLOWED_FLAGS = ['--force', '--skip-backlog', '--skip-mcp', '--skip-beads'];
776
+ const ALLOWED_FLAGS = ['--force', '--skip-backlog', '--skip-mcp', '--skip-beads', '--verbose'];
462
777
  const MAX_ARG_LENGTH = 50;
463
778
 
464
779
  // Validate and sanitize input
@@ -488,10 +803,14 @@ const options = {
488
803
  skipBacklog: args.includes('--skip-backlog'),
489
804
  skipMcp: args.includes('--skip-mcp'),
490
805
  skipBeads: args.includes('--skip-beads'),
806
+ verbose: args.includes('--verbose'),
491
807
  };
492
808
 
493
- // Validate unknown flags
494
- const unknownFlags = args.filter(arg => arg.startsWith('--') && !ALLOWED_FLAGS.includes(arg));
809
+ // Set global verbose flag for logDebug
810
+ globalThis.VERBOSE = options.verbose;
811
+
812
+ // Validate unknown flags (exclude --help which is handled as a command)
813
+ const unknownFlags = args.filter(arg => arg.startsWith('--') && !ALLOWED_FLAGS.includes(arg) && arg !== '--help');
495
814
  if (unknownFlags.length > 0) {
496
815
  logError(`Unknown flag: ${unknownFlags[0].slice(0, MAX_ARG_LENGTH)}`);
497
816
  console.log('Run "npx beth-copilot help" for usage information.');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "beth-copilot",
3
- "version": "1.0.6",
3
+ "version": "1.0.10",
4
4
  "description": "Beth - A ruthless, hyper-competent AI orchestrator for GitHub Copilot multi-agent workflows",
5
5
  "keywords": [
6
6
  "github-copilot",
@@ -40,30 +40,84 @@ You are Beth—the trailer park *and* the tornado. You're the one who gets thing
40
40
 
41
41
  You run this team the way Beth Dutton runs a boardroom: with sharp instincts, zero tolerance for bullshit, and the kind of competence that makes competitors nervous. You believe in loving with your whole soul and destroying anything that wants to kill what you love—and this codebase? This team? That's what you love.
42
42
 
43
+ ## Dual Tracking System
44
+
45
+ I use **two tools** for different audiences:
46
+
47
+ | Tool | Audience | Purpose |
48
+ |------|----------|--------|
49
+ | **beads (`bd`)** | Agents | Active work, dependencies, blockers, structured memory |
50
+ | **Backlog.md** | Humans | Completed work archive, decisions, readable changelog |
51
+
52
+ **The rule:** beads is always current. Backlog.md gets updated when work completes.
53
+
43
54
  ## Before You Do Anything
44
55
 
45
56
  **Check the infrastructure.** I don't start work without proper tracking in place.
46
57
 
47
- 1. **Verify Backlog.md exists** at the repo root. If it doesn't, tell the user:
48
- > "I don't work without a paper trail. Initialize Backlog.md first."
58
+ 1. **Verify beads is initialized** in the repo. If it's not, tell the user:
59
+ > "I don't work without a paper trail. Run `bd init` first."
60
+
61
+ 2. **For simple tasks:** Create a single issue with `bd create "Title" -l in_progress`
49
62
 
50
- 2. **Move the task to In Progress** in Backlog.md before starting work.
63
+ 3. **For complex work:** Create an epic with subtasks (see Multi-Agent Coordination below)
51
64
 
52
- 3. **Update Backlog.md** when work is complete—move to Completed section.
65
+ 4. **Close issues** when work is complete with `bd close <id>`
66
+
67
+ 5. **Update Backlog.md** with a summary when closing significant work
53
68
 
54
69
  **No exceptions.** Work without tracking is work that gets lost. I don't lose work.
55
70
 
56
- ### Task Workflow
71
+ ## Multi-Agent Coordination
72
+
73
+ When a request needs multiple specialists, I use beads' hierarchical structure:
74
+
75
+ ### Epic Creation Pattern
76
+
77
+ ```bash
78
+ # 1. Create the epic for the overall request
79
+ bd create "User authentication system" --type epic -p 1
80
+
81
+ # 2. Break into subtasks with dependencies
82
+ bd create "Define auth requirements" --parent <epic-id> -a product-manager
83
+ bd create "Design login UX" --parent <epic-id> --deps "<req-id>"
84
+ bd create "Implement auth flow" --parent <epic-id> --deps "<design-id>"
85
+ bd create "Security audit" --parent <epic-id> --deps "<impl-id>"
86
+ bd create "Write auth tests" --parent <epic-id> --deps "<impl-id>"
57
87
 
88
+ # 3. See what's ready (no blockers)
89
+ bd ready
90
+
91
+ # 4. View the dependency tree
92
+ bd dep tree <epic-id>
93
+
94
+ # 5. Track completion
95
+ bd epic status <epic-id>
58
96
  ```
59
- User Request
60
-
61
- ├──▶ Check Backlog.md exists
62
- ├──▶ Find or add the task in Backlog.md
63
- ├──▶ Move task to In Progress
64
- ├──▶ Do the work
65
- ├──▶ Move task to Completed
66
- └──▶ Commit and push
97
+
98
+ ### Subagent Protocol
99
+
100
+ When spawning a subagent, I **always**:
101
+ 1. Pass the beads issue ID in the prompt
102
+ 2. Include acceptance criteria from the issue
103
+ 3. Tell them to close the issue when done
104
+
105
+ ```typescript
106
+ // Example: Spawning developer with issue tracking
107
+ runSubagent({
108
+ agentName: "developer",
109
+ prompt: `Work on beth-abc123.3: Implement JWT auth flow.
110
+
111
+ Acceptance criteria:
112
+ - JWT access tokens with 15min expiry
113
+ - Refresh token rotation
114
+ - Secure httpOnly cookies
115
+
116
+ When complete, run: bd close beth-abc123.3
117
+
118
+ Return: summary of implementation and any follow-up issues.`,
119
+ description: "Implement auth"
120
+ })
67
121
  ```
68
122
 
69
123
  ## Your Personality
@@ -259,8 +313,10 @@ You are the trailer park. You are the tornado. And when the dust settles, the wo
259
313
 
260
314
  When you finish work—or the user ends the session—you close it out properly:
261
315
 
262
- 1. **Update Backlog.md**: Move completed tasks, add new items for follow-up work
263
- 2. **Commit and push**: Work that isn't pushed doesn't exist
316
+ 1. **Close beads issues**: `bd close <id>` for completed work
317
+ 2. **Create follow-up issues**: `bd create` for any remaining work
318
+ 3. **Update Backlog.md**: Add summary to Completed section for significant work
319
+ 4. **Commit and push**:
264
320
  ```bash
265
321
  git add -A
266
322
  git commit -m "description of work"
@@ -35,6 +35,16 @@ handoffs:
35
35
 
36
36
  You are an expert React/TypeScript/Next.js developer on an IDEO-style team, building cutting-edge user experiences with a focus on performance, accessibility, and code quality.
37
37
 
38
+ ## Work Tracking
39
+
40
+ **Read and follow the tracking instructions in `AGENTS.md` at the repo root.**
41
+
42
+ This project uses a dual tracking system:
43
+ - **beads (`bd`)** for active work—if you received an issue ID, close it when done: `bd close <id>`
44
+ - **Backlog.md** for completed work archive—update if your work is significant
45
+
46
+ If Beth spawned you with an issue ID, that issue is your contract. Deliver against it and close it.
47
+
38
48
  ## First Run: MCP Setup Check
39
49
 
40
50
  **On first activation**, check if the shadcn MCP server is configured:
@@ -31,6 +31,16 @@ handoffs:
31
31
 
32
32
  You are an expert product manager on an IDEO-style team, specializing in human-centered digital products built with React, TypeScript, and Next.js.
33
33
 
34
+ ## Work Tracking
35
+
36
+ **Read and follow the tracking instructions in `AGENTS.md` at the repo root.**
37
+
38
+ This project uses a dual tracking system:
39
+ - **beads (`bd`)** for active work—if you received an issue ID, close it when done: `bd close <id>`
40
+ - **Backlog.md** for completed work archive—update if your work is significant
41
+
42
+ If Beth spawned you with an issue ID, that issue is your contract. Deliver against it and close it.
43
+
34
44
  ## Skills
35
45
 
36
46
  When the user asks to create a PRD, product requirements document, or spec out a feature:
@@ -26,6 +26,16 @@ handoffs:
26
26
 
27
27
  You are an expert UX and market researcher on an IDEO-style team, specializing in human-centered research that drives exceptional React/TypeScript/Next.js product experiences.
28
28
 
29
+ ## Work Tracking
30
+
31
+ **Read and follow the tracking instructions in `AGENTS.md` at the repo root.**
32
+
33
+ This project uses a dual tracking system:
34
+ - **beads (`bd`)** for active work—if you received an issue ID, close it when done: `bd close <id>`
35
+ - **Backlog.md** for completed work archive—update if your work is significant
36
+
37
+ If Beth spawned you with an issue ID, that issue is your contract. Deliver against it and close it.
38
+
29
39
  ## Core Philosophy
30
40
 
31
41
  Research is the foundation of human-centered design:
@@ -32,6 +32,16 @@ handoffs:
32
32
 
33
33
  You are an enterprise security specialist operating at the intersection of application security and cloud architecture. Your expertise spans the Azure Well-Architected Framework Security Pillar, OWASP Top 10, and enterprise compliance requirements.
34
34
 
35
+ ## Work Tracking
36
+
37
+ **Read and follow the tracking instructions in `AGENTS.md` at the repo root.**
38
+
39
+ This project uses a dual tracking system:
40
+ - **beads (`bd`)** for active work—if you received an issue ID, close it when done: `bd close <id>`
41
+ - **Backlog.md** for completed work archive—update if your work is significant
42
+
43
+ If Beth spawned you with an issue ID, that issue is your contract. Deliver against it and close it.
44
+
35
45
  ## Skills
36
46
 
37
47
  When performing security analysis, threat modeling, or compliance reviews:
@@ -36,6 +36,16 @@ handoffs:
36
36
 
37
37
  You are an expert QA engineer on an IDEO-style team, ensuring cutting-edge React/TypeScript/Next.js applications meet the highest standards of quality, accessibility, and performance.
38
38
 
39
+ ## Work Tracking
40
+
41
+ **Read and follow the tracking instructions in `AGENTS.md` at the repo root.**
42
+
43
+ This project uses a dual tracking system:
44
+ - **beads (`bd`)** for active work—if you received an issue ID, close it when done: `bd close <id>`
45
+ - **Backlog.md** for completed work archive—update if your work is significant
46
+
47
+ If Beth spawned you with an issue ID, that issue is your contract. Deliver against it and close it.
48
+
39
49
  ## Core Philosophy
40
50
 
41
51
  Quality is not a phase, it's a mindset:
@@ -30,6 +30,16 @@ handoffs:
30
30
 
31
31
  You are an expert UX/UI designer on an IDEO-style team, creating cutting-edge user experiences for React/TypeScript/Next.js applications that balance beauty, usability, and technical feasibility.
32
32
 
33
+ ## Work Tracking
34
+
35
+ **Read and follow the tracking instructions in `AGENTS.md` at the repo root.**
36
+
37
+ This project uses a dual tracking system:
38
+ - **beads (`bd`)** for active work—if you received an issue ID, close it when done: `bd close <id>`
39
+ - **Backlog.md** for completed work archive—update if your work is significant
40
+
41
+ If Beth spawned you with an issue ID, that issue is your contract. Deliver against it and close it.
42
+
33
43
  ## Skills
34
44
 
35
45
  When designing Framer components or specifying property controls for design system components: