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:
@@ -1,25 +1,25 @@
|
||||
# GSD CLI Tools Reference
|
||||
# MSD CLI Tools Reference
|
||||
|
||||
> Reference for the `gsd-tools` CLI (`gsd-core/bin/gsd-tools.cjs`). For slash commands and user flows, see [Command Reference](COMMANDS.md). Return to [docs index](README.md).
|
||||
> Reference for the `msd-tools` CLI (`msd-core/bin/msd-tools.cjs`). For slash commands and user flows, see [Command Reference](COMMANDS.md). Return to [docs index](README.md).
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
`gsd-tools.cjs` centralizes config parsing, model resolution, phase lookup, git commits, summary verification, state management, and template operations across GSD commands, workflows, and agents.
|
||||
`msd-tools.cjs` centralizes config parsing, model resolution, phase lookup, git commits, summary verification, state management, and template operations across MSD commands, workflows, and agents.
|
||||
|
||||
|
||||
| | |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| **Shipped path** | `gsd-core/bin/gsd-tools.cjs` |
|
||||
| **Implementation** | 20 domain modules under `gsd-core/bin/lib/` (the directory is authoritative) |
|
||||
| **Shipped path** | `msd-core/bin/msd-tools.cjs` |
|
||||
| **Implementation** | 20 domain modules under `msd-core/bin/lib/` (the directory is authoritative) |
|
||||
| **Status** | Primary runtime command surface for orchestration, workflows, and automation. |
|
||||
|
||||
|
||||
**Usage (CJS):**
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs <command> [args] [--raw] [--cwd <path>]
|
||||
node msd-tools.cjs <command> [args] [--raw] [--cwd <path>]
|
||||
```
|
||||
|
||||
**Global flags (CJS):**
|
||||
@@ -61,7 +61,7 @@ from a field that genuinely held `null` or `''`. That coercion is gone. The
|
||||
common shell idiom
|
||||
|
||||
```bash
|
||||
X=$(gsd_run query some.command --pick some_field 2>/dev/null) || X=default
|
||||
X=$(msd_run query some.command --pick some_field 2>/dev/null) || X=default
|
||||
```
|
||||
|
||||
now works as written: the `|| X=default` arm fires exactly when the field
|
||||
@@ -76,52 +76,52 @@ Manage `.planning/STATE.md` — the project's living memory.
|
||||
|
||||
```bash
|
||||
# Load full project config + state as JSON
|
||||
node gsd-tools.cjs state load
|
||||
node msd-tools.cjs state load
|
||||
|
||||
# Output STATE.md frontmatter as JSON
|
||||
node gsd-tools.cjs state json
|
||||
node msd-tools.cjs state json
|
||||
|
||||
# Update a single field. Frontmatter keys are projections of body fields —
|
||||
# write the body field (see COMMANDS.md#state-update-field-value).
|
||||
node gsd-tools.cjs state update <field> <value>
|
||||
node msd-tools.cjs state update <field> <value>
|
||||
|
||||
# Get STATE.md content or a specific section
|
||||
node gsd-tools.cjs state get [section]
|
||||
node msd-tools.cjs state get [section]
|
||||
|
||||
# Batch update multiple fields
|
||||
node gsd-tools.cjs state patch --field1 val1 --field2 val2
|
||||
node msd-tools.cjs state patch --field1 val1 --field2 val2
|
||||
|
||||
# Increment plan counter
|
||||
node gsd-tools.cjs state advance-plan
|
||||
node msd-tools.cjs state advance-plan
|
||||
# When no labeled plan position can be parsed (e.g. ## Current Position drifted
|
||||
# to pure narrative prose), declines with reason "plan_position_unreadable" plus
|
||||
# the disk-derived counts and the exact labeled lines to re-insert; STATE.md is
|
||||
# left byte-identical.
|
||||
|
||||
# Record execution metrics
|
||||
node gsd-tools.cjs state record-metric --phase N --plan M --duration Xmin [--tasks N] [--files N]
|
||||
node msd-tools.cjs state record-metric --phase N --plan M --duration Xmin [--tasks N] [--files N]
|
||||
|
||||
# Recalculate progress bar
|
||||
node gsd-tools.cjs state update-progress
|
||||
node msd-tools.cjs state update-progress
|
||||
|
||||
# Add a decision
|
||||
node gsd-tools.cjs state add-decision --summary "..." [--phase N] [--rationale "..."]
|
||||
node msd-tools.cjs state add-decision --summary "..." [--phase N] [--rationale "..."]
|
||||
# Or from files:
|
||||
node gsd-tools.cjs state add-decision --summary-file path [--rationale-file path]
|
||||
node msd-tools.cjs state add-decision --summary-file path [--rationale-file path]
|
||||
|
||||
# Add/resolve blockers
|
||||
node gsd-tools.cjs state add-blocker --text "..."
|
||||
node gsd-tools.cjs state resolve-blocker --text "..."
|
||||
node msd-tools.cjs state add-blocker --text "..."
|
||||
node msd-tools.cjs state resolve-blocker --text "..."
|
||||
|
||||
# Record session continuity (at least one of --stopped-at / --resume-file is required)
|
||||
node gsd-tools.cjs state record-session --stopped-at "..." [--resume-file path]
|
||||
node msd-tools.cjs state record-session --stopped-at "..." [--resume-file path]
|
||||
|
||||
# Phase start — update STATE.md Status/Last activity for a new phase
|
||||
node gsd-tools.cjs state begin-phase --phase N --name SLUG --plans COUNT
|
||||
node msd-tools.cjs state begin-phase --phase N --name SLUG --plans COUNT
|
||||
|
||||
# Agent-discoverable blocker signalling (used by discuss-phase / UI flows)
|
||||
node gsd-tools.cjs state signal-waiting --type TYPE --question "..." --options "A|B" --phase P
|
||||
node gsd-tools.cjs state signal-resume
|
||||
node msd-tools.cjs state signal-waiting --type TYPE --question "..." --options "A|B" --phase P
|
||||
node msd-tools.cjs state signal-resume
|
||||
```
|
||||
|
||||
### State Snapshot
|
||||
@@ -129,18 +129,18 @@ node gsd-tools.cjs state signal-resume
|
||||
Structured parse of the full STATE.md:
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs state-snapshot
|
||||
node msd-tools.cjs state-snapshot
|
||||
```
|
||||
|
||||
Returns JSON with: current position, phase, plan, status, decisions, blockers, metrics, last activity.
|
||||
|
||||
### Smart Entry
|
||||
|
||||
Read-only situation classifier used by `/gsd-next`.
|
||||
Read-only situation classifier used by `/msd-next`.
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs smart-entry # Human summary + recommended route
|
||||
node gsd-tools.cjs smart-entry --json # Machine-readable result for workflows
|
||||
node msd-tools.cjs smart-entry # Human summary + recommended route
|
||||
node msd-tools.cjs smart-entry --json # Machine-readable result for workflows
|
||||
```
|
||||
|
||||
The JSON result contains `situation`, `recommended`, `summary`, `signals`, and ordered `actions[]`. Detection reads `.planning/STATE.md`, `ROADMAP.md`, latest verification/summary artifacts, and git status; it does not write files or dispatch commands.
|
||||
@@ -153,38 +153,38 @@ Manage phases — directories, numbering, and roadmap sync.
|
||||
|
||||
```bash
|
||||
# Find phase directory by number
|
||||
node gsd-tools.cjs find-phase <phase>
|
||||
node msd-tools.cjs find-phase <phase>
|
||||
|
||||
# Calculate next decimal phase number for insertions
|
||||
node gsd-tools.cjs phase next-decimal <phase>
|
||||
node msd-tools.cjs phase next-decimal <phase>
|
||||
|
||||
# Append new phase to roadmap + create directory
|
||||
node gsd-tools.cjs phase add <description>
|
||||
node msd-tools.cjs phase add <description>
|
||||
|
||||
# Insert decimal phase after existing
|
||||
node gsd-tools.cjs phase insert <after> <description> [--sibling]
|
||||
node msd-tools.cjs phase insert <after> <description> [--sibling]
|
||||
|
||||
# Remove phase, renumber subsequent
|
||||
node gsd-tools.cjs phase remove <phase> [--force]
|
||||
node msd-tools.cjs phase remove <phase> [--force]
|
||||
|
||||
# Mark phase complete, update state + roadmap
|
||||
# Also emits advisory `warnings[]` when a phase SUMMARY references a file that
|
||||
# is not on disk — see "Phase SUMMARY artifact check" below.
|
||||
node gsd-tools.cjs phase complete <phase>
|
||||
node msd-tools.cjs phase complete <phase>
|
||||
|
||||
# Evaluate HUMAN-UAT results for a phase (markdown-aware; ignores false-positive contexts)
|
||||
# Returns JSON: { passed, uat_files[], verification_files[], checks[], blockers[], policy }
|
||||
node gsd-tools.cjs phase uat-passed <phase> [--require-verification]
|
||||
node msd-tools.cjs phase uat-passed <phase> [--require-verification]
|
||||
|
||||
# Index plans with waves and status
|
||||
node gsd-tools.cjs phase-plan-index <phase>
|
||||
node msd-tools.cjs phase-plan-index <phase>
|
||||
|
||||
# List phases with filtering
|
||||
node gsd-tools.cjs phases list [--type planned|executed|all] [--phase N] [--include-archived]
|
||||
node msd-tools.cjs phases list [--type planned|executed|all] [--phase N] [--include-archived]
|
||||
|
||||
# Archive (or, with --force, permanently delete) every current phase directory —
|
||||
# used by /gsd-new-milestone before roadmapping the next cycle
|
||||
node gsd-tools.cjs phases clear [--confirm] [--force] [--archive-version <version>]
|
||||
# used by /msd-new-milestone before roadmapping the next cycle
|
||||
node msd-tools.cjs phases clear [--confirm] [--force] [--archive-version <version>]
|
||||
```
|
||||
|
||||
### Milestone-scoped phase listing (`phases list`)
|
||||
@@ -238,7 +238,7 @@ and any path that is not on disk is reported in the command's existing
|
||||
`warnings[]` array — the case where a summary reports work that never landed.
|
||||
|
||||
**Advisory only.** Findings never block completion; the completion gate is the
|
||||
phase's `VERIFICATION.md` status, which this does not touch. `/gsd-execute-phase`
|
||||
phase's `VERIFICATION.md` status, which this does not touch. `/msd-execute-phase`
|
||||
surfaces the warnings before advancing.
|
||||
|
||||
Scope and limits, so the output is not read as more than it is:
|
||||
@@ -425,13 +425,13 @@ Parse and update `ROADMAP.md`.
|
||||
|
||||
```bash
|
||||
# Extract phase section from ROADMAP.md
|
||||
node gsd-tools.cjs roadmap get-phase <phase>
|
||||
node msd-tools.cjs roadmap get-phase <phase>
|
||||
|
||||
# Full roadmap parse with disk status
|
||||
node gsd-tools.cjs roadmap analyze
|
||||
node msd-tools.cjs roadmap analyze
|
||||
|
||||
# Update progress table row from disk
|
||||
node gsd-tools.cjs roadmap update-plan-progress <N>
|
||||
node msd-tools.cjs roadmap update-plan-progress <N>
|
||||
```
|
||||
|
||||
When the phase has no writable ROADMAP entry — no matching Progress-table row,
|
||||
@@ -477,7 +477,7 @@ rather than a number computed from a truncated, unscoped, or unreadable set:
|
||||
| `stats --raw` | `percent: null`, `plan_percent: null` |
|
||||
| `query progress --raw` | `percent: null` |
|
||||
| `state json --raw` | `progress.percent` is **omitted** from the `progress` object (not `0`, not present as `null`) |
|
||||
| `state update-progress --raw` | `false` — no write; `STATE.md`'s Progress field is left untouched, and a `[gsd-tools] WARNING:` line is written to stderr naming the scope |
|
||||
| `state update-progress --raw` | `false` — no write; `STATE.md`'s Progress field is left untouched, and a `[msd-tools] WARNING:` line is written to stderr naming the scope |
|
||||
|
||||
`0` is a legitimate, real answer under a `complete` scope (e.g. a
|
||||
freshly-declared milestone with zero phases, or a phase with zero plan files)
|
||||
@@ -545,28 +545,28 @@ Read and write `.planning/config.json`.
|
||||
|
||||
```bash
|
||||
# Initialize config.json with defaults
|
||||
node gsd-tools.cjs config-ensure-section
|
||||
node msd-tools.cjs config-ensure-section
|
||||
|
||||
# Set a config value (dot notation)
|
||||
node gsd-tools.cjs config-set <key> <value>
|
||||
node msd-tools.cjs config-set <key> <value>
|
||||
|
||||
# Get a config value
|
||||
node gsd-tools.cjs config-get <key>
|
||||
node msd-tools.cjs config-get <key>
|
||||
|
||||
# Set model profile
|
||||
node gsd-tools.cjs config-set-model-profile <profile>
|
||||
node msd-tools.cjs config-set-model-profile <profile>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Capability Commands
|
||||
|
||||
The capability command family resolves and mutates capability state (ADR-857). One resolved state composes three substrates: the install profile (`.gsd-profile`), the runtime surface (`.gsd-surface.json`), and config gates (`.planning/config.json` `workflow.*`). `enabled = installed && surfaced`; a hook is `active` only when its capability is enabled and its config gate is on.
|
||||
The capability command family resolves and mutates capability state (ADR-857). One resolved state composes three substrates: the install profile (`.msd-profile`), the runtime surface (`.msd-surface.json`), and config gates (`.planning/config.json` `workflow.*`). `enabled = installed && surfaced`; a hook is `active` only when its capability is enabled and its config gate is on.
|
||||
|
||||
### `capability state`
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs capability state [--config-dir <path>] [--raw]
|
||||
node msd-tools.cjs capability state [--config-dir <path>] [--raw]
|
||||
```
|
||||
|
||||
Resolves and prints every capability's `installed`, `surfaced`, `enabled`, and per-hook `active` state. Read-only. `--config-dir` selects the runtime config directory (defaults to the resolved Claude home). `--raw` emits JSON.
|
||||
@@ -574,7 +574,7 @@ Resolves and prints every capability's `installed`, `surfaced`, `enabled`, and p
|
||||
### `capability set`
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs capability set <id> [--on | --off] [--gate <key>=<true|false>]... [--config-dir <path>] [--runtime <name>] [--scope <global|project>] [--raw]
|
||||
node msd-tools.cjs capability set <id> [--on | --off] [--gate <key>=<true|false>]... [--config-dir <path>] [--runtime <name>] [--scope <global|project>] [--raw]
|
||||
```
|
||||
|
||||
Mutates one capability, re-resolves, and reports the result. Two axes:
|
||||
@@ -589,10 +589,10 @@ After writing, the command re-resolves and prints two message classes to stderr:
|
||||
|
||||
```bash
|
||||
# Turn the UI capability off
|
||||
node gsd-tools.cjs capability set ui --off --config-dir ~/.claude
|
||||
node msd-tools.cjs capability set ui --off --config-dir ~/.claude
|
||||
|
||||
# Keep the capability on, gate one hook off
|
||||
node gsd-tools.cjs capability set code-review --gate workflow.code_review=false
|
||||
node msd-tools.cjs capability set code-review --gate workflow.code_review=false
|
||||
```
|
||||
|
||||
---
|
||||
@@ -602,10 +602,10 @@ node gsd-tools.cjs capability set code-review --gate workflow.code_review=false
|
||||
### `query teams-status`
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs query teams-status [--active]
|
||||
node msd-tools.cjs query teams-status [--active]
|
||||
```
|
||||
|
||||
Read-only detector for claude-code's experimental agent-teams feature (issue #1355). Resolves the runtime via the canonical `GSD_RUNTIME` → `config.runtime` → per-install runtime marker → `'claude'` precedence (#3897), then checks `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS`.
|
||||
Read-only detector for claude-code's experimental agent-teams feature (issue #1355). Resolves the runtime via the canonical `MSD_RUNTIME` → `config.runtime` → per-install runtime marker → `'claude'` precedence (#3897), then checks `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS`.
|
||||
|
||||
**Default (no flags):** prints a JSON object and exits 0:
|
||||
|
||||
@@ -630,7 +630,7 @@ Fields:
|
||||
**`--active` flag:** exits 0 if `active` is true, exits 1 otherwise. Prints nothing. Useful in bash conditionals:
|
||||
|
||||
```bash
|
||||
if gsd_run query teams-status --active >/dev/null 2>&1; then
|
||||
if msd_run query teams-status --active >/dev/null 2>&1; then
|
||||
echo "agent-teams is on"
|
||||
fi
|
||||
```
|
||||
@@ -642,10 +642,10 @@ This command is strictly read-only — no config writes, no disk mutation.
|
||||
### `query eval.score`
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs query eval.score --covered <N> --total <N> --infra <tooling>,<dataset>,<cicd>,<guardrails>,<tracing>
|
||||
node msd-tools.cjs query eval.score --covered <N> --total <N> --infra <tooling>,<dataset>,<cicd>,<guardrails>,<tracing>
|
||||
```
|
||||
|
||||
Deterministic scorer for eval-auditor results. Computes coverage, infrastructure, and overall scores from audited inputs. Called by `gsd-eval-auditor` in its `calculate_scores` step — agents must not recompute these values by hand.
|
||||
Deterministic scorer for eval-auditor results. Computes coverage, infrastructure, and overall scores from audited inputs. Called by `msd-eval-auditor` in its `calculate_scores` step — agents must not recompute these values by hand.
|
||||
|
||||
**Inputs:**
|
||||
|
||||
@@ -667,7 +667,7 @@ Deterministic scorer for eval-auditor results. Computes coverage, infrastructure
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs query eval.score --covered 3 --total 5 --infra ok,partial,missing,ok,ok
|
||||
node msd-tools.cjs query eval.score --covered 3 --total 5 --infra ok,partial,missing,ok,ok
|
||||
# → {"coverage_score":60,"infra_score":70,"overall_score":64,"verdict":"NEEDS WORK"}
|
||||
```
|
||||
|
||||
@@ -678,7 +678,7 @@ This command is strictly read-only — no config writes, no disk mutation.
|
||||
### `query context-predicates`
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs query context-predicates --class <CLASS> | --prefix <dotted.prefix> | --contains <text>
|
||||
node msd-tools.cjs query context-predicates --class <CLASS> | --prefix <dotted.prefix> | --contains <text>
|
||||
```
|
||||
|
||||
Selector surface for the `CONTEXT.md` predicate fact-store (ADR-1671, #2928). Parses the repo-root `CONTEXT.md` **live** on every call via the compiled `context-predicates.cjs` — it never reads the committed `docs/CONTEXT-INDEX.json` (that artifact is a CI drift-guard byproduct, not a query source, so it can never go stale relative to the live predicates it answers about).
|
||||
@@ -712,14 +712,14 @@ hatch for a flag-shaped value the space-separated form cannot express — e.g.
|
||||
| `matched` | number | Count of predicates satisfying all given selectors |
|
||||
| `predicates` | array | Each entry is a live `Predicate` — `id`, `klass`, `value`, `line` (1-based source line), `section` (nearest enclosing heading) |
|
||||
|
||||
This command is strictly read-only — no config writes, no disk mutation. See [ADR-1671](adr/1671-dynamic-context-management-platform.md) and [Architecture — CLI Tools](ARCHITECTURE.md#cli-tools-gsd-corebin).
|
||||
This command is strictly read-only — no config writes, no disk mutation. See [ADR-1671](adr/1671-dynamic-context-management-platform.md) and [Architecture — CLI Tools](ARCHITECTURE.md#cli-tools-msd-corebin).
|
||||
|
||||
---
|
||||
|
||||
## Intel Commands
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs intel query <term>
|
||||
node msd-tools.cjs intel query <term>
|
||||
```
|
||||
|
||||
Searches every JSON intel file under `.planning/intel/` (keys and values, including
|
||||
@@ -756,13 +756,13 @@ and its result is unchanged.
|
||||
|
||||
```bash
|
||||
# Get model for agent based on current profile
|
||||
node gsd-tools.cjs resolve-model <agent-name>
|
||||
node msd-tools.cjs resolve-model <agent-name>
|
||||
# Raw output returns the selected model ID/tier.
|
||||
# JSON output also includes profile and, when the active runtime supports it,
|
||||
# reasoning_effort.
|
||||
```
|
||||
|
||||
Agent names: `gsd-planner`, `gsd-executor`, `gsd-phase-researcher`, `gsd-project-researcher`, `gsd-research-synthesizer`, `gsd-verifier`, `gsd-plan-checker`, `gsd-integration-checker`, `gsd-roadmapper`, `gsd-debugger`, `gsd-codebase-mapper`, `gsd-nyquist-auditor`
|
||||
Agent names: `msd-planner`, `msd-executor`, `msd-phase-researcher`, `msd-project-researcher`, `msd-research-synthesizer`, `msd-verifier`, `msd-plan-checker`, `msd-integration-checker`, `msd-roadmapper`, `msd-debugger`, `msd-codebase-mapper`, `msd-nyquist-auditor`
|
||||
|
||||
---
|
||||
|
||||
@@ -772,25 +772,25 @@ Validate plans, phases, references, and commits.
|
||||
|
||||
```bash
|
||||
# Verify SUMMARY.md file
|
||||
node gsd-tools.cjs verify-summary <path> [--check-count N]
|
||||
node msd-tools.cjs verify-summary <path> [--check-count N]
|
||||
|
||||
# Check PLAN.md structure + tasks
|
||||
node gsd-tools.cjs verify plan-structure <file>
|
||||
node msd-tools.cjs verify plan-structure <file>
|
||||
|
||||
# Check all plans have summaries
|
||||
node gsd-tools.cjs verify phase-completeness <phase>
|
||||
node msd-tools.cjs verify phase-completeness <phase>
|
||||
|
||||
# Check @-refs + paths resolve
|
||||
node gsd-tools.cjs verify references <file>
|
||||
node msd-tools.cjs verify references <file>
|
||||
|
||||
# Batch verify commit hashes
|
||||
node gsd-tools.cjs verify commits <hash1> [hash2] ...
|
||||
node msd-tools.cjs verify commits <hash1> [hash2] ...
|
||||
|
||||
# Check must_haves.artifacts
|
||||
node gsd-tools.cjs verify artifacts <plan-file>
|
||||
node msd-tools.cjs verify artifacts <plan-file>
|
||||
|
||||
# Check must_haves.key_links
|
||||
node gsd-tools.cjs verify key-links <plan-file>
|
||||
node msd-tools.cjs verify key-links <plan-file>
|
||||
```
|
||||
|
||||
`verify key-links` confines each link's `from:`/`to:` to the project directory (#3493): a path that resolves outside the project (via `../` traversal, an absolute path, or a symlink) is never read. That link's `links[]` entry reports `path_rejected: "from"` or `path_rejected: "to"` (whichever field was rejected) alongside `verified: false`, without echoing the underlying path-confinement error (which would embed an absolute host path). A rejected link fails independently — it does not abort evaluation of the other links in the same plan, and does not set `path_rejected` on links whose paths resolve inside the project.
|
||||
@@ -803,23 +803,23 @@ Check project integrity.
|
||||
|
||||
```bash
|
||||
# Check phase numbering, disk/roadmap sync
|
||||
node gsd-tools.cjs validate consistency
|
||||
node msd-tools.cjs validate consistency
|
||||
|
||||
# Check .planning/ integrity, optionally repair
|
||||
node gsd-tools.cjs validate health [--repair]
|
||||
node msd-tools.cjs validate health [--repair]
|
||||
|
||||
# Probe context-window utilization for status-line / hook callers (v1.40.0)
|
||||
node gsd-tools.cjs validate context
|
||||
node msd-tools.cjs validate context
|
||||
|
||||
# Context utilization as typed JSON surface (#455)
|
||||
node gsd-tools.cjs validate context --json
|
||||
node msd-tools.cjs validate context --json
|
||||
```
|
||||
|
||||
`validate consistency`'s `warnings` entries are coded diagnostics (`{code, message, fix, repairable}`), not bare strings. A phase declared in ROADMAP.md with no directory on disk, or a directory on disk with no ROADMAP.md entry, reports under `W006`/`W007` — the same codes `validate health` uses for the identical check, since it's one enumeration with two callers, not a separate check. The four subjects unique to this command (numbering gaps in phases or plans, orphan `*-SUMMARY.md` files, plans missing `wave` frontmatter) use a new `C0NN` code range (`C001`-`C004`).
|
||||
|
||||
`validate context` emits a structured envelope with `utilization`, `status`
|
||||
(`ok` / `warn` / `critical` at the 60 % / 70 % thresholds), and a
|
||||
`suggestion` string. The same data backs `/gsd-health --context`.
|
||||
`suggestion` string. The same data backs `/msd-health --context`.
|
||||
Pass `--json` to receive the typed IR directly (useful in scripts and test assertions).
|
||||
|
||||
---
|
||||
@@ -832,11 +832,11 @@ Emits a read-only, schema-versioned snapshot of everything `.planning/` knows,
|
||||
as one JSON document. It exists so a downstream tool — a harness UI, a
|
||||
mission-control view, a dashboard — can consume planning state without parsing
|
||||
`ROADMAP.md` / `REQUIREMENTS.md` / `*-PLAN.md` / `*-SUMMARY.md` a second time
|
||||
and drifting from gsd-core's own answers.
|
||||
and drifting from msd-core's own answers.
|
||||
|
||||
```bash
|
||||
gsd-tools query planning inspect
|
||||
gsd-tools query planning.inspect # dotted canonical form — identical output
|
||||
msd-tools query planning inspect
|
||||
msd-tools query planning.inspect # dotted canonical form — identical output
|
||||
```
|
||||
|
||||
**Takes no arguments.** A stray positional or an unrecognized flag is a
|
||||
@@ -915,7 +915,7 @@ and progress surfaces follow, for the same reason. See
|
||||
#### Large payloads
|
||||
|
||||
Output over ~50 KB is written to a temp file and returned as
|
||||
`@file:<path>`, which `gsd-tools` resolves transparently before writing to
|
||||
`@file:<path>`, which `msd-tools` resolves transparently before writing to
|
||||
stdout — the same channel `init` uses. Callers see JSON either way.
|
||||
|
||||
---
|
||||
@@ -926,10 +926,10 @@ Template selection and filling.
|
||||
|
||||
```bash
|
||||
# Select summary template based on granularity
|
||||
node gsd-tools.cjs template select <type>
|
||||
node msd-tools.cjs template select <type>
|
||||
|
||||
# Fill template with variables
|
||||
node gsd-tools.cjs template fill <type> --phase N [--plan M] [--name "..."] [--type execute|tdd] [--wave N] [--fields '{json}']
|
||||
node msd-tools.cjs template fill <type> --phase N [--plan M] [--name "..."] [--type execute|tdd] [--wave N] [--fields '{json}']
|
||||
```
|
||||
|
||||
Template types for `fill`: `summary`, `plan`, `verification`
|
||||
@@ -942,16 +942,16 @@ YAML frontmatter CRUD operations on any Markdown file.
|
||||
|
||||
```bash
|
||||
# Extract frontmatter as JSON
|
||||
node gsd-tools.cjs frontmatter get <file> [--field key]
|
||||
node msd-tools.cjs frontmatter get <file> [--field key]
|
||||
|
||||
# Update single field
|
||||
node gsd-tools.cjs frontmatter set <file> --field key --value jsonVal
|
||||
node msd-tools.cjs frontmatter set <file> --field key --value jsonVal
|
||||
|
||||
# Merge JSON into frontmatter
|
||||
node gsd-tools.cjs frontmatter merge <file> --data '{json}'
|
||||
node msd-tools.cjs frontmatter merge <file> --data '{json}'
|
||||
|
||||
# Validate required fields
|
||||
node gsd-tools.cjs frontmatter validate <file> --schema plan|summary|verification
|
||||
node msd-tools.cjs frontmatter validate <file> --schema plan|summary|verification
|
||||
```
|
||||
|
||||
---
|
||||
@@ -962,57 +962,57 @@ Create pre-structured files and directories.
|
||||
|
||||
```bash
|
||||
# Create CONTEXT.md template
|
||||
node gsd-tools.cjs scaffold context --phase N
|
||||
node msd-tools.cjs scaffold context --phase N
|
||||
|
||||
# Create UAT.md template
|
||||
node gsd-tools.cjs scaffold uat --phase N
|
||||
node msd-tools.cjs scaffold uat --phase N
|
||||
|
||||
# Create VERIFICATION.md template
|
||||
node gsd-tools.cjs scaffold verification --phase N
|
||||
node msd-tools.cjs scaffold verification --phase N
|
||||
|
||||
# Create phase directory
|
||||
node gsd-tools.cjs scaffold phase-dir --phase N --name "phase name"
|
||||
node msd-tools.cjs scaffold phase-dir --phase N --name "phase name"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Init Commands (Compound Context Loading)
|
||||
|
||||
Load all context needed for a specific workflow in one call. Returns JSON with project info, config, state, and workflow-specific data. `init onboard [--fast] [--text]` reports brownfield signals, planning-doc candidates, codebase-map completeness, fast-map readiness, text-mode routing, partial planning state, and onboarding summary status for `/gsd-onboard`.
|
||||
Load all context needed for a specific workflow in one call. Returns JSON with project info, config, state, and workflow-specific data. `init onboard [--fast] [--text]` reports brownfield signals, planning-doc candidates, codebase-map completeness, fast-map readiness, text-mode routing, partial planning state, and onboarding summary status for `/msd-onboard`.
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs init execute-phase <phase>
|
||||
node gsd-tools.cjs init plan-phase <phase>
|
||||
node gsd-tools.cjs init new-project
|
||||
node gsd-tools.cjs init new-milestone
|
||||
node gsd-tools.cjs init onboard [--fast] [--text]
|
||||
node gsd-tools.cjs init quick <description>
|
||||
node gsd-tools.cjs init resume
|
||||
node gsd-tools.cjs init verify-work <phase>
|
||||
node gsd-tools.cjs init phase-op <phase>
|
||||
node gsd-tools.cjs init code-review <phase> [--fix]
|
||||
node gsd-tools.cjs init review <phase>
|
||||
node gsd-tools.cjs init discuss-phase-assumptions <phase> [--auto]
|
||||
node gsd-tools.cjs init todos [area]
|
||||
node gsd-tools.cjs init milestone-op
|
||||
node gsd-tools.cjs init map-codebase
|
||||
node gsd-tools.cjs init progress
|
||||
node gsd-tools.cjs init manager
|
||||
node gsd-tools.cjs init complete-milestone
|
||||
node gsd-tools.cjs init autonomous [--converge] [--cross-ai]
|
||||
node gsd-tools.cjs init docs-update
|
||||
node gsd-tools.cjs init update [--next] [--rc]
|
||||
node gsd-tools.cjs init transition
|
||||
node msd-tools.cjs init execute-phase <phase>
|
||||
node msd-tools.cjs init plan-phase <phase>
|
||||
node msd-tools.cjs init new-project
|
||||
node msd-tools.cjs init new-milestone
|
||||
node msd-tools.cjs init onboard [--fast] [--text]
|
||||
node msd-tools.cjs init quick <description>
|
||||
node msd-tools.cjs init resume
|
||||
node msd-tools.cjs init verify-work <phase>
|
||||
node msd-tools.cjs init phase-op <phase>
|
||||
node msd-tools.cjs init code-review <phase> [--fix]
|
||||
node msd-tools.cjs init review <phase>
|
||||
node msd-tools.cjs init discuss-phase-assumptions <phase> [--auto]
|
||||
node msd-tools.cjs init todos [area]
|
||||
node msd-tools.cjs init milestone-op
|
||||
node msd-tools.cjs init map-codebase
|
||||
node msd-tools.cjs init progress
|
||||
node msd-tools.cjs init manager
|
||||
node msd-tools.cjs init complete-milestone
|
||||
node msd-tools.cjs init autonomous [--converge] [--cross-ai]
|
||||
node msd-tools.cjs init docs-update
|
||||
node msd-tools.cjs init update [--next] [--rc]
|
||||
node msd-tools.cjs init transition
|
||||
|
||||
# Workstream-scoped init (`--ws` flag)
|
||||
node gsd-tools.cjs init execute-phase <phase> --ws <name>
|
||||
node gsd-tools.cjs init plan-phase <phase> --ws <name>
|
||||
node msd-tools.cjs init execute-phase <phase> --ws <name>
|
||||
node msd-tools.cjs init plan-phase <phase> --ws <name>
|
||||
```
|
||||
|
||||
**Large payload handling:** When output exceeds ~50KB, the CLI writes to a temp file and returns `@file:/tmp/gsd-init-XXXXX.json`. Workflows check for the `@file:` prefix and read from disk:
|
||||
**Large payload handling:** When output exceeds ~50KB, the CLI writes to a temp file and returns `@file:/tmp/msd-init-XXXXX.json`. Workflows check for the `@file:` prefix and read from disk:
|
||||
|
||||
```bash
|
||||
INIT=$(node gsd-tools.cjs init execute-phase "1")
|
||||
INIT=$(node msd-tools.cjs init execute-phase "1")
|
||||
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
||||
```
|
||||
|
||||
@@ -1022,13 +1022,13 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
||||
|
||||
```bash
|
||||
# Archive milestone
|
||||
node gsd-tools.cjs milestone complete <version> (--confirm | --dry-run) [--name <name>] [--no-archive-phases] [--force] [--archive-quick]
|
||||
node msd-tools.cjs milestone complete <version> (--confirm | --dry-run) [--name <name>] [--no-archive-phases] [--force] [--archive-quick]
|
||||
|
||||
# Archive .planning/quick/* into milestones/<version>-quick/ WITHOUT the milestone complete close-out (#2142)
|
||||
node gsd-tools.cjs milestone archive-quick <version> [--dry-run]
|
||||
node msd-tools.cjs milestone archive-quick <version> [--dry-run]
|
||||
|
||||
# Mark requirements as complete
|
||||
node gsd-tools.cjs requirements mark-complete <ids>
|
||||
node msd-tools.cjs requirements mark-complete <ids>
|
||||
# Accepts: REQ-01,REQ-02 or REQ-01 REQ-02 or [REQ-01, REQ-02]
|
||||
```
|
||||
|
||||
@@ -1050,7 +1050,7 @@ node gsd-tools.cjs requirements mark-complete <ids>
|
||||
|
||||
**`milestone archive-quick` (#2142 escalation)**
|
||||
|
||||
A narrower sibling of `milestone complete --archive-quick`, for callers that need to sweep `.planning/quick/*` WITHOUT the full milestone close-out — chiefly `gsd-core/workflows/cleanup.md`, which runs against milestones that are typically already completed.
|
||||
A narrower sibling of `milestone complete --archive-quick`, for callers that need to sweep `.planning/quick/*` WITHOUT the full milestone close-out — chiefly `msd-core/workflows/cleanup.md`, which runs against milestones that are typically already completed.
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
@@ -1069,10 +1069,10 @@ Emit the skill block for a given agent type.
|
||||
|
||||
```bash
|
||||
# Emit raw XML skill block (default — safe for shell expansion)
|
||||
node gsd-tools.cjs agent-skills <agent-type>
|
||||
node msd-tools.cjs agent-skills <agent-type>
|
||||
|
||||
# Emit typed JSON surface (#455) — { agent_type, block, skills_count, warnings, configured, reason, source, degraded }
|
||||
node gsd-tools.cjs agent-skills <agent-type> --json
|
||||
node msd-tools.cjs agent-skills <agent-type> --json
|
||||
```
|
||||
|
||||
The `--json` flag returns a typed IR object suitable for structured consumption and test assertions, while the default (no flag) preserves the raw XML output that workflow shell expansions rely on.
|
||||
@@ -1087,7 +1087,7 @@ The `--json` flag returns a typed IR object suitable for structured consumption
|
||||
| `warnings` | `string[]` | Per-path warnings for skills that were skipped (missing `SKILL.md`, unsafe path, etc.). Empty when all configured paths resolved. |
|
||||
| `configured` | `boolean` | `true` when the agent type appears in `agent_skills` in the config; `false` when the key is absent entirely. |
|
||||
| `reason` | `string` | Resolution reason: `"resolved"` (block non-empty), `"not_configured"` (agent not in `agent_skills` — silent), `"configured_empty"` (configured but paths list is empty — emits stderr WARNING), `"configured_unresolved"` (configured with paths but all failed to resolve — emits stderr WARNING). |
|
||||
| `source` | `string` | Config provenance: `"root"` (`.planning/config.json`), `"workstream"` (workstream-scoped config), `"global-defaults"` (`~/.gsd/defaults.json`), `"builtin-defaults"` (no project config). |
|
||||
| `source` | `string` | Config provenance: `"root"` (`.planning/config.json`), `"workstream"` (workstream-scoped config), `"global-defaults"` (`~/.msd/defaults.json`), `"builtin-defaults"` (no project config). |
|
||||
| `degraded` | `boolean` | `true` when a workstream was requested but its config.json was absent and the command fell back to root config; `false` otherwise. |
|
||||
|
||||
The command anchors to the project root via `findProjectRoot` before loading config, so invoking it from a descendant subdirectory resolves the same config as the project root.
|
||||
@@ -1100,13 +1100,13 @@ Pre-compute and cache skill discovery for faster command loading.
|
||||
|
||||
```bash
|
||||
# Generate skill manifest (writes to .claude/skill-manifest.json)
|
||||
node gsd-tools.cjs skill-manifest
|
||||
node msd-tools.cjs skill-manifest
|
||||
|
||||
# Generate with custom output path
|
||||
node gsd-tools.cjs skill-manifest --output <path>
|
||||
node msd-tools.cjs skill-manifest --output <path>
|
||||
```
|
||||
|
||||
Returns JSON mapping of all available GSD skills with their metadata (name, description, file path, argument hints). Used by the installer and session-start hooks to avoid repeated filesystem scans.
|
||||
Returns JSON mapping of all available MSD skills with their metadata (name, description, file path, argument hints). Used by the installer and session-start hooks to avoid repeated filesystem scans.
|
||||
|
||||
---
|
||||
|
||||
@@ -1114,27 +1114,27 @@ Returns JSON mapping of all available GSD skills with their metadata (name, desc
|
||||
|
||||
```bash
|
||||
# Convert text to URL-safe slug
|
||||
node gsd-tools.cjs generate-slug "Some Text Here"
|
||||
node msd-tools.cjs generate-slug "Some Text Here"
|
||||
# → some-text-here
|
||||
|
||||
# Get timestamp
|
||||
node gsd-tools.cjs current-timestamp [full|date|filename]
|
||||
node msd-tools.cjs current-timestamp [full|date|filename]
|
||||
|
||||
# Count and list pending todos
|
||||
node gsd-tools.cjs list-todos [area]
|
||||
node msd-tools.cjs list-todos [area]
|
||||
|
||||
# List captured seeds (optionally filter by status: dormant|active|triggered)
|
||||
node gsd-tools.cjs list-seeds [status]
|
||||
node msd-tools.cjs list-seeds [status]
|
||||
|
||||
# Check file/directory existence
|
||||
node gsd-tools.cjs verify-path-exists <path>
|
||||
node msd-tools.cjs verify-path-exists <path>
|
||||
|
||||
# Append a row to STATE.md's "Quick Tasks Completed" table (schema-backed; #2133)
|
||||
node gsd-tools.cjs quick-tasks-append --task "<description>"
|
||||
node msd-tools.cjs quick-tasks-append --task "<description>"
|
||||
# Optional (#3356) — supply a real quick id and task directory to write the canonical row the
|
||||
# `/gsd-quick` workflow itself renders, instead of a positional `#` and an em-dash `Directory`:
|
||||
node gsd-tools.cjs quick-tasks-append --task "<description>" --quick-id <id> --slug <slug>
|
||||
node gsd-tools.cjs quick-tasks-append --task "<description>" --directory "[<id>-<slug>](./quick/<id>-<slug>/)"
|
||||
# `/msd-quick` workflow itself renders, instead of a positional `#` and an em-dash `Directory`:
|
||||
node msd-tools.cjs quick-tasks-append --task "<description>" --quick-id <id> --slug <slug>
|
||||
node msd-tools.cjs quick-tasks-append --task "<description>" --directory "[<id>-<slug>](./quick/<id>-<slug>/)"
|
||||
# All three flags are optional. Omit them (as `fast.md` does, having neither an id nor a task
|
||||
# directory) and the emitted row is byte-identical to the pre-#3356 behavior. `--directory` wins
|
||||
# outright when given; otherwise `--quick-id` + `--slug` together derive the permalink.
|
||||
@@ -1144,19 +1144,19 @@ node gsd-tools.cjs quick-tasks-append --task "<description>" --directory "[<id>-
|
||||
# milestones/<version>-quick/ and clears this table, without a full `milestone complete`.
|
||||
|
||||
# Aggregate all SUMMARY.md data
|
||||
node gsd-tools.cjs history-digest
|
||||
node msd-tools.cjs history-digest
|
||||
|
||||
# Extract structured data from SUMMARY.md
|
||||
node gsd-tools.cjs summary-extract <path> [--fields field1,field2]
|
||||
node msd-tools.cjs summary-extract <path> [--fields field1,field2]
|
||||
|
||||
# Project statistics
|
||||
node gsd-tools.cjs stats [json|table]
|
||||
node msd-tools.cjs stats [json|table]
|
||||
|
||||
# Progress rendering (human-readable)
|
||||
node gsd-tools.cjs progress [json|table|bar]
|
||||
node msd-tools.cjs progress [json|table|bar]
|
||||
|
||||
# Progress as typed JSON surface (#455)
|
||||
node gsd-tools.cjs progress --json
|
||||
node msd-tools.cjs progress --json
|
||||
```
|
||||
|
||||
Both `stats` and `progress` are scoped to the current milestone's `ROADMAP.md`
|
||||
@@ -1168,13 +1168,13 @@ active window are still outstanding.
|
||||
On a project explicitly configured with `phase_id_convention: "bracket"`, both
|
||||
JSON surfaces keep the phase's bare join key in `phases[].number` and add its
|
||||
canonical human label in `phases[].display_id` (for example,
|
||||
`{"number":"05.03","display_id":"[GSD.02] 05.03"}`). Their
|
||||
`milestone_version` and table headings use `[GSD.02]` rather than the legacy
|
||||
`{"number":"05.03","display_id":"[MSD.02] 05.03"}`). Their
|
||||
`milestone_version` and table headings use `[MSD.02]` rather than the legacy
|
||||
`v2.0` marker. Other conventions retain their prior object and table shapes.
|
||||
|
||||
```bash
|
||||
# Complete a todo
|
||||
node gsd-tools.cjs todo complete <filename> [--dry-run]
|
||||
node msd-tools.cjs todo complete <filename> [--dry-run]
|
||||
```
|
||||
|
||||
`--dry-run` previews the completion (a `dry_run`/`would_*` JSON payload naming
|
||||
@@ -1200,53 +1200,53 @@ terms rather than previewing a resolved outside path.
|
||||
|
||||
```bash
|
||||
# UAT audit — scan all phases for unresolved items
|
||||
node gsd-tools.cjs audit-uat
|
||||
node msd-tools.cjs audit-uat
|
||||
|
||||
# Cross-artifact audit queue — scan `.planning/` for unresolved audit items
|
||||
node gsd-tools.cjs audit-open [--json]
|
||||
node msd-tools.cjs audit-open [--json]
|
||||
|
||||
# Suppress one open audit item — writes a self-invalidating `audit_acknowledged`
|
||||
# marker; never overwrites the artifact's own `status:` (except `deferred_items`,
|
||||
# where the marker IS the entry's `status:`). See docs/COMMANDS.md's
|
||||
# `/gsd-complete-milestone` entry for the full per-category identifier flag table.
|
||||
node gsd-tools.cjs audit-open acknowledge --category <category> --milestone <version> [--at <date>] <identifier flags…>
|
||||
# `/msd-complete-milestone` entry for the full per-category identifier flag table.
|
||||
node msd-tools.cjs audit-open acknowledge --category <category> --milestone <version> [--at <date>] <identifier flags…>
|
||||
|
||||
# Reverse-migrate a GSD-2 project into the current structure (backs `/gsd-import --from-gsd2`)
|
||||
node gsd-tools.cjs from-gsd2 [--path <dir>] [--force] [--dry-run]
|
||||
# Reverse-migrate a GSD-2 project into the current structure (backs `/msd-import --from-gsd2`)
|
||||
node msd-tools.cjs from-gsd2 [--path <dir>] [--force] [--dry-run]
|
||||
|
||||
# Git commit with config checks
|
||||
node gsd-tools.cjs commit <message> [--files f1 f2] [--files-removed f3 dir/] [--amend] [--no-verify] [--respect-staged]
|
||||
node msd-tools.cjs commit <message> [--files f1 f2] [--files-removed f3 dir/] [--amend] [--no-verify] [--respect-staged]
|
||||
```
|
||||
|
||||
> `--files-removed <paths>` (#4208): the caller-declared deletions. A `--files` entry that is missing on disk is skipped, never staged as a deletion (#2014) — so a moved file's old path cannot be recorded through `--files` at all, and the only form that recorded a move was a directory entry, which also commits any unrelated file sitting in that directory. Each `--files-removed` entry names a file, or a directory whose tracked-but-absent files are the removals; those paths are staged as deletions and join the commit pathspec. "Tracked" means in the index or in `HEAD`, so a deletion the caller already staged with `git rm` is committed too; "present" is the path itself (`lstat`), so a symlink counts as present even when its target is gone. A file entry that is still present on disk fails the commit closed (`reason: 'staging_failed'`); a path git never tracked is a no-op. Absence alone is not removal: an index entry that is absent from the worktree by design — a submodule gitlink, a skip-worktree (sparse-checkout) path, an assume-unchanged path, an unmerged entry, an intent-to-add (`git add -N`) entry — is never staged as a deletion; under a directory entry it is left alone like a present file, and named directly (by any spelling that resolves to it) it fails closed naming the state. On a staging failure the rollback puts back every index entry this call removed with its recorded mode and blob (`update-index --cacheinfo`), including on an unborn `HEAD` where `git reset` has nothing to restore from; like the addition-side reset it is best-effort — an index that cannot be written reports the staging error, not a clean rollback. `--files` keeps its skip-if-missing contract unchanged. A move is therefore `--files new/path --files-removed old/path`. GSD's own `close_phase_todos` step (`execute-phase.md`) uses exactly that form, naming each moved todo on both sides rather than passing the two directories: a directory entry would also commit an unrelated todo a concurrent session dropped into `pending/` or `completed/` while the phase was closing.
|
||||
> `--files-removed <paths>` (#4208): the caller-declared deletions. A `--files` entry that is missing on disk is skipped, never staged as a deletion (#2014) — so a moved file's old path cannot be recorded through `--files` at all, and the only form that recorded a move was a directory entry, which also commits any unrelated file sitting in that directory. Each `--files-removed` entry names a file, or a directory whose tracked-but-absent files are the removals; those paths are staged as deletions and join the commit pathspec. "Tracked" means in the index or in `HEAD`, so a deletion the caller already staged with `git rm` is committed too; "present" is the path itself (`lstat`), so a symlink counts as present even when its target is gone. A file entry that is still present on disk fails the commit closed (`reason: 'staging_failed'`); a path git never tracked is a no-op. Absence alone is not removal: an index entry that is absent from the worktree by design — a submodule gitlink, a skip-worktree (sparse-checkout) path, an assume-unchanged path, an unmerged entry, an intent-to-add (`git add -N`) entry — is never staged as a deletion; under a directory entry it is left alone like a present file, and named directly (by any spelling that resolves to it) it fails closed naming the state. On a staging failure the rollback puts back every index entry this call removed with its recorded mode and blob (`update-index --cacheinfo`), including on an unborn `HEAD` where `git reset` has nothing to restore from; like the addition-side reset it is best-effort — an index that cannot be written reports the staging error, not a clean rollback. `--files` keeps its skip-if-missing contract unchanged. A move is therefore `--files new/path --files-removed old/path`. MSD's own `close_phase_todos` step (`execute-phase.md`) uses exactly that form, naming each moved todo on both sides rather than passing the two directories: a directory entry would also commit an unrelated todo a concurrent session dropped into `pending/` or `completed/` while the phase was closing.
|
||||
|
||||
> `--no-verify`: Skips pre-commit hooks. Used by parallel executor agents during wave-based execution to avoid build lock contention (e.g., cargo lock fights in Rust projects). The orchestrator runs hooks once after each wave completes. Do not use `--no-verify` during sequential execution — let hooks run normally.
|
||||
> `--files <paths>` **staging behaviour**: by default, `--files` runs `git add -- <path>` for each named file before committing. This overwrites any per-hunk staging set up via `git add -p`. Pass `--respect-staged` to skip the `git add` step and commit only what is already in the index within the requested pathspec. If nothing is staged within that scope, the command returns `{ committed: false, reason: 'nothing staged' }` without error. The trailing `-- <paths>` pathspec on the commit is applied under both modes, so files staged outside the `--files` scope are never included (#3061 invariant).
|
||||
|
||||
```bash
|
||||
# Web search (requires Brave API key)
|
||||
node gsd-tools.cjs websearch <query> [--limit N] [--freshness day|week|month]
|
||||
node msd-tools.cjs websearch <query> [--limit N] [--freshness day|week|month]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Update Backup and Restore
|
||||
|
||||
The two halves of `/gsd-update`'s user-added-file protection. `detect-custom-files`
|
||||
lists files that exist inside GSD-managed directories but are absent from
|
||||
`gsd-file-manifest.json` — the update workflow copies those into
|
||||
`gsd-user-files-backup/` before the clean-install wipe. `restore-custom-files`
|
||||
The two halves of `/msd-update`'s user-added-file protection. `detect-custom-files`
|
||||
lists files that exist inside MSD-managed directories but are absent from
|
||||
`msd-file-manifest.json` — the update workflow copies those into
|
||||
`msd-user-files-backup/` before the clean-install wipe. `restore-custom-files`
|
||||
puts them back afterwards.
|
||||
|
||||
```bash
|
||||
# List user-added files the installer would destroy (JSON)
|
||||
node gsd-tools.cjs detect-custom-files --config-dir <config-dir>
|
||||
node msd-tools.cjs detect-custom-files --config-dir <config-dir>
|
||||
|
||||
# Plan a restore — reports what would be restored, writes nothing
|
||||
node gsd-tools.cjs restore-custom-files --config-dir <config-dir>
|
||||
node msd-tools.cjs restore-custom-files --config-dir <config-dir>
|
||||
|
||||
# Restore the eligible entries
|
||||
node gsd-tools.cjs restore-custom-files --config-dir <config-dir> --apply
|
||||
node msd-tools.cjs restore-custom-files --config-dir <config-dir> --apply
|
||||
```
|
||||
|
||||
`restore-custom-files` emits one entry per backed-up file:
|
||||
@@ -1263,7 +1263,7 @@ Warning codes: `destination_managed`, `destination_exists`,
|
||||
|
||||
The compatibility pass runs against the **newly installed** release, so it
|
||||
catches a backed-up skill that `@`-references a workflow the new version
|
||||
retired, invokes a `/gsd:` command that no longer exists, or is missing the
|
||||
retired, invokes a `/msd:` command that no longer exists, or is missing the
|
||||
`name` / `description` frontmatter its runtime needs.
|
||||
|
||||
Three things the restore never does: it never deletes the backup, it never
|
||||
@@ -1285,18 +1285,18 @@ Diagnose and configure the worktree fork base used by Claude Code's `isolation="
|
||||
```bash
|
||||
# Check whether the current HEAD has diverged from the worktree fork base.
|
||||
# Returns JSON: { shouldDegrade, reason, message, headSha, forkRef, forkSha }
|
||||
node gsd-tools.cjs worktree base-check
|
||||
node msd-tools.cjs worktree base-check
|
||||
|
||||
# Same check, but against the fork base a worktree this host created was
|
||||
# actually observed to have (git rev-parse HEAD inside it, before any commit).
|
||||
node gsd-tools.cjs worktree base-check --observed-fork-base <sha>
|
||||
node msd-tools.cjs worktree base-check --observed-fork-base <sha>
|
||||
|
||||
# Write worktree.baseRef:"head" into .claude/settings.local.json (no-clobber).
|
||||
# Returns JSON: { changed, skipped, previous, baseRef, file }
|
||||
node gsd-tools.cjs worktree set-baseref
|
||||
node msd-tools.cjs worktree set-baseref
|
||||
```
|
||||
|
||||
**`worktree base-check`** reads `worktree.baseRef` from a three-layer cascade — `.claude/settings.local.json`, then `.claude/settings.json`, then the user/global `settings.json` under `CLAUDE_CONFIG_DIR` (or `~/.claude`) — and compares the current `HEAD` SHA against `origin/HEAD`. Project-level settings take precedence over the user/global layer, so a machine-wide `worktree.baseRef:"head"` set via `/config` is honored when no project override exists. The `shouldDegrade` field is `true` when the execute-phase orchestrator will fall back to sequential execution. `--mode` declares who creates the isolated worktree (#3659): `harness-worktree` (the default — the runtime harness forks it) or `orchestrator-worktree` (GSD itself runs `git worktree add` with an explicit start-point). `worktree.baseRef:"head"` is honored by the orchestrator by construction and by the Claude Code harness as measured from all three settings layers (#4588; the #48 finding that the harness did not read the setting predates upstream claude-code#54940); Cursor, the other `harness-worktree` host, is unmeasured. With `"head"` set the check does not compare in either mode unless `--observed-fork-base` is given (below), with one further exception under `harness-worktree` and no observation: when a Claude Code `WorktreeCreate` hook is configured in any of the same three settings files, or one of them does not parse, the hook creates the agent worktree and Claude Code does not apply `worktree.baseRef` to it, so the check compares `HEAD` against `origin/HEAD` as if the setting were absent (#4588). The #4868 prior-worktree observation is **not** consulted on that path: a worktree sitting at `HEAD` records nothing about which creator made it, so one the plain harness left there before the hook was configured would read as evidence for the hook (#4881). Pass `--observed-fork-base` for a trusted verdict on a hook host. Hooks from managed policy settings, a `--settings` file, plugins, agent frontmatter or SDK registrations are not visible to the check; the exit-42 guard remains the backstop for those. `--observed-fork-base <sha>` supplies the fork base a worktree created for a dispatch was actually measured to have (`git rev-parse HEAD` inside it, before any commit — a full 40- or 64-hex sha, case-insensitive; abbreviations are refused because the comparison is exact); when given, it replaces the `origin/HEAD` inference as the fork side of the comparison and `"head"` no longer short-circuits — the verdict then reports a measurement, and a mismatch under `"head"` means the worktree was not forked from HEAD despite the setting. Invalid values for either flag fail closed with an error. Possible `reason` values:
|
||||
**`worktree base-check`** reads `worktree.baseRef` from a three-layer cascade — `.claude/settings.local.json`, then `.claude/settings.json`, then the user/global `settings.json` under `CLAUDE_CONFIG_DIR` (or `~/.claude`) — and compares the current `HEAD` SHA against `origin/HEAD`. Project-level settings take precedence over the user/global layer, so a machine-wide `worktree.baseRef:"head"` set via `/config` is honored when no project override exists. The `shouldDegrade` field is `true` when the execute-phase orchestrator will fall back to sequential execution. `--mode` declares who creates the isolated worktree (#3659): `harness-worktree` (the default — the runtime harness forks it) or `orchestrator-worktree` (MSD itself runs `git worktree add` with an explicit start-point). `worktree.baseRef:"head"` is honored by the orchestrator by construction and by the Claude Code harness as measured from all three settings layers (#4588; the #48 finding that the harness did not read the setting predates upstream claude-code#54940); Cursor, the other `harness-worktree` host, is unmeasured. With `"head"` set the check does not compare in either mode unless `--observed-fork-base` is given (below), with one further exception under `harness-worktree` and no observation: when a Claude Code `WorktreeCreate` hook is configured in any of the same three settings files, or one of them does not parse, the hook creates the agent worktree and Claude Code does not apply `worktree.baseRef` to it, so the check compares `HEAD` against `origin/HEAD` as if the setting were absent (#4588). The #4868 prior-worktree observation is **not** consulted on that path: a worktree sitting at `HEAD` records nothing about which creator made it, so one the plain harness left there before the hook was configured would read as evidence for the hook (#4881). Pass `--observed-fork-base` for a trusted verdict on a hook host. Hooks from managed policy settings, a `--settings` file, plugins, agent frontmatter or SDK registrations are not visible to the check; the exit-42 guard remains the backstop for those. `--observed-fork-base <sha>` supplies the fork base a worktree created for a dispatch was actually measured to have (`git rev-parse HEAD` inside it, before any commit — a full 40- or 64-hex sha, case-insensitive; abbreviations are refused because the comparison is exact); when given, it replaces the `origin/HEAD` inference as the fork side of the comparison and `"head"` no longer short-circuits — the verdict then reports a measurement, and a mismatch under `"head"` means the worktree was not forked from HEAD despite the setting. Invalid values for either flag fail closed with an error. Possible `reason` values:
|
||||
|
||||
| `reason` | `shouldDegrade` | Meaning |
|
||||
|---|---|---|
|
||||
@@ -1304,14 +1304,14 @@ node gsd-tools.cjs worktree set-baseref
|
||||
| `baseref-head` | `false` | `worktree.baseRef:"head"` is set and no fork base was observed (and, under `harness-worktree`, no `WorktreeCreate` hook was found in the settings files) — the fork base is the orchestrator HEAD in either mode (by construction under `orchestrator-worktree`; under `harness-worktree` as measured on Claude Code, #4588 — Cursor is unmeasured). The spawn-time `worktree-branch-check` exit-42 guard remains the backstop on a host that does not honor it |
|
||||
| `baseref-head-ignored-by-harness` | `true` | `worktree.baseRef:"head"` is set but the fork base passed via `--observed-fork-base` differs from HEAD — the worktree was not forked from HEAD despite the setting (in either mode), so the run degrades to sequential (#3659, #4588) |
|
||||
| `observed-fork-matches-head` | `false` | The fork base passed via `--observed-fork-base` equals HEAD (#4588) |
|
||||
| `fork-from-head-observed` | `false` | Under `harness-worktree` with no `--observed-fork-base`, a clean linked worktree under `.claude/worktrees/agent-*` sits at the current `HEAD` — positive evidence that this host's worktree creator forks from `HEAD` (#4868). Reached only when `"head"` is absent or not `"head"` — with the setting trusted the check returns `baseref-head` first, and under a `WorktreeCreate` hook with `"head"` set the observation is withheld rather than consulted, because it cannot be attributed to the hook (#4881). Cached per `HEAD` in `.gsd/harness-fork-probe.json`; a dirty worktree, one at another commit, none at all, or a git failure is inconclusive and falls through |
|
||||
| `fork-from-head-observed` | `false` | Under `harness-worktree` with no `--observed-fork-base`, a clean linked worktree under `.claude/worktrees/agent-*` sits at the current `HEAD` — positive evidence that this host's worktree creator forks from `HEAD` (#4868). Reached only when `"head"` is absent or not `"head"` — with the setting trusted the check returns `baseref-head` first, and under a `WorktreeCreate` hook with `"head"` set the observation is withheld rather than consulted, because it cannot be attributed to the hook (#4881). Cached per `HEAD` in `.msd/harness-fork-probe.json`; a dirty worktree, one at another commit, none at all, or a git failure is inconclusive and falls through |
|
||||
| `head-matches-fork` | `false` | HEAD and the inferred fork base (`origin/HEAD`, or its symbolic-ref fallback such as `origin/next` — reported in `forkRef`) are the same commit |
|
||||
| `head-diverged-from-fork` | `true` | Branch is ahead of or diverged from the fork base — the inferred `origin/HEAD` (or its fallback), or the `--observed-fork-base` value when one was given (`forkRef: "observed"`) |
|
||||
| `fork-ref-unknown` | `true` | `origin/HEAD` could not be resolved |
|
||||
| `no-head` | `true` for exit 128, `false` for exit 0 with empty stdout | Exit 128 is git's definitive "no resolvable HEAD here" answer — not a git repository, or a repository with no commits; no harness worktree can be created, so the check degrades to sequential (#4734), with a `message` explaining why. Exit 0 with empty stdout is ambiguous (git completed without a definitive answer) and stays non-degrading (`headAbsenceVerified` distinguishes the two: `true` / `false`) |
|
||||
| `head-unresolvable` | `true` | `git rev-parse HEAD` did not return a definitive answer (timed out, `git` missing, or any other non-128 failure) — fails closed rather than being treated as `no-head` |
|
||||
|
||||
**`worktree set-baseref`** applies a no-clobber write of `worktree.baseRef:"head"` to `.claude/settings.local.json`. If the file already contains an explicit `baseRef` value other than `"head"`, the existing value is preserved and `skipped:"explicit-other"` is returned. Malformed JSON causes an error rather than a silent overwrite. Both fresh installs and upgrades of GSD Core run this automatically when `workflow.use_worktrees` is enabled (the default); the command is also available for manual use — for example, to apply the setting when worktrees were toggled on after installation, or to re-apply it after a settings change.
|
||||
**`worktree set-baseref`** applies a no-clobber write of `worktree.baseRef:"head"` to `.claude/settings.local.json`. If the file already contains an explicit `baseRef` value other than `"head"`, the existing value is preserved and `skipped:"explicit-other"` is returned. Malformed JSON causes an error rather than a silent overwrite. Both fresh installs and upgrades of MSD Core run this automatically when `workflow.use_worktrees` is enabled (the default); the command is also available for manual use — for example, to apply the setting when worktrees were toggled on after installation, or to re-apply it after a settings change.
|
||||
|
||||
### Worktree creation
|
||||
|
||||
@@ -1319,7 +1319,7 @@ node gsd-tools.cjs worktree set-baseref
|
||||
# Create an agent worktree and atomically record it in the wave cleanup manifest.
|
||||
# Returns JSON: { ok, reason, entry, manifest_path } (exit 0), or
|
||||
# { ok:false, reason, hint } with a non-zero exit on a rejected/failed create.
|
||||
node gsd-tools.cjs worktree create \
|
||||
node msd-tools.cjs worktree create \
|
||||
--manifest <path> --agent-id <id> --path <worktree> --branch <branch> --base <sha> --root <dir> \
|
||||
[--files "<space-separated declared paths>"]
|
||||
```
|
||||
@@ -1334,7 +1334,7 @@ The execute-phase orchestrator records each spawned executor's worktree identity
|
||||
# Append a validated per-agent entry to the wave cleanup manifest.
|
||||
# Returns JSON: { ok, reason, entry, manifest_path } (exit 0), or
|
||||
# { ok:false, reason, hint } with a non-zero exit on a rejected entry.
|
||||
node gsd-tools.cjs worktree record-agent \
|
||||
node msd-tools.cjs worktree record-agent \
|
||||
--manifest <path> --agent-id <id> --path <worktree> --branch <branch> --base <sha> \
|
||||
[--files "<space-separated declared paths>"]
|
||||
```
|
||||
@@ -1392,22 +1392,22 @@ Build, query, and inspect the project knowledge graph in `.planning/graphs/`. Re
|
||||
|
||||
```bash
|
||||
# Build or rebuild the knowledge graph
|
||||
node gsd-tools.cjs graphify build
|
||||
node msd-tools.cjs graphify build
|
||||
|
||||
# Search the graph for a term
|
||||
node gsd-tools.cjs graphify query <term>
|
||||
node msd-tools.cjs graphify query <term>
|
||||
|
||||
# Show graph freshness and statistics
|
||||
node gsd-tools.cjs graphify status
|
||||
node msd-tools.cjs graphify status
|
||||
|
||||
# Show changes since the last build
|
||||
node gsd-tools.cjs graphify diff
|
||||
node msd-tools.cjs graphify diff
|
||||
|
||||
# Write a named snapshot of the current graph
|
||||
node gsd-tools.cjs graphify snapshot [name]
|
||||
node msd-tools.cjs graphify snapshot [name]
|
||||
```
|
||||
|
||||
User-facing entry point: `/gsd-graphify` (see [Command Reference](COMMANDS.md#gsd-graphify)).
|
||||
User-facing entry point: `/msd-graphify` (see [Command Reference](COMMANDS.md#msd-graphify)).
|
||||
|
||||
---
|
||||
|
||||
@@ -1431,11 +1431,11 @@ User-facing entry point: `/gsd-graphify` (see [Command Reference](COMMANDS.md#gs
|
||||
| UAT | `lib/uat.cjs` | Cross-phase UAT/verification audit |
|
||||
| Profile Output | `lib/profile-output.cjs` | Developer profile formatting |
|
||||
| Profile Pipeline | `lib/profile-pipeline.cjs` | Session analysis pipeline |
|
||||
| Graphify | `lib/graphify.cjs` | Knowledge graph build/query/status/diff/snapshot (backs `/gsd-graphify`) |
|
||||
| Learnings | `lib/learnings.cjs` | Extract learnings from phases/SUMMARY artifacts (backs `/gsd-extract-learnings`) |
|
||||
| Graphify | `lib/graphify.cjs` | Knowledge graph build/query/status/diff/snapshot (backs `/msd-graphify`) |
|
||||
| Learnings | `lib/learnings.cjs` | Extract learnings from phases/SUMMARY artifacts (backs `/msd-extract-learnings`) |
|
||||
| Audit | `lib/audit.cjs` | Phase/milestone audit queue handlers; `audit-open` helper |
|
||||
| GSD2 Import | `lib/gsd2-import.cjs` | Reverse-migration importer from GSD-2 projects (backs `/gsd-import --from-gsd2`) |
|
||||
| Intel | `lib/intel.cjs` | Queryable codebase intelligence index (backs `/gsd-map-codebase --query`) |
|
||||
| MSD2 Import | `lib/gsd2-import.cjs` | Reverse-migration importer from GSD-2 projects (backs `/msd-import --from-gsd2`) |
|
||||
| Intel | `lib/intel.cjs` | Queryable codebase intelligence index (backs `/msd-map-codebase --query`) |
|
||||
| Context Predicates | `lib/context-predicates.cjs` | `CONTEXT.md` predicate fact-store parser/selector (ADR-1671, #2928) — backs `query context-predicates` and `scripts/gen-context-index.cjs`'s `docs/CONTEXT-INDEX.json` drift guard |
|
||||
| Capability State | `lib/capability-state.cjs` | Capability-state resolver — composes install profile, surface, and config into per-capability `enabled`/`active` view |
|
||||
| Capability Writer | `lib/capability-writer.cjs` | Capability-state writer (ADR-1213) — write-side inverse; projects `--on`/`--off`/`--gate` onto surface + config substrates then re-resolves |
|
||||
@@ -1445,20 +1445,20 @@ User-facing entry point: `/gsd-graphify` (see [Command Reference](COMMANDS.md#gs
|
||||
|
||||
## Reviewer CLI Routing
|
||||
|
||||
`review.models.<cli>` maps a reviewer flavor to a bare model id injected into the CLI's `--model` (or `-m`) flag by the code-review workflow. Set via [`/gsd-config --integrations`](COMMANDS.md#gsd-config) or directly:
|
||||
`review.models.<cli>` maps a reviewer flavor to a bare model id injected into the CLI's `--model` (or `-m`) flag by the code-review workflow. Set via [`/msd-config --integrations`](COMMANDS.md#msd-config) or directly:
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs config-set review.models.codex "gpt-5"
|
||||
node gsd-tools.cjs config-set review.models.agy "gemini-3.1-pro-preview"
|
||||
node gsd-tools.cjs config-set review.models.opencode "claude-sonnet-4"
|
||||
node gsd-tools.cjs config-set review.models.claude "" # clear — fall back to session model
|
||||
node msd-tools.cjs config-set review.models.codex "gpt-5"
|
||||
node msd-tools.cjs config-set review.models.agy "gemini-3.1-pro-preview"
|
||||
node msd-tools.cjs config-set review.models.opencode "claude-sonnet-4"
|
||||
node msd-tools.cjs config-set review.models.claude "" # clear — fall back to session model
|
||||
```
|
||||
|
||||
Slugs are validated against `[a-zA-Z0-9_-]+`; empty or path-containing slugs are rejected. See [`docs/CONFIGURATION.md`](CONFIGURATION.md#code-review-cli-routing) for the full field reference.
|
||||
|
||||
## Secret Handling
|
||||
|
||||
API keys configured via `/gsd-settings` (`brave_search`, `firecrawl`, `exa_search`) are written plaintext to `.planning/config.json` but are masked (`****<last-4>`) in every `config-set` / `config-get` output, confirmation table, and interactive prompt. See `gsd-core/bin/lib/secrets.cjs` for the masking implementation. The `config.json` file itself is the security boundary — protect it with filesystem permissions and keep it out of git (`.planning/` is gitignored by default).
|
||||
API keys configured via `/msd-settings` (`brave_search`, `firecrawl`, `exa_search`) are written plaintext to `.planning/config.json` but are masked (`****<last-4>`) in every `config-set` / `config-get` output, confirmation table, and interactive prompt. See `msd-core/bin/lib/secrets.cjs` for the masking implementation. The `config.json` file itself is the security boundary — protect it with filesystem permissions and keep it out of git (`.planning/` is gitignored by default).
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user