fix: preserve standalone module provenance in path-utils serializers
toDashName/toUnderscoreName collapsed core and standalone to the same filename, making parseDashName/parseUnderscoreName unable to round-trip standalone agents. Split the branches so standalone gets a distinct token (e.g., bmad-agent-standalone-fred.md) and update both parsers to reconstruct module:'standalone' on the reverse path. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
646b003b48
commit
517e253db4
|
|
@ -12,6 +12,7 @@
|
||||||
* - bmm/workflows/plan-project.md → bmad-bmm-plan-project.md
|
* - bmm/workflows/plan-project.md → bmad-bmm-plan-project.md
|
||||||
* - bmm/tasks/create-story.md → bmad-bmm-create-story.md
|
* - bmm/tasks/create-story.md → bmad-bmm-create-story.md
|
||||||
* - core/agents/brainstorming.md → bmad-agent-brainstorming.md (core agents skip module name)
|
* - core/agents/brainstorming.md → bmad-agent-brainstorming.md (core agents skip module name)
|
||||||
|
* - standalone/agents/fred.md → bmad-agent-standalone-fred.md
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Type segments - agents are included in naming, others are filtered out
|
// Type segments - agents are included in naming, others are filtered out
|
||||||
|
|
@ -26,8 +27,9 @@ const BMAD_FOLDER_NAME = '_bmad';
|
||||||
* Converts: 'bmm', 'agents', 'pm' → 'bmad-agent-bmm-pm.md'
|
* Converts: 'bmm', 'agents', 'pm' → 'bmad-agent-bmm-pm.md'
|
||||||
* Converts: 'bmm', 'workflows', 'correct-course' → 'bmad-bmm-correct-course.md'
|
* Converts: 'bmm', 'workflows', 'correct-course' → 'bmad-bmm-correct-course.md'
|
||||||
* Converts: 'core', 'agents', 'brainstorming' → 'bmad-agent-brainstorming.md' (core agents skip module name)
|
* Converts: 'core', 'agents', 'brainstorming' → 'bmad-agent-brainstorming.md' (core agents skip module name)
|
||||||
|
* Converts: 'standalone', 'agents', 'fred' → 'bmad-agent-standalone-fred.md'
|
||||||
*
|
*
|
||||||
* @param {string} module - Module name (e.g., 'bmm', 'core')
|
* @param {string} module - Module name (e.g., 'bmm', 'core', 'standalone')
|
||||||
* @param {string} type - Artifact type ('agents', 'workflows', 'tasks', 'tools')
|
* @param {string} type - Artifact type ('agents', 'workflows', 'tasks', 'tools')
|
||||||
* @param {string} name - Artifact name (e.g., 'pm', 'brainstorming')
|
* @param {string} name - Artifact name (e.g., 'pm', 'brainstorming')
|
||||||
* @returns {string} Flat filename like 'bmad-agent-bmm-pm.md' or 'bmad-bmm-correct-course.md'
|
* @returns {string} Flat filename like 'bmad-agent-bmm-pm.md' or 'bmad-bmm-correct-course.md'
|
||||||
|
|
@ -36,9 +38,13 @@ function toDashName(module, type, name) {
|
||||||
const isAgent = type === AGENT_SEGMENT;
|
const isAgent = type === AGENT_SEGMENT;
|
||||||
|
|
||||||
// For core module, skip the module name: use 'bmad-agent-name.md' instead of 'bmad-agent-core-name.md'
|
// For core module, skip the module name: use 'bmad-agent-name.md' instead of 'bmad-agent-core-name.md'
|
||||||
if (module === 'core' || module === 'standalone') {
|
if (module === 'core') {
|
||||||
return isAgent ? `bmad-agent-${name}.md` : `bmad-${name}.md`;
|
return isAgent ? `bmad-agent-${name}.md` : `bmad-${name}.md`;
|
||||||
}
|
}
|
||||||
|
// For standalone module, include 'standalone' in the name
|
||||||
|
if (module === 'standalone') {
|
||||||
|
return isAgent ? `bmad-agent-standalone-${name}.md` : `bmad-standalone-${name}.md`;
|
||||||
|
}
|
||||||
|
|
||||||
// Module artifacts: bmad-module-name.md or bmad-agent-module-name.md
|
// Module artifacts: bmad-module-name.md or bmad-agent-module-name.md
|
||||||
// eslint-disable-next-line unicorn/prefer-string-replace-all -- regex replace is intentional here
|
// eslint-disable-next-line unicorn/prefer-string-replace-all -- regex replace is intentional here
|
||||||
|
|
@ -110,6 +116,8 @@ function isDashFormat(filename) {
|
||||||
* Parses: 'bmad-bmm-correct-course.md' → { prefix: 'bmad', module: 'bmm', type: 'workflows', name: 'correct-course' }
|
* Parses: 'bmad-bmm-correct-course.md' → { prefix: 'bmad', module: 'bmm', type: 'workflows', name: 'correct-course' }
|
||||||
* Parses: 'bmad-agent-brainstorming.md' → { prefix: 'bmad', module: 'core', type: 'agents', name: 'brainstorming' } (core agents)
|
* Parses: 'bmad-agent-brainstorming.md' → { prefix: 'bmad', module: 'core', type: 'agents', name: 'brainstorming' } (core agents)
|
||||||
* Parses: 'bmad-brainstorming.md' → { prefix: 'bmad', module: 'core', type: 'workflows', name: 'brainstorming' } (core workflows)
|
* Parses: 'bmad-brainstorming.md' → { prefix: 'bmad', module: 'core', type: 'workflows', name: 'brainstorming' } (core workflows)
|
||||||
|
* Parses: 'bmad-agent-standalone-fred.md' → { prefix: 'bmad', module: 'standalone', type: 'agents', name: 'fred' }
|
||||||
|
* Parses: 'bmad-standalone-foo.md' → { prefix: 'bmad', module: 'standalone', type: 'workflows', name: 'foo' }
|
||||||
*
|
*
|
||||||
* @param {string} filename - Dash-formatted filename
|
* @param {string} filename - Dash-formatted filename
|
||||||
* @returns {Object|null} Parsed parts or null if invalid format
|
* @returns {Object|null} Parsed parts or null if invalid format
|
||||||
|
|
@ -127,7 +135,16 @@ function parseDashName(filename) {
|
||||||
|
|
||||||
if (isAgent) {
|
if (isAgent) {
|
||||||
// This is an agent file
|
// This is an agent file
|
||||||
// Format: bmad-agent-name (core) or bmad-agent-module-name
|
// Format: bmad-agent-name (core) or bmad-agent-standalone-name or bmad-agent-module-name
|
||||||
|
if (parts.length >= 4 && parts[2] === 'standalone') {
|
||||||
|
// Standalone agent: bmad-agent-standalone-name
|
||||||
|
return {
|
||||||
|
prefix: parts[0],
|
||||||
|
module: 'standalone',
|
||||||
|
type: 'agents',
|
||||||
|
name: parts.slice(3).join('-'),
|
||||||
|
};
|
||||||
|
}
|
||||||
if (parts.length === 3) {
|
if (parts.length === 3) {
|
||||||
// Core agent: bmad-agent-name
|
// Core agent: bmad-agent-name
|
||||||
return {
|
return {
|
||||||
|
|
@ -158,6 +175,16 @@ function parseDashName(filename) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for standalone non-agent: bmad-standalone-name
|
||||||
|
if (parts[1] === 'standalone') {
|
||||||
|
return {
|
||||||
|
prefix: parts[0],
|
||||||
|
module: 'standalone',
|
||||||
|
type: 'workflows', // Default to workflows for non-agent standalone items
|
||||||
|
name: parts.slice(2).join('-'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Otherwise, it's a module workflow/tool/task (bmad-module-name)
|
// Otherwise, it's a module workflow/tool/task (bmad-module-name)
|
||||||
return {
|
return {
|
||||||
prefix: parts[0],
|
prefix: parts[0],
|
||||||
|
|
@ -177,9 +204,12 @@ function parseDashName(filename) {
|
||||||
*/
|
*/
|
||||||
function toUnderscoreName(module, type, name) {
|
function toUnderscoreName(module, type, name) {
|
||||||
const isAgent = type === AGENT_SEGMENT;
|
const isAgent = type === AGENT_SEGMENT;
|
||||||
if (module === 'core' || module === 'standalone') {
|
if (module === 'core') {
|
||||||
return isAgent ? `bmad_agent_${name}.md` : `bmad_${name}.md`;
|
return isAgent ? `bmad_agent_${name}.md` : `bmad_${name}.md`;
|
||||||
}
|
}
|
||||||
|
if (module === 'standalone') {
|
||||||
|
return isAgent ? `bmad_agent_standalone_${name}.md` : `bmad_standalone_${name}.md`;
|
||||||
|
}
|
||||||
return isAgent ? `bmad_${module}_agent_${name}.md` : `bmad_${module}_${name}.md`;
|
return isAgent ? `bmad_${module}_agent_${name}.md` : `bmad_${module}_${name}.md`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -231,6 +261,15 @@ function parseUnderscoreName(filename) {
|
||||||
|
|
||||||
if (agentIndex !== -1) {
|
if (agentIndex !== -1) {
|
||||||
if (agentIndex === 1) {
|
if (agentIndex === 1) {
|
||||||
|
// bmad_agent_... - check for standalone
|
||||||
|
if (parts.length >= 4 && parts[2] === 'standalone') {
|
||||||
|
return {
|
||||||
|
prefix: parts[0],
|
||||||
|
module: 'standalone',
|
||||||
|
type: 'agents',
|
||||||
|
name: parts.slice(3).join('_'),
|
||||||
|
};
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
prefix: parts[0],
|
prefix: parts[0],
|
||||||
module: 'core',
|
module: 'core',
|
||||||
|
|
@ -256,6 +295,16 @@ function parseUnderscoreName(filename) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for standalone non-agent: bmad_standalone_name
|
||||||
|
if (parts[1] === 'standalone') {
|
||||||
|
return {
|
||||||
|
prefix: parts[0],
|
||||||
|
module: 'standalone',
|
||||||
|
type: 'workflows',
|
||||||
|
name: parts.slice(2).join('_'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
prefix: parts[0],
|
prefix: parts[0],
|
||||||
module: parts[1],
|
module: parts[1],
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue