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.
This commit is contained in:
@@ -2,8 +2,8 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* gen-loop-host-contract.cjs — generates gsd-core/bin/lib/loop-host-contract.cjs
|
||||
* from the <!-- gsd:loop-host ... --> blocks in the five step workflows.
|
||||
* gen-loop-host-contract.cjs — generates msd-core/bin/lib/loop-host-contract.cjs
|
||||
* from the <!-- msd:loop-host ... --> blocks in the five step workflows.
|
||||
*
|
||||
* Usage:
|
||||
* node scripts/gen-loop-host-contract.cjs # print to stdout
|
||||
@@ -20,12 +20,12 @@ const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const { ExitError, runMain } = require('./lib/cli-exit.cjs');
|
||||
const { escapeRegex: escapeRegExp } = require('../gsd-core/bin/lib/pattern.cjs');
|
||||
const { normalizeEol } = require('../gsd-core/bin/lib/text-lines.cjs');
|
||||
const { escapeRegex: escapeRegExp } = require('../msd-core/bin/lib/pattern.cjs');
|
||||
const { normalizeEol } = require('../msd-core/bin/lib/text-lines.cjs');
|
||||
|
||||
const ROOT = path.resolve(__dirname, '..');
|
||||
const WORKFLOWS_DIR = path.join(ROOT, 'gsd-core', 'workflows');
|
||||
const CONTRACT_PATH = path.join(ROOT, 'gsd-core', 'bin', 'lib', 'loop-host-contract.cjs');
|
||||
const WORKFLOWS_DIR = path.join(ROOT, 'msd-core', 'workflows');
|
||||
const CONTRACT_PATH = path.join(ROOT, 'msd-core', 'bin', 'lib', 'loop-host-contract.cjs');
|
||||
|
||||
// The five step workflows in pipeline order
|
||||
const STEP_WORKFLOWS = [
|
||||
@@ -69,13 +69,13 @@ const EXPECTED_POINTS_BY_STEP = {
|
||||
|
||||
// Role → agent-name mapping used for cross-check.
|
||||
// Each non-orchestrator role must correspond to an actual agent reference in
|
||||
// the workflow file (e.g. gsd-planner, gsd-executor, gsd-verifier, etc.).
|
||||
// the workflow file (e.g. msd-planner, msd-executor, msd-verifier, etc.).
|
||||
const ROLE_TO_AGENT = {
|
||||
researcher: 'gsd-phase-researcher',
|
||||
planner: 'gsd-planner',
|
||||
checker: 'gsd-plan-checker',
|
||||
executor: 'gsd-executor',
|
||||
verifier: 'gsd-verifier',
|
||||
researcher: 'msd-phase-researcher',
|
||||
planner: 'msd-planner',
|
||||
checker: 'msd-plan-checker',
|
||||
executor: 'msd-executor',
|
||||
verifier: 'msd-verifier',
|
||||
};
|
||||
|
||||
// #4740 — Role → family mapping. Three families: orchestration, planning,
|
||||
@@ -98,12 +98,12 @@ const EXPECTED_FAMILY_BY_STEP = {
|
||||
// ─── Parser ───────────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Parse a single <!-- gsd:loop-host ... --> block from file content.
|
||||
* Parse a single <!-- msd:loop-host ... --> block from file content.
|
||||
* Returns a plain object with keys: step, points[], agentRoles[], produces[], consumes[].
|
||||
* Throws a descriptive error if the block is malformed or missing.
|
||||
*
|
||||
* Block format (one key: value per line, comma-separated list values):
|
||||
* <!-- gsd:loop-host
|
||||
* <!-- msd:loop-host
|
||||
* step: plan
|
||||
* points: plan:pre, plan:post
|
||||
* agent-roles: researcher, planner, checker
|
||||
@@ -119,14 +119,14 @@ const EXPECTED_FAMILY_BY_STEP = {
|
||||
*/
|
||||
function parseLoopHostBlock(content, fileName) {
|
||||
// FIX 2: Detect ALL marker blocks — more than one is a hard error.
|
||||
const blockRe = /<!--\s*gsd:loop-host\s*([\s\S]*?)-->/g;
|
||||
const blockRe = /<!--\s*msd:loop-host\s*([\s\S]*?)-->/g;
|
||||
const allMatches = Array.from(content.matchAll(blockRe));
|
||||
if (allMatches.length === 0) {
|
||||
throw new Error(fileName + ': missing <!-- gsd:loop-host ... --> block');
|
||||
throw new Error(fileName + ': missing <!-- msd:loop-host ... --> block');
|
||||
}
|
||||
if (allMatches.length > 1) {
|
||||
throw new Error(
|
||||
fileName + ': expected exactly one gsd:loop-host marker block, found ' + allMatches.length,
|
||||
fileName + ': expected exactly one msd:loop-host marker block, found ' + allMatches.length,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ function parseLoopHostBlock(content, fileName) {
|
||||
}
|
||||
for (const key of RECOGNIZED_KEYS) {
|
||||
if (keyCounts[key] > 1) {
|
||||
throw new Error(fileName + ': duplicate key \'' + key + '\' in gsd:loop-host marker');
|
||||
throw new Error(fileName + ': duplicate key \'' + key + '\' in msd:loop-host marker');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ function parseLoopHostBlock(content, fileName) {
|
||||
return raw.split(',').map((s) => s.trim()).filter((s) => s.length > 0);
|
||||
}
|
||||
}
|
||||
throw new Error(fileName + ': gsd:loop-host block missing required field "' + key + '"');
|
||||
throw new Error(fileName + ': msd:loop-host block missing required field "' + key + '"');
|
||||
}
|
||||
|
||||
function parseScalar(key) {
|
||||
@@ -176,12 +176,12 @@ function parseLoopHostBlock(content, fileName) {
|
||||
const colonIdx = trimmed.indexOf(':');
|
||||
const val = trimmed.slice(colonIdx + 1).trim();
|
||||
if (val === '') {
|
||||
throw new Error(fileName + ': gsd:loop-host block field "' + key + '" must be a non-empty string');
|
||||
throw new Error(fileName + ': msd:loop-host block field "' + key + '" must be a non-empty string');
|
||||
}
|
||||
return val;
|
||||
}
|
||||
}
|
||||
throw new Error(fileName + ': gsd:loop-host block missing required field "' + key + '"');
|
||||
throw new Error(fileName + ': msd:loop-host block missing required field "' + key + '"');
|
||||
}
|
||||
|
||||
const step = parseScalar('step');
|
||||
@@ -191,10 +191,10 @@ function parseLoopHostBlock(content, fileName) {
|
||||
const consumes = parseField('consumes');
|
||||
|
||||
if (points.length === 0) {
|
||||
throw new Error(fileName + ': gsd:loop-host block "points" must have at least one value');
|
||||
throw new Error(fileName + ': msd:loop-host block "points" must have at least one value');
|
||||
}
|
||||
if (agentRoles.length === 0) {
|
||||
throw new Error(fileName + ': gsd:loop-host block "agent-roles" must have at least one value');
|
||||
throw new Error(fileName + ': msd:loop-host block "agent-roles" must have at least one value');
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -227,8 +227,8 @@ function crossCheckRoles(content, agentRoles, fileName) {
|
||||
);
|
||||
continue;
|
||||
}
|
||||
// FIX 3: Use word-boundary match so "gsd-plan-checker-v2" does NOT satisfy a required
|
||||
// "gsd-plan-checker". Treat '-' as part of the token: boundary = start/end of string or
|
||||
// FIX 3: Use word-boundary match so "msd-plan-checker-v2" does NOT satisfy a required
|
||||
// "msd-plan-checker". Treat '-' as part of the token: boundary = start/end of string or
|
||||
// a character that is neither \w nor '-'.
|
||||
// Note: this is a presence check (any reference in the file), not a spawn-site check —
|
||||
// a known limitation; spawn-site checks would require AST-level analysis.
|
||||
@@ -385,7 +385,7 @@ function buildContract(workflowsDir) {
|
||||
// Validate the declared step matches the expected step for this file
|
||||
if (entry.step !== step) {
|
||||
allErrors.push(
|
||||
file + ': gsd:loop-host block declares step "' + entry.step +
|
||||
file + ': msd:loop-host block declares step "' + entry.step +
|
||||
'" but expected "' + step + '"',
|
||||
);
|
||||
}
|
||||
@@ -488,7 +488,7 @@ function main() {
|
||||
|
||||
if (!fs.existsSync(CONTRACT_PATH)) {
|
||||
process.stderr.write(
|
||||
'gsd-core/bin/lib/loop-host-contract.cjs does not exist. Run:\n' +
|
||||
'msd-core/bin/lib/loop-host-contract.cjs does not exist. Run:\n' +
|
||||
' node scripts/gen-loop-host-contract.cjs --write\n',
|
||||
);
|
||||
throw new ExitError(1);
|
||||
@@ -498,13 +498,13 @@ function main() {
|
||||
// FIX 4: Compare full content (no generated-by stripping) so header drift is caught.
|
||||
if (normalizeEol(committed) !== normalizeEol(live)) {
|
||||
process.stderr.write(
|
||||
'gsd-core/bin/lib/loop-host-contract.cjs is stale. Run:\n' +
|
||||
'msd-core/bin/lib/loop-host-contract.cjs is stale. Run:\n' +
|
||||
' node scripts/gen-loop-host-contract.cjs --write\n',
|
||||
);
|
||||
throw new ExitError(1);
|
||||
}
|
||||
|
||||
process.stdout.write('gsd-core/bin/lib/loop-host-contract.cjs is up to date.\n');
|
||||
process.stdout.write('msd-core/bin/lib/loop-host-contract.cjs is up to date.\n');
|
||||
} else if (flag === '--write') {
|
||||
let contract;
|
||||
try {
|
||||
@@ -539,8 +539,8 @@ function main() {
|
||||
* a separate hardcoded list.
|
||||
*/
|
||||
const HOST_LOOP_FILES = STEP_WORKFLOWS.flatMap(({ file, auxiliaryHosts = [] }) => [
|
||||
'gsd-core/workflows/' + file,
|
||||
...auxiliaryHosts.map((host) => 'gsd-core/workflows/' + host.file),
|
||||
'msd-core/workflows/' + file,
|
||||
...auxiliaryHosts.map((host) => 'msd-core/workflows/' + host.file),
|
||||
]);
|
||||
|
||||
/**
|
||||
@@ -577,7 +577,7 @@ const HOOK_KINDS = ['contribution', 'step', 'gate'];
|
||||
* call site, up to the next call site or the region cap, judged LINE by line:
|
||||
*
|
||||
* - A deferral line (one carrying an `@`-included path to the generic
|
||||
* contract, e.g. `@gsd-core/references/loop-hook-dispatch.md`) that names a
|
||||
* contract, e.g. `@msd-core/references/loop-hook-dispatch.md`) that names a
|
||||
* kind (`kind == "step"`) covers that kind; a deferral line with no kind
|
||||
* discriminator ("apply each entry") covers every kind only when no role
|
||||
* target is required. With `expectedInto`, the same segment must explicitly
|
||||
|
||||
Reference in New Issue
Block a user