diff --git a/packages/cli/src/services/SkillCommandLoader.test.ts b/packages/cli/src/services/SkillCommandLoader.test.ts index 33d9813cb4..af98ba5909 100644 --- a/packages/cli/src/services/SkillCommandLoader.test.ts +++ b/packages/cli/src/services/SkillCommandLoader.test.ts @@ -108,4 +108,18 @@ describe('SkillCommandLoader', () => { postSubmitPrompt: 'hello world', }); }); + + it('should sanitize skill names with spaces', async () => { + const mockSkills = [{ name: 'my awesome skill', description: 'Desc' }]; + mockSkillManager.getDisplayableSkills.mockReturnValue(mockSkills); + + const loader = new SkillCommandLoader(mockConfig); + const commands = await loader.loadCommands(new AbortController().signal); + + expect(commands[0].name).toBe('my-awesome-skill'); + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const actionResult = await commands[0].action!({} as any, ''); + expect(actionResult.toolArgs).toEqual({ name: 'my awesome skill' }); + }); }); diff --git a/packages/cli/src/services/SkillCommandLoader.ts b/packages/cli/src/services/SkillCommandLoader.ts index e2a2823890..85f1884299 100644 --- a/packages/cli/src/services/SkillCommandLoader.ts +++ b/packages/cli/src/services/SkillCommandLoader.ts @@ -31,23 +31,23 @@ export class SkillCommandLoader implements ICommandLoader { return []; } - // Only include enabled skills that are not built-in (since built-in skills - // are usually internal or have dedicated slash commands). - // Actually, the user says "if you have a skill called google-foo", so we - // should probably include all user/workspace/extension skills. + // Convert all displayable skills into slash commands. const skills = skillManager.getDisplayableSkills(); - return skills.map((skill) => ({ - name: skill.name, - description: skill.description || `Activate the ${skill.name} skill`, - kind: CommandKind.SKILL, - autoExecute: true, - action: async (_context, args) => ({ + return skills.map((skill) => { + const commandName = skill.name.trim().replace(/\s+/g, '-'); + return { + name: commandName, + description: skill.description || `Activate the ${skill.name} skill`, + kind: CommandKind.SKILL, + autoExecute: true, + action: async (_context, args) => ({ type: 'tool', toolName: ACTIVATE_SKILL_TOOL_NAME, toolArgs: { name: skill.name }, postSubmitPrompt: args.trim().length > 0 ? args.trim() : undefined, }), - })); + }; + }); } }