* docs: design spec for /gsd smart-entry command
Hybrid approach porting gsd-pi's smart-entry wizard to gsd-core:
deterministic classifier (gsd-tools smart-entry --json) + markdown
command/workflow with AskUserQuestion + --text fallback. Routing-first
('what now?' menu), 10 situations redesigned for gsd-core's phase loop.
* feat: add /gsd-start smart-entry command
State-aware front door adapted from gsd-pi's smart-entry wizard,
redesigned for gsd-core's markdown-first, multi-runtime architecture.
- src/smart-entry.cts: deterministic situation classifier (no-project,
paused, blocked, verify-failed, needs-first-phase, planning, executing,
verify-pending, idle-stranded, complete, unknown). Reads STATE.md,
ROADMAP.md, git, and verify signals; emits JSON the workflow consumes.
- gsd-tools.cjs: wire case + help listing.
- commands/gsd/start.md + gsd-core/workflows/gsd.md: thin markdown
dispatcher presenting an AskUserQuestion menu (with --text fallback for
non-Claude runtimes) and dispatching to existing commands. Falls back
to /gsd:progress if detection is unavailable.
- help.md: document /gsd:start (parity with bug-2954).
- tests: smart-entry.unit.test.cjs (classifier behavior across all
situations + priority + JSON shape) and gsd-workflow.structure.test.cjs
(markdown-layer invariants + every emitted command resolves to a real
slash command).
Spec: docs/superpowers/specs/2026-06-27-gsd-smart-entry-design.md
Note: command-contract (ADR-0002) requires a gsd:* prefix, so the bare
/gsd from the spec surfaces as /gsd-start.
* refactor: rename smart-entry command to /gsd:next
Rename the command from /gsd:start to /gsd:next per feedback. The
command file is now commands/gsd/next.md (name: gsd:next) and the
backing workflow is gsd-core/workflows/smart-entry.md (named for the
smart-entry classifier and gsd-tools smart-entry subcommand; does not
collide with the existing workflows/next.md, which is the progress
--next sub-workflow). help.md and the spec updated to match.
All affected tests (188) pass; lint:ci clean.
* fix: smart-entry reads real STATE.md schema (nested progress YAML + body Phase field)
Codex review found the classifier misread this repo's own STATE.md: it
looked only for scalar current_phase/total_phases frontmatter and body
fields named 'Current Phase'/'Total Phases', but real STATE.md stores
the phase as body 'Phase: N' and total_phases/percent under a nested
'progress:' YAML object. Both came back null, so active projects
(e.g. this repo at Phase 3 / verifying) wrongly classified as
needs-first-phase.
- detectSignals now reads total_phases + percent from nested progress{}
first, then scalar fm, then body; current_phase falls back to the
body 'Phase:' field (parseProsePhaseField lineage).
- Add regression tests against the real schema (nested progress YAML +
body Phase field) covering verify-pending + executing situations.
Verified against this repo: now classifies verify-pending (was
needs-first-phase). Coverage 93.25% lines / 86.99% branches.
* fix(workflow): tiered fallback when gsd-tools is broken (not just smart-entry)
Live test exposed a self-defeating fallback: when smart-entry --json
failed because gsd-tools itself was broken (missing
markdown-sectionizer.cjs), the workflow fell back to /gsd:progress —
which also depends on gsd-tools and would dead-end too.
Replace the single /gsd:progress fallback with a tiered recovery:
1. Probe gsd_run state-snapshot. If it ALSO errors, the whole tool
layer is down — read .planning/STATE.md directly with the Read tool
and synthesize a minimal situation + actions menu so /gsd:next stays
useful. Surface a rebuild hint.
2. Only if smart-entry alone is missing (older gsd-core), fall back to
/gsd:progress as before.
Matches the direct-read resilience the live agent already did by hand.
* docs: add gsd-next skill surface
* chore: trigger no-mistakes validation
* no-mistakes(review): Fix smart-entry phase ordering
* no-mistakes(review): Fix decimal smart-entry phase ordering
* no-mistakes(test): Fix smart-entry next test contracts
* no-mistakes(document): Docs synced for smart entry
* chore: add changeset fragment for #1798 (/gsd:next smart-entry workflow)
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
* fix: shorten next.md description and update golden install parity fixtures
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
* fix: update /gsd-next refs to /gsd:next in docs and add Smart Entry topic alias
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
* chore: trigger no-mistakes validation
* fix: regenerate INVENTORY-MANIFEST.json for new /gsd-next files
Full CI caught that adding commands/gsd/next.md + gsd-core/workflows/smart-entry.md
left docs/INVENTORY-MANIFEST.json stale (not in the affected-test scope that
no-mistakes' test gate runs, so it surfaced in CI). Regenerated via
node scripts/gen-inventory-manifest.cjs --write; inventory-manifest-sync
test now passes.
* fix: add 'next' to core_loop cluster, update INVENTORY-MANIFEST, fix gates.md ref
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
* fix: regenerate golden install parity fixtures for /gsd:next
Full CI (shard 3/3) caught that adding commands/gsd/next.md + the
smart-entry workflow/lib made the per-runtime golden install parity
fixtures stale across all 16 runtimes. Regenerated via
UPDATE_GOLDEN=1 node --test tests/golden-install-parity.test.cjs.
All 16 fixtures + inventory-manifest-sync now pass.
* Fix smart-entry verify-failed phase scoping and empty resolve shim step
Scope detectVerifyFailed to STATE.md's current phase so leftover higher
phase directories cannot force verify-failed routing. Move the gsd_run
shim resolver into the workflow resolve step so agents define gsd_run
before the detect step runs smart-entry.
* fix: recapture golden fixtures with updated gates.md hash (/gsd:next)
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
* fix: recapture all 16 golden fixtures with updated smart-entry.md hash
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
* chore: regenerate fixtures + inventory manifest after rebase onto next
Rebased onto next which adopted #1837 (package-version normalization to
<VERSION> in golden-install-parity hashes). Recaptured the golden fixture
that needed it (hermes), re-sorted INVENTORY-MANIFEST.json, and regenerated
the gsd-next / ns-workflow skill descriptions to match the command surface.
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
* refactor(#1787): delegate /gsd:next in-project advancement to gated /gsd:progress --next
Reconciles the /gsd:next smart-entry front door with the existing
/gsd:progress --next engine (davesienkowski review on PR #1798). The
classifier previously recommended /gsd:execute-phase directly for the
`executing` situation, bypassing workflows/next.md Route 0
(resume-incomplete-phase invariant, #160) and Gates 1-3 — reproducing the
duplication that got the old flat /gsd-next removed (#3054), plus a
correctness hazard (executing the recorded current phase while an earlier
phase is silently incomplete).
Now planning/executing/verify-pending recommend `/gsd:progress --next`
(single gated engine); the specific command stays an explicit secondary.
Off-path states (no-project, paused, blocked, verify-failed,
idle-stranded, complete) keep direct recommendations — smart-entry's
distinct value over --next. Adds docs/adr/1787-gsd-next-smart-entry.md and
a regression test locking the delegation contract.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* docs(#1787): avoid literal /gsd-next token in ADR (bug-3054 guard)
The repo-invariants #3054 guard bans the removed /gsd-next slash form in
docs surfaces. Refer to the removed command as `gsd-next` (prose) — the
historical reference is unchanged, just the banned token is dropped.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* chore: gitignore compiled host-integration-sdk + handshake-serialized .cjs
Pre-existing gap from #1683: these two src/*.cts modules compile to
gsd-core/bin/lib/*.cjs but were omitted from the per-file ignore list, so
`npm run build`/`npm test` left them as untracked build artifacts (dirty
tree + accidental-commit footgun). Adds them alongside their siblings
(host-integration.cjs, mcp-server.cjs, …). Found while finishing #1798.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* test(#1787): lock per-situation action invariants for all 11 situations + ADR typo
Adversarial-review follow-ups:
- Add a test asserting every situation's action set has exactly one
recommended action, 1-4 unique-id /gsd:* actions (previously the
one-recommended/1-4 invariant was only sampled for 6 of 11 situations).
- Fix ADR typo: /gsd-progress → /gsd:progress.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* fix(#1798): split oversized test chunks so a slow shard can't trip the per-chunk timeout
Root-cause of the intermittent `full test (windows-latest, 22, shard 1/3)`
failure. It was NOT a leaked handle (the runner's kill message guesses that,
but --test-force-exit already exits leaks cleanly). Diagnosis:
- Ran every shard-1/3 file WITHOUT --test-force-exit + a 45s kill-timer:
zero hangs, zero leaks — every file self-exits. So no leaked handle / hang.
- CI activity profile: output kept flowing (slowly) right up to the 600.0s
kill — a dead hang would go silent. => pure slowness.
- Per-file timing: install-minimal-hooks.test.cjs is a 4987-line / 250-case
consolidation file doing dozens of real installs — 41s even on a fast Mac
(much worse on the slow Windows I/O path), plus an install-heavy cluster.
Mechanism: MAX_FILES_PER_CHUNK=180 packed the whole ~171-file shard into ONE
`node --test` chunk, so the entire shard's wall-clock ran against a single
600s per-chunk backstop. On slow Windows runners that single chunk crossed
600s and was killed mid-run — an intermittent false-negative gate that also
hits `next` directly.
Fix: lower MAX_FILES_PER_CHUNK 180 -> 90 so each shard splits into ~2 chunks,
each with its own fresh 600s budget and a fresh node process (also relieves
per-process memory pressure). Verified locally: shard 1/3 now runs as
chunk 1/2 (90 files) + chunk 2/2 (81 files), 5323 tests, 0 fail. Also made the
timeout kill-message name slowness as a cause instead of asserting a leak, so
the next debugger isn't sent hunting a nonexistent handle leak.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Tom Boucher <trekkie@nomorestars.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -93,6 +93,17 @@ node gsd-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`.
|
||||
|
||||
```bash
|
||||
node gsd-tools.cjs smart-entry # Human summary + recommended route
|
||||
node gsd-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.
|
||||
|
||||
---
|
||||
|
||||
## Phase Commands
|
||||
|
||||
@@ -28,7 +28,7 @@ Six namespace routers ship as the first-stage entry points in v1.40. They keep t
|
||||
|
||||
| Command | Routes to |
|
||||
|---------|-----------|
|
||||
| `/gsd-workflow` | Phase pipeline — discuss / plan / execute / verify / phase / progress |
|
||||
| `/gsd-workflow` | Phase pipeline — discuss / plan / execute / verify / phase / progress / next |
|
||||
| `/gsd-project` | Project lifecycle — milestones, audits, summary |
|
||||
| `/gsd-quality` | Quality gates — code review, debug, audit, security, eval, ui |
|
||||
| `/gsd-context` | Codebase intelligence — map, graphify, docs, learnings |
|
||||
@@ -578,9 +578,21 @@ node gsd-tools.cjs phase uat-passed 3 --raw # Machine-readable
|
||||
|
||||
## Navigation Commands
|
||||
|
||||
### `/gsd:next`
|
||||
|
||||
Open the state-aware smart-entry launcher. It reads `.planning/STATE.md`, `ROADMAP.md`, verification artifacts, and git status, classifies the current situation, shows a short menu, then dispatches exactly one existing GSD command.
|
||||
|
||||
This is a launcher/router only — it never performs project work directly. Detection is handled by `gsd-tools smart-entry --json`; the markdown workflow presents the menu with `AskUserQuestion` or a numbered `--text` fallback.
|
||||
|
||||
**Situations detected:** no project, paused work, blockers, failed verification, first-phase setup, planning, executing, pending verification, idle stranded work, complete milestone, or unknown state.
|
||||
|
||||
```bash
|
||||
/gsd:next # Detect state and route to the best next action
|
||||
```
|
||||
|
||||
### `/gsd-progress`
|
||||
|
||||
Show status, next steps, and automatically advance to the next logical workflow step. Reads project state and determines the appropriate action.
|
||||
Show status, next steps, and automatically advance to the next logical workflow step. Reads project state and determines the appropriate action. Use `/gsd:next` when you want an interactive smart-entry menu before dispatch; use `/gsd-progress --next` when you want GSD to advance directly.
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
@@ -1419,6 +1431,7 @@ Reviewers are prompted to verify the plan's claims against the actual repository
|
||||
**Default reviewer behavior (no flags):**
|
||||
- If `review.default_reviewers` is **unset**, `/gsd-review` runs all detected reviewers (current default behavior).
|
||||
- If `review.default_reviewers` is **set**, `/gsd-review` runs only that subset (for example `["gemini","codex"]`).
|
||||
- `review.default_reviewers` may include names from `review.reviewer_instances`; each instance runs as its own reviewer identity using its configured adapter/model. Instance names are not CLI flags.
|
||||
- `--all` always overrides config and runs the full detected set.
|
||||
- Explicit flags (for example `--cursor`) override both `--all` and config defaults for that run.
|
||||
|
||||
|
||||
@@ -82,6 +82,7 @@ GSD stores project settings in `.planning/config.json`. Created during `/gsd-new
|
||||
},
|
||||
"review": {
|
||||
"default_reviewers": null,
|
||||
"reviewer_instances": {},
|
||||
"models": {}
|
||||
},
|
||||
"parallelization": {
|
||||
@@ -220,7 +221,7 @@ Use `review.default_reviewers` to scope the no-flag `/gsd-review` run to a subse
|
||||
|
||||
| Setting | Type | Default | Description |
|
||||
|---------|------|---------|-------------|
|
||||
| `review.default_reviewers` | string[] \| null | `null` (all detected reviewers) | Optional default subset for no-flag `/gsd-review`, e.g. `["gemini","codex"]`. Precedence is: explicit reviewer flags > `--all` > `review.default_reviewers` > all detected. Unknown slugs are ignored with a warning; known-but-undetected slugs are ignored with an info note; empty arrays are rejected by `config-set`. |
|
||||
| `review.default_reviewers` | string[] \| null | `null` (all detected reviewers) | Optional default subset for no-flag `/gsd-review`, e.g. `["gemini","codex"]`. Entries may be built-in reviewer slugs or configured `review.reviewer_instances` names. Precedence is: explicit reviewer flags > `--all` > `review.default_reviewers` > all detected. Unknown slugs are ignored with a warning when no instances are configured; with `review.reviewer_instances` present, unknown entries are hard errors to catch typoed instance names. Known-but-undetected slugs are ignored with an info note; empty arrays are rejected by `config-set`. |
|
||||
|
||||
Example:
|
||||
|
||||
@@ -972,7 +973,7 @@ Configure per-CLI model selection for `/gsd-review`. When set, overrides the CLI
|
||||
| `review.models.ollama` | string | (server default) | Model name passed to Ollama when `--ollama` reviewer is invoked. If unset, the first available model reported by the server is used (e.g. `llama3`). Set to a specific tag: `gsd config-set review.models.ollama codellama` |
|
||||
| `review.models.lm_studio` | string | (server default) | Model name passed to LM Studio when `--lm-studio` reviewer is invoked. If unset, the first available model reported by the server is used. |
|
||||
| `review.models.llama_cpp` | string | (server default) | Model name passed to llama.cpp when `--llama-cpp` reviewer is invoked. If unset, the first model reported by `/v1/models` is used. |
|
||||
| `review.default_reviewers` | string[] \| null | (all detected reviewers) | Default reviewer subset for no-flag `/gsd-review`. Example: `["gemini","codex"]`. Explicit flags and `--all` override this setting. |
|
||||
| `review.default_reviewers` | string[] \| null | (all detected reviewers) | Default reviewer subset for no-flag `/gsd-review`. Example: `["gemini","codex"]`. May include configured `review.reviewer_instances` names. Explicit flags and `--all` override this setting. |
|
||||
| `review.max_prompt_tokens` | number\|null | null | Default maximum estimated tokens for the assembled review prompt. When set, the prompt is deterministically trimmed before being sent to each reviewer. Per-reviewer overrides via `review.max_prompt_tokens_per_reviewer` take precedence. null = no trim (current behavior). |
|
||||
| `review.max_prompt_tokens_per_reviewer` | object | {} | Per-reviewer token budget overrides. Keys are reviewer slugs (ollama, llama_cpp, lm_studio, gemini, claude, codex, opencode, qwen, cursor). Values override `review.max_prompt_tokens` for that reviewer. Recommended for local model servers. |
|
||||
| `review.ollama_host` | string | `http://localhost:11434` | Base URL of the Ollama server. Override when running Ollama on a non-default port or remote host: `gsd config-set review.ollama_host http://192.168.1.10:11434` |
|
||||
|
||||
@@ -1223,6 +1223,7 @@ When verification returns `human_needed`, items are persisted as a trackable HUM
|
||||
|
||||
**User configuration note:**
|
||||
- Set `review.default_reviewers` in `.planning/config.json` (or via `gsd config-set`) to control no-flag `/gsd-review` fan-out.
|
||||
- `review.default_reviewers` may include configured `review.reviewer_instances` names; each instance runs as an independent reviewer identity backed by its configured adapter/model. Instance names are not CLI flags.
|
||||
- Use `--all` for a full pre-merge sweep without changing project defaults.
|
||||
- For local model servers with small context windows, set `review.max_prompt_tokens_per_reviewer` to auto-trim prompts per reviewer — see [Prompt budgets for small-context reviewers](../docs/CONFIGURATION.md#prompt-budgets-for-small-context-reviewers) in CONFIGURATION.md.
|
||||
|
||||
@@ -2638,7 +2639,7 @@ Users who run a memory / knowledge-base MCP server (for example, ExoCortex-style
|
||||
|
||||
### 122. Skill Surface Consolidation
|
||||
|
||||
**Purpose:** Cut the eager skill-listing overhead by folding 31 micro-skills into 4 new grouped parents and 6 existing parents that absorb sub-operations as flags. Zero functional loss — every removed micro-skill's behavior survives via a flag on a consolidated parent. After consolidation, `commands/gsd/*.md` ships 59 sub-skills (plus 6 namespace meta-skills, see #123).
|
||||
**Purpose:** Cut the eager skill-listing overhead by folding 31 micro-skills into 4 new grouped parents and 6 existing parents that absorb sub-operations as flags. Zero functional loss — every removed micro-skill's behavior survives via a flag on a consolidated parent. After consolidation, `commands/gsd/*.md` ships 60 sub-skills (plus 6 namespace meta-skills, see #123).
|
||||
|
||||
**Requirements:**
|
||||
- REQ-CONSOLIDATE-01: Four new grouped skills replace clusters of micro-skills:
|
||||
@@ -2647,8 +2648,9 @@ Users who run a memory / knowledge-base MCP server (for example, ExoCortex-style
|
||||
- `/gsd-config` — folds settings-advanced (`--advanced`), settings-integrations (`--integrations`), set-profile (`--profile`)
|
||||
- `/gsd-workspace` — folds new-workspace (`--new`), list-workspaces (`--list`), remove-workspace (`--remove`)
|
||||
- REQ-CONSOLIDATE-02: Six existing parents absorb wrap-up / sub-operations as flags: `/gsd-update --sync`, `/gsd-update --reapply`, `/gsd-sketch --wrap-up`, `/gsd-spike --wrap-up`, `/gsd-map-codebase --fast`, `/gsd-map-codebase --query`, `/gsd-code-review --fix`, `/gsd-progress --do`, `/gsd-progress --next`.
|
||||
- REQ-CONSOLIDATE-03: Deleted micro-skill slash forms (the bare `gsd-add-todo`, `gsd-add-backlog`, `gsd-plant-seed`, `gsd-check-todos`, `gsd-add-phase`, `gsd-insert-phase`, `gsd-remove-phase`, `gsd-edit-phase`, `gsd-new-workspace`, `gsd-list-workspaces`, `gsd-remove-workspace`, `gsd-settings-advanced`, `gsd-settings-integrations`, `gsd-set-profile`, `gsd-sketch-wrap-up`, `gsd-spike-wrap-up`, `gsd-reapply-patches`, `gsd-code-review-fix`, …) MUST resolve to "Unknown command" — no shadow stubs.
|
||||
- REQ-CONSOLIDATE-04: `autonomous.md` invokes `/gsd-code-review --fix` (was previously calling the deleted `gsd-code-review-fix`).
|
||||
- REQ-CONSOLIDATE-03: `/gsd:next` is not the retired workflow-advance command; it is reserved for the state-aware smart-entry launcher. Workflow advancement remains under `/gsd-progress --next`.
|
||||
- REQ-CONSOLIDATE-04: Deleted micro-skill slash forms (the bare `gsd-add-todo`, `gsd-add-backlog`, `gsd-plant-seed`, `gsd-check-todos`, `gsd-add-phase`, `gsd-insert-phase`, `gsd-remove-phase`, `gsd-edit-phase`, `gsd-new-workspace`, `gsd-list-workspaces`, `gsd-remove-workspace`, `gsd-settings-advanced`, `gsd-settings-integrations`, `gsd-set-profile`, `gsd-sketch-wrap-up`, `gsd-spike-wrap-up`, `gsd-reapply-patches`, `gsd-code-review-fix`, …) MUST resolve to "Unknown command" — no shadow stubs.
|
||||
- REQ-CONSOLIDATE-05: `autonomous.md` invokes `/gsd-code-review --fix` (was previously calling the deleted `gsd-code-review-fix`).
|
||||
|
||||
**Reference issue:** [#2790](https://github.com/open-gsd/gsd-core/issues/2790)
|
||||
|
||||
@@ -2659,7 +2661,7 @@ Users who run a memory / knowledge-base MCP server (for example, ExoCortex-style
|
||||
**Purpose:** Replace the flat eager skill listing with a two-stage hierarchical routing layer. The model sees 6 namespace routers instead of 86 entries, selects a namespace, then routes to the sub-skill. Descriptions use pipe-separated keyword tags (≤ 60 chars) for routing density.
|
||||
|
||||
**Commands:**
|
||||
- `/gsd-workflow` — phase pipeline router (discuss / plan / execute / verify / phase / progress)
|
||||
- `/gsd-workflow` — phase pipeline router (discuss / plan / execute / verify / phase / progress / next)
|
||||
- `/gsd-project` — project lifecycle (milestones, audits, summary)
|
||||
- `/gsd-quality` — quality gates (code review, debug, audit, security, eval, ui)
|
||||
- `/gsd-context` — codebase intelligence (map, graphify, docs, learnings)
|
||||
@@ -2677,11 +2679,13 @@ Users who run a memory / knowledge-base MCP server (for example, ExoCortex-style
|
||||
- REQ-NS-01: Six `commands/gsd/ns-*.md` namespace routers ship with pipe-separated keyword-tag descriptions (≤ 60 chars).
|
||||
- REQ-NS-02: Existing sub-skills are unchanged and still invocable directly — namespace skills are additive, not a replacement for direct slash forms.
|
||||
- REQ-NS-03: The body of each namespace router contains a routing table that maps user intent to the correct concrete sub-skill on the post-#2790 consolidated surface.
|
||||
- REQ-NS-04: Tests validate namespace files exist, include matching command `requires`, and reference only existing sub-skill files.
|
||||
|
||||
**Reference issue:** [#2792](https://github.com/open-gsd/gsd-core/issues/2792)
|
||||
|
||||
---
|
||||
|
||||
|
||||
### 124. Context-Window Utilization Guard
|
||||
|
||||
**Command:** `/gsd-health --context`
|
||||
@@ -3192,6 +3196,7 @@ The load-bearing wire is the `plan-phase` lift into `must_haves.prohibitions`, s
|
||||
|
||||
**Reference:** [Prohibition Probe](../gsd-core/references/prohibition-probe.md)
|
||||
|
||||
|
||||
### 147. Capability Management Command
|
||||
|
||||
**Command:** `gsd capability install | update | remove | list | outdated | disable | enable`
|
||||
@@ -3209,3 +3214,23 @@ The load-bearing wire is the `plan-phase` lift into `must_haves.prohibitions`, s
|
||||
**Trust boundary:** install never executes capability code (copy-only staging); executable surfaces require explicit consent; sources are gated by the **project-scoped** `capabilities.strict_known_registries` policy (fail-closed on a malformed/unparseable value); every shared-config write/delete is realpath-confined to the scope root, and a name collision with a user's `mcpServers` entry is never clobbered.
|
||||
|
||||
**Reference:** [`gsd capability` command reference](reference/gsd-capability-command.md) · [ADR-1244](adr/1244-capability-ecosystem.md)
|
||||
### 148. Smart Entry Launcher
|
||||
|
||||
**Command:** `/gsd:next`
|
||||
|
||||
**Tool:** `gsd-tools smart-entry [--json]`
|
||||
|
||||
**Purpose:** Provide a state-aware front door that reads project/workflow state, classifies the user's situation, presents a short menu, and dispatches exactly one existing GSD command.
|
||||
|
||||
**Requirements:**
|
||||
- REQ-SMART-ENTRY-01: Detection MUST be read-only and deterministic; classification lives in `gsd-tools smart-entry`.
|
||||
- REQ-SMART-ENTRY-02: The launcher MUST never perform project work directly; it only displays a menu and dispatches one command.
|
||||
- REQ-SMART-ENTRY-03: The workflow MUST fall back to `/gsd-progress` if detection fails.
|
||||
- REQ-SMART-ENTRY-04: Each classified situation MUST provide exactly one recommended action and valid slash commands.
|
||||
- REQ-SMART-ENTRY-05: Text-mode runtimes MUST receive a numbered-list fallback instead of being stranded by interactive UI assumptions.
|
||||
|
||||
**Situations:** no project, paused, blocked, verify failed, needs first phase, planning, executing, verify pending, idle stranded, complete, unknown.
|
||||
|
||||
**Reference:** [Smart Entry Design](superpowers/specs/2026-06-27-gsd-smart-entry-design.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
"/gsd-mvp-phase",
|
||||
"/gsd-new-milestone",
|
||||
"/gsd-new-project",
|
||||
"/gsd-next",
|
||||
"/gsd-ns-context",
|
||||
"/gsd-ns-ideate",
|
||||
"/gsd-ns-manage",
|
||||
@@ -182,6 +183,7 @@
|
||||
"ship.md",
|
||||
"sketch-wrap-up.md",
|
||||
"sketch.md",
|
||||
"smart-entry.md",
|
||||
"spec-phase.md",
|
||||
"spike-wrap-up.md",
|
||||
"spike.md",
|
||||
@@ -340,8 +342,8 @@
|
||||
"gsd2-import.cjs",
|
||||
"handshake-serialized.cjs",
|
||||
"hook-bus.cjs",
|
||||
"host-integration.cjs",
|
||||
"host-integration-sdk.cjs",
|
||||
"host-integration.cjs",
|
||||
"init-command-router.cjs",
|
||||
"init.cjs",
|
||||
"install-engine.cjs",
|
||||
@@ -402,6 +404,7 @@
|
||||
"security.cjs",
|
||||
"semver-compare.cjs",
|
||||
"shell-command-projection.cjs",
|
||||
"smart-entry.cjs",
|
||||
"stale-bake-guard.cjs",
|
||||
"state-command-router.cjs",
|
||||
"state-document.cjs",
|
||||
|
||||
@@ -67,7 +67,7 @@ These six routers are descriptor-only entries that the model picks first; the bo
|
||||
|
||||
| Command | Role | Source |
|
||||
|---------|------|--------|
|
||||
| `/gsd-workflow` | Phase pipeline router — discuss / plan / execute / verify / phase / progress. | [commands/gsd/ns-workflow.md](../commands/gsd/ns-workflow.md) |
|
||||
| `/gsd-workflow` | Phase pipeline router — discuss / plan / execute / verify / phase / progress / next. | [commands/gsd/ns-workflow.md](../commands/gsd/ns-workflow.md) |
|
||||
| `/gsd-project` | Project lifecycle router — milestones, audits, summary. | [commands/gsd/ns-project.md](../commands/gsd/ns-project.md) |
|
||||
| `/gsd-quality` | Quality-gate router — code review, debug, audit, security, eval, ui. | [commands/gsd/ns-review.md](../commands/gsd/ns-review.md) |
|
||||
| `/gsd-context` | Codebase-intelligence router — map, graphify, docs, learnings. | [commands/gsd/ns-context.md](../commands/gsd/ns-context.md) |
|
||||
@@ -123,6 +123,7 @@ These six routers are descriptor-only entries that the model picks first; the bo
|
||||
|
||||
| Command | Role | Source |
|
||||
|---------|------|--------|
|
||||
| `/gsd:next` | State-aware smart-entry launcher — reads project state, shows a contextual menu, and dispatches one existing GSD command. | [commands/gsd/next.md](../commands/gsd/next.md) |
|
||||
| `/gsd-progress` | Check project progress, show context, and route to next action; use `--next` to advance automatically or `--do` to run a freeform task. | [commands/gsd/progress.md](../commands/gsd/progress.md) |
|
||||
| `/gsd-capture` | Capture ideas, tasks, notes, and seeds — todo (default), `--note`, `--backlog`, `--seed`, or `--list` pending todos. | [commands/gsd/capture.md](../commands/gsd/capture.md) |
|
||||
| `/gsd-stats` | Display project statistics — phases, plans, requirements, git metrics, timeline. | [commands/gsd/stats.md](../commands/gsd/stats.md) |
|
||||
|
||||
123
docs/adr/1787-gsd-next-smart-entry.md
Normal file
123
docs/adr/1787-gsd-next-smart-entry.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# ADR 1787: `/gsd:next` smart-entry front door delegates advancement to `/gsd:progress --next`
|
||||
|
||||
- **Status:** Accepted
|
||||
- **Date:** 2026-07-03
|
||||
- **Issue:** #1787
|
||||
- **Implementation:** PR #1798 (`feat(#1787): add /gsd:next smart entry workflow`)
|
||||
- **Supersedes context:** the removal of the flat `gsd-next` command (#3054)
|
||||
|
||||
## Context
|
||||
|
||||
gsd-core has no state-aware front door. A user must already know whether to
|
||||
reach for `/gsd:progress`, `/gsd:plan-phase`, `/gsd:execute-phase`, `/gsd:quick`,
|
||||
or `/gsd:new-project`. gsd-pi ships a `/gsd` smart-entry wizard (a state-aware
|
||||
menu with one recommended action) that users run first; gsd-core wants the same
|
||||
"run one command, get told what to do next" feel without gsd-pi's TUI, since
|
||||
gsd-core is a markdown prompt framework installed into AI agents, not a Node app.
|
||||
|
||||
Two facts constrain the design:
|
||||
|
||||
1. **A `gsd-next` command already existed and was deliberately removed (#3054),**
|
||||
with `/gsd:progress --next` established as the canonical "advance to the next
|
||||
logical step" engine. `tests/bug-3054-stale-gsd-next-references.test.cjs`
|
||||
guards against user-facing surfaces re-referencing the removed flat command.
|
||||
Re-introducing a `next` entry point re-opens a settled question: it must not
|
||||
recreate the duplication that justified the removal.
|
||||
|
||||
2. **`/gsd:progress` is the "unified GSD situational command."** Its `--next`
|
||||
mode (`gsd-core/workflows/next.md`) is a *gated* advancement engine:
|
||||
- **Route 0** — the resume-incomplete-phase invariant (#160): if a session
|
||||
died mid-execution and `STATE.md`'s `current_phase` advanced past a phase
|
||||
that still has `PLAN.md` files without matching `SUMMARY.md`, `--next`
|
||||
resumes the *incomplete earlier* phase rather than the recorded current one.
|
||||
- **Gates 1–3** — unresolved checkpoint, error/failed state, and unchecked
|
||||
verification failures each hard-stop advancement.
|
||||
|
||||
The initial implementation of the new `smart-entry` classifier
|
||||
(`src/smart-entry.cts`) re-derived in-project forward routing itself. For the
|
||||
`executing` situation it recommended dispatching `/gsd:execute-phase` **directly**,
|
||||
bypassing Route 0 and Gates 1–3. That reproduced exactly the duplication that got
|
||||
`gsd-next` removed — two front doors that can route the *same* in-project state
|
||||
to *different* phases — and introduced a correctness hazard (executing the
|
||||
recorded current phase while an earlier phase is silently incomplete). A
|
||||
maintainer (davesienkowski) flagged the overlap on PR #1798.
|
||||
|
||||
## Decision
|
||||
|
||||
Ship `/gsd:next` as a **menu front door only**, with a hard boundary against
|
||||
re-implementing advancement:
|
||||
|
||||
1. **Detection + classification** live in Node as `gsd-tools smart-entry [--json]`
|
||||
(`src/smart-entry.cts`): a pure, unit-tested classifier over `.planning/STATE.md`,
|
||||
`ROADMAP.md`, and read-only git signals, producing one of 11 situations with a
|
||||
recommended action and an action menu. **Presentation + dispatch** live in the
|
||||
markdown layer (`commands/gsd/next.md` → `gsd-core/workflows/smart-entry.md`),
|
||||
using `AskUserQuestion` with a `--text` numbered-list fallback for non-Claude
|
||||
runtimes. The command carries no `requires` field so it works pre-project.
|
||||
|
||||
2. **In-project forward motion delegates to the single gated engine.** For the
|
||||
`planning`, `executing`, and `verify-pending` situations, the *recommended*
|
||||
action is `/gsd:progress --next`. smart-entry never re-derives forward routing;
|
||||
it hands linear advancement to `workflows/next.md` so Route 0 and Gates 1–3 are
|
||||
always honored. The specific command (`/gsd:plan-phase`, `/gsd:execute-phase`,
|
||||
`/gsd:verify-work`) remains available as an explicit secondary menu option for a
|
||||
user who deliberately wants to bypass advancement gating.
|
||||
|
||||
3. **smart-entry's distinct value is the states `--next` cannot reach.** For
|
||||
situations *off* the linear advance path it keeps direct recommendations, since
|
||||
these are precisely what `/gsd:progress --next` does not (or cannot, given its
|
||||
`requires: [phase]`) handle: `no-project` → `/gsd:new-project`, `paused` →
|
||||
`/gsd:resume-work`, `blocked` → `/gsd:debug`, `verify-failed` →
|
||||
`/gsd:verify-work`, `needs-first-phase` → `/gsd:discuss-phase`, `idle-stranded`
|
||||
→ `/gsd:ship`, `complete` → `/gsd:new-milestone`, `unknown` → `/gsd:progress`.
|
||||
|
||||
This makes the spec's stated decision #4 ("complementary, not redundant") true in
|
||||
the implementation, not just the prose: there is exactly one advancement engine,
|
||||
and `/gsd:next` is a menu over it plus the off-path states.
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
|
||||
- **One advancement engine.** `/gsd:next` and `/gsd:progress --next` can never
|
||||
disagree about the next in-project step, and Route 0 / Gates 1–3 cannot be
|
||||
bypassed through the new front door. The #3054 duplication does not return.
|
||||
- **Genuine new value, no overlap.** The front door adds pre-project, remediation,
|
||||
and lifecycle-exit routing that `--next` structurally cannot serve.
|
||||
- **Testable boundary.** `tests/smart-entry.unit.test.cjs` asserts that every
|
||||
forward-motion situation recommends `/gsd:progress --next` and every off-path
|
||||
situation keeps its direct recommendation — the delegation is a regression-locked
|
||||
contract, not a convention.
|
||||
|
||||
### Negative / trade-offs
|
||||
|
||||
- One extra indirection hop for the common "just continue" case (`/gsd:next` →
|
||||
`/gsd:progress --next` → dispatched command) versus dispatching the phase command
|
||||
directly. Accepted: the hop is what buys gate-safety and single-engine behavior.
|
||||
- The classifier reads STATE.md via shared primitives (`frontmatter.cjs`,
|
||||
`state-document.cjs`, `phase-id.cjs`) rather than through `workflows/next.md`'s
|
||||
own detection, so detection logic exists in two places. Accepted: they share
|
||||
parsing primitives and only the *routing decision* is centralized (in `--next`),
|
||||
which is where divergence would actually harm the user.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
1. **Keep smart-entry as an independent in-project router (as first implemented).**
|
||||
Rejected: reproduces the #3054 duplication and the Route 0 / Gates 1–3 bypass
|
||||
hazard.
|
||||
2. **Fold everything into `/gsd:progress` (add a menu mode) and ship no new
|
||||
command.** Rejected: `/gsd:progress` carries `requires: [phase]` and cannot
|
||||
serve the pre-project `no-project` front-door case, which is a primary goal.
|
||||
3. **Replace `workflows/next.md`'s inline detection with the new classifier so
|
||||
there is one detection *and* routing engine.** Rejected for this PR: `--next`
|
||||
couples detection to safety gates and convergence flags the classifier does not
|
||||
model; swapping its detection wholesale would risk regressing those invariants.
|
||||
Left as possible future consolidation.
|
||||
|
||||
## References
|
||||
|
||||
- Spec: `docs/superpowers/specs/2026-06-27-gsd-smart-entry-design.md`
|
||||
- Removed flat command guard: `tests/bug-3054-stale-gsd-next-references.test.cjs`
|
||||
- Gated engine: `gsd-core/workflows/next.md` (Route 0 = resume-incomplete-phase, #160)
|
||||
- Classifier: `src/smart-entry.cts` → `gsd-core/bin/lib/smart-entry.cjs`
|
||||
- Command contract naming (`gsd:*`): ADR-0002
|
||||
@@ -45,6 +45,8 @@ gsd config-set review.default_reviewers '["gemini","codex"]'
|
||||
|
||||
For the full integration settings schema (API keys, model overrides per reviewer, local server host addresses), see [Configuration](../CONFIGURATION.md).
|
||||
|
||||
If you need multiple independent reviewer voices from the same adapter, configure `review.reviewer_instances` and add those instance names to `review.default_reviewers`. Instance names run only through `review.default_reviewers`; they are not valid `/gsd-review` flags. See [Reviewer instances](../CONFIGURATION.md#reviewer-instances) for the schema.
|
||||
|
||||
---
|
||||
|
||||
## Run a review
|
||||
|
||||
310
docs/superpowers/specs/2026-06-27-gsd-smart-entry-design.md
Normal file
310
docs/superpowers/specs/2026-06-27-gsd-smart-entry-design.md
Normal file
@@ -0,0 +1,310 @@
|
||||
# Design: /gsd 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.
|
||||
|
||||
---
|
||||
|
||||
## 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.
|
||||
|
||||
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 command is therefore `gsd:next` → `/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.
|
||||
|
||||
---
|
||||
|
||||
## 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`.
|
||||
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
## Resolved design decisions
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
## Non-goals
|
||||
|
||||
- **No init/onboarding wizard.** `/gsd-new-project` already owns first-run project setup. `/gsd: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 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.
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
```text
|
||||
/gsd:next (commands/gsd/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
|
||||
│ step 3: render AskUserQuestion (or TEXT_MODE list)
|
||||
│ step 4: show GSD ► ROUTING banner
|
||||
│ step 5: dispatch + stop
|
||||
▼
|
||||
gsd-tools smart-entry --json ◄── NEW deterministic detection
|
||||
│ reads: state-snapshot (.planning/STATE.md)
|
||||
│ + .planning/ existence
|
||||
│ + git status / branch / unpushed
|
||||
│ + verify signals
|
||||
│ emits: { situation, recommended, summary, actions[] }
|
||||
▼
|
||||
(existing command: progress / plan-phase / execute-phase / quick / ship …)
|
||||
```
|
||||
|
||||
Two artifacts, one contract — the JSON shape in §"JSON contract". The workflow is thin because all branching logic lives in Node.
|
||||
|
||||
---
|
||||
|
||||
## The classifier — `gsd-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)`).
|
||||
|
||||
### 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).
|
||||
- **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.
|
||||
|
||||
### Inputs
|
||||
|
||||
| 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 |
|
||||
| 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 |
|
||||
|
||||
Git calls are **guarded** — any git error (not a repo, no upstream, detached HEAD) is swallowed and treated as "no git signal," never fatal.
|
||||
|
||||
### 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.
|
||||
|
||||
| # | situation | when (predicate over inputs) | recommended action |
|
||||
|---|---|---|---|
|
||||
| 1 | `no-project` | `.planning/` absent | `new-project` |
|
||||
| 2 | `paused` | `paused_at` set (non-empty) | `resume-work` |
|
||||
| 3 | `blocked` | `blockers[]` non-empty | `debug` |
|
||||
| 4 | `verify-failed` | latest verify report `STATUS:` indicates failure/blocked | `verify-work` |
|
||||
| 5 | `needs-first-phase` | STATE exists but `total_phases` ≤ 0 or no `ROADMAP.md` | `discuss-phase` |
|
||||
| 6 | `planning` | `status` = planning (phase has no plan yet) | `plan-phase` |
|
||||
| 7 | `executing` | `status` = executing / active | `execute-phase` |
|
||||
| 8 | `verify-pending` | `status` = needs-verify / review-pending | `verify-work` |
|
||||
| 9 | `idle-stranded` | clean tree + unpushed/stranded commits OR stale `last_activity` with committed-but-unshipped work | `ship` |
|
||||
| 10 | `complete` | `total_phases` > 0 and current phase ≥ total and `status` = complete | `new-milestone` |
|
||||
| — | `unknown` | fallback (no predicate matched) | `progress` |
|
||||
|
||||
**Note on `idle-stranded`:** this is the richest heuristic and the most likely to need tuning. Predicates: working tree clean **AND** (`git log @{u}..` non-empty **OR** `last_activity` older than threshold with non-complete `status`). Threshold: 72h (configurable later via config; hardcoded for v1). If this proves brittle in testing it is the first situation to relax — but it is in scope per the richness decision.
|
||||
|
||||
### Action set per situation
|
||||
|
||||
Each situation produces an ordered `actions[]` array. The recommended action is always first and carries `recommended: true`; the workflow shows the top 4 (`AskUserQuestion` cap). Every situation **always** includes `progress` ("Show progress") and `quick` ("Quick task") as escape hatches, and `help` is appended when room remains.
|
||||
|
||||
```
|
||||
no-project → new-project*, map-codebase, quick, help
|
||||
paused → resume-work*, progress, quick, help
|
||||
blocked → debug*, verify-work, capture, progress
|
||||
verify-failed → verify-work*, debug, code-review, progress
|
||||
needs-first-phase→ discuss-phase*, plan-phase, quick, progress
|
||||
planning → plan-phase*, discuss-phase, quick, progress
|
||||
executing → execute-phase*, "progress --next", quick, code-review
|
||||
verify-pending → verify-work*, code-review, "ship", progress
|
||||
idle-stranded → ship*, complete-milestone, progress, capture
|
||||
complete → new-milestone*, extract-learnings, quick, progress
|
||||
unknown → progress*, "progress --next", quick, help
|
||||
(* = recommended)
|
||||
```
|
||||
|
||||
### JSON contract (machine output, `--json`)
|
||||
|
||||
```json
|
||||
{
|
||||
"situation": "executing",
|
||||
"recommended": "execute-phase",
|
||||
"summary": "Phase 2 of 5 · plan 1/3 · 60% · active",
|
||||
"signals": {
|
||||
"current_phase": 2,
|
||||
"total_phases": 5,
|
||||
"status": "executing",
|
||||
"progress": 60,
|
||||
"has_planning": true,
|
||||
"git_dirty": false,
|
||||
"paused": false,
|
||||
"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 }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- `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`).
|
||||
|
||||
---
|
||||
|
||||
## The markdown layer
|
||||
|
||||
### Command — `commands/gsd/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).
|
||||
|
||||
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."
|
||||
- `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`
|
||||
|
||||
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)
|
||||
|
||||
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 2 — `detect` (run the classifier):**
|
||||
```bash
|
||||
SNAPSHOT=$(gsd_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.
|
||||
|
||||
**Step 3 — `present` (render the menu):**
|
||||
|
||||
TEXT_MODE handling copied verbatim from `do.md:15` (set `TEXT_MODE=true` when `--text` in `$ARGUMENTS` or `text_mode` from init JSON is true; replace every `AskUserQuestion` with a numbered list).
|
||||
|
||||
Present via `AskUserQuestion`:
|
||||
- `header`: derived from `situation` (e.g. `executing` → "Continue work").
|
||||
- `question`: the `summary` line + "What next?"
|
||||
- `options`: the first 4 of `actions[]`, label = action `label`, recommended first. (AskUserQuestion shows the first option as recommended.)
|
||||
- Always allow the user to type a custom command ("Other" is provided automatically by the tool).
|
||||
|
||||
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 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`.)
|
||||
|
||||
### TEXT_MODE / multi-runtime
|
||||
|
||||
The `--text` fallback is mandatory and is the reason we keep menus small and logic in Node. The fallback is copied from `do.md`, not reinvented.
|
||||
|
||||
---
|
||||
|
||||
## Error handling
|
||||
|
||||
| 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` |
|
||||
| `.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.
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
Per CONTRIBUTING: `node:test` + `node:assert/strict`, behavior assertions only, no source-grep tests.
|
||||
|
||||
### `tests/smart-entry.unit.test.cjs` (NEW)
|
||||
|
||||
Fixture-driven: create temp dirs with crafted `.planning/STATE.md` + optional git repo, run the classifier, assert situation + recommended + action set. Cases (one per situation at minimum):
|
||||
|
||||
- `no-project` — empty cwd → situation `no-project`, recommended `new-project`, actions include `map-codebase`.
|
||||
- `paused` — STATE.md with `paused_at` set → situation `paused`, recommended `resume-work`.
|
||||
- `blocked` — STATE.md with blockers → situation `blocked`, recommended `debug`.
|
||||
- `verify-failed` — latest summary `STATUS: blocked` → situation `verify-failed`.
|
||||
- `needs-first-phase` — STATE.md present, `total_phases: 0` → situation `needs-first-phase`.
|
||||
- `planning` / `executing` / `verify-pending` — respective `status` values.
|
||||
- `idle-stranded` — clean tree + unpushed commits → situation `idle-stranded`, recommended `ship`.
|
||||
- `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`.
|
||||
|
||||
### `tests/gsd-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).
|
||||
- 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).
|
||||
|
||||
### Coverage & baseline
|
||||
|
||||
- The new `.cjs` enters the `c8` coverage gate (`--lines 70 --branches 60`).
|
||||
- After adding `workflows/smart-entry.md`, run `npm run size:baseline` to update `tests/workflow-size-baseline.json`; justify the new entry in the PR.
|
||||
|
||||
---
|
||||
|
||||
## File changes
|
||||
|
||||
| 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 (`gsd:next` → `/gsd:next`) | small |
|
||||
| `gsd-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/workflow-size-baseline.json` | regenerate via `npm run size:baseline` | — |
|
||||
| `docs/superpowers/specs/2026-06-27-gsd-smart-entry-design.md` | this document | — |
|
||||
|
||||
No existing command or workflow is modified. No new npm dependencies.
|
||||
|
||||
---
|
||||
|
||||
## Open questions for implementation
|
||||
|
||||
None blocking. Two noted for the implementer's judgment (not spec-level):
|
||||
|
||||
1. **`idle-stranded` threshold** — 72h hardcoded for v1. If brittle in practice, relax to "unpushed commits only" (drop the staleness clause).
|
||||
2. **Action label wording** — exact strings are an implementation/tuning detail; the contract is `id` + `command`.
|
||||
|
||||
---
|
||||
|
||||
## 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.
|
||||
- [ ] New workflow under 32 KiB; `size:baseline` updated; coverage gate passes.
|
||||
- [ ] No new dependencies; no existing command modified.
|
||||
Reference in New Issue
Block a user