Files
msd-core/tests/mvp-phase-command.test.cjs
Jakub Zych a9a7a328e6 refactor: hard-fork GSD -> MSD (Make Software Done)
Mechanical rename produced by scripts/msd-rename.cjs: gsd/Gsd/GSD -> msd/Msd/MSD
across contents and paths, upstream package/repo coordinates -> @golem15/msd-core
and golem15com/msd-core. Deep links into upstream history, sibling upstream
packages, the GSD-2 import feature, CHANGELOG.md and .changeset/ are kept as-is.

Hand edits on top: MSD block-letter banner and logos, LICENSE copyright line,
package/plugin identity, regenerated lockfile, install-tree fixtures, derived
registries and benchmark baseline; migration checksum baseline re-locked
(MSD keeps its own install state, so no install had applied the old sums);
sort-order and regex-escaped expectations in tests adjusted.
2026-10-06 01:47:40 +02:00

93 lines
3.2 KiB
JavaScript

/**
* /msd mvp-phase command — frontmatter contract test
* Verifies the command exists, has required frontmatter fields, and
* points to the workflow file.
*/
const { test, describe } = require('node:test');
const assert = require('node:assert/strict');
const fs = require('fs');
const path = require('path');
const CMD = path.join(__dirname, '..', 'commands', 'msd', 'mvp-phase.md');
function parseCommandContract(content) {
const lines = content.split(/\r?\n/);
const firstFence = lines.indexOf('---');
const secondFence = lines.indexOf('---', firstFence + 1);
assert.ok(firstFence === 0 && secondFence > 0, 'command must start with YAML frontmatter');
const frontmatterLines = lines.slice(firstFence + 1, secondFence);
const frontmatter = {};
const allowedTools = [];
let inAllowedTools = false;
for (const raw of frontmatterLines) {
const line = raw.trim();
if (line === 'allowed-tools:') {
inAllowedTools = true;
continue;
}
if (inAllowedTools) {
if (line.startsWith('- ')) {
allowedTools.push(line.slice(2).trim());
continue;
}
inAllowedTools = false;
}
const sep = line.indexOf(':');
if (sep > 0) {
frontmatter[line.slice(0, sep).trim()] = line.slice(sep + 1).trim();
}
}
const executionContextStart = lines.findIndex(line => line.trim() === '<execution_context>');
const executionContextEnd = lines.findIndex(
(line, idx) => idx > executionContextStart && line.trim() === '</execution_context>'
);
const executionContextRefs = executionContextStart >= 0 && executionContextEnd > executionContextStart
? lines.slice(executionContextStart + 1, executionContextEnd).map(line => line.trim()).filter(Boolean)
: [];
return {
name: frontmatter.name || '',
argumentHint: frontmatter['argument-hint'] || '',
executionContextRefs,
allowedTools,
};
}
describe('/msd mvp-phase command frontmatter', () => {
test('command file exists', () => {
assert.ok(fs.existsSync(CMD), `${CMD} must exist`);
});
test('frontmatter declares correct command name', () => {
const contract = parseCommandContract(fs.readFileSync(CMD, 'utf-8'));
assert.equal(contract.name, 'msd:mvp-phase');
});
test('argument-hint mentions phase number', () => {
const contract = parseCommandContract(fs.readFileSync(CMD, 'utf-8'));
assert.ok(contract.argumentHint.toLowerCase().includes('phase'));
});
test('allowed-tools includes Read, Write, Bash, (Task or Agent), AskUserQuestion', () => {
const contract = parseCommandContract(fs.readFileSync(CMD, 'utf-8'));
for (const tool of ['Read', 'Write', 'Bash', 'AskUserQuestion']) {
assert.ok(contract.allowedTools.includes(tool), `allowed-tools must include ${tool}`);
}
assert.ok(
contract.allowedTools.includes('Task') || contract.allowedTools.includes('Agent'),
'allowed-tools must include Task or Agent for delegation'
);
});
test('execution_context points to the workflow file', () => {
const contract = parseCommandContract(fs.readFileSync(CMD, 'utf-8'));
assert.ok(
contract.executionContextRefs.some(ref => ref.endsWith('workflows/mvp-phase.md')),
'execution_context must include workflows/mvp-phase.md'
);
});
});