Compare commits

...

4 Commits

Author SHA1 Message Date
Alex Verkhovsky 70b3dbd5e3
Merge branch 'main' into support-junie 2026-03-27 23:55:44 -06:00
Brian e0ea6a0500
fix: support skills/ folder as module source location (#2149)
The installer now finds module.yaml in both skills/ and src/ directories,
including one level deep in subfolders. Updates bmb module-definition to
skills/module.yaml to match its actual structure.
2026-03-28 00:33:10 -05:00
Alex Verkhovsky ac89e9a0be fix: disable ancestor_conflict_check for Junie platform
Junie does not traverse ancestor directories looking for skills,
so ancestor_conflict_check should be false.

Co-authored-by: Junie <junie@jetbrains.com>
2026-03-27 23:32:06 -06:00
Brian c91db0db4b
fix: revert bmb module-definition path to src/module.yaml (#2146)
bmad-builder reverted its skills/ directory back to src/ for installer
compatibility (bmad-code-org/bmad-builder#40). Update the external
modules manifest to match.
2026-03-27 08:46:18 -06:00
2 changed files with 35 additions and 4 deletions

View File

@ -107,7 +107,7 @@ platforms:
preferred: false preferred: false
installer: installer:
target_dir: .agents/skills target_dir: .agents/skills
ancestor_conflict_check: true ancestor_conflict_check: false
kilo: kilo:
name: "KiloCoder" name: "KiloCoder"

View File

@ -313,10 +313,41 @@ class ExternalModuleManager {
// The module-definition specifies the path to module.yaml relative to repo root // The module-definition specifies the path to module.yaml relative to repo root
// We need to return the directory containing module.yaml // We need to return the directory containing module.yaml
const moduleDefinitionPath = moduleInfo.moduleDefinition; // e.g., 'src/module.yaml' const moduleDefinitionPath = moduleInfo.moduleDefinition; // e.g., 'skills/module.yaml'
const moduleDir = path.dirname(path.join(cloneDir, moduleDefinitionPath)); const configuredPath = path.join(cloneDir, moduleDefinitionPath);
return moduleDir; if (await fs.pathExists(configuredPath)) {
return path.dirname(configuredPath);
}
// Fallback: search skills/ and src/ (root level and one level deep for subfolders)
for (const dir of ['skills', 'src']) {
const rootCandidate = path.join(cloneDir, dir, 'module.yaml');
if (await fs.pathExists(rootCandidate)) {
return path.dirname(rootCandidate);
}
const dirPath = path.join(cloneDir, dir);
if (await fs.pathExists(dirPath)) {
const entries = await fs.readdir(dirPath, { withFileTypes: true });
for (const entry of entries) {
if (entry.isDirectory()) {
const subCandidate = path.join(dirPath, entry.name, 'module.yaml');
if (await fs.pathExists(subCandidate)) {
return path.dirname(subCandidate);
}
}
}
}
}
// Check repo root as last fallback
const rootCandidate = path.join(cloneDir, 'module.yaml');
if (await fs.pathExists(rootCandidate)) {
return path.dirname(rootCandidate);
}
// Nothing found: return configured path (preserves old behavior for error messaging)
return path.dirname(configuredPath);
} }
} }