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:
240
src/init.cts
240
src/init.cts
@@ -42,7 +42,7 @@ import scanPhasePlans = require('./plan-scan.cjs');
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports -- plan-document.cjs is an export= CommonJS module
|
||||
import planDocument = require('./plan-document.cjs');
|
||||
import { stateExtractField } from './state-document.cjs';
|
||||
import { formatGsdSlash, resolveRuntime } from './runtime-slash.cjs';
|
||||
import { formatMsdSlash, resolveRuntime } from './runtime-slash.cjs';
|
||||
import { resolveReportedRuntime } from './host-runtime-detection.cjs';
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports -- commands.cjs is an export= CommonJS module
|
||||
import commandsMod = require('./commands.cjs');
|
||||
@@ -364,9 +364,9 @@ function withProjectRoot(cwd: string, result: Record<string, unknown>): Record<s
|
||||
}
|
||||
// #4455 follow-up (self-discovered): PROJECT.md is shared across a
|
||||
// project's own workstreams (never cloned per workstream) but DOES
|
||||
// respect the separate GSD_PROJECT multi-project namespace (#3749) — see
|
||||
// respect the separate MSD_PROJECT multi-project namespace (#3749) — see
|
||||
// cmdInitCompleteMilestone's projectPath comment for the full evidence.
|
||||
// `ws` explicitly nulled, `project` left to default from GSD_PROJECT.
|
||||
// `ws` explicitly nulled, `project` left to default from MSD_PROJECT.
|
||||
// Reading via the workstream-aware planningDir(cwd) meant every init.*
|
||||
// call's project_title silently vanished whenever a workstream was
|
||||
// active, since no PROJECT.md ever exists at the workstream path.
|
||||
@@ -455,16 +455,16 @@ function getInitGitState(cwd: string): GitState {
|
||||
}
|
||||
|
||||
// #2932 (Phase 5, ADR-1671): shipped, generated artifact — see
|
||||
// scripts/gen-section-manifest.cjs and gsd-core/workflows/section-manifest.json.
|
||||
// scripts/gen-section-manifest.cjs and msd-core/workflows/section-manifest.json.
|
||||
// Resolved the same way model-catalog.cts resolves model-catalog.json: relative
|
||||
// to the compiled module's own directory (gsd-core/bin/lib -> gsd-core/workflows),
|
||||
// with a GSD_SECTION_MANIFEST env override so tests can point at a temp fixture
|
||||
// to the compiled module's own directory (msd-core/bin/lib -> msd-core/workflows),
|
||||
// with a MSD_SECTION_MANIFEST env override so tests can point at a temp fixture
|
||||
// (missing/malformed-JSON degraded-path coverage) without mutating the shipped
|
||||
// artifact — the shipped file is a shared, concurrently-read resource across
|
||||
// parallel test runs and must never be moved/corrupted in place.
|
||||
const _sectionManifestCandidatePath = (): string =>
|
||||
process.env['GSD_SECTION_MANIFEST']
|
||||
? path.resolve(process.env['GSD_SECTION_MANIFEST'])
|
||||
process.env['MSD_SECTION_MANIFEST']
|
||||
? path.resolve(process.env['MSD_SECTION_MANIFEST'])
|
||||
: path.resolve(__dirname, '..', '..', 'workflows', 'section-manifest.json');
|
||||
|
||||
/** A manifest entry as shipped on disk: {@link sectionManifest.SelectableSection} plus the `read` step-file path. */
|
||||
@@ -635,7 +635,7 @@ function readConfigJsonValue(cwd: string, keyPath: readonly string[]): unknown {
|
||||
/**
|
||||
* `state:fallow-enabled` ground truth (#2994): resolves `code-review.md`'s
|
||||
* `structural_pre_pass` fallow config gate — previously re-derived INSIDE the
|
||||
* gated section body itself (`gsd_run query config-get code_quality.fallow.*`),
|
||||
* gated section body itself (`msd_run query config-get code_quality.fallow.*`),
|
||||
* which is circular/self-disabling the moment a section is gated on a fact
|
||||
* its own body computes (the same hazard `state:chunked-mode` /
|
||||
* `state:ui-phase-active` document for a compound condition). Fail-closed
|
||||
@@ -665,7 +665,7 @@ function detectFallowConfig(cwd: string): {
|
||||
/**
|
||||
* `state:git-create-tag` ground truth (#2994): resolves `complete-milestone.md`'s
|
||||
* `git_tag` step config gate — previously re-derived INSIDE a `<config-check>`
|
||||
* sub-tag at the top of the step itself (`gsd-tools.cjs query config-get
|
||||
* sub-tag at the top of the step itself (`msd-tools.cjs query config-get
|
||||
* git.create_tag 2>/dev/null || echo "true"`), gating the step's OWN inclusion
|
||||
* on a fact only that same step computed. Fail-OPEN default `true` (an unset
|
||||
* or missing `git.create_tag` key means "create the tag"), matching the
|
||||
@@ -737,7 +737,7 @@ function detectUiPhaseActive(cwd: string, phaseInfo: Record<string, unknown> | n
|
||||
const state = resolveCapabilityRuntimeState(cwd, undefined, config) as {
|
||||
capabilities: Array<{ id: string; enabled?: boolean; active: boolean }>;
|
||||
};
|
||||
const registry = loadRegistry({ includeInstalled: true, cwd, gsdHome: process.env['GSD_HOME'] });
|
||||
const registry = loadRegistry({ includeInstalled: true, cwd, msdHome: process.env['MSD_HOME'] });
|
||||
const capabilityStatesById = new Map<string, { enabled?: boolean; active: boolean }>();
|
||||
for (const cap of state.capabilities || []) {
|
||||
capabilityStatesById.set(cap.id, cap);
|
||||
@@ -1007,8 +1007,8 @@ function cmdInitExecutePhase(
|
||||
const threatIdDuplicates = findDuplicateThreatIds(cwd, phaseInfo?.['directory'] as string | undefined);
|
||||
|
||||
const result: Record<string, unknown> = {
|
||||
executor_model: resolveModelInternal(cwd, 'gsd-executor'),
|
||||
verifier_model: resolveModelInternal(cwd, 'gsd-verifier'),
|
||||
executor_model: resolveModelInternal(cwd, 'msd-executor'),
|
||||
verifier_model: resolveModelInternal(cwd, 'msd-verifier'),
|
||||
|
||||
tdd_mode: options['tdd'] || Boolean(config.tdd_mode) || false,
|
||||
commit_docs: config.commit_docs,
|
||||
@@ -1102,8 +1102,8 @@ function cmdInitExecutePhase(
|
||||
// planningDir(cwd, null) on the assumption that config.json is shared
|
||||
// like PROJECT.md (workstream-flag.md's directory diagram marks it
|
||||
// `# Shared`) — but ADR-0006's own tests (tests/init.test.cjs, "init
|
||||
// handlers honor GSD_WORKSTREAM") assert config_path IS workstream-scoped
|
||||
// for execute-phase/new-project/new-milestone/progress, and gsd-test
|
||||
// handlers honor MSD_WORKSTREAM") assert config_path IS workstream-scoped
|
||||
// for execute-phase/new-project/new-milestone/progress, and msd-test
|
||||
// caught the regression immediately. The diagram is stale for
|
||||
// config.json specifically (same class of staleness already found for
|
||||
// `milestones/` during the #4455 follow-up) — reverted to the
|
||||
@@ -1111,7 +1111,7 @@ function cmdInitExecutePhase(
|
||||
// ADR-governed, tested contract.
|
||||
config_path: toPosixPath(path.join(planningDir(cwd), 'config.json')),
|
||||
// #2376: execute-phase.md's verify_phase_goal step reads this instead of
|
||||
// hardcoding '.planning/REQUIREMENTS.md' into the gsd-verifier spawn prompt.
|
||||
// hardcoding '.planning/REQUIREMENTS.md' into the msd-verifier spawn prompt.
|
||||
requirements_path: fs.existsSync(requirementsPath) ? toPosixPath(requirementsPath) : null,
|
||||
};
|
||||
|
||||
@@ -1217,9 +1217,9 @@ function cmdInitPlanPhase(
|
||||
const requirementsPath = path.join(planningDir(cwd), 'REQUIREMENTS.md');
|
||||
|
||||
const result: Record<string, unknown> = {
|
||||
researcher_model: resolveModelInternal(cwd, 'gsd-phase-researcher'),
|
||||
planner_model: resolveModelInternal(cwd, 'gsd-planner'),
|
||||
checker_model: resolveModelInternal(cwd, 'gsd-plan-checker'),
|
||||
researcher_model: resolveModelInternal(cwd, 'msd-phase-researcher'),
|
||||
planner_model: resolveModelInternal(cwd, 'msd-planner'),
|
||||
checker_model: resolveModelInternal(cwd, 'msd-plan-checker'),
|
||||
|
||||
tdd_mode: options['tdd'] || Boolean(config.tdd_mode) || false,
|
||||
granularity,
|
||||
@@ -1469,13 +1469,13 @@ function cmdInitNewProject(cwd: string, raw: boolean, options: Record<string, un
|
||||
const config = loadConfig(cwd);
|
||||
|
||||
const homedir = os.homedir();
|
||||
const braveKeyFile = path.join(homedir, '.gsd', 'brave_api_key');
|
||||
const braveKeyFile = path.join(homedir, '.msd', 'brave_api_key');
|
||||
const hasBraveSearch = !!(process.env['BRAVE_API_KEY'] || fs.existsSync(braveKeyFile));
|
||||
|
||||
const firecrawlKeyFile = path.join(homedir, '.gsd', 'firecrawl_api_key');
|
||||
const firecrawlKeyFile = path.join(homedir, '.msd', 'firecrawl_api_key');
|
||||
const hasFirecrawl = !!(process.env['FIRECRAWL_API_KEY'] || fs.existsSync(firecrawlKeyFile));
|
||||
|
||||
const exaKeyFile = path.join(homedir, '.gsd', 'exa_api_key');
|
||||
const exaKeyFile = path.join(homedir, '.msd', 'exa_api_key');
|
||||
const hasExaSearch = !!(process.env['EXA_API_KEY'] || fs.existsSync(exaKeyFile));
|
||||
|
||||
const hasCode = hasCodeFilesInternal(cwd);
|
||||
@@ -1485,9 +1485,9 @@ function cmdInitNewProject(cwd: string, raw: boolean, options: Record<string, un
|
||||
const hasCodebaseMap = codebaseMapFiles.length === REQUIRED_CODEBASE_MAP_FILES.length;
|
||||
|
||||
const result: Record<string, unknown> = {
|
||||
researcher_model: resolveModelInternal(cwd, 'gsd-project-researcher'),
|
||||
synthesizer_model: resolveModelInternal(cwd, 'gsd-research-synthesizer'),
|
||||
roadmapper_model: resolveModelInternal(cwd, 'gsd-roadmapper'),
|
||||
researcher_model: resolveModelInternal(cwd, 'msd-project-researcher'),
|
||||
synthesizer_model: resolveModelInternal(cwd, 'msd-research-synthesizer'),
|
||||
roadmapper_model: resolveModelInternal(cwd, 'msd-roadmapper'),
|
||||
|
||||
commit_docs: config.commit_docs,
|
||||
|
||||
@@ -1534,8 +1534,8 @@ function cmdInitNewProject(cwd: string, raw: boolean, options: Record<string, un
|
||||
// planningDir(cwd, null) on the assumption that config.json is shared
|
||||
// like PROJECT.md (workstream-flag.md's directory diagram marks it
|
||||
// `# Shared`) — but ADR-0006's own tests (tests/init.test.cjs, "init
|
||||
// handlers honor GSD_WORKSTREAM") assert config_path IS workstream-scoped
|
||||
// for execute-phase/new-project/new-milestone/progress, and gsd-test
|
||||
// handlers honor MSD_WORKSTREAM") assert config_path IS workstream-scoped
|
||||
// for execute-phase/new-project/new-milestone/progress, and msd-test
|
||||
// caught the regression immediately. The diagram is stale for
|
||||
// config.json specifically (same class of staleness already found for
|
||||
// `milestones/` during the #4455 follow-up) — reverted to the
|
||||
@@ -1568,9 +1568,9 @@ function cmdInitNewMilestone(cwd: string, raw: boolean, options: Record<string,
|
||||
const phaseDirCount = listMilestonePhaseDirs(phasesDir, { cwd }).value.length;
|
||||
|
||||
const result: Record<string, unknown> = {
|
||||
researcher_model: resolveModelInternal(cwd, 'gsd-project-researcher'),
|
||||
synthesizer_model: resolveModelInternal(cwd, 'gsd-research-synthesizer'),
|
||||
roadmapper_model: resolveModelInternal(cwd, 'gsd-roadmapper'),
|
||||
researcher_model: resolveModelInternal(cwd, 'msd-project-researcher'),
|
||||
synthesizer_model: resolveModelInternal(cwd, 'msd-research-synthesizer'),
|
||||
roadmapper_model: resolveModelInternal(cwd, 'msd-roadmapper'),
|
||||
|
||||
commit_docs: config.commit_docs,
|
||||
research_enabled: config.research,
|
||||
@@ -1609,8 +1609,8 @@ function cmdInitNewMilestone(cwd: string, raw: boolean, options: Record<string,
|
||||
// planningDir(cwd, null) on the assumption that config.json is shared
|
||||
// like PROJECT.md (workstream-flag.md's directory diagram marks it
|
||||
// `# Shared`) — but ADR-0006's own tests (tests/init.test.cjs, "init
|
||||
// handlers honor GSD_WORKSTREAM") assert config_path IS workstream-scoped
|
||||
// for execute-phase/new-project/new-milestone/progress, and gsd-test
|
||||
// handlers honor MSD_WORKSTREAM") assert config_path IS workstream-scoped
|
||||
// for execute-phase/new-project/new-milestone/progress, and msd-test
|
||||
// caught the regression immediately. The diagram is stale for
|
||||
// config.json specifically (same class of staleness already found for
|
||||
// `milestones/` during the #4455 follow-up) — reverted to the
|
||||
@@ -1641,7 +1641,7 @@ function cmdInitNewMilestone(cwd: string, raw: boolean, options: Record<string,
|
||||
// SEPARATE, positively-phrased atom whose fact is the inverse is the
|
||||
// sanctioned resolution (same discipline as `state:chunked-mode` folding
|
||||
// an OR — never an operator in the grammar itself). Same authoritative
|
||||
// source as `cmdInitTransition`: `GSD_WORKSTREAM` env, falling back to the
|
||||
// source as `cmdInitTransition`: `MSD_WORKSTREAM` env, falling back to the
|
||||
// stored active-workstream pointer (mirrors `cmdInitProgress`'s own
|
||||
// resolution above).
|
||||
//
|
||||
@@ -1691,17 +1691,17 @@ function cmdInitQuick(
|
||||
: null;
|
||||
|
||||
const result: Record<string, unknown> = {
|
||||
planner_model: resolveModelInternal(cwd, 'gsd-planner'),
|
||||
executor_model: resolveModelInternal(cwd, 'gsd-executor'),
|
||||
checker_model: resolveModelInternal(cwd, 'gsd-plan-checker'),
|
||||
verifier_model: resolveModelInternal(cwd, 'gsd-verifier'),
|
||||
// #3936: Step 4.75 dispatches gsd-phase-researcher; resolve its own tier
|
||||
planner_model: resolveModelInternal(cwd, 'msd-planner'),
|
||||
executor_model: resolveModelInternal(cwd, 'msd-executor'),
|
||||
checker_model: resolveModelInternal(cwd, 'msd-plan-checker'),
|
||||
verifier_model: resolveModelInternal(cwd, 'msd-verifier'),
|
||||
// #3936: Step 4.75 dispatches msd-phase-researcher; resolve its own tier
|
||||
// (parity with cmdInitPlanPhase) so the research spawn stops pinning
|
||||
// planner_model.
|
||||
researcher_model: resolveModelInternal(cwd, 'gsd-phase-researcher'),
|
||||
// #2072: the quick review step spawns gsd-code-reviewer; resolve its own model
|
||||
researcher_model: resolveModelInternal(cwd, 'msd-phase-researcher'),
|
||||
// #2072: the quick review step spawns msd-code-reviewer; resolve its own model
|
||||
// so model_overrides / models.verification apply (was reusing executor_model).
|
||||
reviewer_model: resolveModelInternal(cwd, 'gsd-code-reviewer'),
|
||||
reviewer_model: resolveModelInternal(cwd, 'msd-code-reviewer'),
|
||||
|
||||
commit_docs: config.commit_docs,
|
||||
branch_name: quickBranchName,
|
||||
@@ -1731,7 +1731,7 @@ function cmdInitQuick(
|
||||
// builds its `InvocationFacts.flags` Set, so `discussion-phase`/`research-phase`/
|
||||
// `plan-checker-loop`/`quick-verification` (all gated on their own single
|
||||
// `flag:--discuss`/`flag:--research`/`flag:--validate` atom) include correctly
|
||||
// for a bare `/gsd:quick --full` invocation that never passed the individual
|
||||
// for a bare `/msd:quick --full` invocation that never passed the individual
|
||||
// tokens — the grammar still sees exactly one atom per marker, no OR.
|
||||
const sectionManifestOptions: Record<string, unknown> = options['full']
|
||||
? { ...options, discuss: true, research: true, validate: true }
|
||||
@@ -1768,12 +1768,12 @@ function cmdInitQuickBatch(
|
||||
const config = loadConfig(cwd);
|
||||
|
||||
const result: Record<string, unknown> = {
|
||||
planner_model: resolveModelInternal(cwd, 'gsd-planner'),
|
||||
executor_model: resolveModelInternal(cwd, 'gsd-executor'),
|
||||
checker_model: resolveModelInternal(cwd, 'gsd-plan-checker'),
|
||||
verifier_model: resolveModelInternal(cwd, 'gsd-verifier'),
|
||||
researcher_model: resolveModelInternal(cwd, 'gsd-phase-researcher'),
|
||||
reviewer_model: resolveModelInternal(cwd, 'gsd-code-reviewer'),
|
||||
planner_model: resolveModelInternal(cwd, 'msd-planner'),
|
||||
executor_model: resolveModelInternal(cwd, 'msd-executor'),
|
||||
checker_model: resolveModelInternal(cwd, 'msd-plan-checker'),
|
||||
verifier_model: resolveModelInternal(cwd, 'msd-verifier'),
|
||||
researcher_model: resolveModelInternal(cwd, 'msd-phase-researcher'),
|
||||
reviewer_model: resolveModelInternal(cwd, 'msd-code-reviewer'),
|
||||
|
||||
commit_docs: config.commit_docs,
|
||||
|
||||
@@ -1804,7 +1804,7 @@ function cmdInitIngestDocs(cwd: string, raw: boolean): void {
|
||||
...getInitGitState(cwd),
|
||||
// #2376: absolute — see comment on phase_dir in cmdInitExecutePhase. The
|
||||
// classify_parallel/synthesize/route_new_mode spawns in ingest-docs.md
|
||||
// (gsd-doc-classifier, gsd-doc-synthesizer, gsd-roadmapper) previously
|
||||
// (msd-doc-classifier, msd-doc-synthesizer, msd-roadmapper) previously
|
||||
// hardcoded bare '.planning/intel/...', '.planning/PROJECT.md', etc.
|
||||
// literals into their Agent(prompt=...) blocks; those now interpolate
|
||||
// these fields instead.
|
||||
@@ -1922,8 +1922,8 @@ function cmdInitVerifyWork(cwd: string, phase: string, raw: boolean): void {
|
||||
const uiPhaseActive = detectUiPhaseActive(cwd, phaseInfo);
|
||||
|
||||
const result: Record<string, unknown> = {
|
||||
planner_model: resolveModelInternal(cwd, 'gsd-planner'),
|
||||
checker_model: resolveModelInternal(cwd, 'gsd-plan-checker'),
|
||||
planner_model: resolveModelInternal(cwd, 'msd-planner'),
|
||||
checker_model: resolveModelInternal(cwd, 'msd-plan-checker'),
|
||||
|
||||
commit_docs: config.commit_docs,
|
||||
|
||||
@@ -1949,7 +1949,7 @@ function cmdInitVerifyWork(cwd: string, phase: string, raw: boolean): void {
|
||||
|
||||
// #2994 (resolver-hoist-guard G5): hoisted `state:ui-phase-active` ground
|
||||
// truth (previously re-derived inline inside the automated_ui_verification
|
||||
// step body via its own `gsd_run loop render-hooks plan:pre --raw` call —
|
||||
// step body via its own `msd_run loop render-hooks plan:pre --raw` call —
|
||||
// a circular, self-disabling resolver, since the section is only read
|
||||
// when this same fact is already true). Resolved once here, exposed so
|
||||
// the step body can consume it directly instead of recomputing it.
|
||||
@@ -2140,7 +2140,7 @@ function cmdInitReview(
|
||||
* carried: `state:auto-advance-active` — the workflow's own `auto_advance`
|
||||
* step resolves `--auto` OR a consolidated `check auto-mode --pick active`
|
||||
* fact (itself `workflow._auto_chain_active` OR `workflow.auto_advance`) via
|
||||
* a runtime `gsd_run` call; that identical disjunction is folded into ONE
|
||||
* a runtime `msd_run` call; that identical disjunction is folded into ONE
|
||||
* boolean FACT here (same discipline as `state:chunked-mode` /
|
||||
* `state:plan-strategy-converge`), exposed as `auto_advance_active`.
|
||||
*/
|
||||
@@ -2427,7 +2427,7 @@ function cmdInitPhaseOp(cwd: string, phase: string, raw: boolean): void {
|
||||
// 240 matches the bound already vetted by maintainer review on the prior
|
||||
// attempt at this issue (PR #2662) — re-deriving a different number would be
|
||||
// pure bikeshedding, not a correctness improvement. See
|
||||
// .gsd/phase/feat-2618-compact-todo-pointers/40-design.md.
|
||||
// .msd/phase/feat-2618-compact-todo-pointers/40-design.md.
|
||||
const PENDING_TODO_BULLET_MAX_CHARS = 240;
|
||||
const PENDING_TODO_TITLE_FLOOR = 15;
|
||||
const PENDING_TODO_AREA_FLOOR = 3;
|
||||
@@ -2448,7 +2448,7 @@ function truncatePendingTodoText(value: string, maxLen: number): string {
|
||||
/**
|
||||
* #2618: pure renderer for STATE.md's "### Pending Todos" section BODY (not
|
||||
* the heading). One bullet per todo, each capped at
|
||||
* PENDING_TODO_BULLET_MAX_CHARS. `gsd-core/workflows/add-todo.md` and
|
||||
* PENDING_TODO_BULLET_MAX_CHARS. `msd-core/workflows/add-todo.md` and
|
||||
* `check-todos.md` splice this string in verbatim instead of free-hand
|
||||
* editing STATE.md — see the design doc for why this is real, unit-tested
|
||||
* code rather than a prose algorithm (DEFECT.GENERATIVE-FIX: a prose
|
||||
@@ -2802,7 +2802,7 @@ function cmdInitMapCodebase(cwd: string, raw: boolean): void {
|
||||
// below (and verify.cts's codebase drift check) — has_maps/existing_maps
|
||||
// reading the flat root made the same payload claim a scoped codebase dir
|
||||
// exists while reporting zero maps, so map-codebase's Refresh/Skip gate
|
||||
// always forced a re-map under GSD_PROJECT.
|
||||
// always forced a re-map under MSD_PROJECT.
|
||||
const codebaseDir = path.join(planningDir(cwd), 'codebase');
|
||||
let existingMaps: string[] = [];
|
||||
try {
|
||||
@@ -2812,7 +2812,7 @@ function cmdInitMapCodebase(cwd: string, raw: boolean): void {
|
||||
}
|
||||
|
||||
const result: Record<string, unknown> = {
|
||||
mapper_model: resolveModelInternal(cwd, 'gsd-codebase-mapper'),
|
||||
mapper_model: resolveModelInternal(cwd, 'msd-codebase-mapper'),
|
||||
|
||||
commit_docs: config.commit_docs,
|
||||
search_gitignored: config.search_gitignored,
|
||||
@@ -2825,7 +2825,7 @@ function cmdInitMapCodebase(cwd: string, raw: boolean): void {
|
||||
// #2376: absolute — see comment on phase_dir in cmdInitExecutePhase.
|
||||
// #3964: scoped like verify.cts's codebase drift check (planningDir, not
|
||||
// the flat planningRoot) so the two surfaces cannot disagree under
|
||||
// GSD_PROJECT.
|
||||
// MSD_PROJECT.
|
||||
codebase_dir: toPosixPath(path.join(planningDir(cwd), 'codebase')),
|
||||
|
||||
existing_maps: existingMaps,
|
||||
@@ -2857,10 +2857,10 @@ function cmdInitManager(cwd: string, raw: boolean): void {
|
||||
const paths = planningPaths(cwd);
|
||||
|
||||
if (!fs.existsSync(paths.roadmap)) {
|
||||
error(`No ROADMAP.md found. Run ${formatGsdSlash('new-milestone', _slashRuntime) as string} first.`);
|
||||
error(`No ROADMAP.md found. Run ${formatMsdSlash('new-milestone', _slashRuntime) as string} first.`);
|
||||
}
|
||||
if (!fs.existsSync(paths.state)) {
|
||||
error(`No STATE.md found. Run ${formatGsdSlash('new-milestone', _slashRuntime) as string} first.`);
|
||||
error(`No STATE.md found. Run ${formatMsdSlash('new-milestone', _slashRuntime) as string} first.`);
|
||||
}
|
||||
const rawContent = fs.readFileSync(paths.roadmap, 'utf-8');
|
||||
const content = extractCurrentMilestone(rawContent, cwd);
|
||||
@@ -3171,12 +3171,12 @@ function cmdInitManager(cwd: string, raw: boolean): void {
|
||||
|
||||
let waitingSignal: unknown = null;
|
||||
try {
|
||||
// #3964: mirror cmdSignalWaiting's write locations exactly — `.gsd/`
|
||||
// #3964: mirror cmdSignalWaiting's write locations exactly — `.msd/`
|
||||
// first when it exists, else the project-aware planning dir — so the
|
||||
// signal is read from the project (and location) it is written to.
|
||||
const gsdWaiting = path.join(cwd, '.gsd', 'WAITING.json');
|
||||
const waitingPath = fs.existsSync(path.join(cwd, '.gsd'))
|
||||
? gsdWaiting
|
||||
const msdWaiting = path.join(cwd, '.msd', 'WAITING.json');
|
||||
const waitingPath = fs.existsSync(path.join(cwd, '.msd'))
|
||||
? msdWaiting
|
||||
: path.join(planningDir(cwd), 'WAITING.json');
|
||||
const waitingRaw = platformReadSync(waitingPath);
|
||||
if (waitingRaw !== null) {
|
||||
@@ -3206,7 +3206,7 @@ function cmdInitManager(cwd: string, raw: boolean): void {
|
||||
phase_name: phase['name'],
|
||||
action: 'execute',
|
||||
reason: `${phase['plan_count'] as number} plans ready, dependencies met`,
|
||||
command: `${formatGsdSlash('execute-phase', _slashRuntime) as string} ${phase['number'] as string}`,
|
||||
command: `${formatMsdSlash('execute-phase', _slashRuntime) as string} ${phase['number'] as string}`,
|
||||
});
|
||||
} else if (
|
||||
phase['disk_status'] === 'discussed' ||
|
||||
@@ -3217,7 +3217,7 @@ function cmdInitManager(cwd: string, raw: boolean): void {
|
||||
phase_name: phase['name'],
|
||||
action: 'plan',
|
||||
reason: 'Context gathered, ready for planning',
|
||||
command: `${formatGsdSlash('plan-phase', _slashRuntime) as string} ${phase['number'] as string}`,
|
||||
command: `${formatMsdSlash('plan-phase', _slashRuntime) as string} ${phase['number'] as string}`,
|
||||
});
|
||||
} else if (
|
||||
(phase['disk_status'] === 'empty' || phase['disk_status'] === 'no_directory') &&
|
||||
@@ -3228,7 +3228,7 @@ function cmdInitManager(cwd: string, raw: boolean): void {
|
||||
phase_name: phase['name'],
|
||||
action: 'discuss',
|
||||
reason: 'Unblocked, ready to gather context',
|
||||
command: `${formatGsdSlash('discuss-phase', _slashRuntime) as string} ${phase['number'] as string}`,
|
||||
command: `${formatMsdSlash('discuss-phase', _slashRuntime) as string} ${phase['number'] as string}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -3273,7 +3273,7 @@ function cmdInitManager(cwd: string, raw: boolean): void {
|
||||
);
|
||||
if (!safe) {
|
||||
process.stderr.write(
|
||||
`gsd-tools: warning: manager.flags contains invalid tokens, ignoring: ${val}\n`,
|
||||
`msd-tools: warning: manager.flags contains invalid tokens, ignoring: ${val}\n`,
|
||||
);
|
||||
return '';
|
||||
}
|
||||
@@ -3364,7 +3364,7 @@ function cmdInitCompleteMilestone(
|
||||
const milestonesPath = path.join(planningBase, 'MILESTONES.md');
|
||||
// #4455 follow-up round 2 (self-discovered regression): PROJECT.md, unlike
|
||||
// MILESTONES.md, is genuinely SHARED across a project's own workstreams —
|
||||
// never cloned per workstream. gsd-core/references/workstream-flag.md's
|
||||
// never cloned per workstream. msd-core/references/workstream-flag.md's
|
||||
// directory diagram marks it `# Shared`; new-milestone.md states it
|
||||
// outright ("PROJECT.md is shared across workstreams") and explicitly
|
||||
// SKIPS writing its `## Current Milestone` heading under an active
|
||||
@@ -3374,13 +3374,13 @@ function cmdInitCompleteMilestone(
|
||||
// wrongly generalized from planningPaths()'s structural shape (which
|
||||
// composes `project` under the workstream base) without checking an
|
||||
// actual PROJECT.md write path — resolved against planningRoot(cwd)
|
||||
// (round 2), but that ALSO ignores the separate GSD_PROJECT dimension
|
||||
// (round 2), but that ALSO ignores the separate MSD_PROJECT dimension
|
||||
// (multi-project namespacing, #3749: PROJECT.md legitimately lives at
|
||||
// `.planning/<project>/PROJECT.md` when GSD_PROJECT is set — a real,
|
||||
// `.planning/<project>/PROJECT.md` when MSD_PROJECT is set — a real,
|
||||
// tested, pre-existing feature planningRoot's blanket root-only read
|
||||
// broke), caught by gsd-test on this fix's own first push. `planningDir`
|
||||
// with `ws` explicitly nulled (never read from GSD_WORKSTREAM) but
|
||||
// `project` left to default from GSD_PROJECT is the correct middle
|
||||
// broke), caught by msd-test on this fix's own first push. `planningDir`
|
||||
// with `ws` explicitly nulled (never read from MSD_WORKSTREAM) but
|
||||
// `project` left to default from MSD_PROJECT is the correct middle
|
||||
// ground: respects project-namespacing, ignores workstream-namespacing.
|
||||
const projectPath = path.join(planningDir(cwd, null), 'PROJECT.md');
|
||||
// REQUIREMENTS.md is workstream-scoped the same way (planningPaths(cwd).requirements,
|
||||
@@ -3446,7 +3446,7 @@ function cmdInitAutonomous(
|
||||
|
||||
/**
|
||||
* `docs-update.md`'s dedicated init entry point (#2994, epic #1671 Phase
|
||||
* 6.3 — final slice). `docs-update.md` previously carried NO `gsd_run query
|
||||
* 6.3 — final slice). `docs-update.md` previously carried NO `msd_run query
|
||||
* init.*` call at all: its own `docs-init` command (`cmdDocsInit`,
|
||||
* src/docs.cts) is a SEPARATE, pre-existing entry point outside this
|
||||
* `init.*` family and is left untouched here. This function's only job is
|
||||
@@ -3473,17 +3473,17 @@ function cmdInitDocsUpdate(cwd: string, raw: boolean, options: Record<string, un
|
||||
|
||||
/**
|
||||
* `update.md`'s dedicated init entry point (#2994, epic #1671 Phase 6.3 —
|
||||
* final slice). `update.md` previously carried NO `gsd_run query init.*`
|
||||
* call at all: it resolves `gsd-tools.cjs` itself (its own bespoke
|
||||
* `PREFERRED_CONFIG_DIR`/`PREFERRED_RUNTIME`-aware `$GSD_TOOLS` cascade,
|
||||
* final slice). `update.md` previously carried NO `msd_run query init.*`
|
||||
* call at all: it resolves `msd-tools.cjs` itself (its own bespoke
|
||||
* `PREFERRED_CONFIG_DIR`/`PREFERRED_RUNTIME`-aware `$MSD_TOOLS` cascade,
|
||||
* `update.md` ~lines 13-45) because the update workflow must run BEFORE any
|
||||
* install can be assumed resolvable — the canonical launcher preamble's
|
||||
* fixed candidate list is not a substitute for that cascade, and both
|
||||
* resolutions assign the identical `$GSD_TOOLS` shell variable, so copying
|
||||
* resolutions assign the identical `$MSD_TOOLS` shell variable, so copying
|
||||
* the canonical preamble in ADDITION to the existing cascade would silently
|
||||
* clobber the value `backup_custom_files`/`restore_custom_files` (later
|
||||
* steps) still depend on. This function is invoked via that ALREADY
|
||||
* resolved `$GSD_TOOLS`, not a redundant `gsd_run()` shell function.
|
||||
* resolved `$MSD_TOOLS`, not a redundant `msd_run()` shell function.
|
||||
*
|
||||
* `state:next-channel` ground truth: `--next` OR its documented alias
|
||||
* `--rc` (same disjunction-to-one-boolean discipline as
|
||||
@@ -3492,7 +3492,7 @@ function cmdInitDocsUpdate(cwd: string, raw: boolean, options: Record<string, un
|
||||
* (`TAG="next"`/`TAG="latest"`) — issue #815's regression test
|
||||
* (`tests/update-workflow.test.cjs`) asserts that literal
|
||||
* case-statement text stays in `update.md` verbatim (the npm dist-tag
|
||||
* selection has to run in the workflow's own shell before any `gsd_run`
|
||||
* selection has to run in the workflow's own shell before any `msd_run`
|
||||
* round-trip), so `next_channel` exists purely to gate the `channel-banner`
|
||||
* section's admission — a parallel, consistent-but-not-replacing
|
||||
* resolution of the same flags.
|
||||
@@ -3514,22 +3514,22 @@ function cmdInitUpdate(cwd: string, raw: boolean, options: Record<string, unknow
|
||||
/**
|
||||
* `transition.md`'s dedicated init entry point (#2994, epic #1671 Phase
|
||||
* 6.3 — final slice). `transition.md` is an internal workflow (no
|
||||
* user-facing `/gsd-transition` command) that previously carried NO
|
||||
* `gsd_run query init.*` call at all; it already establishes `gsd_run()`
|
||||
* user-facing `/msd-transition` command) that previously carried NO
|
||||
* `msd_run query init.*` call at all; it already establishes `msd_run()`
|
||||
* via the canonical launcher preamble in its `update_roadmap_and_state`
|
||||
* step (before this call's insertion point in `offer_next_phase`), so no
|
||||
* second preamble copy is needed in the host file.
|
||||
*
|
||||
* `state:workstream-active` ground truth: a workstream is active — resolved
|
||||
* via `GSD_WORKSTREAM` env, falling back to the stored active-workstream
|
||||
* via `MSD_WORKSTREAM` env, falling back to the stored active-workstream
|
||||
* pointer (mirrors `cmdInitProgress`'s own `_resolvedWorkstream` resolution
|
||||
* above, the established authoritative source for "is a workstream active"
|
||||
* in this file).
|
||||
*
|
||||
* `other_active_workstreams` hoists the resolver-in-body hazard out of
|
||||
* `transition.md`'s `workstream-collision-check` step: that step's body
|
||||
* previously re-derived this via an inline `gsd_run query workstream.list
|
||||
* --raw` call gated on the identical `if [ -n "$GSD_WORKSTREAM" ]`
|
||||
* previously re-derived this via an inline `msd_run query workstream.list
|
||||
* --raw` call gated on the identical `if [ -n "$MSD_WORKSTREAM" ]`
|
||||
* condition that now backs this section's OWN admission — resolving it here
|
||||
* instead reuses `getOtherActiveWorkstreamInventories` (src/workstream-
|
||||
* inventory.cts), the SAME primitive `workstream.list` itself calls
|
||||
@@ -3537,7 +3537,7 @@ function cmdInitUpdate(cwd: string, raw: boolean, options: Record<string, unknow
|
||||
* step's own prose described (excludes the current workstream and any
|
||||
* workstream whose status contains "milestone complete" or "archived",
|
||||
* case-insensitively — `isCompletedInventory`), so the step body becomes a
|
||||
* pure JSON consumer with no `gsd_run` call of its own.
|
||||
* pure JSON consumer with no `msd_run` call of its own.
|
||||
*/
|
||||
function cmdInitTransition(cwd: string, raw: boolean, options: Record<string, unknown> = {}): void {
|
||||
// #3579 root-cause fix: read-only informational field — peek, don't
|
||||
@@ -3563,9 +3563,9 @@ function cmdInitTransition(cwd: string, raw: boolean, options: Record<string, un
|
||||
|
||||
/**
|
||||
* `debug.md`'s dedicated init entry point (#3149; prerequisite for #3128).
|
||||
* `debug.md` previously carried NO `gsd_run query init.*` call at all — it made
|
||||
* `debug.md` previously carried NO `msd_run query init.*` call at all — it made
|
||||
* THREE separate round-trips instead: `state.load` (for `commit_docs`,
|
||||
* `config.response_language` and `debug_dir`), `resolve-model gsd-debugger
|
||||
* `config.response_language` and `debug_dir`), `resolve-model msd-debugger
|
||||
* --pick model`, and `config-get workflow.tdd_mode --raw`. Because no
|
||||
* debug-scoped fact was computed at any entry point, a `when=` atom naming one
|
||||
* would have evaluated FALSE forever — ADR-1671's admission gate (2) and the
|
||||
@@ -3584,14 +3584,14 @@ function cmdInitTransition(cwd: string, raw: boolean, options: Record<string, un
|
||||
* - `debugger_model` — `resolveModelInternal`, which IS what `query
|
||||
* resolve-model --pick model` returns (`cmdResolveModel`, src/commands.cts).
|
||||
* - `tdd_mode` — the `Boolean(config.tdd_mode)` idiom `cmdInitExecutePhase` and
|
||||
* `cmdInitPlanPhase` already use. `/gsd:debug` has no `--tdd` flag, so the
|
||||
* `cmdInitPlanPhase` already use. `/msd:debug` has no `--tdd` flag, so the
|
||||
* sibling handlers' `options['tdd'] ||` disjunct is deliberately omitted
|
||||
* rather than carried as a phantom.
|
||||
*
|
||||
* `state.load` is deliberately NOT narrowed — see the note beside its own
|
||||
* `debug_dir` field. This handler is purely additive alongside it.
|
||||
*
|
||||
* `diagnose` is the one flag `/gsd:debug` already documents. Exposing it as a
|
||||
* `diagnose` is the one flag `/msd:debug` already documents. Exposing it as a
|
||||
* top-level fact follows `cmdInitUpdate`'s `next_channel` and
|
||||
* `cmdInitAutonomous`'s `plan_strategy_converge` precedent, and is what makes
|
||||
* the router's flag forwarding observable. No `when=` atom consumes it yet:
|
||||
@@ -3605,16 +3605,16 @@ function cmdInitDebug(cwd: string, raw: boolean, options: Record<string, unknown
|
||||
const result: Record<string, unknown> = {
|
||||
commit_docs: config.commit_docs,
|
||||
// #2376: absolute — debug.md builds `debug_file_path` as
|
||||
// `{debug_dir}/{slug}.md` for its gsd-debug-session-manager spawns, whose
|
||||
// `{debug_dir}/{slug}.md` for its msd-debug-session-manager spawns, whose
|
||||
// own cwd may differ from the orchestrator's.
|
||||
debug_dir: toPosixPath(planningPaths(cwd).debug),
|
||||
debugger_model: resolveModelInternal(cwd, 'gsd-debugger'),
|
||||
debugger_model: resolveModelInternal(cwd, 'msd-debugger'),
|
||||
tdd_mode: Boolean(config.tdd_mode),
|
||||
diagnose: options['diagnose'] === true,
|
||||
};
|
||||
|
||||
// Additive, optional field — degrades to null while `debug` has no key in
|
||||
// `gsd-core/workflows/section-manifest.json` (it has no `gsd:section` markers
|
||||
// `msd-core/workflows/section-manifest.json` (it has no `msd:section` markers
|
||||
// until #3128). null means "read everything", which is NOT the same as a
|
||||
// computed empty selection.
|
||||
result['section_manifest'] = buildSectionManifestField(cwd, null, options, 'debug', {});
|
||||
@@ -3635,8 +3635,8 @@ function cmdInitProgress(cwd: string, raw: boolean, options: Record<string, unkn
|
||||
// #1912: fail safe in workstream mode with no active workstream. With no active
|
||||
// workstream and no --ws, planningDir(cwd) resolves to root .planning — silently
|
||||
// reporting a stale root milestone. Require an explicit workstream instead.
|
||||
// Mirror planningDir's resolution (GSD_WORKSTREAM env > stored active pointer) so
|
||||
// an explicit --ws (which sets GSD_WORKSTREAM) satisfies the check.
|
||||
// Mirror planningDir's resolution (MSD_WORKSTREAM env > stored active pointer) so
|
||||
// an explicit --ws (which sets MSD_WORKSTREAM) satisfies the check.
|
||||
const _availableWorkstreams = listAvailableWorkstreams(cwd);
|
||||
// #3579 root-cause fix: this is a check, not a consuming read — use the
|
||||
// non-mutating peek so an unresolvable pointer isn't self-healed (cleared)
|
||||
@@ -3654,7 +3654,7 @@ function cmdInitProgress(cwd: string, raw: boolean, options: Record<string, unkn
|
||||
if (_diagnosis.present) {
|
||||
error(
|
||||
`init.progress requires a workstream in workstream mode — the active-workstream marker names '${_diagnosis.value}', but it did not resolve: ${describeUnresolvedWorkstreamReason(_diagnosis.reason)}. Root STATE.md (likely stale) would be reported otherwise. ` +
|
||||
`Pass --ws <name> or run ${formatGsdSlash('workstream set', _slashRuntime) as string} to point it at an existing workstream. ` +
|
||||
`Pass --ws <name> or run ${formatMsdSlash('workstream set', _slashRuntime) as string} to point it at an existing workstream. ` +
|
||||
`Available workstreams: ${_availableWorkstreams.join(', ')}`,
|
||||
ERROR_REASON.WORKSTREAM_MODE_MARKER_UNRESOLVED,
|
||||
{ marker_value: _diagnosis.value, marker_reason: _diagnosis.reason },
|
||||
@@ -3662,7 +3662,7 @@ function cmdInitProgress(cwd: string, raw: boolean, options: Record<string, unkn
|
||||
}
|
||||
error(
|
||||
`init.progress requires a workstream in workstream mode — no active workstream is set, so root STATE.md (likely stale) would be reported. ` +
|
||||
`Pass --ws <name> or run ${formatGsdSlash('workstream set', _slashRuntime) as string} first. ` +
|
||||
`Pass --ws <name> or run ${formatMsdSlash('workstream set', _slashRuntime) as string} first. ` +
|
||||
`Available workstreams: ${_availableWorkstreams.join(', ')}`,
|
||||
ERROR_REASON.WORKSTREAM_MODE_NONE_ACTIVE,
|
||||
);
|
||||
@@ -3844,7 +3844,7 @@ function cmdInitProgress(cwd: string, raw: boolean, options: Record<string, unkn
|
||||
|
||||
// #2994: the CURRENT phase's number, used both to expose `phase_mvp_mode`
|
||||
// at the top level (so the `mvp-display` step body can consume an
|
||||
// already-resolved fact instead of re-invoking `gsd_run query
|
||||
// already-resolved fact instead of re-invoking `msd_run query
|
||||
// phase.mvp-mode` itself — that inline resolver would otherwise gate a
|
||||
// section on a fact the section's own body recomputes, which is circular
|
||||
// and self-disabling) and to thread a real `phase_number` into
|
||||
@@ -3857,8 +3857,8 @@ function cmdInitProgress(cwd: string, raw: boolean, options: Record<string, unkn
|
||||
const phaseMvpMode = detectPhaseMvpMode(cwd, currentPhaseNumber);
|
||||
|
||||
const result: Record<string, unknown> = {
|
||||
executor_model: resolveModelInternal(cwd, 'gsd-executor'),
|
||||
planner_model: resolveModelInternal(cwd, 'gsd-planner'),
|
||||
executor_model: resolveModelInternal(cwd, 'msd-executor'),
|
||||
planner_model: resolveModelInternal(cwd, 'msd-planner'),
|
||||
|
||||
commit_docs: config.commit_docs,
|
||||
|
||||
@@ -3901,8 +3901,8 @@ function cmdInitProgress(cwd: string, raw: boolean, options: Record<string, unkn
|
||||
// planningDir(cwd, null) on the assumption that config.json is shared
|
||||
// like PROJECT.md (workstream-flag.md's directory diagram marks it
|
||||
// `# Shared`) — but ADR-0006's own tests (tests/init.test.cjs, "init
|
||||
// handlers honor GSD_WORKSTREAM") assert config_path IS workstream-scoped
|
||||
// for execute-phase/new-project/new-milestone/progress, and gsd-test
|
||||
// handlers honor MSD_WORKSTREAM") assert config_path IS workstream-scoped
|
||||
// for execute-phase/new-project/new-milestone/progress, and msd-test
|
||||
// caught the regression immediately. The diagram is stale for
|
||||
// config.json specifically (same class of staleness already found for
|
||||
// `milestones/` during the #4455 follow-up) — reverted to the
|
||||
@@ -3951,7 +3951,7 @@ function detectChildRepos(dir: string): { name: string; path: string; has_uncomm
|
||||
|
||||
function cmdInitNewWorkspace(cwd: string, raw: boolean): void {
|
||||
const homedir = process.env['HOME'] || os.homedir();
|
||||
const defaultBase = path.join(homedir, 'gsd-workspaces');
|
||||
const defaultBase = path.join(homedir, 'msd-workspaces');
|
||||
|
||||
const childRepos = detectChildRepos(cwd);
|
||||
|
||||
@@ -3972,7 +3972,7 @@ function cmdInitNewWorkspace(cwd: string, raw: boolean): void {
|
||||
|
||||
function cmdInitListWorkspaces(cwd: string, raw: boolean): void {
|
||||
const homedir = process.env['HOME'] || os.homedir();
|
||||
const defaultBase = path.join(homedir, 'gsd-workspaces');
|
||||
const defaultBase = path.join(homedir, 'msd-workspaces');
|
||||
|
||||
const workspaces: Record<string, unknown>[] = [];
|
||||
if (fs.existsSync(defaultBase)) {
|
||||
@@ -4026,7 +4026,7 @@ function cmdInitListWorkspaces(cwd: string, raw: boolean): void {
|
||||
|
||||
function cmdInitRemoveWorkspace(cwd: string, name: string | undefined, raw: boolean): void {
|
||||
const homedir = process.env['HOME'] || os.homedir();
|
||||
const defaultBase = path.join(homedir, 'gsd-workspaces');
|
||||
const defaultBase = path.join(homedir, 'msd-workspaces');
|
||||
|
||||
if (!name) {
|
||||
error('workspace name required for init remove-workspace');
|
||||
@@ -4302,7 +4302,7 @@ function cmdAgentSkills(
|
||||
// documented "unconfigured → empty block" contract that agent-skills tests
|
||||
// pin.
|
||||
//
|
||||
// #4407 (ADR-4139 stream 2): this is the one place GSD's own agent-persona
|
||||
// #4407 (ADR-4139 stream 2): this is the one place MSD's own agent-persona
|
||||
// content is served through a real code seam rather than an eagerly
|
||||
// @-included file, so the compact/canonical choice is made here in code
|
||||
// (a real exit code) instead of a prose config-get gate. Compact is tried
|
||||
@@ -4310,7 +4310,7 @@ function cmdAgentSkills(
|
||||
// with the fallback disclosed in the payload itself, never a silent switch.
|
||||
let agentPayloadVariant: 'compact' | 'canonical' | null = null;
|
||||
if (!block) {
|
||||
const runtime = (config && (config['runtime'] as string)) || process.env['GSD_RUNTIME'] || 'claude';
|
||||
const runtime = (config && (config['runtime'] as string)) || process.env['MSD_RUNTIME'] || 'claude';
|
||||
if (runtime !== 'claude') {
|
||||
const agentCheck = checkAgentsInstalled(runtime, projectRoot) as unknown as { agents_dir?: string } | null;
|
||||
const agentsDir = agentCheck?.agents_dir;
|
||||
@@ -4326,7 +4326,7 @@ function cmdAgentSkills(
|
||||
const canonicalContent = readNonEmptyFileOrNull(path.join(agentsDir, `${agentType}.md`));
|
||||
if (canonicalContent !== null) {
|
||||
block = compactRequested
|
||||
? `<!-- gsd: no compact payload registered for ${agentType}; serving canonical -->\n\n${canonicalContent}`
|
||||
? `<!-- msd: no compact payload registered for ${agentType}; serving canonical -->\n\n${canonicalContent}`
|
||||
: canonicalContent;
|
||||
agentPayloadVariant = 'canonical';
|
||||
}
|
||||
@@ -4434,7 +4434,7 @@ interface SkillManifest {
|
||||
skills: SkillEntry[];
|
||||
roots: RootSummary[];
|
||||
installation: {
|
||||
gsd_skills_installed: boolean;
|
||||
msd_skills_installed: boolean;
|
||||
legacy_claude_commands_installed: boolean;
|
||||
};
|
||||
counts: {
|
||||
@@ -4512,7 +4512,7 @@ function buildSkillManifest(cwd: string, skillsDir: string | null = null): Skill
|
||||
{
|
||||
// Codex's deprecated fallback skill root ($CODEX_HOME/skills). Kept as a
|
||||
// discovery-only legacy root so pre-move installs remain inventoried;
|
||||
// GSD no longer installs here (#2088).
|
||||
// MSD no longer installs here (#2088).
|
||||
root: '~/.codex/skills',
|
||||
path: path.join(getGlobalConfigDir('codex'), 'skills'),
|
||||
scope: 'global',
|
||||
@@ -4520,15 +4520,15 @@ function buildSkillManifest(cwd: string, skillsDir: string | null = null): Skill
|
||||
deprecated: true,
|
||||
},
|
||||
{
|
||||
root: '.claude/gsd-core/skills',
|
||||
path: path.join(os.homedir(), '.claude', 'gsd-core', 'skills'),
|
||||
root: '.claude/msd-core/skills',
|
||||
path: path.join(os.homedir(), '.claude', 'msd-core', 'skills'),
|
||||
scope: 'import-only',
|
||||
kind: 'skills',
|
||||
deprecated: true,
|
||||
},
|
||||
{
|
||||
root: '.claude/commands/gsd',
|
||||
path: path.join(os.homedir(), '.claude', 'commands', 'gsd'),
|
||||
root: '.claude/commands/msd',
|
||||
path: path.join(os.homedir(), '.claude', 'commands', 'msd'),
|
||||
scope: 'legacy-commands',
|
||||
kind: 'commands',
|
||||
deprecated: true,
|
||||
@@ -4580,7 +4580,7 @@ function buildSkillManifest(cwd: string, skillsDir: string | null = null): Skill
|
||||
}
|
||||
|
||||
// Track skill names seen within this root to deduplicate dual-routed concretes
|
||||
// (e.g. spec-phase nested under both gsd-ns-workflow and gsd-ns-manage).
|
||||
// (e.g. spec-phase nested under both msd-ns-workflow and msd-ns-manage).
|
||||
const seenNamesInRoot = new Set<string>();
|
||||
|
||||
function pushSkillEntry(
|
||||
@@ -4640,9 +4640,9 @@ function buildSkillManifest(cwd: string, skillsDir: string | null = null): Skill
|
||||
// Nested layout: <entry>/skills/<stem>/SKILL.md
|
||||
// Used by cline, qwen, hermes, augment, trae, antigravity (#69 nested=true).
|
||||
// Descend exactly one level into <entry>/skills/ — no deeper recursion.
|
||||
// Scope to gsd-ns-* routers only: never vacuum up an unrelated user skill
|
||||
// Scope to msd-ns-* routers only: never vacuum up an unrelated user skill
|
||||
// that happens to have its own `skills/` subdirectory.
|
||||
if (!entry.name.startsWith('gsd-ns-')) continue;
|
||||
if (!entry.name.startsWith('msd-ns-')) continue;
|
||||
const nestedSkillsDir = path.join(rootPath, entry.name, 'skills');
|
||||
let nestedEntries: fs.Dirent[] = [];
|
||||
try {
|
||||
@@ -4672,13 +4672,13 @@ function buildSkillManifest(cwd: string, skillsDir: string | null = null): Skill
|
||||
return rootCmp !== 0 ? rootCmp : a.name.localeCompare(b.name);
|
||||
});
|
||||
|
||||
const gsdSkillsInstalled = skills.some((skill) => skill.name.startsWith('gsd-'));
|
||||
const msdSkillsInstalled = skills.some((skill) => skill.name.startsWith('msd-'));
|
||||
|
||||
return {
|
||||
skills,
|
||||
roots,
|
||||
installation: {
|
||||
gsd_skills_installed: gsdSkillsInstalled,
|
||||
msd_skills_installed: msdSkillsInstalled,
|
||||
legacy_claude_commands_installed: legacyClaudeCommandsInstalled,
|
||||
},
|
||||
counts: {
|
||||
|
||||
Reference in New Issue
Block a user