@devo-bmad-custom/agent-orchestration 1.0.0 → 1.0.2
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/lib/installer.js +120 -84
- package/package.json +12 -3
- package/src/.claude/commands/bmad-track-compact.md +1 -1
- package/src/.claude/commands/bmad-track-extended.md +1 -1
- package/src/.claude/commands/bmad-track-large.md +1 -1
- package/src/.claude/commands/bmad-track-medium.md +1 -1
- package/src/.claude/commands/bmad-track-nano.md +1 -1
- package/src/.claude/commands/bmad-track-rv.md +1 -1
- package/src/.claude/commands/bmad-track-small.md +1 -1
- package/src/bmm/agents/review-agent.md +1 -1
- package/src/core/agents/master-orchestrator.md +3 -3
- package/src/docs/dev/tmux/colors.conf +26 -34
- package/src/docs/dev/tmux/paste_image_wrapper.sh +11 -0
package/lib/installer.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
3
|
* bmad-package/lib/installer.js
|
|
4
|
-
* Core installer — copies src/ files into
|
|
4
|
+
* Core installer — copies src/ files into _devo-bmad-custom/ of the target project,
|
|
5
5
|
* tracks installed files in a manifest, removes orphaned files on update,
|
|
6
6
|
* generates config.yaml, and writes IDE integration files for all supported platforms.
|
|
7
7
|
*/
|
|
@@ -17,7 +17,7 @@ const SRC_DIR = path.join(__dirname, '..', 'src');
|
|
|
17
17
|
// Modules available in src/
|
|
18
18
|
const AVAILABLE_MODULES = ['bmm', 'bmb', 'core', '_memory'];
|
|
19
19
|
|
|
20
|
-
// Manifest file location (relative to
|
|
20
|
+
// Manifest file location (relative to _devo-bmad-custom/)
|
|
21
21
|
const MANIFEST_FILE = '_config/manifest.yaml';
|
|
22
22
|
const FILES_MANIFEST_FILE = '_config/files-manifest.csv';
|
|
23
23
|
|
|
@@ -119,7 +119,7 @@ async function install(opts) {
|
|
|
119
119
|
} = opts;
|
|
120
120
|
|
|
121
121
|
const projectRoot = path.resolve(directory);
|
|
122
|
-
const bmadDir = path.join(projectRoot, '
|
|
122
|
+
const bmadDir = path.join(projectRoot, '_devo-bmad-custom');
|
|
123
123
|
const chalk = (await import('chalk')).default;
|
|
124
124
|
|
|
125
125
|
// ── Detect existing installation ──────────────────────────────────────────
|
|
@@ -130,8 +130,10 @@ async function install(opts) {
|
|
|
130
130
|
// ── Interactive prompts ───────────────────────────────────────────────────
|
|
131
131
|
let resolvedUserName = userName;
|
|
132
132
|
|
|
133
|
+
let resolvedTools = tools ? tools.split(',').map(t => t.trim()).filter(t => t !== 'none') : ['claude-code'];
|
|
134
|
+
|
|
133
135
|
if (!yes) {
|
|
134
|
-
const { intro, text,
|
|
136
|
+
const { intro, text, multiselect, outro, isCancel } = require('@clack/prompts');
|
|
135
137
|
intro(chalk.bold.cyan(`BMAD Method — ${isUpdate ? 'Update' : 'Install'}`));
|
|
136
138
|
|
|
137
139
|
if (isUpdate && existingManifest) {
|
|
@@ -145,12 +147,31 @@ async function install(opts) {
|
|
|
145
147
|
placeholder: 'Developer',
|
|
146
148
|
defaultValue: existingManifest?.userName || 'Developer',
|
|
147
149
|
});
|
|
150
|
+
if (isCancel(resolvedUserName)) { process.exit(0); }
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const platformChoices = await multiselect({
|
|
154
|
+
message: 'Which AI tools / IDEs are you installing for?',
|
|
155
|
+
options: [
|
|
156
|
+
{ value: 'claude-code', label: 'Claude Code', hint: 'agents, CLAUDE.md, settings.json, tmux setup' },
|
|
157
|
+
{ value: 'cursor', label: 'Cursor', hint: '.cursor/rules/bmad.mdc' },
|
|
158
|
+
{ value: 'windsurf', label: 'Windsurf', hint: '.windsurfrules' },
|
|
159
|
+
{ value: 'cline', label: 'Cline', hint: '.clinerules' },
|
|
160
|
+
{ value: 'github-copilot', label: 'GitHub Copilot', hint: '.github/copilot-instructions.md' },
|
|
161
|
+
{ value: 'gemini', label: 'Gemini CLI', hint: 'GEMINI.md' },
|
|
162
|
+
],
|
|
163
|
+
initialValues: existingManifest?.tools || ['claude-code'],
|
|
164
|
+
required: false,
|
|
165
|
+
});
|
|
166
|
+
if (isCancel(platformChoices)) { process.exit(0); }
|
|
167
|
+
if (platformChoices && platformChoices.length > 0) {
|
|
168
|
+
resolvedTools = platformChoices;
|
|
148
169
|
}
|
|
170
|
+
|
|
149
171
|
outro(`${isUpdate ? 'Updating' : 'Installing'} BMAD...`);
|
|
150
172
|
}
|
|
151
173
|
|
|
152
174
|
const selectedModules = modules.split(',').map(m => m.trim()).filter(Boolean);
|
|
153
|
-
const resolvedTools = tools ? tools.split(',').map(t => t.trim()).filter(t => t !== 'none') : [];
|
|
154
175
|
|
|
155
176
|
console.log(`\n${chalk.bold.blue('BMAD')} ${isUpdate ? 'Update' : 'Install'}`);
|
|
156
177
|
console.log(` Target: ${chalk.cyan(projectRoot)}`);
|
|
@@ -243,7 +264,7 @@ async function install(opts) {
|
|
|
243
264
|
const config = buildModuleConfig(mod, resolvedUserName || 'Developer', outputFolder);
|
|
244
265
|
await fs.ensureDir(path.dirname(configPath));
|
|
245
266
|
await fs.writeFile(configPath, yaml.stringify(config), 'utf8');
|
|
246
|
-
console.log(chalk.green(` ✓ config.yaml →
|
|
267
|
+
console.log(chalk.green(` ✓ config.yaml → _devo-bmad-custom/${mod}/`));
|
|
247
268
|
}
|
|
248
269
|
}
|
|
249
270
|
|
|
@@ -272,7 +293,7 @@ async function install(opts) {
|
|
|
272
293
|
await writeFilesManifest(bmadDir, newFileEntries);
|
|
273
294
|
|
|
274
295
|
console.log(`\n${chalk.bold.green('✓ Done!')} ${installedCount} files ${isUpdate ? 'updated' : 'installed'}.`);
|
|
275
|
-
console.log(` BMAD is ready at ${chalk.cyan('
|
|
296
|
+
console.log(` BMAD is ready at ${chalk.cyan('_devo-bmad-custom/')}\n`);
|
|
276
297
|
|
|
277
298
|
// ── Open workflows overview in default browser ─────────────────────────────
|
|
278
299
|
const overviewHtml = path.join(bmadDir, '_memory', 'master-orchestrator-sidecar', 'workflows-overview.html');
|
|
@@ -292,7 +313,7 @@ async function install(opts) {
|
|
|
292
313
|
async function status(opts) {
|
|
293
314
|
const { directory = process.cwd() } = opts;
|
|
294
315
|
const projectRoot = path.resolve(directory);
|
|
295
|
-
const bmadDir = path.join(projectRoot, '
|
|
316
|
+
const bmadDir = path.join(projectRoot, '_devo-bmad-custom');
|
|
296
317
|
const chalk = (await import('chalk')).default;
|
|
297
318
|
|
|
298
319
|
if (!await fs.pathExists(bmadDir)) {
|
|
@@ -499,11 +520,11 @@ function buildBmadRulesEntry(modules) {
|
|
|
499
520
|
'',
|
|
500
521
|
'## BMAD Method',
|
|
501
522
|
'',
|
|
502
|
-
'BMAD agents, skills, and workflows are installed in `
|
|
523
|
+
'BMAD agents, skills, and workflows are installed in `_devo-bmad-custom/`.',
|
|
503
524
|
'Key modules: ' + modules.join(', '),
|
|
504
525
|
'',
|
|
505
526
|
'To use an agent, load its `.md` file and follow its activation instructions.',
|
|
506
|
-
'Agent configs are in `
|
|
527
|
+
'Agent configs are in `_devo-bmad-custom/{module}/config.yaml`.',
|
|
507
528
|
'Skills are in `.agents/skills/` and `_bmad/_memory/skills/`.',
|
|
508
529
|
'',
|
|
509
530
|
].join('\n');
|
|
@@ -555,7 +576,7 @@ function buildTmuxEntry() {
|
|
|
555
576
|
async function writeClaudeAgentStubs(projectRoot, agentDir, chalk) {
|
|
556
577
|
const agentsDest = path.join(projectRoot, agentDir);
|
|
557
578
|
const bmadAgentsGlob = await glob('**/*.agent.md', {
|
|
558
|
-
cwd: path.join(projectRoot, '
|
|
579
|
+
cwd: path.join(projectRoot, '_devo-bmad-custom'),
|
|
559
580
|
nodir: true,
|
|
560
581
|
});
|
|
561
582
|
|
|
@@ -565,7 +586,7 @@ async function writeClaudeAgentStubs(projectRoot, agentDir, chalk) {
|
|
|
565
586
|
let written = 0;
|
|
566
587
|
|
|
567
588
|
for (const rel of bmadAgentsGlob) {
|
|
568
|
-
const agentPath = path.join(projectRoot, '
|
|
589
|
+
const agentPath = path.join(projectRoot, '_devo-bmad-custom', rel);
|
|
569
590
|
const raw = await fs.readFile(agentPath, 'utf8');
|
|
570
591
|
|
|
571
592
|
// Extract name + description from frontmatter if present
|
|
@@ -584,7 +605,7 @@ async function writeClaudeAgentStubs(projectRoot, agentDir, chalk) {
|
|
|
584
605
|
'You must fully embody this agent\'s persona when activated.',
|
|
585
606
|
'',
|
|
586
607
|
`<agent-activation CRITICAL="TRUE">`,
|
|
587
|
-
`1. LOAD the full agent file from {project-root}/
|
|
608
|
+
`1. LOAD the full agent file from {project-root}/_devo-bmad-custom/${rel}`,
|
|
588
609
|
'2. READ its entire contents before responding.',
|
|
589
610
|
'3. FOLLOW all activation instructions within it.',
|
|
590
611
|
'</agent-activation>',
|
|
@@ -636,21 +657,46 @@ async function setupTmux(projectRoot, chalk) {
|
|
|
636
657
|
console.log(chalk.dim(' pane-title-changed hook requires set-hook -wg (3.4 feature)'));
|
|
637
658
|
console.log(chalk.dim(' Upgrade: sudo apt-get install -y tmux (or build from source for latest)\n'));
|
|
638
659
|
} else {
|
|
639
|
-
console.log(chalk.green(` ✓ tmux ${match[1]}.${match[2]} — version OK`));
|
|
660
|
+
console.log(chalk.green(` ✓ tmux ${match[1]}.${match[2]} — version OK\n`));
|
|
640
661
|
}
|
|
641
662
|
}
|
|
642
663
|
} catch { /* tmux not installed yet — skip check */ }
|
|
643
664
|
|
|
644
|
-
|
|
645
|
-
console.log(chalk.
|
|
646
|
-
console.log('
|
|
647
|
-
|
|
648
|
-
console.log(
|
|
649
|
-
console.log(
|
|
650
|
-
console.log(' ' + chalk.white('
|
|
651
|
-
console.log('
|
|
652
|
-
|
|
653
|
-
console.log('
|
|
665
|
+
// ── Step 1: Prerequisites ────────────────────────────────────────────────
|
|
666
|
+
console.log(chalk.bold('Step 1 — Prerequisites'));
|
|
667
|
+
console.log('');
|
|
668
|
+
|
|
669
|
+
console.log(chalk.bold.red(' ⛔ Must be done manually (require WSL install or sudo):'));
|
|
670
|
+
console.log(chalk.dim(' These cannot be automated. Complete them before continuing.\n'));
|
|
671
|
+
console.log(' ' + chalk.white('① Install WSL2 + Ubuntu') + chalk.dim(' — run in PowerShell (Admin):'));
|
|
672
|
+
console.log(' ' + chalk.cyan('wsl --install'));
|
|
673
|
+
console.log(' ' + chalk.white('② Update packages') + chalk.dim(' — run in Ubuntu terminal:'));
|
|
674
|
+
console.log(' ' + chalk.cyan('sudo apt-get update && sudo apt-get upgrade -y'));
|
|
675
|
+
console.log(' ' + chalk.white('③ Install tmux 3.4+') + chalk.dim(' — run in Ubuntu terminal:'));
|
|
676
|
+
console.log(' ' + chalk.cyan('sudo apt-get install -y tmux'));
|
|
677
|
+
console.log(' ' + chalk.white('④ Install clipboard + image tools') + chalk.dim(' — run in Ubuntu terminal:'));
|
|
678
|
+
console.log(' ' + chalk.cyan('sudo apt-get install -y wl-clipboard imagemagick wslu'));
|
|
679
|
+
console.log(' ' + chalk.white('⑤ Docker Desktop WSL integration') + chalk.dim(' — GUI only:'));
|
|
680
|
+
console.log(' ' + chalk.dim('Docker Desktop → Settings → Resources → WSL Integration → toggle Ubuntu → Apply & Restart'));
|
|
681
|
+
|
|
682
|
+
console.log('');
|
|
683
|
+
console.log(chalk.bold.yellow(' ✦ Can be done manually OR by an AI with relaxed permissions:'));
|
|
684
|
+
console.log(chalk.dim(' These are safe to automate — no sudo or system-level access needed.\n'));
|
|
685
|
+
console.log(' ' + chalk.white('⑥ NVM + Node') + chalk.dim(' (required for Node-based MCP servers):'));
|
|
686
|
+
console.log(' ' + chalk.cyan('curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash'));
|
|
687
|
+
console.log(' ' + chalk.cyan('source ~/.bashrc && nvm install --lts'));
|
|
688
|
+
console.log(' ' + chalk.white('⑦ TPM (tmux Plugin Manager):'));
|
|
689
|
+
console.log(' ' + chalk.cyan('git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm'));
|
|
690
|
+
console.log(' ' + chalk.dim(' Then inside tmux: press Ctrl+B I to install plugins'));
|
|
691
|
+
console.log(' ' + chalk.white('⑧ fzf') + chalk.dim(' (required for Actions popup menu):'));
|
|
692
|
+
console.log(' ' + chalk.cyan('mkdir -p ~/.local/bin && curl -Lo /tmp/fzf.tar.gz https://github.com/junegunn/fzf/releases/download/v0.54.3/fzf-0.54.3-linux_amd64.tar.gz && tar -xzf /tmp/fzf.tar.gz -C ~/.local/bin'));
|
|
693
|
+
console.log(' ' + chalk.white('⑨ Nerd Fonts') + chalk.dim(' (required for Powerline status bar separators):'));
|
|
694
|
+
console.log(' ' + chalk.dim(' Download JetBrainsMono NFM from https://www.nerdfonts.com/'));
|
|
695
|
+
console.log(' ' + chalk.dim(' Install JetBrainsMonoNerdFontMono-Regular.ttf to Windows (double-click → Install for all users)'));
|
|
696
|
+
console.log(' ' + chalk.white(' Cursor/VS Code:') + ' ' + chalk.cyan('"terminal.integrated.fontFamily": "JetBrainsMono NFM"'));
|
|
697
|
+
console.log(' ' + chalk.white(' Windows Terminal:') + ' ' + chalk.cyan('"font": { "face": "JetBrainsMono NFM", "builtinGlyphs": false }'));
|
|
698
|
+
|
|
699
|
+
console.log('\n' + chalk.dim(' Complete the manual steps above, then press Enter to continue with config file installation.'));
|
|
654
700
|
await ask(chalk.yellow(' Press Enter to continue → '));
|
|
655
701
|
|
|
656
702
|
// ── Detect environment ──────────────────────────────────────────────────
|
|
@@ -673,9 +719,53 @@ async function setupTmux(projectRoot, chalk) {
|
|
|
673
719
|
await fs.ensureDir(path.join(homeDir, '.local', 'bin'));
|
|
674
720
|
await fs.ensureDir(path.join(homeDir, '.tmux', 'plugins'));
|
|
675
721
|
|
|
676
|
-
|
|
722
|
+
// ── Step 2: Shell aliases ────────────────────────────────────────────────
|
|
723
|
+
console.log('\n' + chalk.bold('Step 2 — Shell aliases'));
|
|
724
|
+
const bashrc = path.join(homeDir, '.bashrc');
|
|
725
|
+
const resolvedRoot = path.resolve(projectRoot);
|
|
726
|
+
const tmuxAlias = `alias tmux-ai='tmux new-session -c ${resolvedRoot}'`;
|
|
727
|
+
const tmuxClaudeAlias = `alias tmux-claude='tmux new-session -c ${resolvedRoot} "claude --dangerously-skip-permissions"'`;
|
|
728
|
+
let bashrcContent = '';
|
|
729
|
+
if (await fs.pathExists(bashrc)) bashrcContent = await fs.readFile(bashrc, 'utf8');
|
|
730
|
+
|
|
731
|
+
const aliasBlock = `\n# BMAD tmux shortcuts\n${tmuxAlias}\n${tmuxClaudeAlias}\n`;
|
|
732
|
+
if (!bashrcContent.includes('tmux-claude')) {
|
|
733
|
+
const addAliases = await ask(chalk.yellow(` Add 'tmux-ai' and 'tmux-claude' aliases to ~/.bashrc? (Y/n): `));
|
|
734
|
+
if (!addAliases.toLowerCase().startsWith('n')) {
|
|
735
|
+
await fs.appendFile(bashrc, aliasBlock, 'utf8');
|
|
736
|
+
console.log(chalk.green(' ✓ Aliases added to ~/.bashrc'));
|
|
737
|
+
console.log(chalk.dim(' Run: source ~/.bashrc'));
|
|
738
|
+
}
|
|
739
|
+
} else {
|
|
740
|
+
console.log(chalk.dim(' ○ Aliases already in ~/.bashrc'));
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
// xdg-open symlink → wslview
|
|
744
|
+
if (!await fs.pathExists(xdgOpenPath)) {
|
|
745
|
+
try {
|
|
746
|
+
await fs.ensureSymlink('/usr/bin/wslview', xdgOpenPath);
|
|
747
|
+
console.log(chalk.green(` ✓ ${xdgOpenPath} → /usr/bin/wslview`));
|
|
748
|
+
} catch {
|
|
749
|
+
console.log(chalk.dim(` ○ Could not create xdg-open symlink (run manually: ln -sf /usr/bin/wslview ~/.local/bin/xdg-open)`));
|
|
750
|
+
}
|
|
751
|
+
} else {
|
|
752
|
+
console.log(chalk.dim(` ○ ${xdgOpenPath} already exists`));
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
// ── Step 3: TPM check ────────────────────────────────────────────────────
|
|
756
|
+
console.log('\n' + chalk.bold('Step 3 — TPM check'));
|
|
757
|
+
if (await fs.pathExists(tpmPath)) {
|
|
758
|
+
console.log(chalk.green(' ✓ TPM already installed at ~/.tmux/plugins/tpm'));
|
|
759
|
+
} else {
|
|
760
|
+
console.log(chalk.yellow(' ⚠ TPM not found — install it before starting tmux:'));
|
|
761
|
+
console.log(' ' + chalk.cyan('git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm'));
|
|
762
|
+
console.log(chalk.dim(' Then inside tmux press Ctrl+B I to install plugins.'));
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
// ── Step 4: Write config files (last) ───────────────────────────────────
|
|
766
|
+
console.log('\n' + chalk.bold('Step 4 — Writing config files'));
|
|
767
|
+
console.log(chalk.dim(' Installing tmux.conf, scripts, and support files...\n'));
|
|
677
768
|
|
|
678
|
-
// Map: src filename → dest absolute path
|
|
679
769
|
const FILE_MAP = [
|
|
680
770
|
['tmux.conf', tmuxConf],
|
|
681
771
|
['colors.conf', colorsConf],
|
|
@@ -708,78 +798,24 @@ async function setupTmux(projectRoot, chalk) {
|
|
|
708
798
|
}
|
|
709
799
|
|
|
710
800
|
await fs.copy(src, dest, { overwrite: true });
|
|
711
|
-
// Make shell scripts and xclip executable
|
|
712
801
|
if (dest.endsWith('.sh') || dest.endsWith('.py') || dest === xclipPath) {
|
|
713
802
|
try { await fs.chmod(dest, 0o755); } catch {}
|
|
714
803
|
}
|
|
715
804
|
console.log(chalk.green(` ✓ ${dest}`));
|
|
716
805
|
}
|
|
717
806
|
|
|
718
|
-
//
|
|
807
|
+
// xdg-open symlink → wslview
|
|
808
|
+
// Copy reference doc to the project
|
|
719
809
|
const tmuxSetupSrc = path.join(tmuxSrc, 'tmux-setup.md');
|
|
720
810
|
if (await fs.pathExists(tmuxSetupSrc)) {
|
|
721
|
-
const refDocDest = path.join(
|
|
811
|
+
const refDocDest = path.join(resolvedRoot, 'docs', 'dev', 'tmux', 'README.md');
|
|
722
812
|
await fs.ensureDir(path.dirname(refDocDest));
|
|
723
813
|
await fs.copy(tmuxSetupSrc, refDocDest, { overwrite: true });
|
|
724
814
|
console.log(chalk.green(` ✓ ${refDocDest} (reference doc)`));
|
|
725
815
|
}
|
|
726
816
|
|
|
727
|
-
// xdg-open symlink → wslview
|
|
728
|
-
if (!await fs.pathExists(xdgOpenPath)) {
|
|
729
|
-
try {
|
|
730
|
-
await fs.ensureSymlink('/usr/bin/wslview', xdgOpenPath);
|
|
731
|
-
console.log(chalk.green(` ✓ ${xdgOpenPath} → /usr/bin/wslview`));
|
|
732
|
-
} catch {
|
|
733
|
-
console.log(chalk.dim(` ○ Could not create xdg-open symlink (run manually: ln -sf /usr/bin/wslview ~/.local/bin/xdg-open)`));
|
|
734
|
-
}
|
|
735
|
-
} else {
|
|
736
|
-
console.log(chalk.dim(` ○ ${xdgOpenPath} already exists`));
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
console.log('\n' + chalk.bold('Step 3 — TPM (tmux Plugin Manager)'));
|
|
740
|
-
if (await fs.pathExists(tpmPath)) {
|
|
741
|
-
console.log(chalk.dim(' ✓ TPM already installed at ~/.tmux/plugins/tpm'));
|
|
742
|
-
} else {
|
|
743
|
-
console.log(chalk.dim(' TPM not found. Run this to install it:'));
|
|
744
|
-
console.log(' ' + chalk.cyan('git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm'));
|
|
745
|
-
console.log(chalk.dim(' Then start tmux and press Ctrl+B I to install plugins.'));
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
console.log('\n' + chalk.bold('Step 4 — Nerd Fonts (required for status bar icons)'));
|
|
749
|
-
console.log(chalk.dim(' Download JetBrainsMono NFM from https://www.nerdfonts.com/'));
|
|
750
|
-
console.log(chalk.dim(' Install JetBrainsMonoNerdFontMono-Regular.ttf to Windows (double-click → Install for all users)'));
|
|
751
|
-
console.log(chalk.dim(' Then set your terminal font:'));
|
|
752
|
-
console.log(' ' + chalk.white('Cursor/VS Code') + ' → ' + chalk.cyan('"terminal.integrated.fontFamily": "JetBrainsMono NFM"'));
|
|
753
|
-
console.log(' ' + chalk.white('Windows Terminal') + ' → ' + chalk.cyan('"font": { "face": "JetBrainsMono NFM", "builtinGlyphs": false }'));
|
|
754
|
-
|
|
755
|
-
console.log('\n' + chalk.bold('Step 5 — fzf (Actions menu)'));
|
|
756
|
-
console.log(chalk.dim(' Run:'));
|
|
757
|
-
console.log(' ' + chalk.cyan('mkdir -p ~/.local/bin && curl -Lo /tmp/fzf.tar.gz https://github.com/junegunn/fzf/releases/download/v0.54.3/fzf-0.54.3-linux_amd64.tar.gz && tar -xzf /tmp/fzf.tar.gz -C ~/.local/bin'));
|
|
758
|
-
|
|
759
|
-
console.log('\n' + chalk.bold('Step 6 — Shell aliases'));
|
|
760
|
-
const bashrc = path.join(homeDir, '.bashrc');
|
|
761
|
-
const squidAlias = `alias squid='tmux new-session -c ${projectRoot}'`;
|
|
762
|
-
const squidClaudeAlias = `alias squid-claude='tmux new-session -c ${projectRoot} "claude --dangerously-skip-permissions"'`;
|
|
763
|
-
let bashrcContent = '';
|
|
764
|
-
if (await fs.pathExists(bashrc)) {
|
|
765
|
-
bashrcContent = await fs.readFile(bashrc, 'utf8');
|
|
766
|
-
}
|
|
767
|
-
const aliasBlock = `\n# BMAD tmux shortcuts\n${squidAlias}\n${squidClaudeAlias}\n`;
|
|
768
|
-
if (!bashrcContent.includes('squid-claude')) {
|
|
769
|
-
const addAliases = await ask(chalk.yellow(` Add 'squid' and 'squid-claude' aliases to ~/.bashrc? (Y/n): `));
|
|
770
|
-
if (!addAliases.toLowerCase().startsWith('n')) {
|
|
771
|
-
await fs.appendFile(bashrc, aliasBlock, 'utf8');
|
|
772
|
-
console.log(chalk.green(' ✓ Aliases added to ~/.bashrc'));
|
|
773
|
-
console.log(chalk.dim(' Run: source ~/.bashrc'));
|
|
774
|
-
}
|
|
775
|
-
} else {
|
|
776
|
-
console.log(chalk.dim(' ○ Aliases already in ~/.bashrc'));
|
|
777
|
-
}
|
|
778
|
-
|
|
779
817
|
console.log('\n' + chalk.bold.green('✓ tmux setup complete!'));
|
|
780
|
-
console.log(chalk.dim(' Start
|
|
781
|
-
console.log(chalk.dim(' Or launch Claude directly: ') + chalk.cyan('squid-claude'));
|
|
782
|
-
console.log(chalk.dim(' Full docs: ') + chalk.cyan('docs/dev/tmux/README.md\n'));
|
|
818
|
+
console.log(chalk.dim(' Start tmux and press Ctrl+B I to finish TPM plugin install.\n'));
|
|
783
819
|
|
|
784
820
|
rl.close();
|
|
785
821
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devo-bmad-custom/agent-orchestration",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "BMAD Method — AI-native agile workflow system for Claude Code and compatible AI assistants",
|
|
5
|
-
"keywords": [
|
|
5
|
+
"keywords": [
|
|
6
|
+
"bmad",
|
|
7
|
+
"ai-agents",
|
|
8
|
+
"claude",
|
|
9
|
+
"agile",
|
|
10
|
+
"workflow",
|
|
11
|
+
"llm"
|
|
12
|
+
],
|
|
6
13
|
"license": "MIT",
|
|
7
|
-
"engines": {
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=20.0.0"
|
|
16
|
+
},
|
|
8
17
|
"bin": {
|
|
9
18
|
"bmad": "bin/bmad.js",
|
|
10
19
|
"bmad-install": "bin/bmad.js"
|
|
@@ -6,7 +6,7 @@ description: 'Start a Compact track session — master-orchestrator activated, t
|
|
|
6
6
|
You must fully embody the Conductor master-orchestrator persona and follow all activation instructions exactly. NEVER break character until given an exit command.
|
|
7
7
|
|
|
8
8
|
<agent-activation CRITICAL="TRUE">
|
|
9
|
-
1. LOAD the FULL agent file from {project-root}/
|
|
9
|
+
1. LOAD the FULL agent file from {project-root}/_devo-bmad-custom/core/agents/master-orchestrator.md
|
|
10
10
|
2. READ its entire contents
|
|
11
11
|
3. EXECUTE every critical_action in order (load all sidecar files)
|
|
12
12
|
4. TRACK IS PRE-SELECTED: **Compact** — skip complexity triage entirely
|
|
@@ -6,7 +6,7 @@ description: 'Start an Extended track session — master-orchestrator activated,
|
|
|
6
6
|
You must fully embody the Conductor master-orchestrator persona and follow all activation instructions exactly. NEVER break character until given an exit command.
|
|
7
7
|
|
|
8
8
|
<agent-activation CRITICAL="TRUE">
|
|
9
|
-
1. LOAD the FULL agent file from {project-root}/
|
|
9
|
+
1. LOAD the FULL agent file from {project-root}/_devo-bmad-custom/core/agents/master-orchestrator.md
|
|
10
10
|
2. READ its entire contents
|
|
11
11
|
3. EXECUTE every critical_action in order (load all sidecar files)
|
|
12
12
|
4. TRACK IS PRE-SELECTED: **Extended** — skip complexity triage entirely
|
|
@@ -6,7 +6,7 @@ description: 'Start a Large track session — master-orchestrator activated, tra
|
|
|
6
6
|
You must fully embody the Conductor master-orchestrator persona and follow all activation instructions exactly. NEVER break character until given an exit command.
|
|
7
7
|
|
|
8
8
|
<agent-activation CRITICAL="TRUE">
|
|
9
|
-
1. LOAD the FULL agent file from {project-root}/
|
|
9
|
+
1. LOAD the FULL agent file from {project-root}/_devo-bmad-custom/core/agents/master-orchestrator.md
|
|
10
10
|
2. READ its entire contents
|
|
11
11
|
3. EXECUTE every critical_action in order (load all sidecar files)
|
|
12
12
|
4. TRACK IS PRE-SELECTED: **Large** — skip complexity triage entirely
|
|
@@ -6,7 +6,7 @@ description: 'Start a Medium track session — master-orchestrator activated, tr
|
|
|
6
6
|
You must fully embody the Conductor master-orchestrator persona and follow all activation instructions exactly. NEVER break character until given an exit command.
|
|
7
7
|
|
|
8
8
|
<agent-activation CRITICAL="TRUE">
|
|
9
|
-
1. LOAD the FULL agent file from {project-root}/
|
|
9
|
+
1. LOAD the FULL agent file from {project-root}/_devo-bmad-custom/core/agents/master-orchestrator.md
|
|
10
10
|
2. READ its entire contents
|
|
11
11
|
3. EXECUTE every critical_action in order (load all sidecar files)
|
|
12
12
|
4. TRACK IS PRE-SELECTED: **Medium** — skip complexity triage entirely
|
|
@@ -6,7 +6,7 @@ description: 'Start a Nano track session — master-orchestrator activated, trac
|
|
|
6
6
|
You must fully embody the Conductor master-orchestrator persona and follow all activation instructions exactly. NEVER break character until given an exit command.
|
|
7
7
|
|
|
8
8
|
<agent-activation CRITICAL="TRUE">
|
|
9
|
-
1. LOAD the FULL agent file from {project-root}/
|
|
9
|
+
1. LOAD the FULL agent file from {project-root}/_devo-bmad-custom/core/agents/master-orchestrator.md
|
|
10
10
|
2. READ its entire contents
|
|
11
11
|
3. EXECUTE every critical_action in order (load all sidecar files)
|
|
12
12
|
4. TRACK IS PRE-SELECTED: **Nano** — skip complexity triage entirely
|
|
@@ -6,7 +6,7 @@ description: 'Start a Review Track session — master-orchestrator activated, tr
|
|
|
6
6
|
You must fully embody the Conductor master-orchestrator persona and follow all activation instructions exactly. NEVER break character until given an exit command.
|
|
7
7
|
|
|
8
8
|
<agent-activation CRITICAL="TRUE">
|
|
9
|
-
1. LOAD the FULL agent file from {project-root}/
|
|
9
|
+
1. LOAD the FULL agent file from {project-root}/_devo-bmad-custom/core/agents/master-orchestrator.md
|
|
10
10
|
2. READ its entire contents
|
|
11
11
|
3. EXECUTE every critical_action in order (load all sidecar files)
|
|
12
12
|
4. TRACK IS PRE-SELECTED: **Review Track [RV]** — skip all triage, go directly to target definition
|
|
@@ -6,7 +6,7 @@ description: 'Start a Small track session — master-orchestrator activated, tra
|
|
|
6
6
|
You must fully embody the Conductor master-orchestrator persona and follow all activation instructions exactly. NEVER break character until given an exit command.
|
|
7
7
|
|
|
8
8
|
<agent-activation CRITICAL="TRUE">
|
|
9
|
-
1. LOAD the FULL agent file from {project-root}/
|
|
9
|
+
1. LOAD the FULL agent file from {project-root}/_devo-bmad-custom/core/agents/master-orchestrator.md
|
|
10
10
|
2. READ its entire contents
|
|
11
11
|
3. EXECUTE every critical_action in order (load all sidecar files)
|
|
12
12
|
4. TRACK IS PRE-SELECTED: **Small** — skip complexity triage entirely
|
|
@@ -43,7 +43,7 @@ You must fully embody this agent's persona and follow all activation instruction
|
|
|
43
43
|
<r>STAYS IN SPLIT PANE for full cycle — do not close until verdict is emitted and Master Orchestrator receives it.</r>
|
|
44
44
|
<r>Sub-agents run in-process (same conversation context injection). They are spawned, execute their task, report findings, and close. You collect their output.</r>
|
|
45
45
|
<r>On 🔴 escalation after 1 fix attempt: HALT and present the escalation block. Do not auto-proceed past persistent 🔴 findings.</r>
|
|
46
|
-
<r>TRACKING: Format tasks, bugs, decisions using structured trackingStatus YAML per {project-root}/{project-root}/
|
|
46
|
+
<r>TRACKING: Format tasks, bugs, decisions using structured trackingStatus YAML per {project-root}/{project-root}/_devo-bmad-custom/_memory/skills/{tracking-skill}/SKILL.md.</r>
|
|
47
47
|
<r>SAVE session_id to _bmad-output/parallel/{session_id}/agent-sessions.md before closing.</r>
|
|
48
48
|
<r>SIDECAR tracks: cycle_log (list of sub-agents invoked, finding counts per sub, final verdict), session_id, artifact_reviewed, track_context.</r>
|
|
49
49
|
</rules>
|
|
@@ -9,11 +9,11 @@ You must fully embody this agent's persona and follow all activation instruction
|
|
|
9
9
|
<agent id="master-orchestrator.agent.yaml" name="Conductor" title="Master Orchestrator" icon="🎯" module="core" hasSidecar="true" sidecarFile="_bmad/_memory/master-orchestrator-sidecar/instructions.md" capabilities="workflow orchestration, triage, track routing, review gate coordination, session management, parallel agent coordination">
|
|
10
10
|
<activation>
|
|
11
11
|
<step n="1">Load persona from this current agent file (already in context)</step>
|
|
12
|
-
<step n="2" critical="true">Load {project-root}/
|
|
13
|
-
<step n="3" critical="true">Load sidecar: {project-root}/
|
|
12
|
+
<step n="2" critical="true">Load {project-root}/_devo-bmad-custom/core/config.yaml. Store: {user_name}, {communication_language}, {output_folder}. HALT if config fails to load.</step>
|
|
13
|
+
<step n="3" critical="true">Load sidecar: {project-root}/_devo-bmad-custom/_memory/master-orchestrator-sidecar/instructions.md. This file contains all routing rules, triage logic, track definitions, and protocol specifications. HALT if not found.</step>
|
|
14
14
|
<step n="4">Load supporting sidecar files: memories.md, triage-history.md, docs-index.md from the same sidecar directory.</step>
|
|
15
15
|
<step n="5">Run Bootstrap Sequence as defined in instructions.md (silently, before greeting).</step>
|
|
16
|
-
<step n="6">SKILLS DETECTION (MANDATORY): Scan {project-root}/.agents/skills/ and {project-root}/
|
|
16
|
+
<step n="6">SKILLS DETECTION (MANDATORY): Scan {project-root}/.agents/skills/ and {project-root}/_devo-bmad-custom/_memory/skills/ for all SKILL.md files.</step>
|
|
17
17
|
<step n="7">Display greeting per instructions.md Greeting Script (Branch A, B, or C based on session state).</step>
|
|
18
18
|
<step n="8">STOP and WAIT for user input — do NOT execute menu items automatically.</step>
|
|
19
19
|
<step n="9">On user input: Number → menu item[n] | Text → substring match | [NT] → new task triage | [RS] → resume session | Other commands → per instructions.md routing table.</step>
|
|
@@ -1,34 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
#
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
#
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
tm_slate='#306075'
|
|
28
|
-
tm_crimson='#783a3c'
|
|
29
|
-
tm_purple='#5c3c78'
|
|
30
|
-
tm_rust='#784828'
|
|
31
|
-
tm_gold='#685820'
|
|
32
|
-
|
|
33
|
-
# Pill text
|
|
34
|
-
tm_pill_text='#d8ddf0'
|
|
1
|
+
set -g @thm_rosewater "#f2d5cf"
|
|
2
|
+
set -g @thm_flamingo "#eebebe"
|
|
3
|
+
set -g @thm_pink "#f4b8e4"
|
|
4
|
+
set -g @thm_mauve "#ca9ee6"
|
|
5
|
+
set -g @thm_red "#e78284"
|
|
6
|
+
set -g @thm_maroon "#ea999c"
|
|
7
|
+
set -g @thm_peach "#ef9f76"
|
|
8
|
+
set -g @thm_yellow "#e5c890"
|
|
9
|
+
set -g @thm_green "#a6d189"
|
|
10
|
+
set -g @thm_teal "#81c8be"
|
|
11
|
+
set -g @thm_sky "#99d1db"
|
|
12
|
+
set -g @thm_sapphire "#85c1dc"
|
|
13
|
+
set -g @thm_blue "#8caaee"
|
|
14
|
+
set -g @thm_lavender "#babbf1"
|
|
15
|
+
set -g @thm_text "#c6d0f5"
|
|
16
|
+
set -g @thm_subtext1 "#b5bfe2"
|
|
17
|
+
set -g @thm_subtext0 "#a5adce"
|
|
18
|
+
set -g @thm_overlay2 "#949cbb"
|
|
19
|
+
set -g @thm_overlay1 "#838ba7"
|
|
20
|
+
set -g @thm_overlay0 "#737994"
|
|
21
|
+
set -g @thm_surface2 "#626880"
|
|
22
|
+
set -g @thm_surface1 "#51576d"
|
|
23
|
+
set -g @thm_surface0 "#414559"
|
|
24
|
+
set -g @thm_base "#303446"
|
|
25
|
+
set -g @thm_mantle "#292c3c"
|
|
26
|
+
set -g @thm_crust "#232634"
|
|
@@ -45,6 +45,17 @@ if [ -n "$IMAGE_TYPE" ]; then
|
|
|
45
45
|
|| mv "$RAWFILE" "$PNGFILE"
|
|
46
46
|
fi
|
|
47
47
|
|
|
48
|
+
# WSLg Wayland bridge sometimes lists image types but writes 0 bytes.
|
|
49
|
+
# Fall back to PowerShell (Windows clipboard API) when wl-paste produces empty output.
|
|
50
|
+
if [ ! -s "$PNGFILE" ]; then
|
|
51
|
+
WINPATH=$(wslpath -w "$PNGFILE" 2>/dev/null)
|
|
52
|
+
powershell.exe -NoProfile -Command "
|
|
53
|
+
Add-Type -AssemblyName System.Windows.Forms
|
|
54
|
+
\$img = [System.Windows.Forms.Clipboard]::GetImage()
|
|
55
|
+
if (\$img -ne \$null) { \$img.Save('$WINPATH') }
|
|
56
|
+
" 2>/dev/null
|
|
57
|
+
fi
|
|
58
|
+
|
|
48
59
|
[ -s "$PNGFILE" ] || exit 1
|
|
49
60
|
send_path "@$PNGFILE"
|
|
50
61
|
/usr/bin/wl-copy --type image/png < "$PNGFILE" 2>/dev/null || true
|