fix(#2543): replace legacy /gsd-<cmd> syntax with /gsd:<cmd> across all source files (#2595)

Commands are now installed as commands/gsd/<name>.md and invoked as
/gsd:<name> in Claude Code. The old hyphen form /gsd-<name> was still
hardcoded in hundreds of places across workflows, references, templates,
lib modules, and command files — causing "Unknown command" errors
whenever GSD suggested a command to the user.

Replace all /gsd-<cmd> occurrences where <cmd> is a known command name
(derived at runtime from commands/gsd/*.md) using a targeted Node.js
script. Agent names, tool names (gsd-sdk, gsd-tools), directory names,
and path fragments are not touched.

Adds regression test tests/bug-2543-gsd-slash-namespace.test.cjs that
enforces zero legacy occurrences going forward. Removes inverted
tests/stale-colon-refs.test.cjs (bug #1748) which enforced the now-obsolete
hyphen form; the new bug-2543 test supersedes it. Updates 5 assertion
tests that hardcoded the old hyphen form to accept the new colon form.

Closes #2543

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tom Boucher
2026-04-22 12:04:25 -04:00
committed by GitHub
parent 533973700c
commit 73c1af5168
150 changed files with 962 additions and 939 deletions

View File

@@ -45,7 +45,7 @@ promoted: false
| Arguments are empty (no text at all) | **list** |
| Anything else | **append** (the text IS the note) |
**Critical**: `list` is only a subcommand when it's the ENTIRE argument. `/gsd-note list of groceries` saves a note with text "list of groceries". Same for `promote` — only a subcommand when followed by exactly one number.
**Critical**: `list` is only a subcommand when it's the ENTIRE argument. `/gsd:note list of groceries` saves a note with text "list of groceries". Same for `promote` — only a subcommand when followed by exactly one number.
</step>
<step name="append">
@@ -89,7 +89,7 @@ Project (.planning/notes/):
Global (~/.claude/notes/):
4. [2026-02-08 10:00] cross-project idea about shared config
{count} active note(s). Use `/gsd-note promote <N>` to convert to a todo.
{count} active note(s). Use `/gsd:note promote <N>` to convert to a todo.
```
If a scope has no directory or no entries, show: `(no notes)`
@@ -101,7 +101,7 @@ If a scope has no directory or no entries, show: `(no notes)`
1. Run the **list** logic to build the numbered index (both scopes)
2. Find entry N from the numbered list
3. If N is invalid or refers to an already-promoted note, tell the user and stop
4. **Requires `.planning/` directory** — if it doesn't exist, warn: "Todos require a GSD project. Run `/gsd-new-project` to initialize one."
4. **Requires `.planning/` directory** — if it doesn't exist, warn: "Todos require a GSD project. Run `/gsd:new-project` to initialize one."
5. Ensure `.planning/todos/pending/` directory exists
6. Generate todo ID: `{NNN}-{slug}` where NNN is the next sequential number (scan both `.planning/todos/pending/` and `.planning/todos/completed/` for the highest existing number, increment by 1, zero-pad to 3 digits) and slug is the first ~4 meaningful words of the note text
7. Extract the note text from the source file (body after frontmatter)
@@ -112,7 +112,7 @@ If a scope has no directory or no entries, show: `(no notes)`
title: "{note text}"
status: pending
priority: P2
source: "promoted from /gsd-note"
source: "promoted from /gsd:note"
created: {YYYY-MM-DD}
theme: general
---
@@ -137,9 +137,9 @@ Promoted from quick note captured on {original date}.
</process>
<edge_cases>
1. **"list" as note text**: `/gsd-note list of things` saves note "list of things" (subcommand only when `list` is the entire arg)
1. **"list" as note text**: `/gsd:note list of things` saves note "list of things" (subcommand only when `list` is the entire arg)
2. **No `.planning/`**: Falls back to global `~/.claude/notes/` — works in any directory
3. **Promote without project**: Warns that todos require `.planning/`, suggests `/gsd-new-project`
3. **Promote without project**: Warns that todos require `.planning/`, suggests `/gsd:new-project`
4. **Large files**: `list` shows last 10 when >20 active entries
5. **Duplicate slugs**: Append `-2`, `-3` etc. to filename if slug already used on same date
6. **`--global` position**: Stripped from anywhere — `--global my idea` and `my idea --global` both save "my idea" globally