feat(do): add freeform text router command (#1067)

* feat(do): add freeform text router command

* test(do): update expected skill count from 36 to 37
This commit is contained in:
Rezolv
2026-03-15 21:30:46 -04:00
committed by GitHub
parent 6de816f68c
commit 4aea69e02c
4 changed files with 150 additions and 2 deletions

30
commands/gsd/do.md Normal file
View File

@@ -0,0 +1,30 @@
---
name: gsd:do
description: Route freeform text to the right GSD command automatically
argument-hint: "<description of what you want to do>"
allowed-tools:
- Read
- Bash
- AskUserQuestion
---
<objective>
Analyze freeform natural language input and dispatch to the most appropriate GSD command.
Acts as a smart dispatcher — never does the work itself. Matches intent to the best GSD command using routing rules, confirms the match, then hands off.
Use when you know what you want but don't know which `/gsd:*` command to run.
</objective>
<execution_context>
@~/.claude/get-shit-done/workflows/do.md
@~/.claude/get-shit-done/references/ui-brand.md
</execution_context>
<context>
$ARGUMENTS
</context>
<process>
Execute the do workflow from @~/.claude/get-shit-done/workflows/do.md end-to-end.
Route user intent to the best GSD command and invoke it.
</process>

View File

@@ -0,0 +1,104 @@
<purpose>
Analyze freeform text from the user and route to the most appropriate GSD command. This is a dispatcher — it never does the work itself. Match user intent to the best command, confirm the routing, and hand off.
</purpose>
<required_reading>
Read all files referenced by the invoking prompt's execution_context before starting.
</required_reading>
<process>
<step name="validate">
**Check for input.**
If `$ARGUMENTS` is empty, ask via AskUserQuestion:
```
What would you like to do? Describe the task, bug, or idea and I'll route it to the right GSD command.
```
Wait for response before continuing.
</step>
<step name="check_project">
**Check if project exists.**
```bash
INIT=$(node "~/.claude/get-shit-done/bin/gsd-tools.cjs" state load 2>/dev/null)
```
Track whether `.planning/` exists — some routes require it, others don't.
</step>
<step name="route">
**Match intent to command.**
Evaluate `$ARGUMENTS` against these routing rules. Apply the **first matching** rule:
| If the text describes... | Route to | Why |
|--------------------------|----------|-----|
| Starting a new project, "set up", "initialize" | `/gsd:new-project` | Needs full project initialization |
| Mapping or analyzing an existing codebase | `/gsd:map-codebase` | Codebase discovery |
| A bug, error, crash, failure, or something broken | `/gsd:debug` | Needs systematic investigation |
| Exploring, researching, comparing, or "how does X work" | `/gsd:research-phase` | Domain research before planning |
| Discussing vision, "how should X look", brainstorming | `/gsd:discuss-phase` | Needs context gathering |
| A complex task: refactoring, migration, multi-file architecture, system redesign | `/gsd:add-phase` | Needs a full phase with plan/build cycle |
| Planning a specific phase or "plan phase N" | `/gsd:plan-phase` | Direct planning request |
| Executing a phase or "build phase N", "run phase N" | `/gsd:execute-phase` | Direct execution request |
| Running all remaining phases automatically | `/gsd:autonomous` | Full autonomous execution |
| A review or quality concern about existing work | `/gsd:verify-work` | Needs verification |
| Checking progress, status, "where am I" | `/gsd:progress` | Status check |
| Resuming work, "pick up where I left off" | `/gsd:resume-work` | Session restoration |
| A note, idea, or "remember to..." | `/gsd:add-todo` | Capture for later |
| Adding tests, "write tests", "test coverage" | `/gsd:add-tests` | Test generation |
| Completing a milestone, shipping, releasing | `/gsd:complete-milestone` | Milestone lifecycle |
| A specific, actionable, small task (add feature, fix typo, update config) | `/gsd:quick` | Self-contained, single executor |
**Requires `.planning/` directory:** All routes except `/gsd:new-project`, `/gsd:map-codebase`, `/gsd:help`, and `/gsd:join-discord`. If the project doesn't exist and the route requires it, suggest `/gsd:new-project` first.
**Ambiguity handling:** If the text could reasonably match multiple routes, ask the user via AskUserQuestion with the top 2-3 options. For example:
```
"Refactor the authentication system" could be:
1. /gsd:add-phase — Full planning cycle (recommended for multi-file refactors)
2. /gsd:quick — Quick execution (if scope is small and clear)
Which approach fits better?
```
</step>
<step name="display">
**Show the routing decision.**
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
GSD ► ROUTING
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
**Input:** {first 80 chars of $ARGUMENTS}
**Routing to:** {chosen command}
**Reason:** {one-line explanation}
```
</step>
<step name="dispatch">
**Invoke the chosen command.**
Run the selected `/gsd:*` command, passing `$ARGUMENTS` as args.
If the chosen command expects a phase number and one wasn't provided in the text, extract it from context or ask via AskUserQuestion.
After invoking the command, stop. The dispatched command handles everything from here.
</step>
</process>
<success_criteria>
- [ ] Input validated (not empty)
- [ ] Intent matched to exactly one GSD command
- [ ] Ambiguity resolved via user question (if needed)
- [ ] Project existence checked for routes that require it
- [ ] Routing decision displayed before dispatch
- [ ] Command invoked with appropriate arguments
- [ ] No work done directly — dispatcher only
</success_criteria>

View File

@@ -116,6 +116,20 @@ Execute all plans in a phase.
Usage: `/gsd:execute-phase 5`
### Smart Router
**`/gsd:do <description>`**
Route freeform text to the right GSD command automatically.
- Analyzes natural language input to find the best matching GSD command
- Acts as a dispatcher — never does the work itself
- Resolves ambiguity by asking you to pick between top matches
- Use when you know what you want but don't know which `/gsd:*` command to run
Usage: `/gsd:do fix the login button`
Usage: `/gsd:do refactor the auth system`
Usage: `/gsd:do I want to start a new milestone`
### Quick Mode
**`/gsd:quick [--full] [--discuss] [--research]`**

View File

@@ -626,7 +626,7 @@ describe('copyCommandsAsCopilotSkills', () => {
// Count gsd-* directories — should be 31
const dirs = fs.readdirSync(tempDir, { withFileTypes: true })
.filter(e => e.isDirectory() && e.name.startsWith('gsd-'));
assert.strictEqual(dirs.length, 36, `expected 36 skill folders, got ${dirs.length}`);
assert.strictEqual(dirs.length, 37, `expected 37 skill folders, got ${dirs.length}`);
} finally {
fs.rmSync(tempDir, { recursive: true });
}
@@ -1120,7 +1120,7 @@ const { execFileSync } = require('child_process');
const crypto = require('crypto');
const INSTALL_PATH = path.join(__dirname, '..', 'bin', 'install.js');
const EXPECTED_SKILLS = 36;
const EXPECTED_SKILLS = 37;
const EXPECTED_AGENTS = 15;
function runCopilotInstall(cwd) {