Skip to content

Extension-registered slash commands (/gsd, /kill, etc.) unreachable — "Unknown command" error in v2.59.0 #3479

@corey-csg

Description

@corey-csg

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.tsisExtensionCommand() method

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions