Version
2.59.0
Symptom
Typing /gsd, /gsd auto, /gsd status, /gsd forensics, /kill, or any other extension-registered slash command returns:
Error: Unknown command: /gsd. Type /help for available commands.
Extension-registered tools (e.g. gsd_decision_save, gsd_plan_milestone) work correctly. Only slash commands are affected.
Root Cause
input-controller.js dispatches all /-prefixed input to dispatchSlashCommand() in slash-command-handlers.js. This function is a hardcoded if/else chain covering only built-in commands (/settings, /model, /export, /compact, /debug, /quit, etc.). It never consults the extension runner's registered command map before reaching the catch-all fallthrough:
// slash-command-handlers.js ~L149
if (text.startsWith("/")) {
const command = text.split(/\s/)[0];
ctx.showError(`Unknown command: ${command}. Type /help for available commands.`);
return true;
}
The extension runner does have the commands registered — isExtensionCommand() in interactive-mode.js correctly resolves /gsd via extensionRunner.getCommand("gsd"). However, this check is only invoked in three non-standard paths:
- During compaction (
input-controller.js:31)
- During streaming steer (
interactive-mode.js:1904)
- During queue flush (
interactive-mode.js:2185, 2199, 2220)
The normal submit path at input-controller.js:7-10 goes straight to dispatchSlashCommand() without checking extension commands.
Impact
All extension-registered commands are unreachable in normal interactive mode. This includes:
- Core GSD workflow commands:
/gsd, /gsd auto, /gsd status, /gsd stop, /gsd queue, /gsd quick
- Other extension commands:
/kill, /worktree, /exit
- Any commands registered by third-party extensions
Autocomplete for these commands works (they appear in the suggestion list) because interactive-mode.js:224 correctly includes extension commands in the autocomplete provider — only dispatch is broken.
Suggested Fix
In input-controller.js, check host.isExtensionCommand(text) before calling dispatchSlashCommand(), or add an extension command lookup inside dispatchSlashCommand() before the catch-all. The same dispatch pattern already exists in the compaction path.
Files Involved
packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts — submit handler
packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts — hardcoded dispatch
packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts — isExtensionCommand() method
Version
2.59.0
Symptom
Typing
/gsd,/gsd auto,/gsd status,/gsd forensics,/kill, or any other extension-registered slash command returns:Extension-registered tools (e.g.
gsd_decision_save,gsd_plan_milestone) work correctly. Only slash commands are affected.Root Cause
input-controller.jsdispatches all/-prefixed input todispatchSlashCommand()inslash-command-handlers.js. This function is a hardcoded if/else chain covering only built-in commands (/settings,/model,/export,/compact,/debug,/quit, etc.). It never consults the extension runner's registered command map before reaching the catch-all fallthrough:The extension runner does have the commands registered —
isExtensionCommand()ininteractive-mode.jscorrectly resolves/gsdviaextensionRunner.getCommand("gsd"). However, this check is only invoked in three non-standard paths:input-controller.js:31)interactive-mode.js:1904)interactive-mode.js:2185, 2199, 2220)The normal submit path at
input-controller.js:7-10goes straight todispatchSlashCommand()without checking extension commands.Impact
All extension-registered commands are unreachable in normal interactive mode. This includes:
/gsd,/gsd auto,/gsd status,/gsd stop,/gsd queue,/gsd quick/kill,/worktree,/exitAutocomplete for these commands works (they appear in the suggestion list) because
interactive-mode.js:224correctly includes extension commands in the autocomplete provider — only dispatch is broken.Suggested Fix
In
input-controller.js, checkhost.isExtensionCommand(text)before callingdispatchSlashCommand(), or add an extension command lookup insidedispatchSlashCommand()before the catch-all. The same dispatch pattern already exists in the compaction path.Files Involved
packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts— submit handlerpackages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts— hardcoded dispatchpackages/pi-coding-agent/src/modes/interactive/interactive-mode.ts—isExtensionCommand()method