test(docs): add command-count sync test; fix ARCHITECTURE.md drift (#2257) (#2259)

Add tests/command-count-sync.test.cjs which programmatically counts
.md files in commands/gsd/ and compares against the two count
occurrences in docs/ARCHITECTURE.md ("Total commands: N" prose line and
"# N slash commands" directory-tree comment). Counts are extracted from
the doc at runtime — never hardcoded — so future drift is caught
immediately in CI regardless of whether the doc or the filesystem moves.

Fix the current drift: ARCHITECTURE.md said 69 commands; the actual
committed count is 73. Both occurrences updated.

Closes #2257

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Tom Boucher
2026-04-15 08:58:13 -04:00
committed by GitHub
parent 62b5278040
commit c051e71851
2 changed files with 95 additions and 2 deletions

View File

@@ -113,7 +113,7 @@ User-facing entry points. Each file contains YAML frontmatter (name, description
- **Copilot:** Slash commands (`/gsd-command-name`)
- **Antigravity:** Skills
**Total commands:** 69
**Total commands:** 73
### Workflows (`get-shit-done/workflows/*.md`)
@@ -409,7 +409,7 @@ UI-SPEC.md (per phase) ───────────────────
```
~/.claude/ # Claude Code (global install)
├── commands/gsd/*.md # 69 slash commands
├── commands/gsd/*.md # 73 slash commands
├── get-shit-done/
│ ├── bin/gsd-tools.cjs # CLI utility
│ ├── bin/lib/*.cjs # 19 domain modules

View File

@@ -0,0 +1,93 @@
/**
* Regression test: command count in docs/ARCHITECTURE.md must match
* the actual number of .md files in commands/gsd/.
*
* Counts are extracted from the doc programmatically — never hardcoded
* in this test — so any future drift (adding a command without updating
* the doc, or vice-versa) is caught immediately.
*
* Related: issue #2257
*/
'use strict';
const { describe, test } = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const ROOT = path.resolve(__dirname, '..');
const COMMANDS_DIR = path.join(ROOT, 'commands', 'gsd');
const ARCH_MD = path.join(ROOT, 'docs', 'ARCHITECTURE.md');
/**
* Count .md files that actually live in commands/gsd/.
* Does not recurse into subdirectories.
*/
function actualCommandCount() {
return fs
.readdirSync(COMMANDS_DIR)
.filter((f) => f.endsWith('.md'))
.length;
}
/**
* Extract the integer from the "**Total commands:** N" prose line in
* ARCHITECTURE.md. Returns null if the pattern is not found.
*/
function docProseCount(content) {
const m = content.match(/\*\*Total commands:\*\*\s+(\d+)/);
return m ? parseInt(m[1], 10) : null;
}
/**
* Extract the integer from the directory-tree comment line:
* ├── commands/gsd/*.md # N slash commands
* Returns null if the pattern is not found.
*/
function docTreeCount(content) {
const m = content.match(/commands\/gsd\/\*\.md[^\n]*#\s*(\d+)\s+slash commands/);
return m ? parseInt(m[1], 10) : null;
}
describe('ARCHITECTURE.md command count sync', () => {
const archContent = fs.readFileSync(ARCH_MD, 'utf8');
const actual = actualCommandCount();
test('docs/ARCHITECTURE.md contains a "Total commands:" prose count', () => {
const count = docProseCount(archContent);
assert.notEqual(count, null, 'Expected "**Total commands:** N" line not found in ARCHITECTURE.md');
});
test('docs/ARCHITECTURE.md contains a directory-tree slash-command count', () => {
const count = docTreeCount(archContent);
assert.notEqual(count, null, 'Expected "# N slash commands" tree comment not found in ARCHITECTURE.md');
});
test('"Total commands:" prose count matches actual commands/gsd/ file count', () => {
const prose = docProseCount(archContent);
assert.equal(
prose,
actual,
`ARCHITECTURE.md "Total commands:" says ${prose} but commands/gsd/ has ${actual} .md files — update the doc`,
);
});
test('directory-tree slash-command count matches actual commands/gsd/ file count', () => {
const tree = docTreeCount(archContent);
assert.equal(
tree,
actual,
`ARCHITECTURE.md directory tree says ${tree} slash commands but commands/gsd/ has ${actual} .md files — update the doc`,
);
});
test('"Total commands:" prose count and directory-tree count agree with each other', () => {
const prose = docProseCount(archContent);
const tree = docTreeCount(archContent);
assert.equal(
prose,
tree,
`ARCHITECTURE.md has two mismatched counts: "Total commands: ${prose}" vs tree "# ${tree} slash commands"`,
);
});
});