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:
Jakub Zych
2026-10-06 01:47:40 +02:00
parent fe069b2a56
commit a9a7a328e6
2763 changed files with 78465 additions and 78434 deletions

View File

@@ -1,4 +1,4 @@
# Design: /gsd-ultraplan-phase [BETA]
# Design: /msd-ultraplan-phase [BETA]
**Date:** 2026-04-17
**Status:** Approved — ready for implementation
@@ -8,23 +8,23 @@
## Summary
A standalone `/gsd-ultraplan-phase` command that offloads GSD's research+plan phase to Claude Code's ultraplan cloud infrastructure. The plan drafts remotely while the terminal stays free, is reviewed in a rich browser UI with inline comments, then imports back into GSD via the existing `/gsd-import --from` workflow.
A standalone `/msd-ultraplan-phase` command that offloads MSD's research+plan phase to Claude Code's ultraplan cloud infrastructure. The plan drafts remotely while the terminal stays free, is reviewed in a rich browser UI with inline comments, then imports back into MSD via the existing `/msd-import --from` workflow.
This is a **beta of a beta**: ultraplan itself is in research preview, so this command is intentionally isolated from the core `/gsd-plan-phase` pipeline to prevent breakage if ultraplan changes.
This is a **beta of a beta**: ultraplan itself is in research preview, so this command is intentionally isolated from the core `/msd-plan-phase` pipeline to prevent breakage if ultraplan changes.
---
## Scope
**In scope:**
- New `commands/gsd/ultraplan-phase.md` command
- New `gsd-core/workflows/ultraplan-phase.md` workflow
- New `commands/msd/ultraplan-phase.md` command
- New `msd-core/workflows/ultraplan-phase.md` workflow
- Runtime gate: Claude Code only (checks `$CLAUDE_CODE_VERSION`)
- Builds structured ultraplan prompt from GSD phase context
- Return path via existing `/gsd-import --from <file>` (no new import logic)
- Builds structured ultraplan prompt from MSD phase context
- Return path via existing `/msd-import --from <file>` (no new import logic)
**Out of scope (future):**
- Parallel next-phase planning during `/gsd-execute-phase`
- Parallel next-phase planning during `/msd-execute-phase`
- Auto-detection of ultraplan's saved file path
- Text mode / non-interactive fallback
@@ -33,10 +33,10 @@ This is a **beta of a beta**: ultraplan itself is in research preview, so this c
## Architecture
```text
/gsd-ultraplan-phase [phase]
/msd-ultraplan-phase [phase]
│
├─ Runtime gate (CLAUDE_CODE_VERSION check)
├─ gsd-sdk query init.plan-phase → phase context
├─ msd-sdk query init.plan-phase → phase context
├─ Build ultraplan prompt (phase scope + requirements + research)
├─ Display return-path instructions card
└─ /ultraplan <prompt>
@@ -47,32 +47,32 @@ This is a **beta of a beta**: ultraplan itself is in research preview, so this c
│
[terminal: Cancel → saves to file]
│
/gsd-import --from <saved file path>
/msd-import --from <saved file path>
│
├─ Conflict detection
├─ GSD format conversion
├─ gsd-plan-checker validation
├─ MSD format conversion
├─ msd-plan-checker validation
├─ ROADMAP.md update
└─ Commit
```
---
## Command File (`commands/gsd/ultraplan-phase.md`)
## Command File (`commands/msd/ultraplan-phase.md`)
Frontmatter:
- `name: gsd:ultraplan-phase`
- `name: msd:ultraplan-phase`
- `description:` includes `[BETA]` marker
- `argument-hint: [phase-number]`
- `allowed-tools:` Read, Bash, Glob, Grep
- References: `@~/.claude/gsd-core/workflows/ultraplan-phase.md`, ui-brand
- References: `@~/.claude/msd-core/workflows/ultraplan-phase.md`, ui-brand
---
## Workflow Steps
### 1. Banner
Display GSD `► ULTRAPLAN PHASE [BETA]` banner.
Display MSD `► ULTRAPLAN PHASE [BETA]` banner.
### 2. Runtime Gate
```bash
@@ -80,18 +80,18 @@ echo $CLAUDE_CODE_VERSION
```
If unset/empty: print error and exit.
```text
⚠ /gsd-ultraplan-phase requires Claude Code.
⚠ /msd-ultraplan-phase requires Claude Code.
/ultraplan is not available in this runtime.
Use /gsd-plan-phase for local planning.
Use /msd-plan-phase for local planning.
```
### 3. Initialize
```bash
INIT=$(gsd-sdk query init.plan-phase "$PHASE")
INIT=$(msd-sdk query init.plan-phase "$PHASE")
```
Parse: phase number, phase name, phase slug, phase dir, roadmap path, requirements path, research path.
If no `.planning/` exists: error — run `/gsd-new-project` first.
If no `.planning/` exists: error — run `/msd-new-project` first.
### 4. Build Ultraplan Prompt
Construct a prompt that includes:
@@ -99,7 +99,7 @@ Construct a prompt that includes:
- Phase scope block from ROADMAP.md
- Requirements summary (if REQUIREMENTS.md exists)
- Research summary (if RESEARCH.md exists — reduces cloud redundancy)
- Output format instruction: produce a GSD PLAN.md with standard frontmatter fields
- Output format instruction: produce a MSD PLAN.md with standard frontmatter fields
### 5. Return-Path Instructions Card
Display prominently before triggering (visible in terminal scroll-back):
@@ -109,7 +109,7 @@ When ◆ ultraplan ready:
2. Review, comment, and revise the plan
3. When satisfied: "Approve plan and teleport back to terminal"
4. At the terminal dialog: choose Cancel (saves plan to file)
5. Run: /gsd-import --from <the file path Claude prints>
5. Run: /msd-import --from <the file path Claude prints>
```
### 6. Trigger Ultraplan
@@ -121,7 +121,7 @@ When ◆ ultraplan ready:
## Return Path
No new code needed. The user runs `/gsd-import --from <path>` after ultraplan saves the file. That workflow handles everything: conflict detection, GSD format conversion, plan-checker, ROADMAP update, commit.
No new code needed. The user runs `/msd-import --from <path>` after ultraplan saves the file. That workflow handles everything: conflict detection, MSD format conversion, plan-checker, ROADMAP update, commit.
---
@@ -153,8 +153,8 @@ Ultraplan runs as a standard Claude Code on the web session. For Pro/Max subscri
- Command references workflow
- Workflow has runtime gate (`CLAUDE_CODE_VERSION`)
- Workflow has beta warning
- Workflow has init step (gsd-sdk query)
- Workflow has init step (msd-sdk query)
- Workflow builds ultraplan prompt with phase context
- Workflow triggers `/ultraplan`
- Workflow has return-path instructions (Cancel path, `/gsd-import --from`)
- Workflow does NOT directly implement plan writing (delegates to `/gsd-import`)
- Workflow has return-path instructions (Cancel path, `/msd-import --from`)
- Workflow does NOT directly implement plan writing (delegates to `/msd-import`)

View File

@@ -1,26 +1,26 @@
# Design: /gsd Smart Entry
# Design: /msd Smart Entry
**Date:** 2026-06-27
**Status:** Approved — ready for implementation planning
**Origin:** Adapted from the `/gsd` smart-entry wizard in `open-gsd/gsd-pi`, redesigned for gsd-core's markdown-first, multi-runtime architecture.
**Origin:** Adapted from the `/msd` smart-entry wizard in `open-gsd/gsd-pi`, redesigned for msd-core's markdown-first, multi-runtime architecture.
---
## Summary
A `/gsd-next` command that acts as gsd-core's **state-aware front door**. It reads project + workflow state, classifies the user's situation, and presents a small menu of the right next actions — then dispatches to an existing command. The "smart" part is deterministic detection living in Node (a new `gsd-tools smart-entry` subcommand); the presentation is an idiomatic markdown command + workflow using `AskUserQuestion` with a `--text` fallback for non-Claude runtimes.
A `/msd-next` command that acts as msd-core's **state-aware front door**. It reads project + workflow state, classifies the user's situation, and presents a small menu of the right next actions — then dispatches to an existing command. The "smart" part is deterministic detection living in Node (a new `msd-tools smart-entry` subcommand); the presentation is an idiomatic markdown command + workflow using `AskUserQuestion` with a `--text` fallback for non-Claude runtimes.
This is a **launcher / router**, not an executor. It never does the work itself.
> **Implementation note (command name):** the command-contract (ADR-0002) requires `name:` to be `gsd:*` or `gsd-*` prefixed; a bare `/gsd` is not expressible. The frontmatter is therefore `name: gsd:next`, surfacing as `/gsd-next` (file `commands/gsd/next.md`, backed by `gsd-core/workflows/smart-entry.md`). The "smart entry" concept and behavior are unchanged; only the surfaced name differs from the original `/gsd` sketch.
> **Implementation note (command name):** the command-contract (ADR-0002) requires `name:` to be `msd:*` or `msd-*` prefixed; a bare `/msd` is not expressible. The frontmatter is therefore `name: msd:next`, surfacing as `/msd-next` (file `commands/msd/next.md`, backed by `msd-core/workflows/smart-entry.md`). The "smart entry" concept and behavior are unchanged; only the surfaced name differs from the original `/msd` sketch.
---
## Motivation
gsd-pi ships a `/gsd` smart-entry wizard — a state-aware menu that branches on detected project state (phase loop, blockers, stranded work) and surfaces one well-chosen set of options with a single recommended action. It is the command users run first. gsd-core has no equivalent front door: users must already know whether to reach for `progress`, `plan-phase`, `execute-phase`, `quick`, or `new-project`.
gsd-pi ships a `/msd` smart-entry wizard — a state-aware menu that branches on detected project state (phase loop, blockers, stranded work) and surfaces one well-chosen set of options with a single recommended action. It is the command users run first. msd-core has no equivalent front door: users must already know whether to reach for `progress`, `plan-phase`, `execute-phase`, `quick`, or `new-project`.
We want the same daily-driver feel — "run `/gsd`, get told what to do next" — without fighting gsd-core's nature. gsd-core is a **markdown prompt framework installed into AI agents**, not a Node CLI app. So gsd-pi's full-screen TUI and its imperative TypeScript branch tree do not port directly. What ports is the **behavior**: detect state → classify situation → offer contextual options → dispatch.
We want the same daily-driver feel — "run `/msd`, get told what to do next" — without fighting msd-core's nature. msd-core is a **markdown prompt framework installed into AI agents**, not a Node CLI app. So gsd-pi's full-screen TUI and its imperative TypeScript branch tree do not port directly. What ports is the **behavior**: detect state → classify situation → offer contextual options → dispatch.
---
@@ -28,21 +28,21 @@ We want the same daily-driver feel — "run `/gsd`, get told what to do next"
These were chosen during brainstorming and are fixed inputs to this spec:
1. **Approach: Hybrid.** Detection + classification as a new `gsd-tools smart-entry --json` subcommand (deterministic, unit-tested in Node); presentation + dispatch as a markdown command + workflow that shells out to it via the existing `gsd_run` shim. This mirrors how `gsd-core/workflows/do.md` already drives tooling. Rationale: code-driven detection is reliable and testable; the markdown surface keeps multi-runtime reach (Codex, Gemini, Copilot) and adds zero dependencies.
1. **Approach: Hybrid.** Detection + classification as a new `msd-tools smart-entry --json` subcommand (deterministic, unit-tested in Node); presentation + dispatch as a markdown command + workflow that shells out to it via the existing `msd_run` shim. This mirrors how `msd-core/workflows/do.md` already drives tooling. Rationale: code-driven detection is reliable and testable; the markdown surface keeps multi-runtime reach (Codex, Gemini, Copilot) and adds zero dependencies.
2. **Priority: workflow routing ("what now?").** The wizard optimizes for the ongoing-work menu (gsd-pi's `showSmartEntry`), not first-run onboarding (gsd-pi's `showProjectInit`). Onboarding routes to the existing `/gsd-new-project`, which already handles project detection and setup. We are **not** building an init wizard.
2. **Priority: workflow routing ("what now?").** The wizard optimizes for the ongoing-work menu (gsd-pi's `showSmartEntry`), not first-run onboarding (gsd-pi's `showProjectInit`). Onboarding routes to the existing `/msd-new-project`, which already handles project detection and setup. We are **not** building an init wizard.
3. **Richness: phase + smart signals.** The classifier branches on gsd-core's phase loop **and** richer gsd-pi-style signals (blocked/recover, idle/stranded, paused, complete). All 10 situations below are in scope.
3. **Richness: phase + smart signals.** The classifier branches on msd-core's phase loop **and** richer gsd-pi-style signals (blocked/recover, idle/stranded, paused, complete). All 10 situations below are in scope.
4. **Relationship to `/gsd-progress`: complementary, not redundant.** `/gsd-next` is the **front door / launcher** — a state-aware *menu* the user picks the next action from. `/gsd-progress` remains the **detailed situational report + auto-advance** (`--next` chaining). `/gsd-next` will frequently recommend `/gsd-progress`; it does not replace or deprecate it.
4. **Relationship to `/msd-progress`: complementary, not redundant.** `/msd-next` is the **front door / launcher** — a state-aware *menu* the user picks the next action from. `/msd-progress` remains the **detailed situational report + auto-advance** (`--next` chaining). `/msd-next` will frequently recommend `/msd-progress`; it does not replace or deprecate it.
---
## Non-goals
- **No init/onboarding wizard.** `/gsd-new-project` already owns first-run project setup. `/gsd-next` routes to it.
- **No init/onboarding wizard.** `/msd-new-project` already owns first-run project setup. `/msd-next` routes to it.
- **No new prompt/TUI library.** `AskUserQuestion` (Claude) + `--text` numbered-list fallback (other runtimes) — matching repo convention. No inquirer/clack/ink.
- **No copy of gsd-pi's branch tree.** gsd-pi's milestone/slice/task model does not exist here. The situation table is **redesigned for gsd-core's phase loop** (`.planning/`).
- **No copy of gsd-pi's branch tree.** gsd-pi's milestone/slice/task model does not exist here. The situation table is **redesigned for msd-core's phase loop** (`.planning/`).
- **No execution.** Pure launcher. Picked action dispatches to an existing command and stops.
- **No new state storage.** Reads existing artifacts (`.planning/STATE.md`, `ROADMAP.md`, git). Writes nothing.
@@ -51,17 +51,17 @@ These were chosen during brainstorming and are fixed inputs to this spec:
## Architecture
```text
/gsd-next (commands/gsd/next.md — thin markdown dispatcher)
/msd-next (commands/msd/next.md — thin markdown dispatcher)
│
▼
workflow: gsd-core/workflows/smart-entry.md ◄── presentation + dispatch
│ step 1: resolve gsd_run shim
│ step 2: gsd_run smart-entry --json
workflow: msd-core/workflows/smart-entry.md ◄── presentation + dispatch
│ step 1: resolve msd_run shim
│ step 2: msd_run smart-entry --json
│ step 3: render AskUserQuestion (or TEXT_MODE list)
│ step 4: show GSD ► ROUTING banner
│ step 4: show MSD ► ROUTING banner
│ step 5: dispatch + stop
▼
gsd-tools smart-entry --json ◄── NEW deterministic detection
msd-tools smart-entry --json ◄── NEW deterministic detection
│ reads: state-snapshot (.planning/STATE.md)
│ + .planning/ existence
│ + git status / branch / unpushed
@@ -75,14 +75,14 @@ Two artifacts, one contract — the JSON shape in §"JSON contract". The workflo
---
## The classifier — `gsd-tools smart-entry`
## The classifier — `msd-tools smart-entry`
New `src/smart-entry.cts` → compiled (build-at-publish, ADR-457) to `gsd-core/bin/lib/smart-entry.cjs`. Registered in `gsd-tools.cjs` as `case 'smart-entry':` (≈2 lines, delegating to `smartEntry.run(cwd, { json: true }, raw)`).
New `src/smart-entry.cts` → compiled (build-at-publish, ADR-457) to `msd-core/bin/lib/smart-entry.cjs`. Registered in `msd-tools.cjs` as `case 'smart-entry':` (≈2 lines, delegating to `smartEntry.run(cwd, { json: true }, raw)`).
### Contract
- **Pure detection → classification.** No side effects. No writes. No `process.exit()` (throw `ExitError` per repo convention; the `runMain` wrapper translates exit codes).
- **Output modes:** `--json` (machine, used by the workflow) and default (human-readable summary line, for `gsd-tools` users / debugging).
- **Output modes:** `--json` (machine, used by the workflow) and default (human-readable summary line, for `msd-tools` users / debugging).
- **Idempotent, fast, no network.** Read-only filesystem + `git` calls only.
- **Never throws in `--json` mode when `.planning/` is absent** — it returns `situation: "no-project"` so the workflow always has a menu to render.
@@ -90,7 +90,7 @@ New `src/smart-entry.cts` → compiled (build-at-publish, ADR-457) to `gsd-core/
| input | source | what we read |
|---|---|---|
| workflow state | `gsd_run query state.load` / `cmdStateSnapshot` | `current_phase`, `total_phases`, `current_plan`, `total_plans_in_phase`, `status`, `progress`, `blockers[]`, `paused_at`, `last_activity`, session |
| workflow state | `msd_run query state.load` / `cmdStateSnapshot` | `current_phase`, `total_phases`, `current_plan`, `total_plans_in_phase`, `status`, `progress`, `blockers[]`, `paused_at`, `last_activity`, session |
| planning dir | filesystem at cwd | existence of `.planning/`, `.planning/STATE.md`, `.planning/ROADMAP.md` |
| git signals | `git status --porcelain`, `git branch`, `git log @{u}..` (guarded) | dirty tree, branch, unpushed commits |
| verify signals | filesystem | latest phase's verify report presence; `STATUS:` marker on most recent summary |
@@ -99,7 +99,7 @@ Git calls are **guarded** — any git error (not a repo, no upstream, detached H
### Situations (priority order — first match wins)
This is the gsd-core analog of gsd-pi's phase enum. Evaluated top-down; the first matching row is the situation.
This is the msd-core analog of gsd-pi's phase enum. Evaluated top-down; the first matching row is the situation.
| # | situation | when (predicate over inputs) | recommended action |
|---|---|---|---|
@@ -154,10 +154,10 @@ unknown → progress*, "progress --next", quick, help
"blockers": []
},
"actions": [
{ "id": "execute-phase", "label": "Continue executing phase 2", "command": "/gsd-execute-phase", "recommended": true },
{ "id": "progress-next", "label": "Advance to the next step", "command": "/gsd-progress --next", "recommended": false },
{ "id": "quick", "label": "Quick task", "command": "/gsd-quick", "recommended": false },
{ "id": "code-review", "label": "Review recent work", "command": "/gsd-code-review", "recommended": false }
{ "id": "execute-phase", "label": "Continue executing phase 2", "command": "/msd-execute-phase", "recommended": true },
{ "id": "progress-next", "label": "Advance to the next step", "command": "/msd-progress --next", "recommended": false },
{ "id": "quick", "label": "Quick task", "command": "/msd-quick", "recommended": false },
{ "id": "code-review", "label": "Review recent work", "command": "/msd-code-review", "recommended": false }
]
}
```
@@ -165,38 +165,38 @@ unknown → progress*, "progress --next", quick, help
- `situation`, `recommended`, `actions[]` are the contract the workflow depends on.
- `signals` is informational (shown in the summary banner); the workflow does not branch on it.
- `summary` is a one-line human string; the workflow may show it verbatim or reformat.
- `actions[].command` is the full slash command string the workflow dispatches, including flags (e.g. `/gsd-progress --next`).
- `actions[].command` is the full slash command string the workflow dispatches, including flags (e.g. `/msd-progress --next`).
---
## The markdown layer
### Command — `commands/gsd/next.md` (NEW)
### Command — `commands/msd/next.md` (NEW)
Thin dispatcher, modeled on `commands/gsd/progress.md` and `commands/gsd/help.md`. Backed by `gsd-core/workflows/smart-entry.md` (named for the `smart-entry` classifier + `gsd-tools smart-entry` subcommand; does not collide with the existing `workflows/next.md`, which is the progress `--next` sub-workflow).
Thin dispatcher, modeled on `commands/msd/progress.md` and `commands/msd/help.md`. Backed by `msd-core/workflows/smart-entry.md` (named for the `smart-entry` classifier + `msd-tools smart-entry` subcommand; does not collide with the existing `workflows/next.md`, which is the progress `--next` sub-workflow).
Frontmatter:
- `name: gsd:next` (surfaces as `/gsd-next`; the command-contract requires a `gsd:*`/`gsd-*` prefix — a bare `/gsd` is not expressible, see ADR-0002)
- `description:` "GSD smart entry — the state-aware front door. Reads your project state and routes you to the right next action."
- `name: msd:next` (surfaces as `/msd-next`; the command-contract requires a `msd:*`/`msd-*` prefix — a bare `/msd` is not expressible, see ADR-0002)
- `description:` "MSD smart entry — the state-aware front door. Reads your project state and routes you to the right next action."
- `argument-hint: ""` (no args for v1; reserved)
- `effort: low`
- `allowed-tools:` `Read, Bash, Glob, SlashCommand, AskUserQuestion`
- **No `requires: [phase]`** (unlike `progress`) — must work pre-project.
- `<execution_context>` → `@~/.claude/gsd-core/workflows/smart-entry.md` + `@~/.claude/gsd-core/references/ui-brand.md`
- `<execution_context>` → `@~/.claude/msd-core/workflows/smart-entry.md` + `@~/.claude/msd-core/references/ui-brand.md`
Body: a short `<objective>` stating this is a state-aware launcher, then `<process>` delegating entirely to the workflow. No inline logic.
### Workflow — `gsd-core/workflows/smart-entry.md` (NEW)
### Workflow — `msd-core/workflows/smart-entry.md` (NEW)
Five steps. **Must stay under 32 KiB (NEW_FILE_CAP)** — lean, because all branching is in Node.
**Step 1 — `resolve` (resolve the gsd_run shim):** Copy the `check_project`-style shim-resolution block verbatim from `gsd-core/workflows/do.md:29` (the long `_GSD_SHIM_NAME` resolver). This finds `gsd-tools.cjs` across all supported runtime homes. It is a proven, required block; do not paraphrase.
**Step 1 — `resolve` (resolve the msd_run shim):** Copy the `check_project`-style shim-resolution block verbatim from `msd-core/workflows/do.md:29` (the long `_MSD_SHIM_NAME` resolver). This finds `msd-tools.cjs` across all supported runtime homes. It is a proven, required block; do not paraphrase.
**Step 2 — `detect` (run the classifier):**
```bash
SNAPSHOT=$(gsd_run smart-entry --json 2>/dev/null)
SNAPSHOT=$(msd_run smart-entry --json 2>/dev/null)
```
Parse `SNAPSHOT` as JSON. If missing or unparseable → fall back to `/gsd-progress` (Step 5, with a one-line note "smart-entry unavailable — showing progress"). The agent never gets stuck.
Parse `SNAPSHOT` as JSON. If missing or unparseable → fall back to `/msd-progress` (Step 5, with a one-line note "smart-entry unavailable — showing progress"). The agent never gets stuck.
**Step 3 — `present` (render the menu):**
@@ -210,7 +210,7 @@ Present via `AskUserQuestion`:
In TEXT_MODE: print `summary`, then a numbered list of all `actions[]` (not capped — text has no 4-option limit), ask the user to type a number.
**Step 4 — `display` (routing banner):** Copy the `display` step from `do.md:77-89` verbatim — the `GSD ► ROUTING` banner showing input / routing-to / reason. Input here is the chosen `label`; routing-to is the chosen `command`.
**Step 4 — `display` (routing banner):** Copy the `display` step from `do.md:77-89` verbatim — the `MSD ► ROUTING` banner showing input / routing-to / reason. Input here is the chosen `label`; routing-to is the chosen `command`.
**Step 5 — `dispatch`:** Invoke the chosen `command`. Pass `$ARGUMENTS` through if the user typed a custom command. Then **stop** — the dispatched command owns everything from here. (Same contract as `do.md:91-99`.)
@@ -224,14 +224,14 @@ The `--text` fallback is mandatory and is the reason we keep menus small and log
| failure | behavior |
|---|---|
| `gsd_run` shim not found | the shim block itself errors with the standard install hint (from `do.md:29`); not our concern |
| `smart-entry` command missing (older gsd-core) | workflow sees empty/unparseable output → falls back to `/gsd-progress` with a note |
| `smart-entry` throws | same: caught by the `2>/dev/null` + parse check → fallback to `/gsd-progress` |
| `msd_run` shim not found | the shim block itself errors with the standard install hint (from `do.md:29`); not our concern |
| `smart-entry` command missing (older msd-core) | workflow sees empty/unparseable output → falls back to `/msd-progress` with a note |
| `smart-entry` throws | same: caught by the `2>/dev/null` + parse check → fallback to `/msd-progress` |
| `.planning/` absent | `smart-entry` returns `situation: "no-project"` → menu offers `new-project` |
| git unavailable / not a repo | classifier swallows git errors; works without git signals |
| `AskUserQuestion` unavailable (non-Claude) | TEXT_MODE numbered list |
**Invariant:** `/gsd` always produces *some* actionable menu and never strands the user. The ultimate fallback is `/gsd-progress`, which is always safe and always exists.
**Invariant:** `/msd` always produces *some* actionable menu and never strands the user. The ultimate fallback is `/msd-progress`, which is always safe and always exists.
---
@@ -253,15 +253,15 @@ Fixture-driven: create temp dirs with crafted `.planning/STATE.md` + optional gi
- `complete` — current ≥ total, status complete → situation `complete`, recommended `new-milestone`.
- `unknown` — malformed state → situation `unknown`, recommended `progress`.
- **Priority ordering** — a STATE.md that is both paused AND blocked resolves to `paused` (earlier row wins).
- **JSON shape** — `actions[].command` always starts with `/gsd:`; exactly one action has `recommended: true`.
- **JSON shape** — `actions[].command` always starts with `/msd:`; exactly one action has `recommended: true`.
### `tests/gsd-workflow.structure.test.cjs` (NEW)
### `tests/msd-workflow.structure.test.cjs` (NEW)
Invariants over the markdown layer (these are structural/format assertions on shipped artifacts, not source-grep of logic — permitted since they test the *contract* the workflow exposes):
- `commands/gsd/next.md` exists with frontmatter `name: gsd:next`, no `requires` field, `allowed-tools` includes `AskUserQuestion`.
- `gsd-core/workflows/smart-entry.md` exists and is **under 32 KiB** (NEW_FILE_CAP).
- Every `command` string referenced by the classifier's action table resolves to a real existing slash command file in `commands/gsd/` (guard against dead routes).
- `commands/msd/next.md` exists with frontmatter `name: msd:next`, no `requires` field, `allowed-tools` includes `AskUserQuestion`.
- `msd-core/workflows/smart-entry.md` exists and is **under 32 KiB** (NEW_FILE_CAP).
- Every `command` string referenced by the classifier's action table resolves to a real existing slash command file in `commands/msd/` (guard against dead routes).
- The workflow contains the TEXT_MODE fallback clause and the shim-resolution block (contract assertions).
- The workflow dispatches exactly one command and then stops (no inline execution).
@@ -277,14 +277,14 @@ Invariants over the markdown layer (these are structural/format assertions on sh
| file | change | size budget |
|---|---|---|
| `src/smart-entry.cts` | NEW — detection + classifier; `--json` + human output | — |
| `gsd-core/bin/lib/smart-entry.cjs` | generated by `build:lib` (gitignored) | — |
| `gsd-core/bin/gsd-tools.cjs` | add `case 'smart-entry':` (~2 lines) | — |
| `commands/gsd/next.md` | NEW — thin dispatcher command (`name: gsd:next` → `/gsd-next`) | small |
| `gsd-core/workflows/smart-entry.md` | NEW — presentation + dispatch | < 32 KiB |
| `msd-core/bin/lib/smart-entry.cjs` | generated by `build:lib` (gitignored) | — |
| `msd-core/bin/msd-tools.cjs` | add `case 'smart-entry':` (~2 lines) | — |
| `commands/msd/next.md` | NEW — thin dispatcher command (`name: msd:next` → `/msd-next`) | small |
| `msd-core/workflows/smart-entry.md` | NEW — presentation + dispatch | < 32 KiB |
| `tests/smart-entry.unit.test.cjs` | NEW — classifier behavior | — |
| `tests/gsd-workflow.structure.test.cjs` | NEW — markdown-layer invariants | — |
| `tests/msd-workflow.structure.test.cjs` | NEW — markdown-layer invariants | — |
| `tests/workflow-size-baseline.json` | regenerate via `npm run size:baseline` | — |
| `docs/superpowers/specs/2026-06-27-gsd-smart-entry-design.md` | this document | — |
| `docs/superpowers/specs/2026-06-27-msd-smart-entry-design.md` | this document | — |
No existing command or workflow is modified. No new npm dependencies.
@@ -301,10 +301,10 @@ None blocking. Two noted for the implementer's judgment (not spec-level):
## Success criteria
- [ ] `gsd-tools smart-entry --json` classifies all 10 situations + `unknown` correctly from fixtures.
- [ ] `/gsd` in a real project shows a situation-appropriate menu and dispatches the chosen command.
- [ ] `/gsd` pre-project offers `new-project`.
- [ ] `/gsd` works under TEXT_MODE (no `AskUserQuestion`).
- [ ] Any `smart-entry` failure falls back to `/gsd-progress` without erroring.
- [ ] `msd-tools smart-entry --json` classifies all 10 situations + `unknown` correctly from fixtures.
- [ ] `/msd` in a real project shows a situation-appropriate menu and dispatches the chosen command.
- [ ] `/msd` pre-project offers `new-project`.
- [ ] `/msd` works under TEXT_MODE (no `AskUserQuestion`).
- [ ] Any `smart-entry` failure falls back to `/msd-progress` without erroring.
- [ ] New workflow under 32 KiB; `size:baseline` updated; coverage gate passes.
- [ ] No new dependencies; no existing command modified.