refactor(catalog): rename after/before to preceded-by/followed-by (#2360)
* refactor(catalog): rename after/before columns to preceded-by/followed-by The bare prepositions `after` and `before` had no subject anchor, leaving the dependency direction ambiguous: "X has Y in its `after` column" reads plausibly as either "Y comes after X" or "X comes after Y". An LLM catalog consumer just got the direction wrong because of this. `preceded-by` / `followed-by` are passive-voice participles whose grammar locks the subject (the skill in this row) and forces a single reading: "X is preceded by Y" can only mean Y comes first. Rename applied to: - module-help.csv headers (bmm-skills, core-skills) - bmad-help SKILL.md schema doc + descriptions - installer.js mergeModuleHelpCatalogs header string - plugin-resolver.js _buildSynthesizedHelpCsv header string - bmad-manifest.json keys (bmad-product-brief, bmad-prfaq) - distillate-format-reference.md example manifest The separate `required` column continues to carry hard-gate semantics; the renamed columns are pure soft sequencing hints, as already documented in bmad-help. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * style(installer): wrap long header strings per prettier * feat(installer): warn on non-canonical module-help.csv headers mergeModuleHelpCatalogs now compares each per-module file's header against the canonical schema and emits a one-shot prompts.log.warn per module on drift, naming both the expected and actual header. Data continues to load positionally so external modules built against the old after/before schema still install cleanly — the warning is the maintainer signal to rename their columns. Centralize the canonical header in modules/module-help-schema.js so the merger and the synthesizer (PluginResolver._buildSynthesizedHelpCsv) read the same source of truth; future column renames are one edit. Verified by installing all four bmad-org external modules (bmb, cis, gds, tea) — every one ships the legacy after/before header today and now fires an advisory warning while still merging cleanly into _bmad/_config/bmad-help.csv with the canonical column names. --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9debc165aa
commit
e36f219c81
|
|
@ -7,8 +7,8 @@
|
|||
"description": "Produces battle-tested PRFAQ document and optional LLM distillate for PRD input.",
|
||||
"supports-headless": true,
|
||||
"phase-name": "1-analysis",
|
||||
"after": ["brainstorming", "perform-research"],
|
||||
"before": ["create-prd"],
|
||||
"preceded-by": ["brainstorming", "perform-research"],
|
||||
"followed-by": ["create-prd"],
|
||||
"is-required": false,
|
||||
"output-location": "{planning_artifacts}"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
"description": "Produces executive product brief and optional LLM distillate for PRD input.",
|
||||
"supports-headless": true,
|
||||
"phase-name": "1-analysis",
|
||||
"after": ["brainstorming", "perform-research"],
|
||||
"before": ["create-prd"],
|
||||
"preceded-by": ["brainstorming", "perform-research"],
|
||||
"followed-by": ["create-prd"],
|
||||
"is-required": true,
|
||||
"output-location": "{planning_artifacts}"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
module,skill,display-name,menu-code,description,action,args,phase,after,before,required,output-location,outputs
|
||||
module,skill,display-name,menu-code,description,action,args,phase,preceded-by,followed-by,required,output-location,outputs
|
||||
BMad Method,_meta,,,,,,,,,false,https://docs.bmad-method.org/llms.txt,
|
||||
BMad Method,bmad-document-project,Document Project,DP,Analyze an existing project to produce useful documentation.,,,anytime,,,false,project-knowledge,*
|
||||
BMad Method,bmad-generate-project-context,Generate Project Context,GPC,Scan existing codebase to generate a lean LLM-optimized project-context.md. Essential for brownfield projects.,,,anytime,,,false,output_folder,project context
|
||||
|
|
|
|||
|
|
|
@ -139,7 +139,7 @@ parts: 1
|
|||
|
||||
## Solution Architecture
|
||||
- Plugins: skill bundles with Anthropic plugin standard as base format + bmad-manifest.json extending for BMAD-specific metadata (installer options, capabilities, help integration, phase ordering, dependencies)
|
||||
- Existing manifest example: `{"module-code":"bmm","replaces-skill":"bmad-create-product-brief","capabilities":[{"name":"create-brief","menu-code":"CB","supports-headless":true,"phase-name":"1-analysis","after":["brainstorming"],"before":["create-prd"],"is-required":true}]}`
|
||||
- Existing manifest example: `{"module-code":"bmm","replaces-skill":"bmad-create-product-brief","capabilities":[{"name":"create-brief","menu-code":"CB","supports-headless":true,"phase-name":"1-analysis","preceded-by":["brainstorming"],"followed-by":["create-prd"],"is-required":true}]}`
|
||||
- Vercel skills CLI handles platform translation; integration pattern (wrap/fork/call) is PRD decision
|
||||
- bmad-setup: global skill scanning installed bmad-manifest.json files, registering capabilities, configuring project settings; always included as base skill in every bundle (solves bootstrapping)
|
||||
- bmad-update: plugin update path without full reinstall; technical approach (diff/replace/preserve customizations) is PRD decision
|
||||
|
|
|
|||
|
|
@ -33,16 +33,16 @@ When this skill completes, the user should:
|
|||
The catalog uses this format:
|
||||
|
||||
```
|
||||
module,skill,display-name,menu-code,description,action,args,phase,after,before,required,output-location,outputs
|
||||
module,skill,display-name,menu-code,description,action,args,phase,preceded-by,followed-by,required,output-location,outputs
|
||||
```
|
||||
|
||||
**Phases** determine the high-level flow:
|
||||
- `anytime` — available regardless of workflow state
|
||||
- Numbered phases (`1-analysis`, `2-planning`, etc.) flow in order; naming varies by module
|
||||
|
||||
**Dependencies** determine ordering within and across phases:
|
||||
- `after` — skills that should ideally complete before this one
|
||||
- `before` — skills that should run after this one
|
||||
**Sequencing** determines recommended ordering within and across phases (these are soft suggestions, not hard gates — see `required` for gating):
|
||||
- `preceded-by` — skills that should ideally complete before this one
|
||||
- `followed-by` — skills that should ideally run after this one
|
||||
- Format: `skill-name` for single-action skills, `skill-name:action` for multi-action skills
|
||||
|
||||
**Required gates**:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
module,skill,display-name,menu-code,description,action,args,phase,after,before,required,output-location,outputs
|
||||
module,skill,display-name,menu-code,description,action,args,phase,preceded-by,followed-by,required,output-location,outputs
|
||||
Core,_meta,,,,,,,,,false,https://docs.bmad-method.org/llms.txt,
|
||||
Core,bmad-brainstorming,Brainstorming,BSP,Use early in ideation or when stuck generating ideas.,,,anytime,,,false,{output_folder}/brainstorming,brainstorming session
|
||||
Core,bmad-party-mode,Party Mode,PM,Orchestrate multi-agent discussions when you need multiple perspectives or want agents to collaborate.,,,anytime,,,false,,
|
||||
|
|
|
|||
|
|
|
@ -12,6 +12,7 @@ const { BMAD_FOLDER_NAME } = require('../ide/shared/path-utils');
|
|||
const { InstallPaths } = require('./install-paths');
|
||||
const { ExternalModuleManager } = require('../modules/external-manager');
|
||||
const { resolveModuleVersion } = require('../modules/version-resolver');
|
||||
const { MODULE_HELP_CSV_HEADER } = require('../modules/module-help-schema');
|
||||
|
||||
const { ExistingInstall } = require('./existing-install');
|
||||
const { warnPreNativeSkillsLegacy } = require('./legacy-warnings');
|
||||
|
|
@ -942,7 +943,7 @@ class Installer {
|
|||
*/
|
||||
async mergeModuleHelpCatalogs(bmadDir, _agentEntries = []) {
|
||||
const allRows = [];
|
||||
const headerRow = 'module,skill,display-name,menu-code,description,action,args,phase,after,before,required,output-location,outputs';
|
||||
const headerRow = MODULE_HELP_CSV_HEADER;
|
||||
const COLUMN_COUNT = 13;
|
||||
const PHASE_INDEX = 7;
|
||||
|
||||
|
|
@ -975,9 +976,19 @@ class Installer {
|
|||
const content = await fs.readFile(helpFilePath, 'utf8');
|
||||
const lines = content.split('\n').filter((line) => line.trim() && !line.startsWith('#'));
|
||||
|
||||
let headerWarned = false;
|
||||
for (const line of lines) {
|
||||
// Skip header row
|
||||
// Header row: warn on drift from canonical schema, then skip.
|
||||
// Data rows are loaded positionally regardless, so the warning
|
||||
// is advisory — the maintainer should rename their columns.
|
||||
if (line.startsWith('module,')) {
|
||||
if (!headerWarned && line.trim() !== headerRow) {
|
||||
await prompts.log.warn(
|
||||
` ${moduleName}/module-help.csv header does not match canonical schema. ` +
|
||||
`Expected: ${headerRow} | Found: ${line.trim()} | Data loaded positionally.`,
|
||||
);
|
||||
headerWarned = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* Canonical schema for per-module `module-help.csv` files.
|
||||
*
|
||||
* Both the merger (`Installer.mergeModuleHelpCatalogs`) and the synthesizer
|
||||
* (`PluginResolver._buildSynthesizedHelpCsv`) emit this exact header. The
|
||||
* merger compares each per-module file's header against this string and
|
||||
* warns on drift, so any rename here must be matched in external module
|
||||
* authors' CSVs (or accepted as a positional fall-through with a warning).
|
||||
*/
|
||||
const MODULE_HELP_CSV_HEADER =
|
||||
'module,skill,display-name,menu-code,description,action,args,phase,preceded-by,followed-by,required,output-location,outputs';
|
||||
|
||||
module.exports = { MODULE_HELP_CSV_HEADER };
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
const fs = require('../fs-native');
|
||||
const path = require('node:path');
|
||||
const yaml = require('yaml');
|
||||
const { MODULE_HELP_CSV_HEADER } = require('./module-help-schema');
|
||||
|
||||
/**
|
||||
* Resolves how to install a plugin from marketplace.json by analyzing
|
||||
|
|
@ -338,8 +339,7 @@ class PluginResolver {
|
|||
* @returns {string} CSV content
|
||||
*/
|
||||
_buildSynthesizedHelpCsv(moduleName, skillInfos) {
|
||||
const header = 'module,skill,display-name,menu-code,description,action,args,phase,after,before,required,output-location,outputs';
|
||||
const rows = [header];
|
||||
const rows = [MODULE_HELP_CSV_HEADER];
|
||||
|
||||
for (const info of skillInfos) {
|
||||
const displayName = this._formatDisplayName(info.name || info.dirName);
|
||||
|
|
|
|||
Loading…
Reference in New Issue