-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
feat: extend Layer 1 file-ref validator to scan CSV workflow-file references #1573
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
bmadcode
merged 8 commits into
bmad-code-org:main
from
arcaven:feat/csv-file-ref-validation
Feb 8, 2026
Merged
Changes from 3 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
1cc2fd1
feat: extend validate-file-refs.js to scan CSV workflow-file references
arcaven ac156fc
fix: include test:refs in aggregate test script
arcaven e2acf1e
Merge branch 'main' into feat/csv-file-ref-validation
arcaven c7cdaa7
fix: address review feedback on CSV validator extension
arcaven 3f5d059
refactor: collect-then-print to eliminate confusing !VERBOSE pattern
arcaven 1ac25c2
feat: promote extensionless unresolved paths from silent skip to [UNR…
arcaven 8c4058b
Merge branch 'main' into feat/csv-file-ref-validation
alexeyv 1f97b1b
Merge branch 'main' into feat/csv-file-ref-validation
bmadcode File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| module,phase,name,workflow-file,description | ||
| bmm,anytime,Document,,Analyze project | ||
| bmm,1-analysis,Brainstorm,,Brainstorm ideas |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| module,phase,name,workflow-file,description |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| name,code,description,agent | ||
| brainstorm,BSP,"Generate ideas",analyst | ||
| party,PM,"Multi-agent",facilitator |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| module,phase,name,workflow-file,description | ||
| bmm,anytime,Template Var,{output_folder}/something.md,Has unresolvable template var | ||
| bmm,anytime,Normal Ref,_bmad/core/tasks/help.md,Normal resolvable ref |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| module,phase,name,code,sequence,workflow-file,command,required,agent,options,description,output-location,outputs, | ||
| bmm,anytime,Document Project,DP,,_bmad/bmm/workflows/document-project/workflow.yaml,bmad-bmm-document-project,false,analyst,Create Mode,"Analyze project",project-knowledge,*, | ||
| bmm,1-analysis,Brainstorm Project,BP,10,_bmad/core/workflows/brainstorming/workflow.md,bmad-brainstorming,false,analyst,data=template.md,"Brainstorming",planning_artifacts,"session", |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| module,phase,name,code,sequence,workflow-file,command,required,agent,options,description,output-location,outputs | ||
| core,anytime,Brainstorming,BSP,,_bmad/core/workflows/brainstorming/workflow.md,bmad-brainstorming,false,analyst,,"Generate ideas",{output_folder}/brainstorming.md, | ||
| core,anytime,Party Mode,PM,,_bmad/core/workflows/party-mode/workflow.md,bmad-party-mode,false,facilitator,,"Multi-agent discussion",, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| name,workflow-file,description | ||
| test,_bmad/core/tasks/help.md,A test entry |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,133 @@ | ||
| /** | ||
| * CSV File Reference Extraction Test Runner | ||
| * | ||
| * Tests extractCsvRefs() from validate-file-refs.js against fixtures. | ||
| * Verifies correct extraction of workflow-file references from CSV files. | ||
| * | ||
| * Usage: node test/test-file-refs-csv.js | ||
| * Exit codes: 0 = all tests pass, 1 = test failures | ||
| */ | ||
|
|
||
| const fs = require('node:fs'); | ||
| const path = require('node:path'); | ||
| const { extractCsvRefs } = require('../tools/validate-file-refs.js'); | ||
|
|
||
| // ANSI color codes | ||
| const colors = { | ||
| reset: '\u001B[0m', | ||
| green: '\u001B[32m', | ||
| red: '\u001B[31m', | ||
| cyan: '\u001B[36m', | ||
| dim: '\u001B[2m', | ||
| }; | ||
|
|
||
| const FIXTURES = path.join(__dirname, 'fixtures/file-refs-csv'); | ||
|
|
||
| let totalTests = 0; | ||
| let passedTests = 0; | ||
| const failures = []; | ||
|
|
||
| function test(name, fn) { | ||
| totalTests++; | ||
| try { | ||
| fn(); | ||
| passedTests++; | ||
| console.log(` ${colors.green}\u2713${colors.reset} ${name}`); | ||
| } catch (error) { | ||
| console.log(` ${colors.red}\u2717${colors.reset} ${name} ${colors.red}${error.message}${colors.reset}`); | ||
| failures.push({ name, message: error.message }); | ||
| } | ||
| } | ||
|
|
||
| function assert(condition, message) { | ||
| if (!condition) throw new Error(message); | ||
| } | ||
|
|
||
| function loadFixture(relativePath) { | ||
| const fullPath = path.join(FIXTURES, relativePath); | ||
| const content = fs.readFileSync(fullPath, 'utf-8'); | ||
| return { fullPath, content }; | ||
| } | ||
|
|
||
| // --- Valid fixtures --- | ||
|
|
||
| console.log(`\n${colors.cyan}CSV File Reference Extraction Tests${colors.reset}\n`); | ||
| console.log(`${colors.cyan}Valid fixtures${colors.reset}`); | ||
|
|
||
| test('bmm-style.csv: extracts workflow-file refs with trailing commas', () => { | ||
| const { fullPath, content } = loadFixture('valid/bmm-style.csv'); | ||
| const refs = extractCsvRefs(fullPath, content); | ||
| assert(refs.length === 2, `Expected 2 refs, got ${refs.length}`); | ||
| assert(refs[0].raw === '_bmad/bmm/workflows/document-project/workflow.yaml', `Wrong raw[0]: ${refs[0].raw}`); | ||
| assert(refs[1].raw === '_bmad/core/workflows/brainstorming/workflow.md', `Wrong raw[1]: ${refs[1].raw}`); | ||
| assert(refs[0].type === 'project-root', `Wrong type: ${refs[0].type}`); | ||
| assert(refs[0].line === 2, `Wrong line for row 0: ${refs[0].line}`); | ||
| assert(refs[1].line === 3, `Wrong line for row 1: ${refs[1].line}`); | ||
| assert(refs[0].file === fullPath, 'Wrong file path'); | ||
| }); | ||
|
|
||
| test('core-style.csv: extracts refs from core module-help format', () => { | ||
| const { fullPath, content } = loadFixture('valid/core-style.csv'); | ||
| const refs = extractCsvRefs(fullPath, content); | ||
| assert(refs.length === 2, `Expected 2 refs, got ${refs.length}`); | ||
| assert(refs[0].raw === '_bmad/core/workflows/brainstorming/workflow.md', `Wrong raw[0]: ${refs[0].raw}`); | ||
| assert(refs[1].raw === '_bmad/core/workflows/party-mode/workflow.md', `Wrong raw[1]: ${refs[1].raw}`); | ||
| }); | ||
|
|
||
| test('minimal.csv: extracts refs from minimal 3-column CSV', () => { | ||
| const { fullPath, content } = loadFixture('valid/minimal.csv'); | ||
| const refs = extractCsvRefs(fullPath, content); | ||
| assert(refs.length === 1, `Expected 1 ref, got ${refs.length}`); | ||
| assert(refs[0].raw === '_bmad/core/tasks/help.md', `Wrong raw: ${refs[0].raw}`); | ||
| assert(refs[0].line === 2, `Wrong line: ${refs[0].line}`); | ||
| }); | ||
|
|
||
| // --- Invalid fixtures --- | ||
|
|
||
| console.log(`\n${colors.cyan}Invalid fixtures (expect 0 refs)${colors.reset}`); | ||
|
|
||
| test('no-workflow-column.csv: returns 0 refs when workflow-file column missing', () => { | ||
| const { fullPath, content } = loadFixture('invalid/no-workflow-column.csv'); | ||
| const refs = extractCsvRefs(fullPath, content); | ||
| assert(refs.length === 0, `Expected 0 refs, got ${refs.length}`); | ||
| }); | ||
|
|
||
| test('empty-data.csv: returns 0 refs when CSV has header only', () => { | ||
| const { fullPath, content } = loadFixture('invalid/empty-data.csv'); | ||
| const refs = extractCsvRefs(fullPath, content); | ||
| assert(refs.length === 0, `Expected 0 refs, got ${refs.length}`); | ||
| }); | ||
|
|
||
| test('all-empty-workflow.csv: returns 0 refs when all workflow-file cells empty', () => { | ||
| const { fullPath, content } = loadFixture('invalid/all-empty-workflow.csv'); | ||
| const refs = extractCsvRefs(fullPath, content); | ||
| assert(refs.length === 0, `Expected 0 refs, got ${refs.length}`); | ||
| }); | ||
|
|
||
| test('unresolvable-vars.csv: filters out template variables, keeps normal refs', () => { | ||
| const { fullPath, content } = loadFixture('invalid/unresolvable-vars.csv'); | ||
| const refs = extractCsvRefs(fullPath, content); | ||
| assert(refs.length === 1, `Expected 1 ref, got ${refs.length}`); | ||
| assert(refs[0].raw === '_bmad/core/tasks/help.md', `Wrong raw: ${refs[0].raw}`); | ||
| }); | ||
|
|
||
| // --- Summary --- | ||
|
|
||
| console.log(`\n${colors.cyan}${'═'.repeat(55)}${colors.reset}`); | ||
| console.log(`${colors.cyan}Test Results:${colors.reset}`); | ||
| console.log(` Total: ${totalTests}`); | ||
| console.log(` Passed: ${colors.green}${passedTests}${colors.reset}`); | ||
| console.log(` Failed: ${passedTests === totalTests ? colors.green : colors.red}${totalTests - passedTests}${colors.reset}`); | ||
| console.log(`${colors.cyan}${'═'.repeat(55)}${colors.reset}\n`); | ||
|
|
||
| if (failures.length > 0) { | ||
| console.log(`${colors.red}FAILED TESTS:${colors.reset}\n`); | ||
| for (const failure of failures) { | ||
| console.log(`${colors.red}\u2717${colors.reset} ${failure.name}`); | ||
| console.log(` ${failure.message}\n`); | ||
| } | ||
| process.exit(1); | ||
| } | ||
|
|
||
| console.log(`${colors.green}All tests passed!${colors.reset}\n`); | ||
| process.exit(0); | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.