Revert "feat(install): clarify orchestrator custom install path"
This reverts commit e82ea499d4.
This commit is contained in:
parent
e82ea499d4
commit
a906e52c0b
|
|
@ -2,9 +2,11 @@
|
||||||
# Committed to the repo — applies to every developer on the project.
|
# Committed to the repo — applies to every developer on the project.
|
||||||
# Tables deep-merge over base config; keyed entries merge by key.
|
# Tables deep-merge over base config; keyed entries merge by key.
|
||||||
|
|
||||||
# NOTE: Do not declare bmad-orchestrator here to "enable" Copilot agent generation.
|
# Orchestrator agent — enable in custom installs
|
||||||
# Copilot Custom Agents files are generated from installed skill sources
|
[agents.bmad-orchestrator]
|
||||||
# (skill-manifest + skill customize.toml [agent]), not from _bmad/custom overrides.
|
name = "Orchestrator"
|
||||||
# Keep orchestrator source-of-truth in:
|
title = "BMAD Orchestrator"
|
||||||
# - src/bmm-skills/module.yaml
|
icon = "🧭"
|
||||||
# - src/bmm-skills/4-implementation/bmad-orchestrator/customize.toml
|
team = "software-development"
|
||||||
|
module = "bmm"
|
||||||
|
description = "Routes natural-language intent to the right BMAD skill or named agent, verifies lightweight prerequisites, and suggests the next step without forcing the user to memorize commands."
|
||||||
|
|
|
||||||
|
|
@ -105,24 +105,6 @@ Multiple sources can be comma-separated:
|
||||||
--custom-source /path/one,https://github.com/org/repo,/path/two
|
--custom-source /path/one,https://github.com/org/repo,/path/two
|
||||||
```
|
```
|
||||||
|
|
||||||
### Fork BMAD with bmad-orchestrator in BMM
|
|
||||||
|
|
||||||
If your fork ships `bmad-orchestrator` inside `src/bmm-skills`, install from your fork as a custom source and include `bmm` in module selection.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npx bmad-method install \
|
|
||||||
--directory . \
|
|
||||||
--modules bmm \
|
|
||||||
--custom-source https://github.com/your-org/your-bmad-fork \
|
|
||||||
--tools github-copilot \
|
|
||||||
--yes
|
|
||||||
```
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
|
|
||||||
- `bmad-orchestrator` must exist as a native BMM skill source with a valid `[agent]` block in `customize.toml`.
|
|
||||||
- Copilot Custom Agents generation depends on the installer version consuming your fork. If your installer build predates the current agent-discovery behavior, the skill may install correctly while the Copilot agent pointer is not generated yet.
|
|
||||||
|
|
||||||
## How Module Discovery Works
|
## How Module Discovery Works
|
||||||
|
|
||||||
The installer uses two modes to find installable modules in a source:
|
The installer uses two modes to find installable modules in a source:
|
||||||
|
|
|
||||||
|
|
@ -596,7 +596,6 @@ async function runTests() {
|
||||||
'"bmad-master","bmad-master","Workflow with no customize.toml — should NOT appear in Copilot agents picker","core","_bmad/core/bmad-master/SKILL.md"',
|
'"bmad-master","bmad-master","Workflow with no customize.toml — should NOT appear in Copilot agents picker","core","_bmad/core/bmad-master/SKILL.md"',
|
||||||
'"bmad-agent-fixture","bmad-agent-fixture","Persona agent — customize.toml has [agent], SHOULD appear","core","_bmad/core/bmad-agent-fixture/SKILL.md"',
|
'"bmad-agent-fixture","bmad-agent-fixture","Persona agent — customize.toml has [agent], SHOULD appear","core","_bmad/core/bmad-agent-fixture/SKILL.md"',
|
||||||
'"bmad-tea","bmad-tea","Non-conventional id but [agent] in customize.toml — SHOULD appear","core","_bmad/core/bmad-tea/SKILL.md"',
|
'"bmad-tea","bmad-tea","Non-conventional id but [agent] in customize.toml — SHOULD appear","core","_bmad/core/bmad-tea/SKILL.md"',
|
||||||
'"bmad-orchestrator","bmad-orchestrator","BMM orchestrator persona with [agent] in customize.toml — SHOULD appear","bmm","_bmad/bmm/4-implementation/bmad-orchestrator/SKILL.md"',
|
|
||||||
'"bmad-agent-builder","bmad-agent-builder","Skill-builder workflow — id contains -agent- but customize.toml has [workflow] — should NOT appear","core","_bmad/core/bmad-agent-builder/SKILL.md"',
|
'"bmad-agent-builder","bmad-agent-builder","Skill-builder workflow — id contains -agent- but customize.toml has [workflow] — should NOT appear","core","_bmad/core/bmad-agent-builder/SKILL.md"',
|
||||||
'"bmad-help","bmad-help","Meta-help skill — no customize.toml; SHOULD NOT appear in agents picker (toml-driven filter)","core","_bmad/core/bmad-help/SKILL.md"',
|
'"bmad-help","bmad-help","Meta-help skill — no customize.toml; SHOULD NOT appear in agents picker (toml-driven filter)","core","_bmad/core/bmad-help/SKILL.md"',
|
||||||
'',
|
'',
|
||||||
|
|
@ -628,15 +627,6 @@ async function runTests() {
|
||||||
path.join(installedBmadDir17, 'core', 'bmad-tea', 'customize.toml'),
|
path.join(installedBmadDir17, 'core', 'bmad-tea', 'customize.toml'),
|
||||||
['[agent]', 'name = "Murat"', 'title = "Test Architect"', ''].join('\n'),
|
['[agent]', 'name = "Murat"', 'title = "Test Architect"', ''].join('\n'),
|
||||||
);
|
);
|
||||||
await fs.ensureDir(path.join(installedBmadDir17, 'bmm', '4-implementation', 'bmad-orchestrator'));
|
|
||||||
await fs.writeFile(
|
|
||||||
path.join(installedBmadDir17, 'bmm', '4-implementation', 'bmad-orchestrator', 'SKILL.md'),
|
|
||||||
['---', 'name: bmad-orchestrator', 'description: fixture for bmad-orchestrator', '---', '', 'Body of bmad-orchestrator.'].join('\n'),
|
|
||||||
);
|
|
||||||
await fs.writeFile(
|
|
||||||
path.join(installedBmadDir17, 'bmm', '4-implementation', 'bmad-orchestrator', 'customize.toml'),
|
|
||||||
['[agent]', 'name = "Orchestrator"', 'title = "BMAD Orchestrator"', ''].join('\n'),
|
|
||||||
);
|
|
||||||
// [workflow] customize.toml for the meta-skill — its id contains `-agent-`
|
// [workflow] customize.toml for the meta-skill — its id contains `-agent-`
|
||||||
// but it is NOT a persona (mirrors bmad-agent-builder in production).
|
// but it is NOT a persona (mirrors bmad-agent-builder in production).
|
||||||
await fs.writeFile(
|
await fs.writeFile(
|
||||||
|
|
@ -687,7 +677,6 @@ async function runTests() {
|
||||||
const agentsDir17 = path.join(tempProjectDir17, '.github', 'agents');
|
const agentsDir17 = path.join(tempProjectDir17, '.github', 'agents');
|
||||||
const agentFileForPersona17 = path.join(agentsDir17, 'bmad-agent-fixture.agent.md');
|
const agentFileForPersona17 = path.join(agentsDir17, 'bmad-agent-fixture.agent.md');
|
||||||
const agentFileForTea17 = path.join(agentsDir17, 'bmad-tea.agent.md');
|
const agentFileForTea17 = path.join(agentsDir17, 'bmad-tea.agent.md');
|
||||||
const agentFileForOrchestrator17 = path.join(agentsDir17, 'bmad-orchestrator.agent.md');
|
|
||||||
const agentFileForWorkflow17 = path.join(agentsDir17, 'bmad-master.agent.md');
|
const agentFileForWorkflow17 = path.join(agentsDir17, 'bmad-master.agent.md');
|
||||||
const agentFileForMetaSkill17 = path.join(agentsDir17, 'bmad-agent-builder.agent.md');
|
const agentFileForMetaSkill17 = path.join(agentsDir17, 'bmad-agent-builder.agent.md');
|
||||||
const agentFileForBmadHelp17 = path.join(agentsDir17, 'bmad-help.agent.md');
|
const agentFileForBmadHelp17 = path.join(agentsDir17, 'bmad-help.agent.md');
|
||||||
|
|
@ -697,10 +686,6 @@ async function runTests() {
|
||||||
'Persona agent ([agent] in customize.toml) gets a .agent.md file in .github/agents/',
|
'Persona agent ([agent] in customize.toml) gets a .agent.md file in .github/agents/',
|
||||||
);
|
);
|
||||||
assert(await fs.pathExists(agentFileForTea17), 'Non-conventional id with [agent] in customize.toml is included (no allowlist needed)');
|
assert(await fs.pathExists(agentFileForTea17), 'Non-conventional id with [agent] in customize.toml is included (no allowlist needed)');
|
||||||
assert(
|
|
||||||
await fs.pathExists(agentFileForOrchestrator17),
|
|
||||||
'BMM orchestrator with [agent] customize.toml is included in Copilot agents picker',
|
|
||||||
);
|
|
||||||
assert(!(await fs.pathExists(agentFileForWorkflow17)), 'Workflow skill (no customize.toml) is FILTERED OUT of .github/agents/');
|
assert(!(await fs.pathExists(agentFileForWorkflow17)), 'Workflow skill (no customize.toml) is FILTERED OUT of .github/agents/');
|
||||||
assert(
|
assert(
|
||||||
!(await fs.pathExists(agentFileForBmadHelp17)),
|
!(await fs.pathExists(agentFileForBmadHelp17)),
|
||||||
|
|
@ -1331,8 +1316,8 @@ async function runTests() {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
assert(false, 'Pi native skills test succeeds', error.message);
|
assert(false, 'Pi native skills test succeeds', error.message);
|
||||||
} finally {
|
} finally {
|
||||||
if (tempProjectDir28) await fs.remove(tempProjectDir28).catch(() => { });
|
if (tempProjectDir28) await fs.remove(tempProjectDir28).catch(() => {});
|
||||||
if (installedBmadDir28) await fs.remove(path.dirname(installedBmadDir28)).catch(() => { });
|
if (installedBmadDir28) await fs.remove(path.dirname(installedBmadDir28)).catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('');
|
console.log('');
|
||||||
|
|
@ -1479,7 +1464,7 @@ async function runTests() {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
assert(false, 'Unified skill scanner test succeeds', error.message);
|
assert(false, 'Unified skill scanner test succeeds', error.message);
|
||||||
} finally {
|
} finally {
|
||||||
if (tempFixture29) await fs.remove(tempFixture29).catch(() => { });
|
if (tempFixture29) await fs.remove(tempFixture29).catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('');
|
console.log('');
|
||||||
|
|
@ -1546,7 +1531,7 @@ async function runTests() {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
assert(false, 'parseSkillMd validation test succeeds', error.message);
|
assert(false, 'parseSkillMd validation test succeeds', error.message);
|
||||||
} finally {
|
} finally {
|
||||||
if (tempFixture30) await fs.remove(tempFixture30).catch(() => { });
|
if (tempFixture30) await fs.remove(tempFixture30).catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('');
|
console.log('');
|
||||||
|
|
@ -1583,8 +1568,8 @@ async function runTests() {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
assert(false, 'Skill-format unique count test succeeds', error.message);
|
assert(false, 'Skill-format unique count test succeeds', error.message);
|
||||||
} finally {
|
} finally {
|
||||||
if (collisionProjectDir) await fs.remove(collisionProjectDir).catch(() => { });
|
if (collisionProjectDir) await fs.remove(collisionProjectDir).catch(() => {});
|
||||||
if (collisionFixtureRoot) await fs.remove(collisionFixtureRoot).catch(() => { });
|
if (collisionFixtureRoot) await fs.remove(collisionFixtureRoot).catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('');
|
console.log('');
|
||||||
|
|
@ -1674,8 +1659,8 @@ async function runTests() {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
assert(false, 'Ona native skills test succeeds', error.message);
|
assert(false, 'Ona native skills test succeeds', error.message);
|
||||||
} finally {
|
} finally {
|
||||||
if (tempProjectDir32) await fs.remove(tempProjectDir32).catch(() => { });
|
if (tempProjectDir32) await fs.remove(tempProjectDir32).catch(() => {});
|
||||||
if (installedBmadDir32) await fs.remove(path.dirname(installedBmadDir32)).catch(() => { });
|
if (installedBmadDir32) await fs.remove(path.dirname(installedBmadDir32)).catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('');
|
console.log('');
|
||||||
|
|
@ -2120,7 +2105,7 @@ async function runTests() {
|
||||||
assert(teamContent.includes('Installer-managed. Regenerated on every install'), 'config.toml has installer-managed header');
|
assert(teamContent.includes('Installer-managed. Regenerated on every install'), 'config.toml has installer-managed header');
|
||||||
assert(userContent.includes('Holds install answers scoped to YOU personally.'), 'config.user.toml header clarifies user scope');
|
assert(userContent.includes('Holds install answers scoped to YOU personally.'), 'config.user.toml header clarifies user scope');
|
||||||
} finally {
|
} finally {
|
||||||
await fs.remove(tempBmadDir35).catch(() => { });
|
await fs.remove(tempBmadDir35).catch(() => {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2156,7 +2141,7 @@ async function runTests() {
|
||||||
const preservedContent = await fs.readFile(userStub, 'utf8');
|
const preservedContent = await fs.readFile(userStub, 'utf8');
|
||||||
assert(preservedContent === userEdit, 'ensureCustomConfigStubs does not overwrite user-edited custom/config.user.toml');
|
assert(preservedContent === userEdit, 'ensureCustomConfigStubs does not overwrite user-edited custom/config.user.toml');
|
||||||
} finally {
|
} finally {
|
||||||
await fs.remove(tempBmadDir36).catch(() => { });
|
await fs.remove(tempBmadDir36).catch(() => {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2222,7 +2207,7 @@ async function runTests() {
|
||||||
assert(maryMatches.length === 1, 'bmad-agent-analyst emitted exactly once (fresh wins; stale not duplicated)');
|
assert(maryMatches.length === 1, 'bmad-agent-analyst emitted exactly once (fresh wins; stale not duplicated)');
|
||||||
assert(!teamContent.includes('Stale Mary'), 'Stale name from prior config.toml is discarded when fresh module.yaml is read');
|
assert(!teamContent.includes('Stale Mary'), 'Stale name from prior config.toml is discarded when fresh module.yaml is read');
|
||||||
} finally {
|
} finally {
|
||||||
await fs.remove(tempBmadDir37).catch(() => { });
|
await fs.remove(tempBmadDir37).catch(() => {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2320,8 +2305,8 @@ async function runTests() {
|
||||||
} else {
|
} else {
|
||||||
process.env.BMAD_EXTERNAL_MODULES_CACHE = priorCacheEnv;
|
process.env.BMAD_EXTERNAL_MODULES_CACHE = priorCacheEnv;
|
||||||
}
|
}
|
||||||
await fs.remove(tempCacheDir38).catch(() => { });
|
await fs.remove(tempCacheDir38).catch(() => {});
|
||||||
await fs.remove(tempBmadDir38).catch(() => { });
|
await fs.remove(tempBmadDir38).catch(() => {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2367,7 +2352,7 @@ async function runTests() {
|
||||||
} else {
|
} else {
|
||||||
process.env.BMAD_EXTERNAL_MODULES_CACHE = priorCacheEnv39;
|
process.env.BMAD_EXTERNAL_MODULES_CACHE = priorCacheEnv39;
|
||||||
}
|
}
|
||||||
await fs.remove(tempCacheDir39).catch(() => { });
|
await fs.remove(tempCacheDir39).catch(() => {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2399,8 +2384,8 @@ async function runTests() {
|
||||||
} else {
|
} else {
|
||||||
process.env.BMAD_EXTERNAL_MODULES_CACHE = priorCacheEnv39;
|
process.env.BMAD_EXTERNAL_MODULES_CACHE = priorCacheEnv39;
|
||||||
}
|
}
|
||||||
await fs.remove(tempRepo39).catch(() => { });
|
await fs.remove(tempRepo39).catch(() => {});
|
||||||
await fs.remove(tempCacheDir39).catch(() => { });
|
await fs.remove(tempCacheDir39).catch(() => {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2443,8 +2428,8 @@ async function runTests() {
|
||||||
} else {
|
} else {
|
||||||
process.env.BMAD_EXTERNAL_MODULES_CACHE = priorCacheEnv39;
|
process.env.BMAD_EXTERNAL_MODULES_CACHE = priorCacheEnv39;
|
||||||
}
|
}
|
||||||
await fs.remove(tempRepo39).catch(() => { });
|
await fs.remove(tempRepo39).catch(() => {});
|
||||||
await fs.remove(tempCacheDir39).catch(() => { });
|
await fs.remove(tempCacheDir39).catch(() => {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2478,8 +2463,8 @@ async function runTests() {
|
||||||
} else {
|
} else {
|
||||||
process.env.BMAD_EXTERNAL_MODULES_CACHE = priorCacheEnv39;
|
process.env.BMAD_EXTERNAL_MODULES_CACHE = priorCacheEnv39;
|
||||||
}
|
}
|
||||||
await fs.remove(tempHost39).catch(() => { });
|
await fs.remove(tempHost39).catch(() => {});
|
||||||
await fs.remove(tempCacheDir39).catch(() => { });
|
await fs.remove(tempCacheDir39).catch(() => {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2539,8 +2524,8 @@ async function runTests() {
|
||||||
} else {
|
} else {
|
||||||
process.env.BMAD_EXTERNAL_MODULES_CACHE = priorCacheEnv39;
|
process.env.BMAD_EXTERNAL_MODULES_CACHE = priorCacheEnv39;
|
||||||
}
|
}
|
||||||
await fs.remove(tempCacheDir39).catch(() => { });
|
await fs.remove(tempCacheDir39).catch(() => {});
|
||||||
await fs.remove(tempBmadDir39).catch(() => { });
|
await fs.remove(tempBmadDir39).catch(() => {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2682,7 +2667,7 @@ async function runTests() {
|
||||||
prompts.log.warn = async (message) => {
|
prompts.log.warn = async (message) => {
|
||||||
warnings39.push(message);
|
warnings39.push(message);
|
||||||
};
|
};
|
||||||
prompts.log.message = async () => { };
|
prompts.log.message = async () => {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await ui._selectOfficialModules(
|
await ui._selectOfficialModules(
|
||||||
|
|
@ -2780,14 +2765,14 @@ async function runTests() {
|
||||||
return ['core'];
|
return ['core'];
|
||||||
};
|
};
|
||||||
prompts.spinner = async () => ({
|
prompts.spinner = async () => ({
|
||||||
start() { },
|
start() {},
|
||||||
stop() { },
|
stop() {},
|
||||||
error() { },
|
error() {},
|
||||||
});
|
});
|
||||||
prompts.log.warn = async (message) => {
|
prompts.log.warn = async (message) => {
|
||||||
warnings39.push(message);
|
warnings39.push(message);
|
||||||
};
|
};
|
||||||
prompts.log.message = async () => { };
|
prompts.log.message = async () => {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await ui._selectOfficialModules(new Set(), new Map(), { global: null, nextSet: new Set(), pins: new Map(), warnings: [] });
|
await ui._selectOfficialModules(new Set(), new Map(), { global: null, nextSet: new Set(), pins: new Map(), warnings: [] });
|
||||||
|
|
@ -2813,7 +2798,7 @@ async function runTests() {
|
||||||
} else {
|
} else {
|
||||||
process.env.BMAD_EXTERNAL_MODULES_CACHE = priorCacheEnv39;
|
process.env.BMAD_EXTERNAL_MODULES_CACHE = priorCacheEnv39;
|
||||||
}
|
}
|
||||||
await fs.remove(tempCacheDir39).catch(() => { });
|
await fs.remove(tempCacheDir39).catch(() => {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2871,8 +2856,8 @@ async function runTests() {
|
||||||
// fixture above keeps bmad in a separate temp dir, so test 41 below
|
// fixture above keeps bmad in a separate temp dir, so test 41 below
|
||||||
// exercises the in-project layout instead.)
|
// exercises the in-project layout instead.)
|
||||||
|
|
||||||
await fs.remove(tempProjectDir40).catch(() => { });
|
await fs.remove(tempProjectDir40).catch(() => {});
|
||||||
await fs.remove(path.dirname(installedBmadDir40)).catch(() => { });
|
await fs.remove(path.dirname(installedBmadDir40)).catch(() => {});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(`${colors.red}Test Suite 40 setup failed: ${error.message}${colors.reset}`);
|
console.log(`${colors.red}Test Suite 40 setup failed: ${error.message}${colors.reset}`);
|
||||||
failed++;
|
failed++;
|
||||||
|
|
@ -2919,8 +2904,8 @@ async function runTests() {
|
||||||
const entries40b = await fs.readdir(sharedDir40b);
|
const entries40b = await fs.readdir(sharedDir40b);
|
||||||
assert(entries40b.includes('bmad-master'), 'Shared dir is populated by gemini after cursor failure');
|
assert(entries40b.includes('bmad-master'), 'Shared dir is populated by gemini after cursor failure');
|
||||||
|
|
||||||
await fs.remove(tempProjectDir40b).catch(() => { });
|
await fs.remove(tempProjectDir40b).catch(() => {});
|
||||||
await fs.remove(path.dirname(installedBmadDir40b)).catch(() => { });
|
await fs.remove(path.dirname(installedBmadDir40b)).catch(() => {});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(`${colors.red}Test Suite 40b setup failed: ${error.message}${colors.reset}`);
|
console.log(`${colors.red}Test Suite 40b setup failed: ${error.message}${colors.reset}`);
|
||||||
failed++;
|
failed++;
|
||||||
|
|
@ -3023,11 +3008,11 @@ async function runTests() {
|
||||||
assert(sharedSurvivesC, 'shared .agents/skills/ survives partial uninstall (peer still uses it)');
|
assert(sharedSurvivesC, 'shared .agents/skills/ survives partial uninstall (peer still uses it)');
|
||||||
assert(!(await fs.pathExists(cmdC)), 'opencode command pointer is removed on partial uninstall even when peer remains');
|
assert(!(await fs.pathExists(cmdC)), 'opencode command pointer is removed on partial uninstall even when peer remains');
|
||||||
|
|
||||||
await fs.remove(projA).catch(() => { });
|
await fs.remove(projA).catch(() => {});
|
||||||
await fs.remove(path.dirname(bmadA)).catch(() => { });
|
await fs.remove(path.dirname(bmadA)).catch(() => {});
|
||||||
await fs.remove(projB).catch(() => { });
|
await fs.remove(projB).catch(() => {});
|
||||||
await fs.remove(path.dirname(bmadB)).catch(() => { });
|
await fs.remove(path.dirname(bmadB)).catch(() => {});
|
||||||
await fs.remove(projC).catch(() => { });
|
await fs.remove(projC).catch(() => {});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(`${colors.red}Test Suite 40c setup failed: ${error.message}${colors.reset}`);
|
console.log(`${colors.red}Test Suite 40c setup failed: ${error.message}${colors.reset}`);
|
||||||
failed++;
|
failed++;
|
||||||
|
|
@ -3069,7 +3054,7 @@ async function runTests() {
|
||||||
const detected = await cursorHandler.detect(fixtureRoot41);
|
const detected = await cursorHandler.detect(fixtureRoot41);
|
||||||
assert(detected === true, 'detect() recognizes non-bmad-prefixed skill as BMAD-owned via skill-manifest.csv');
|
assert(detected === true, 'detect() recognizes non-bmad-prefixed skill as BMAD-owned via skill-manifest.csv');
|
||||||
|
|
||||||
await fs.remove(fixtureRoot41).catch(() => { });
|
await fs.remove(fixtureRoot41).catch(() => {});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(`${colors.red}Test Suite 41 setup failed: ${error.message}${colors.reset}`);
|
console.log(`${colors.red}Test Suite 41 setup failed: ${error.message}${colors.reset}`);
|
||||||
failed++;
|
failed++;
|
||||||
|
|
@ -3270,9 +3255,9 @@ async function runTests() {
|
||||||
'scalar core gets replaced with {} and bmm.project_name still hoists in',
|
'scalar core gets replaced with {} and bmm.project_name still hoists in',
|
||||||
);
|
);
|
||||||
|
|
||||||
await fs.remove(fixtureRoot43).catch(() => { });
|
await fs.remove(fixtureRoot43).catch(() => {});
|
||||||
await fs.remove(fixtureRoot43b).catch(() => { });
|
await fs.remove(fixtureRoot43b).catch(() => {});
|
||||||
await fs.remove(fixtureRoot43c).catch(() => { });
|
await fs.remove(fixtureRoot43c).catch(() => {});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(`${colors.red}Test Suite 43 setup failed: ${error.message}${colors.reset}`);
|
console.log(`${colors.red}Test Suite 43 setup failed: ${error.message}${colors.reset}`);
|
||||||
console.log(error.stack);
|
console.log(error.stack);
|
||||||
|
|
@ -3438,7 +3423,7 @@ async function runTests() {
|
||||||
`applySetOverrides reports correct routing decisions (got: ${summary})`,
|
`applySetOverrides reports correct routing decisions (got: ${summary})`,
|
||||||
);
|
);
|
||||||
|
|
||||||
await fs.remove(tmp).catch(() => { });
|
await fs.remove(tmp).catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- applySetOverrides creates config.user.toml if missing -----------
|
// ---- applySetOverrides creates config.user.toml if missing -----------
|
||||||
|
|
@ -3458,7 +3443,7 @@ async function runTests() {
|
||||||
!(await fs.pathExists(path.join(bmadDir, 'config.user.toml'))),
|
!(await fs.pathExists(path.join(bmadDir, 'config.user.toml'))),
|
||||||
'applySetOverrides does not create config.user.toml unnecessarily',
|
'applySetOverrides does not create config.user.toml unnecessarily',
|
||||||
);
|
);
|
||||||
await fs.remove(tmp).catch(() => { });
|
await fs.remove(tmp).catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- applySetOverrides skips modules without per-module config.yaml --
|
// ---- applySetOverrides skips modules without per-module config.yaml --
|
||||||
|
|
@ -3476,7 +3461,7 @@ async function runTests() {
|
||||||
assert(!team.includes('[modules.bmm]'), 'applySetOverrides does NOT create section for uninstalled module');
|
assert(!team.includes('[modules.bmm]'), 'applySetOverrides does NOT create section for uninstalled module');
|
||||||
assert(team.includes('user_name = "Updated"'), 'applySetOverrides still applies overrides for installed modules');
|
assert(team.includes('user_name = "Updated"'), 'applySetOverrides still applies overrides for installed modules');
|
||||||
assert(applied.length === 1 && applied[0].module === 'core', 'applySetOverrides reports only the installed-module entries');
|
assert(applied.length === 1 && applied[0].module === 'core', 'applySetOverrides reports only the installed-module entries');
|
||||||
await fs.remove(tmp).catch(() => { });
|
await fs.remove(tmp).catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- applySetOverrides: empty/missing input is a no-op ---------------
|
// ---- applySetOverrides: empty/missing input is a no-op ---------------
|
||||||
|
|
@ -3491,7 +3476,7 @@ async function runTests() {
|
||||||
empty1.length === 0 && empty2.length === 0 && empty3.length === 0,
|
empty1.length === 0 && empty2.length === 0 && empty3.length === 0,
|
||||||
'applySetOverrides is a no-op for empty/null/undefined input',
|
'applySetOverrides is a no-op for empty/null/undefined input',
|
||||||
);
|
);
|
||||||
await fs.remove(tmp).catch(() => { });
|
await fs.remove(tmp).catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- discoverOfficialModuleYamls + formatOptionsList -----------------
|
// ---- discoverOfficialModuleYamls + formatOptionsList -----------------
|
||||||
|
|
@ -3525,7 +3510,7 @@ async function runTests() {
|
||||||
} else {
|
} else {
|
||||||
process.env.BMAD_EXTERNAL_MODULES_CACHE = priorCacheEnv44;
|
process.env.BMAD_EXTERNAL_MODULES_CACHE = priorCacheEnv44;
|
||||||
}
|
}
|
||||||
await fs.remove(tempCacheDir44).catch(() => { });
|
await fs.remove(tempCacheDir44).catch(() => {});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(`${colors.red}Test Suite 44 setup failed: ${error.message}${colors.reset}`);
|
console.log(`${colors.red}Test Suite 44 setup failed: ${error.message}${colors.reset}`);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue