From 6bd786bf8873a791d7035aff8201c58efa4b8cff Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Sun, 5 Apr 2026 10:23:41 -0400 Subject: [PATCH] test: add stale /gsd: colon reference regression guard (#1753) * test: add stale /gsd: colon reference regression guard Fixes #1748 Co-Authored-By: Claude Opus 4.6 * fix: replace 39 stale /gsd: colon references with /gsd- hyphen format Co-Authored-By: Claude Opus 4.6 --------- Co-authored-by: Claude Opus 4.6 --- .github/ISSUE_TEMPLATE/bug_report.yml | 6 +- .github/ISSUE_TEMPLATE/enhancement.yml | 6 +- .github/ISSUE_TEMPLATE/feature_request.yml | 12 +- assets/terminal.svg | 2 +- bin/install.js | 6 +- commands/gsd/analyze-dependencies.md | 2 +- docs/manual-update.md | 2 +- get-shit-done/bin/lib/verify.cjs | 2 +- get-shit-done/references/planning-config.md | 2 +- .../workflows/analyze-dependencies.md | 6 +- get-shit-done/workflows/autonomous.md | 2 +- .../workflows/discuss-phase-power.md | 6 +- get-shit-done/workflows/inbox.md | 384 ++++++++++++++++++ get-shit-done/workflows/manager.md | 10 +- get-shit-done/workflows/ui-review.md | 4 +- hooks/gsd-session-state.sh | 2 +- tests/execute-phase-wave.test.cjs | 2 +- tests/quick-branching.test.cjs | 2 +- tests/quick-research.test.cjs | 2 +- tests/stale-colon-refs.test.cjs | 112 +++++ tests/workspace.test.cjs | 2 +- 21 files changed, 535 insertions(+), 39 deletions(-) create mode 100644 get-shit-done/workflows/inbox.md create mode 100644 tests/stale-colon-refs.test.cjs diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 04bfe9db..e7415de0 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -90,7 +90,7 @@ body: label: What happened? description: Describe what went wrong. Be specific about which GSD command you were running. placeholder: | - When I ran `/gsd:plan`, the system... + When I ran `/gsd-plan`, the system... validations: required: true @@ -111,8 +111,8 @@ body: placeholder: | 1. Install GSD with `npx get-shit-done-cc@latest` 2. Select runtime: Claude Code - 3. Run `/gsd:init` with a new project - 4. Run `/gsd:plan` + 3. Run `/gsd-init` with a new project + 4. Run `/gsd-plan` 5. Error appears at step... validations: required: true diff --git a/.github/ISSUE_TEMPLATE/enhancement.yml b/.github/ISSUE_TEMPLATE/enhancement.yml index a86a1217..c3826e04 100644 --- a/.github/ISSUE_TEMPLATE/enhancement.yml +++ b/.github/ISSUE_TEMPLATE/enhancement.yml @@ -39,7 +39,7 @@ body: attributes: label: What existing feature or behavior does this improve? description: Name the specific command, workflow, output, or behavior you are enhancing. - placeholder: "e.g., `/gsd:plan` output, phase status display in statusline, context summary format" + placeholder: "e.g., `/gsd-plan` output, phase status display in statusline, context summary format" validations: required: true @@ -50,7 +50,7 @@ body: description: | Describe exactly how the thing works today. Be specific. Include example output or commands if helpful. placeholder: | - Currently, `/gsd:status` shows: + Currently, `/gsd-status` shows: ``` Phase 2/5 — In Progress ``` @@ -66,7 +66,7 @@ body: description: | Describe exactly how it should work after the enhancement. Be specific. Include example output or commands. placeholder: | - After the enhancement, `/gsd:status` would show: + After the enhancement, `/gsd-status` would show: ``` Phase 2/5 — In Progress — "Implement core auth module" ``` diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index e6d99957..ca936b18 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -83,14 +83,14 @@ body: Describe exactly what is being added. Be specific about commands, output, behavior, and user interaction. Include example commands or example output where possible. placeholder: | - A new command `/gsd:rollback` that: + A new command `/gsd-rollback` that: 1. Reads the current phase from STATE.md 2. Reverts STATE.md to the previous phase's snapshot 3. Outputs a confirmation with the rolled-back state Example usage: ``` - /gsd:rollback + /gsd-rollback > Rolled back from Phase 3 (failed) to Phase 2 (completed) ``` validations: @@ -139,9 +139,9 @@ body: List the specific, testable conditions that must be true for this feature to be considered complete. These become the basis for reviewer sign-off. Vague criteria ("it works") are not acceptable. placeholder: | - - [ ] `/gsd:rollback` reverts STATE.md to the previous phase when current phase status is `failed` - - [ ] `/gsd:rollback` exits with an error if there is no previous phase to roll back to - - [ ] `/gsd:rollback` outputs the before/after phase names in its confirmation message + - [ ] `/gsd-rollback` reverts STATE.md to the previous phase when current phase status is `failed` + - [ ] `/gsd-rollback` exits with an error if there is no previous phase to roll back to + - [ ] `/gsd-rollback` outputs the before/after phase names in its confirmation message - [ ] Rollback is logged in the phase history so the AI agent can see it happened - [ ] All existing tests still pass - [ ] New tests cover the happy path, no-previous-phase case, and STATE.md corruption case @@ -226,7 +226,7 @@ body: placeholder: | 1. Manual STATE.md editing — rejected because it requires the developer to understand the schema and is error-prone. The AI agent cannot reliably guide this. - 2. A `/gsd:reset` command that wipes all state — rejected because it is too destructive and + 2. A `/gsd-reset` command that wipes all state — rejected because it is too destructive and loses all completed phase history. validations: required: true diff --git a/assets/terminal.svg b/assets/terminal.svg index 90071ea6..62067c3d 100644 --- a/assets/terminal.svg +++ b/assets/terminal.svg @@ -58,7 +58,7 @@ Installed get-shit-done - Done! Run /gsd:help to get started. + Done! Run /gsd-help to get started. ~ diff --git a/bin/install.js b/bin/install.js index 10289fa2..20664f5e 100755 --- a/bin/install.js +++ b/bin/install.js @@ -2990,7 +2990,7 @@ function convertClaudeToOpencodeFrontmatter(content, { isAgent = false } = {}) { convertedContent = convertedContent.replace(/\bAskUserQuestion\b/g, 'question'); convertedContent = convertedContent.replace(/\bSlashCommand\b/g, 'skill'); convertedContent = convertedContent.replace(/\bTodoWrite\b/g, 'todowrite'); - // Replace /gsd:command with /gsd-command for opencode (flat command structure) + // Replace /gsd-command colon variant with /gsd-command for opencode (flat command structure) convertedContent = convertedContent.replace(/\/gsd:/g, '/gsd-'); // Replace ~/.claude and $HOME/.claude with OpenCode's config location convertedContent = convertedContent.replace(/~\/\.claude\b/g, '~/.config/opencode'); @@ -3141,7 +3141,7 @@ function convertClaudeToKiloFrontmatter(content, { isAgent = false } = {}) { convertedContent = convertedContent.replace(/\bAskUserQuestion\b/g, 'question'); convertedContent = convertedContent.replace(/\bSlashCommand\b/g, 'skill'); convertedContent = convertedContent.replace(/\bTodoWrite\b/g, 'todowrite'); - // Replace /gsd:command with /gsd-command for Kilo (flat command structure) + // Replace /gsd-command colon variant with /gsd-command for Kilo (flat command structure) convertedContent = convertedContent.replace(/\/gsd:/g, '/gsd-'); // Replace ~/.claude and $HOME/.claude with Kilo's config location convertedContent = convertedContent.replace(/~\/\.claude\b/g, '~/.config/kilo'); @@ -5824,7 +5824,7 @@ function finishInstall(settingsPath, settings, statuslineCommand, shouldInstallS if (runtime === 'augment') program = 'Augment'; if (runtime === 'trae') program = 'Trae'; - let command = '/gsd:new-project'; + let command = '/gsd-new-project'; if (runtime === 'opencode') command = '/gsd-new-project'; if (runtime === 'kilo') command = '/gsd-new-project'; if (runtime === 'codex') command = '$gsd-new-project'; diff --git a/commands/gsd/analyze-dependencies.md b/commands/gsd/analyze-dependencies.md index 94444213..9d8b6b8e 100644 --- a/commands/gsd/analyze-dependencies.md +++ b/commands/gsd/analyze-dependencies.md @@ -25,7 +25,7 @@ Then suggest `Depends on` updates to ROADMAP.md. No arguments required. Requires an active milestone with ROADMAP.md. -Run this command BEFORE `/gsd:manager` to fill in missing `Depends on` fields and prevent merge conflicts from unordered parallel execution. +Run this command BEFORE `/gsd-manager` to fill in missing `Depends on` fields and prevent merge conflicts from unordered parallel execution. diff --git a/docs/manual-update.md b/docs/manual-update.md index d2bda994..5d759cbb 100644 --- a/docs/manual-update.md +++ b/docs/manual-update.md @@ -59,4 +59,4 @@ The installer performs a clean wipe-and-replace of GSD-managed directories only: - Your `CLAUDE.md` files - Custom hooks -Locally modified GSD files are automatically backed up to `gsd-local-patches/` before the install. Run `/gsd:reapply-patches` after updating to merge your modifications back in. +Locally modified GSD files are automatically backed up to `gsd-local-patches/` before the install. Run `/gsd-reapply-patches` after updating to merge your modifications back in. diff --git a/get-shit-done/bin/lib/verify.cjs b/get-shit-done/bin/lib/verify.cjs index 081dd3a6..0b96494d 100644 --- a/get-shit-done/bin/lib/verify.cjs +++ b/get-shit-done/bin/lib/verify.cjs @@ -777,7 +777,7 @@ function cmdValidateHealth(cwd, options, raw) { if (statusVal !== 'complete' && statusVal !== 'done') { addIssue('warning', 'W011', `STATE.md says current phase is ${statePhase} (status: ${statusVal || 'unknown'}) but ROADMAP.md shows it as [x] complete — state files may be out of sync`, - 'Run /gsd:progress to re-derive current position, or manually update STATE.md'); + 'Run /gsd-progress to re-derive current position, or manually update STATE.md'); } } } diff --git a/get-shit-done/references/planning-config.md b/get-shit-done/references/planning-config.md index de7dcb6b..df8f54b9 100644 --- a/get-shit-done/references/planning-config.md +++ b/get-shit-done/references/planning-config.md @@ -35,7 +35,7 @@ Configuration options for `.planning/` directory behavior. | `git.quick_branch_template` | `null` | Optional branch template for quick-task runs | | `workflow.use_worktrees` | `true` | Whether executor agents run in isolated git worktrees. Set to `false` to disable worktrees — agents execute sequentially on the main working tree instead. Recommended for solo developers or when worktree merges cause issues. | | `workflow.subagent_timeout` | `300000` | Timeout in milliseconds for parallel subagent tasks (e.g. codebase mapping). Increase for large codebases or slower models. Default: 300000 (5 minutes). | -| `manager.flags.discuss` | `""` | Flags passed to `/gsd:discuss-phase` when dispatched from manager (e.g. `"--auto --analyze"`) | +| `manager.flags.discuss` | `""` | Flags passed to `/gsd-discuss-phase` when dispatched from manager (e.g. `"--auto --analyze"`) | | `manager.flags.plan` | `""` | Flags passed to plan workflow when dispatched from manager | | `manager.flags.execute` | `""` | Flags passed to execute workflow when dispatched from manager | | `response_language` | `null` | Language for user-facing questions and prompts across all phases/subagents (e.g. `"Portuguese"`, `"Japanese"`, `"Spanish"`). When set, all spawned agents include a directive to respond in this language. | diff --git a/get-shit-done/workflows/analyze-dependencies.md b/get-shit-done/workflows/analyze-dependencies.md index 376e31c9..618e3c9d 100644 --- a/get-shit-done/workflows/analyze-dependencies.md +++ b/get-shit-done/workflows/analyze-dependencies.md @@ -1,12 +1,12 @@ -Analyze ROADMAP.md phases for dependency relationships before execution. Detect file overlap between phases, semantic API/data-flow dependencies, and suggest `Depends on` entries to prevent merge conflicts during parallel execution by `/gsd:manager`. +Analyze ROADMAP.md phases for dependency relationships before execution. Detect file overlap between phases, semantic API/data-flow dependencies, and suggest `Depends on` entries to prevent merge conflicts during parallel execution by `/gsd-manager`. ## 1. Load ROADMAP.md -Read `.planning/ROADMAP.md`. If it does not exist, error: "No ROADMAP.md found — run `/gsd:new-project` first." +Read `.planning/ROADMAP.md`. If it does not exist, error: "No ROADMAP.md found — run `/gsd-new-project` first." Extract all phases. For each phase capture: - Phase number and name @@ -91,6 +91,6 @@ When writing to ROADMAP.md: - Preserve all other phase content unchanged - Do not reorder phases -After applying: "ROADMAP.md updated. Run `/gsd:manager` to execute phases in the correct order." +After applying: "ROADMAP.md updated. Run `/gsd-manager` to execute phases in the correct order." diff --git a/get-shit-done/workflows/autonomous.md b/get-shit-done/workflows/autonomous.md index 76cdea9b..7072debb 100644 --- a/get-shit-done/workflows/autonomous.md +++ b/get-shit-done/workflows/autonomous.md @@ -784,7 +784,7 @@ Decisions captured: {count} across {area_count} areas Completed through phase ${TO_PHASE} as requested. Remaining phases were not executed. - Resume with: /gsd:autonomous --from ${next_incomplete_phase} + Resume with: /gsd-autonomous --from ${next_incomplete_phase} ``` Proceed directly to lifecycle step (which handles partial completion — skips audit/complete/cleanup since not all phases are done). Exit cleanly. diff --git a/get-shit-done/workflows/discuss-phase-power.md b/get-shit-done/workflows/discuss-phase-power.md index 0877ee6e..57e7671a 100644 --- a/get-shit-done/workflows/discuss-phase-power.md +++ b/get-shit-done/workflows/discuss-phase-power.md @@ -5,7 +5,7 @@ Power user mode for discuss-phase. Generates ALL questions upfront into a JSON s -This workflow executes when `--power` flag is present in ARGUMENTS to `/gsd:discuss-phase`. +This workflow executes when `--power` flag is present in ARGUMENTS to `/gsd-discuss-phase`. The caller (discuss-phase.md) has already: - Validated the phase exists @@ -265,7 +265,7 @@ Process all answered questions from the JSON file and generate CONTEXT.md. ``` Warning: Only {answered}/{total} questions answered ({pct}%). CONTEXT.md generated with available decisions. Unanswered questions listed as deferred. -Consider running /gsd:discuss-phase {N} again to refine before planning. +Consider running /gsd-discuss-phase {N} again to refine before planning. ``` 7. Print completion message: @@ -275,7 +275,7 @@ CONTEXT.md written: {phase_dir}/{padded_phase}-CONTEXT.md Decisions captured: {answered} Deferred: {remaining} -Next step: /gsd:plan-phase {N} +Next step: /gsd-plan-phase {N} ``` diff --git a/get-shit-done/workflows/inbox.md b/get-shit-done/workflows/inbox.md new file mode 100644 index 00000000..4b450d83 --- /dev/null +++ b/get-shit-done/workflows/inbox.md @@ -0,0 +1,384 @@ + +Triage and review all open GitHub issues and PRs against project contribution templates. +Produces a structured report showing compliance status for each item, flags missing +required fields, identifies label gaps, and optionally takes action (label, comment, close). + + + +Before starting, read these project files to understand the review criteria: +- `.github/ISSUE_TEMPLATE/feature_request.yml` — required fields for feature issues +- `.github/ISSUE_TEMPLATE/enhancement.yml` — required fields for enhancement issues +- `.github/ISSUE_TEMPLATE/chore.yml` — required fields for chore issues +- `.github/ISSUE_TEMPLATE/bug_report.yml` — required fields for bug reports +- `.github/PULL_REQUEST_TEMPLATE/feature.md` — required checklist for feature PRs +- `.github/PULL_REQUEST_TEMPLATE/enhancement.md` — required checklist for enhancement PRs +- `.github/PULL_REQUEST_TEMPLATE/fix.md` — required checklist for fix PRs +- `CONTRIBUTING.md` — the issue-first rule and approval gates + + + + + +Verify prerequisites: + +1. **`gh` CLI available and authenticated?** + ```bash + which gh && gh auth status 2>&1 + ``` + If not available: print setup instructions and exit. + +2. **Detect repository:** + If `--repo` flag provided, use that. Otherwise: + ```bash + gh repo view --json nameWithOwner -q '.nameWithOwner' 2>/dev/null + ``` + If no repo detected: error — must be in a git repo with a GitHub remote. + +3. **Parse flags:** + - `--issues` → set REVIEW_ISSUES=true, REVIEW_PRS=false + - `--prs` → set REVIEW_ISSUES=false, REVIEW_PRS=true + - `--label` → set AUTO_LABEL=true + - `--close-incomplete` → set AUTO_CLOSE=true + - Default (no flags): review both issues and PRs, report only (no auto-actions) + + + +Skip if REVIEW_ISSUES=false. + +Fetch all open issues: +```bash +gh issue list --state open --json number,title,labels,body,author,createdAt,updatedAt --limit 100 +``` + +For each issue, classify by labels and body content: + +| Label/Pattern | Type | Template | +|---|---|---| +| `feature-request` | Feature | feature_request.yml | +| `enhancement` | Enhancement | enhancement.yml | +| `bug` | Bug | bug_report.yml | +| `type: chore` | Chore | chore.yml | +| No matching label | Unknown | Flag for manual triage | + +If an issue has no type label, attempt to classify from the body content: +- Contains "### Feature name" → likely Feature +- Contains "### What existing feature" → likely Enhancement +- Contains "### What happened?" → likely Bug +- Contains "### What is the maintenance task?" → likely Chore +- Cannot determine → mark as `needs-triage` + + + +Skip if REVIEW_ISSUES=false. + +For each classified issue, review against its template requirements. + +**Feature Request Review Checklist:** +- [ ] Pre-submission checklist present (4 checkboxes) +- [ ] Feature name provided +- [ ] Type of addition selected +- [ ] Problem statement filled (not placeholder text) +- [ ] What is being added described with examples +- [ ] Full scope of changes listed (files created/modified/systems) +- [ ] User stories present (minimum 2) +- [ ] Acceptance criteria present (testable conditions) +- [ ] Applicable runtimes selected +- [ ] Breaking changes assessment present +- [ ] Maintenance burden described +- [ ] Alternatives considered (not empty) +- **Label check:** Has `needs-review` label? Has `approved-feature` label? +- **Gate check:** If PR exists linking this issue, does issue have `approved-feature`? + +**Enhancement Review Checklist:** +- [ ] Pre-submission checklist present (4 checkboxes) +- [ ] What is being improved identified +- [ ] Current behavior described with examples +- [ ] Proposed behavior described with examples +- [ ] Reason and benefit articulated (not vague) +- [ ] Scope of changes listed +- [ ] Breaking changes assessed +- [ ] Alternatives considered +- [ ] Area affected selected +- **Label check:** Has `needs-review` label? Has `approved-enhancement` label? +- **Gate check:** If PR exists linking this issue, does issue have `approved-enhancement`? + +**Bug Report Review Checklist:** +- [ ] GSD Version provided +- [ ] Runtime selected +- [ ] OS selected +- [ ] Node.js version provided +- [ ] Description of what happened +- [ ] Expected behavior described +- [ ] Steps to reproduce provided +- [ ] Frequency selected +- [ ] Severity/impact selected +- [ ] PII checklist confirmed +- **Label check:** Has `needs-triage` or `confirmed-bug` label? + +**Chore Review Checklist:** +- [ ] Pre-submission checklist confirmed (no user-facing changes) +- [ ] Maintenance task described +- [ ] Type of maintenance selected +- [ ] Current state described with specifics +- [ ] Proposed work listed +- [ ] Acceptance criteria present +- [ ] Area affected selected +- **Label check:** Has `needs-triage` label? + +**Scoring:** For each issue, calculate a completeness percentage: +- Count required fields present vs. total required fields +- Score = (present / total) * 100 +- Status: COMPLETE (100%), MOSTLY COMPLETE (75-99%), INCOMPLETE (50-74%), REJECT (<50%) + + + +Skip if REVIEW_PRS=false. + +Fetch all open PRs: +```bash +gh pr list --state open --json number,title,labels,body,author,headRefName,baseRefName,isDraft,createdAt,reviewDecision,statusCheckRollup --limit 100 +``` + +For each PR, classify by body content and linked issue: + +| Body Pattern | Type | Template | +|---|---|---| +| Contains "## Feature PR" or "## Feature summary" | Feature PR | feature.md | +| Contains "## Enhancement PR" or "## What this enhancement improves" | Enhancement PR | enhancement.md | +| Contains "## Fix PR" or "## What was broken" | Fix PR | fix.md | +| Uses default template | Wrong Template | Flag — must use typed template | +| Cannot determine | Unknown | Flag for manual review | + +Also check for linked issues: +```bash +gh pr view {number} --json body -q '.body' | grep -oE '(Closes|Fixes|Resolves) #[0-9]+' +``` + + + +Skip if REVIEW_PRS=false. + +For each classified PR, review against its template requirements. + +**Feature PR Review Checklist:** +- [ ] Uses feature PR template (not default) +- [ ] Issue linked with `Closes #NNN` +- [ ] Linked issue exists and has `approved-feature` label +- [ ] Feature summary present +- [ ] New files table filled +- [ ] Modified files table filled +- [ ] Implementation notes present +- [ ] Spec compliance checklist present (acceptance criteria from issue) +- [ ] Test coverage described +- [ ] Platforms tested checked (macOS, Windows, Linux) +- [ ] Runtimes tested checked +- [ ] Scope confirmation checked +- [ ] Full checklist completed +- [ ] Breaking changes section filled +- **CI check:** All status checks passing? +- **Review check:** Has review approval? + +**Enhancement PR Review Checklist:** +- [ ] Uses enhancement PR template (not default) +- [ ] Issue linked with `Closes #NNN` +- [ ] Linked issue exists and has `approved-enhancement` label +- [ ] What is improved described +- [ ] Before/after provided +- [ ] Implementation approach described +- [ ] Verification method described +- [ ] Platforms tested checked +- [ ] Runtimes tested checked +- [ ] Scope confirmation checked +- [ ] Full checklist completed +- [ ] Breaking changes section filled +- **CI check:** All status checks passing? + +**Fix PR Review Checklist:** +- [ ] Uses fix PR template (not default) +- [ ] Issue linked with `Fixes #NNN` +- [ ] Linked issue exists and has `confirmed-bug` label +- [ ] What was broken described +- [ ] What the fix does described +- [ ] Root cause explained +- [ ] Verification method described +- [ ] Regression test added (or explained why not) +- [ ] Platforms tested checked +- [ ] Runtimes tested checked +- [ ] Full checklist completed +- [ ] Breaking changes section filled +- **CI check:** All status checks passing? + +**Cross-cutting PR Checks (all types):** +- [ ] PR title is descriptive (not just "fix" or "update") +- [ ] One concern per PR (not mixing fix + enhancement) +- [ ] No unrelated formatting changes visible in diff +- [ ] CHANGELOG.md updated +- [ ] Not using `--no-verify` or skipping hooks + +**Scoring:** Same as issues — completeness percentage per PR. + + + +Cross-reference issues and PRs to enforce the issue-first rule: + +For each open PR: +1. Extract linked issue number from body +2. If no linked issue: **GATE VIOLATION** — PR has no issue +3. If linked issue exists, check its labels: + - Feature PR → issue must have `approved-feature` + - Enhancement PR → issue must have `approved-enhancement` + - Fix PR → issue must have `confirmed-bug` +4. If label is missing: **GATE VIOLATION** — PR opened before approval + +Report gate violations prominently — these are the most important findings because +the project auto-closes PRs without proper approval gates. + + + +Produce a structured triage report: + +``` +=================================================================== + GSD INBOX TRIAGE — {repo} — {date} +=================================================================== + +SUMMARY +------- +Open issues: {count} Open PRs: {count} + Features: {n} Feature PRs: {n} + Enhancements:{n} Enhancement PRs: {n} + Bugs: {n} Fix PRs: {n} + Chores: {n} Wrong template: {n} + Unclassified:{n} No linked issue: {n} + +GATE VIOLATIONS (action required) +--------------------------------- +{For each violation:} + PR #{number}: {title} + Problem: {description — e.g., "No approved-feature label on linked issue #45"} + Action: {what to do — e.g., "Close PR or approve issue #45 first"} + +ISSUES NEEDING ATTENTION +------------------------ +{For each issue sorted by completeness score, lowest first:} + #{number} [{type}] {title} + Score: {percentage}% complete + Missing: {list of missing required fields} + Labels: {current labels} → Suggested: {recommended labels} + Age: {days since created} + +PRS NEEDING ATTENTION +--------------------- +{For each PR sorted by completeness score, lowest first:} + #{number} [{type}] {title} + Score: {percentage}% complete + Missing: {list of missing checklist items} + CI: {passing/failing/pending} + Review: {approved/changes_requested/none} + Linked issue: #{issue_number} ({issue_status}) + Age: {days since created} + +READY TO MERGE +-------------- +{PRs that are 100% complete, CI passing, approved:} + #{number} {title} — ready + +STALE ITEMS (>30 days, no activity) +------------------------------------ +{Issues and PRs with no updates in 30+ days} + +=================================================================== +``` + +Write this report to `.planning/INBOX-TRIAGE.md` if a `.planning/` directory exists, +otherwise print to console only. + + + +Only execute if `--label` or `--close-incomplete` flags were set. + +**If --label:** +For each issue/PR where labels are missing or incorrect: +```bash +gh issue edit {number} --add-label "{label}" +``` +Or: +```bash +gh pr edit {number} --add-label "{label}" +``` + +Label recommendations: +- Unclassified issues → add `needs-triage` +- Feature issues without review → add `needs-review` +- Enhancement issues without review → add `needs-review` +- Bug reports without triage → add `needs-triage` +- PRs with gate violations → add `gate-violation` + +**If --close-incomplete:** +For issues scoring below 50% completeness: +```bash +gh issue close {number} --comment "Closed by GSD inbox triage: this issue is missing required fields per the issue template. Missing: {list}. Please reopen with a complete submission. See CONTRIBUTING.md for requirements." +``` + +For PRs with gate violations: +```bash +gh pr close {number} --comment "Closed by GSD inbox triage: this PR does not meet the issue-first requirement. {specific violation}. See CONTRIBUTING.md for the correct process." +``` + +Always confirm with the user before closing anything: +``` +AskUserQuestion: + question: "Found {N} items to close. Review the list above — proceed with closing?" + options: + - label: "Close all" + description: "Close all {N} non-compliant items with explanation comments" + - label: "Let me pick" + description: "I'll choose which ones to close" + - label: "Skip" + description: "Don't close anything — report only" +``` + + + +``` +─────────────────────────────────────────────────────────────── + +## Inbox Triage Complete + +Reviewed: {issue_count} issues, {pr_count} PRs +Gate violations: {violation_count} +Ready to merge: {ready_count} +Needing attention: {attention_count} +Stale (30+ days): {stale_count} +{If report saved: "Report saved to .planning/INBOX-TRIAGE.md"} + +Next steps: +- Review gate violations first — these block the contribution pipeline +- Address incomplete submissions (comment or close) +- Merge ready PRs +- Triage unclassified issues + +─────────────────────────────────────────────────────────────── +``` + + + + + +After triage: + +- /gsd-review — Run cross-AI peer review on a specific phase plan +- /gsd-ship — Create a PR from completed work +- /gsd-progress — See overall project state +- /gsd-inbox --label — Re-run with auto-labeling enabled + + + +- [ ] All open issues fetched and classified by type +- [ ] Each issue reviewed against its template requirements +- [ ] All open PRs fetched and classified by type +- [ ] Each PR reviewed against its template checklist +- [ ] Issue-first gate violations identified +- [ ] Structured report generated with scores and action items +- [ ] Auto-actions executed only when flagged and user-confirmed + diff --git a/get-shit-done/workflows/manager.md b/get-shit-done/workflows/manager.md index aad59d4b..cb6a56a5 100644 --- a/get-shit-done/workflows/manager.md +++ b/get-shit-done/workflows/manager.md @@ -26,7 +26,7 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi Parse JSON for: `milestone_version`, `milestone_name`, `phase_count`, `completed_count`, `in_progress_count`, `phases`, `recommended_actions`, `all_complete`, `waiting_signal`, `manager_flags`. `manager_flags` contains per-step passthrough flags from config: -- `manager_flags.discuss` — appended to `/gsd:discuss-phase` args (e.g. `"--auto --analyze"`) +- `manager_flags.discuss` — appended to `/gsd-discuss-phase` args (e.g. `"--auto --analyze"`) - `manager_flags.plan` — appended to plan agent init command - `manager_flags.execute` — appended to execute agent init command @@ -113,8 +113,8 @@ If `all_complete` is true: ╚══════════════════════════════════════════════════════════════╝ All {phase_count} phases done. Ready for final steps: - → /gsd:verify-work — run acceptance testing - → /gsd:complete-milestone — archive and wrap up + → /gsd-verify-work — run acceptance testing + → /gsd-complete-milestone — archive and wrap up ``` Ask user via AskUserQuestion: @@ -335,11 +335,11 @@ Display final status with progress bar: {milestone_version} — {milestone_name} {PROGRESS_BAR} {progress_pct}% ({completed_count}/{phase_count} phases) - Resume anytime: /gsd:manager + Resume anytime: /gsd-manager ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ``` -**Note:** Any background agents still running will continue to completion. Their results will be visible on next `/gsd:manager` or `/gsd:progress` invocation. +**Note:** Any background agents still running will continue to completion. Their results will be visible on next `/gsd-manager` or `/gsd-progress` invocation. diff --git a/get-shit-done/workflows/ui-review.md b/get-shit-done/workflows/ui-review.md index 6e8941d8..2b04289f 100644 --- a/get-shit-done/workflows/ui-review.md +++ b/get-shit-done/workflows/ui-review.md @@ -140,8 +140,8 @@ Full review: {path to UI-REVIEW.md} `/clear` then one of: -- `/gsd:verify-work {N}` — UAT testing -- `/gsd:plan-phase {N+1}` — plan next phase +- `/gsd-verify-work {N}` — UAT testing +- `/gsd-plan-phase {N+1}` — plan next phase - `/gsd-verify-work {N}` — UAT testing - `/gsd-plan-phase {N+1}` — plan next phase diff --git a/hooks/gsd-session-state.sh b/hooks/gsd-session-state.sh index 57ebe26c..53f70c64 100755 --- a/hooks/gsd-session-state.sh +++ b/hooks/gsd-session-state.sh @@ -20,7 +20,7 @@ if [ -f .planning/STATE.md ]; then echo 'STATE.md exists - check for blockers and current phase.' head -20 .planning/STATE.md else - echo 'No .planning/ found - suggest /gsd:new-project if starting new work.' + echo 'No .planning/ found - suggest /gsd-new-project if starting new work.' fi echo '' diff --git a/tests/execute-phase-wave.test.cjs b/tests/execute-phase-wave.test.cjs index 090276ab..edf2bd97 100644 --- a/tests/execute-phase-wave.test.cjs +++ b/tests/execute-phase-wave.test.cjs @@ -1,7 +1,7 @@ /** * Execute-phase wave filter tests * - * Validates the /gsd:execute-phase --wave feature contract: + * Validates the /gsd-execute-phase --wave feature contract: * - Command frontmatter advertises --wave * - Workflow parses WAVE_FILTER * - Workflow enforces lower-wave safety diff --git a/tests/quick-branching.test.cjs b/tests/quick-branching.test.cjs index a1b9c3d2..ff15c55c 100644 --- a/tests/quick-branching.test.cjs +++ b/tests/quick-branching.test.cjs @@ -1,7 +1,7 @@ /** * Quick task branching tests * - * Validates that /gsd:quick exposes branch_name from init and that the + * Validates that /gsd-quick exposes branch_name from init and that the * workflow checks out a dedicated quick-task branch when configured. */ diff --git a/tests/quick-research.test.cjs b/tests/quick-research.test.cjs index e1710888..6b1e6306 100644 --- a/tests/quick-research.test.cjs +++ b/tests/quick-research.test.cjs @@ -1,7 +1,7 @@ /** * GSD Quick Research Flag Tests * - * Validates the --research flag for /gsd:quick: + * Validates the --research flag for /gsd-quick: * - Command frontmatter advertises --research * - Workflow includes research step (Step 4.75) * - Research artifacts work within quick task directories diff --git a/tests/stale-colon-refs.test.cjs b/tests/stale-colon-refs.test.cjs new file mode 100644 index 00000000..2f2b93be --- /dev/null +++ b/tests/stale-colon-refs.test.cjs @@ -0,0 +1,112 @@ +/** + * Stale /gsd: colon reference detection test + * + * Guards against regression of bug #1748: after the command naming migration + * from colon to hyphen format, no stale colon references should remain in + * source, workflows, commands, docs, issue templates, or hooks. + * + * Test input strings that deliberately test colon-to-hyphen conversion are + * allowed (they are the INPUT to a converter function). Everything else is stale. + * + * Uses node:test and node:assert/strict (NOT Jest). + */ + +const { test, describe } = require('node:test'); +const assert = require('node:assert/strict'); +const fs = require('fs'); +const path = require('path'); + +const ROOT = path.resolve(__dirname, '..'); + +/** + * Recursively collect files matching the given extensions, excluding + * CHANGELOG.md, node_modules/, .git/, and dist/. + */ +function collectFiles(dir, extensions, results = []) { + const EXCLUDED_DIRS = new Set(['node_modules', '.git', 'dist', '.claude', '.worktrees']); + let entries; + try { + entries = fs.readdirSync(dir, { withFileTypes: true }); + } catch { + return results; + } + for (const entry of entries) { + if (EXCLUDED_DIRS.has(entry.name)) continue; + const full = path.join(dir, entry.name); + if (entry.isDirectory()) { + collectFiles(full, extensions, results); + } else if (entry.isFile()) { + const ext = path.extname(entry.name); + if (extensions.has(ext) && entry.name !== 'CHANGELOG.md') { + results.push(full); + } + } + } + return results; +} + +/** + * Determine whether a /gsd: match in a test file is a legitimate test input + * (i.e., the input string fed to a colon-to-hyphen converter). + */ +function isTestInput(filePath, line) { + const rel = path.relative(ROOT, filePath).replace(/\\/g, '/'); + + // SDK test files (.ts) that test sanitizer stripping of /gsd: patterns + if (rel === 'sdk/src/prompt-sanitizer.test.ts') return true; + if (rel === 'sdk/src/init-runner.test.ts') return true; + if (rel === 'sdk/src/phase-prompt.test.ts') return true; + + // Conversion test files: input strings to convert* functions contain /gsd: + const conversionTestFiles = [ + 'tests/windsurf-conversion.test.cjs', + 'tests/augment-conversion.test.cjs', + 'tests/cursor-conversion.test.cjs', + 'tests/antigravity-install.test.cjs', + 'tests/copilot-install.test.cjs', + 'tests/codex-config.test.cjs', + 'tests/trae-install.test.cjs', + ]; + + if (conversionTestFiles.includes(rel)) { + const trimmed = line.trim(); + // JSDoc block-comment lines with /gsd: in description are stale + if (/^\*/.test(trimmed)) return false; + // Everything else in conversion test files is a test input + return true; + } + + return false; +} + +describe('No stale /gsd: colon references (#1748)', () => { + test('all /gsd: references should be hyphenated except test inputs', () => { + const extensions = new Set(['.md', '.js', '.cjs', '.ts', '.yml', '.sh', '.svg']); + const files = collectFiles(ROOT, extensions); + + const staleRefs = []; + const pattern = /\/gsd:[a-z]/g; + + for (const filePath of files) { + const content = fs.readFileSync(filePath, 'utf8'); + const lines = content.split('\n'); + + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + if (!pattern.test(line)) continue; + pattern.lastIndex = 0; + + if (!isTestInput(filePath, line)) { + const rel = path.relative(ROOT, filePath).replace(/\\/g, '/'); + staleRefs.push(` ${rel}:${i + 1}: ${line.trim()}`); + } + } + } + + if (staleRefs.length > 0) { + assert.fail( + `Found ${staleRefs.length} stale /gsd: colon reference(s) that should use /gsd- hyphen format:\n${staleRefs.join('\n')}` + ); + } + }); +}); diff --git a/tests/workspace.test.cjs b/tests/workspace.test.cjs index b2beb43d..628c2caa 100644 --- a/tests/workspace.test.cjs +++ b/tests/workspace.test.cjs @@ -1,7 +1,7 @@ /** * GSD Workspace Tests * - * Tests for /gsd:new-workspace, /gsd:list-workspaces, /gsd:remove-workspace + * Tests for /gsd-new-workspace, /gsd-list-workspaces, /gsd-remove-workspace * init functions and integration with gsd-tools routing. */