From dea17dc3ba021252311acfb8e3377f75bb0edc4e Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Wed, 31 Dec 2025 03:13:29 +0900 Subject: [PATCH] fix(command-loader): strip incompatible fields before registering with OpenCode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Slash commands with arguments were silently failing in OpenCode TUI because command definitions included 'name' and 'argumentHint' fields that don't exist in OpenCode's Command schema. Strip these fields before registration across all command/skill loaders to ensure compatibility. Affected loaders: - builtin commands - claude-code command loader - opencode skill loader - claude-code plugin loader 🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode) --- src/features/builtin-commands/commands.ts | 6 ++---- src/features/claude-code-command-loader/loader.ts | 3 ++- src/features/claude-code-plugin-loader/loader.ts | 8 ++++++-- src/features/opencode-skill-loader/loader.ts | 3 ++- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/features/builtin-commands/commands.ts b/src/features/builtin-commands/commands.ts index d183a2fc4..c8f5d5469 100644 --- a/src/features/builtin-commands/commands.ts +++ b/src/features/builtin-commands/commands.ts @@ -42,10 +42,8 @@ export function loadBuiltinCommands( for (const [name, definition] of Object.entries(BUILTIN_COMMAND_DEFINITIONS)) { if (!disabled.has(name as BuiltinCommandName)) { - commands[name] = { - name, - ...definition, - } + const { argumentHint: _argumentHint, ...openCodeCompatible } = definition + commands[name] = openCodeCompatible as CommandDefinition } } diff --git a/src/features/claude-code-command-loader/loader.ts b/src/features/claude-code-command-loader/loader.ts index 82e007630..32223cb62 100644 --- a/src/features/claude-code-command-loader/loader.ts +++ b/src/features/claude-code-command-loader/loader.ts @@ -62,7 +62,8 @@ $ARGUMENTS function commandsToRecord(commands: LoadedCommand[]): Record { const result: Record = {} for (const cmd of commands) { - result[cmd.name] = cmd.definition + const { name: _name, argumentHint: _argumentHint, ...openCodeCompatible } = cmd.definition + result[cmd.name] = openCodeCompatible as CommandDefinition } return result } diff --git a/src/features/claude-code-plugin-loader/loader.ts b/src/features/claude-code-plugin-loader/loader.ts index 9042ac1a3..7b4aeed1a 100644 --- a/src/features/claude-code-plugin-loader/loader.ts +++ b/src/features/claude-code-plugin-loader/loader.ts @@ -246,7 +246,7 @@ $ARGUMENTS const formattedDescription = `(plugin: ${plugin.name}) ${data.description || ""}` - commands[namespacedName] = { + const definition = { name: namespacedName, description: formattedDescription, template: wrappedTemplate, @@ -255,6 +255,8 @@ $ARGUMENTS subtask: data.subtask, argumentHint: data["argument-hint"], } + const { name: _name, argumentHint: _argumentHint, ...openCodeCompatible } = definition + commands[namespacedName] = openCodeCompatible as CommandDefinition log(`Loaded plugin command: ${namespacedName}`, { path: commandPath }) } catch (error) { @@ -306,12 +308,14 @@ ${body.trim()} $ARGUMENTS ` - skills[namespacedName] = { + const definition = { name: namespacedName, description: formattedDescription, template: wrappedTemplate, model: sanitizeModelField(data.model), } + const { name: _name, ...openCodeCompatible } = definition + skills[namespacedName] = openCodeCompatible as CommandDefinition log(`Loaded plugin skill: ${namespacedName}`, { path: resolvedPath }) } catch (error) { diff --git a/src/features/opencode-skill-loader/loader.ts b/src/features/opencode-skill-loader/loader.ts index 32ffad410..5f4889807 100644 --- a/src/features/opencode-skill-loader/loader.ts +++ b/src/features/opencode-skill-loader/loader.ts @@ -126,7 +126,8 @@ function loadSkillsFromDir(skillsDir: string, scope: SkillScope): LoadedSkill[] function skillsToRecord(skills: LoadedSkill[]): Record { const result: Record = {} for (const skill of skills) { - result[skill.name] = skill.definition + const { name: _name, argumentHint: _argumentHint, ...openCodeCompatible } = skill.definition + result[skill.name] = openCodeCompatible as CommandDefinition } return result }