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:
@@ -4,40 +4,40 @@
|
||||
*
|
||||
* Enforces the human-facing command form in docs/ (#2903).
|
||||
*
|
||||
* `/gsd:<cmd>` (and bare `gsd:<cmd>`) is a SOURCE-AUTHORING token: install-time
|
||||
* `/msd:<cmd>` (and bare `msd:<cmd>`) is a SOURCE-AUTHORING token: install-time
|
||||
* converters (`transformContentToHyphen`, `convertSlashCommandsTo<Runtime>SkillMentions`)
|
||||
* rewrite it to `/gsd-<cmd>` per-runtime. It is correct in `commands/gsd/**`,
|
||||
* `gsd-core/workflows/**`, and `agents/**` — but docs are never passed through a
|
||||
* converter, so a doc telling a reader to type `/gsd:<cmd>` names a command no
|
||||
* runtime registers. The real user-facing form is `/gsd-<cmd>`.
|
||||
* rewrite it to `/msd-<cmd>` per-runtime. It is correct in `commands/msd/**`,
|
||||
* `msd-core/workflows/**`, and `agents/**` — but docs are never passed through a
|
||||
* converter, so a doc telling a reader to type `/msd:<cmd>` names a command no
|
||||
* runtime registers. The real user-facing form is `/msd-<cmd>`.
|
||||
*
|
||||
* This guard fails any `docs/**\/*.md` file that still contains `/gsd:<cmd>` or
|
||||
* bare `gsd:<cmd>` where `<cmd>` is a real command name (drawn from the
|
||||
* `commands/gsd/*.md` roster). It explicitly permits `/gsd-core:<cmd>` (the
|
||||
* Claude Code plugin namespace) and any `gsd:<token>` whose `<token>` is not a
|
||||
* real command (e.g. the `gsd:section` / `gsd:loop-host` workflow-fragment
|
||||
* This guard fails any `docs/**\/*.md` file that still contains `/msd:<cmd>` or
|
||||
* bare `msd:<cmd>` where `<cmd>` is a real command name (drawn from the
|
||||
* `commands/msd/*.md` roster). It explicitly permits `/msd-core:<cmd>` (the
|
||||
* Claude Code plugin namespace) and any `msd:<token>` whose `<token>` is not a
|
||||
* real command (e.g. the `msd:section` / `msd:loop-host` workflow-fragment
|
||||
* marker syntax documented in docs/reference/workflow-fragments.md, or
|
||||
* `gsd:command-name` used as a placeholder while explaining the Gemini CLI
|
||||
* `msd:command-name` used as a placeholder while explaining the Gemini CLI
|
||||
* colon-form convention).
|
||||
*
|
||||
* Exclusions (never checked):
|
||||
* - docs/adr/** (historical record)
|
||||
* - docs/RELEASE-NOTES-LEGACY.md (maintainer question still open)
|
||||
* - commands/gsd/**, gsd-core/workflows/**, agents/** — never touched by this
|
||||
* - commands/msd/**, msd-core/workflows/**, agents/** — never touched by this
|
||||
* guard at all; the colon form is correct there.
|
||||
*
|
||||
* Exemption — `name:` frontmatter key citations: source command files
|
||||
* (`commands/gsd/*.md`) carry the colon form in their `name:` YAML frontmatter
|
||||
* key (e.g. `name: gsd:next`). A doc that quotes that key verbatim — e.g.
|
||||
* `` `name: gsd:next` `` or `name: gsd:next` — is citing the real source file,
|
||||
* not telling a reader what to type. Rewriting that citation to `gsd-next`
|
||||
* would make the doc lie about the source it's quoting, so a `gsd:<cmd>` token
|
||||
* (`commands/msd/*.md`) carry the colon form in their `name:` YAML frontmatter
|
||||
* key (e.g. `name: msd:next`). A doc that quotes that key verbatim — e.g.
|
||||
* `` `name: msd:next` `` or `name: msd:next` — is citing the real source file,
|
||||
* not telling a reader what to type. Rewriting that citation to `msd-next`
|
||||
* would make the doc lie about the source it's quoting, so a `msd:<cmd>` token
|
||||
* immediately preceded by `name:` (optionally with a backtick/whitespace in
|
||||
* between) is permitted. This is narrow: it does not exempt `gsd:<cmd>`
|
||||
* anywhere else on the line or file, including the reader-facing `/gsd-<cmd>`
|
||||
* between) is permitted. This is narrow: it does not exempt `msd:<cmd>`
|
||||
* anywhere else on the line or file, including the reader-facing `/msd-<cmd>`
|
||||
* form that may appear later in the same sentence.
|
||||
*
|
||||
* Detection is case-insensitive (`/GSD:next`, `Gsd:Next`, etc. are all
|
||||
* Detection is case-insensitive (`/MSD:next`, `Msd:Next`, etc. are all
|
||||
* flagged) since the install-time converters and runtimes treat command names
|
||||
* case-insensitively in practice, and a doc typo in casing is still a lie
|
||||
* about the real command form.
|
||||
@@ -53,23 +53,23 @@ const path = require('path');
|
||||
const { ExitError, runMain } = require('./lib/cli-exit.cjs');
|
||||
|
||||
const SELF_PATH = path.resolve(__filename);
|
||||
// GSD_LINT_DOCS_COMMAND_FORM_REPO_ROOT is used by tests to redirect the guard to
|
||||
// MSD_LINT_DOCS_COMMAND_FORM_REPO_ROOT is used by tests to redirect the guard to
|
||||
// a temporary fixture git repo without touching the real working tree.
|
||||
const REPO_ROOT = process.env.GSD_LINT_DOCS_COMMAND_FORM_REPO_ROOT
|
||||
? path.resolve(process.env.GSD_LINT_DOCS_COMMAND_FORM_REPO_ROOT)
|
||||
const REPO_ROOT = process.env.MSD_LINT_DOCS_COMMAND_FORM_REPO_ROOT
|
||||
? path.resolve(process.env.MSD_LINT_DOCS_COMMAND_FORM_REPO_ROOT)
|
||||
: path.resolve(__dirname, '..');
|
||||
|
||||
const DOCS_PREFIX = 'docs/';
|
||||
const ADR_PREFIX = 'docs/adr/';
|
||||
const RELEASE_NOTES_LEGACY = 'docs/RELEASE-NOTES-LEGACY.md';
|
||||
const COMMANDS_DIR = path.join(REPO_ROOT, 'commands/gsd');
|
||||
const COMMANDS_DIR = path.join(REPO_ROOT, 'commands/msd');
|
||||
|
||||
// Matches `/gsd:<cmd>` and bare `gsd:<cmd>` (not part of `/gsd-core:<cmd>`,
|
||||
// which does not contain the substring `gsd:` — the hyphen breaks it).
|
||||
// Case-insensitive so `/GSD:next` / `Gsd:Next` are also caught.
|
||||
const COMMAND_FORM_RE = /(^|[^A-Za-z0-9_-])(\/)?gsd:([A-Za-z0-9_-]+)/gi;
|
||||
// Matches `/msd:<cmd>` and bare `msd:<cmd>` (not part of `/msd-core:<cmd>`,
|
||||
// which does not contain the substring `msd:` — the hyphen breaks it).
|
||||
// Case-insensitive so `/MSD:next` / `Msd:Next` are also caught.
|
||||
const COMMAND_FORM_RE = /(^|[^A-Za-z0-9_-])(\/)?msd:([A-Za-z0-9_-]+)/gi;
|
||||
|
||||
// A `gsd:<cmd>` token is exempt when it is a citation of a source file's
|
||||
// A `msd:<cmd>` token is exempt when it is a citation of a source file's
|
||||
// YAML `name:` frontmatter key — i.e. the text immediately before the match
|
||||
// (ending exactly where the match begins) is `name:` followed by optional
|
||||
// whitespace and/or a backtick. Only applies to the bare (non-`/`) form,
|
||||
@@ -81,7 +81,7 @@ function loadRoster() {
|
||||
try {
|
||||
entries = fs.readdirSync(COMMANDS_DIR);
|
||||
} catch (err) {
|
||||
throw new ExitError(1, 'ERROR lint-docs-command-form: could not read commands/gsd: ' + err.message);
|
||||
throw new ExitError(1, 'ERROR lint-docs-command-form: could not read commands/msd: ' + err.message);
|
||||
}
|
||||
return new Set(
|
||||
entries.filter((f) => f.endsWith('.md')).map((f) => f.replace(/\.md$/, '')),
|
||||
@@ -117,7 +117,7 @@ function scanContent(relPath, content, roster) {
|
||||
const preContext = line.slice(0, match.index + pre.length);
|
||||
if (NAME_KEY_CITATION_RE.test(preContext)) continue;
|
||||
}
|
||||
const matchedToken = (slash || '') + 'gsd:' + cmd;
|
||||
const matchedToken = (slash || '') + 'msd:' + cmd;
|
||||
violations.push({
|
||||
file: relPath,
|
||||
line: i + 1,
|
||||
@@ -179,7 +179,7 @@ function main() {
|
||||
' colon form names a command no runtime registers. Rewrite to the hyphen form\n',
|
||||
);
|
||||
process.stderr.write(
|
||||
' (`/gsd-<cmd>`), or `/gsd-core:<cmd>` if this is genuinely the Claude Code\n',
|
||||
' (`/msd-<cmd>`), or `/msd-core:<cmd>` if this is genuinely the Claude Code\n',
|
||||
);
|
||||
process.stderr.write(' plugin namespace.\n\n');
|
||||
return 1;
|
||||
|
||||
Reference in New Issue
Block a user