Compare commits

..

1 Commits

Author SHA1 Message Date
Alex Verkhovsky b717cfce05
Merge ca32c0aa65 into 93a1e1dc46 2026-03-21 01:38:24 -06:00
3 changed files with 32 additions and 5 deletions

View File

@ -40,7 +40,7 @@ If version control is available and the tree is dirty, create a local commit wit
- If `code` is not available (command fails), skip gracefully and list the file paths instead. - If `code` is not available (command fails), skip gracefully and list the file paths instead.
2. Display a summary in conversation output, including: 2. Display a summary in conversation output, including:
- The commit hash (if one was created). - The commit hash (if one was created).
- List of files changed with one-line descriptions. Use CWD-relative paths with `:line` notation (e.g., `src/path/file.ts:42`) for terminal clickability. No leading `/`. - List of files changed with one-line descriptions. Use CWD-relative paths (e.g., `src/path/file.ts`) for terminal clickability. No leading `/`.
- Review findings breakdown: patches applied, items deferred, items rejected. If all findings were rejected, say so. - Review findings breakdown: patches applied, items deferred, items rejected. If all findings were rejected, say so.
3. Offer to push and/or create a pull request. 3. Offer to push and/or create a pull request.

View File

@ -704,12 +704,21 @@ class ManifestGenerator {
continue; continue;
} }
// Check if this looks like a module (has agents directory or skill manifests) // Check if this looks like a module (has agents, workflows, or tasks directory)
const modulePath = path.join(bmadDir, entry.name); const modulePath = path.join(bmadDir, entry.name);
const hasAgents = await fs.pathExists(path.join(modulePath, 'agents')); const hasAgents = await fs.pathExists(path.join(modulePath, 'agents'));
const hasSkills = await this._hasSkillMdRecursive(modulePath); const hasWorkflows = await fs.pathExists(path.join(modulePath, 'workflows'));
const hasTasks = await fs.pathExists(path.join(modulePath, 'tasks'));
const hasTools = await fs.pathExists(path.join(modulePath, 'tools'));
if (hasAgents || hasSkills) { // Check for native-entrypoint-only modules: recursive scan for SKILL.md
let hasSkills = false;
if (!hasAgents && !hasWorkflows && !hasTasks && !hasTools) {
hasSkills = await this._hasSkillMdRecursive(modulePath);
}
// If it has any of these directories or skill manifests, it's likely a module
if (hasAgents || hasWorkflows || hasTasks || hasTools || hasSkills) {
modules.push(entry.name); modules.push(entry.name);
} }
} }

View File

@ -27,7 +27,7 @@ async function loadSkillManifest(dirPath) {
/** /**
* Get the canonicalId for a specific file from a loaded skill manifest. * Get the canonicalId for a specific file from a loaded skill manifest.
* @param {Object|null} manifest - Loaded manifest (from loadSkillManifest) * @param {Object|null} manifest - Loaded manifest (from loadSkillManifest)
* @param {string} filename - Source filename to look up (e.g., 'pm.md', 'help.md') * @param {string} filename - Source filename to look up (e.g., 'pm.md', 'help.md', 'pm.agent.yaml')
* @returns {string} canonicalId or empty string * @returns {string} canonicalId or empty string
*/ */
function getCanonicalId(manifest, filename) { function getCanonicalId(manifest, filename) {
@ -36,6 +36,12 @@ function getCanonicalId(manifest, filename) {
if (manifest.__single) return manifest.__single.canonicalId || ''; if (manifest.__single) return manifest.__single.canonicalId || '';
// Multi-entry: look up by filename directly // Multi-entry: look up by filename directly
if (manifest[filename]) return manifest[filename].canonicalId || ''; if (manifest[filename]) return manifest[filename].canonicalId || '';
// Fallback: try alternate extensions for compiled files
const baseName = filename.replace(/\.(md|xml)$/i, '');
const agentKey = `${baseName}.agent.yaml`;
if (manifest[agentKey]) return manifest[agentKey].canonicalId || '';
const xmlKey = `${baseName}.xml`;
if (manifest[xmlKey]) return manifest[xmlKey].canonicalId || '';
return ''; return '';
} }
@ -51,6 +57,12 @@ function getArtifactType(manifest, filename) {
if (manifest.__single) return manifest.__single.type || null; if (manifest.__single) return manifest.__single.type || null;
// Multi-entry: look up by filename directly // Multi-entry: look up by filename directly
if (manifest[filename]) return manifest[filename].type || null; if (manifest[filename]) return manifest[filename].type || null;
// Fallback: try alternate extensions for compiled files
const baseName = filename.replace(/\.(md|xml)$/i, '');
const agentKey = `${baseName}.agent.yaml`;
if (manifest[agentKey]) return manifest[agentKey].type || null;
const xmlKey = `${baseName}.xml`;
if (manifest[xmlKey]) return manifest[xmlKey].type || null;
return null; return null;
} }
@ -66,6 +78,12 @@ function getInstallToBmad(manifest, filename) {
if (manifest.__single) return manifest.__single.install_to_bmad !== false; if (manifest.__single) return manifest.__single.install_to_bmad !== false;
// Multi-entry: look up by filename directly // Multi-entry: look up by filename directly
if (manifest[filename]) return manifest[filename].install_to_bmad !== false; if (manifest[filename]) return manifest[filename].install_to_bmad !== false;
// Fallback: try alternate extensions for compiled files
const baseName = filename.replace(/\.(md|xml)$/i, '');
const agentKey = `${baseName}.agent.yaml`;
if (manifest[agentKey]) return manifest[agentKey].install_to_bmad !== false;
const xmlKey = `${baseName}.xml`;
if (manifest[xmlKey]) return manifest[xmlKey].install_to_bmad !== false;
return true; return true;
} }