import { describe, expect, it } from 'vitest'; import { buildSlashCommandSuggestions } from '@renderer/utils/skillCommandSuggestions'; import { KNOWN_SLASH_COMMANDS } from '@shared/utils/slashCommands'; import type { SkillCatalogItem } from '@shared/types/extensions'; function createSkill(overrides: Partial): SkillCatalogItem { return { id: overrides.id ?? 'skill-id', sourceType: 'filesystem', name: overrides.name ?? 'Skill Name', description: overrides.description ?? 'Skill description', folderName: overrides.folderName ?? 'skill-name', scope: overrides.scope ?? 'project', rootKind: overrides.rootKind ?? 'claude', projectRoot: overrides.projectRoot ?? '/Users/test/project', discoveryRoot: overrides.discoveryRoot ?? '/Users/test/project/.claude/skills', skillDir: overrides.skillDir ?? '/Users/test/project/.claude/skills/skill-name', skillFile: overrides.skillFile ?? '/Users/test/project/.claude/skills/skill-name/SKILL.md', metadata: overrides.metadata ?? {}, invocationMode: overrides.invocationMode ?? 'manual-only', flags: overrides.flags ?? { hasScripts: false, hasReferences: false, hasAssets: false }, isValid: overrides.isValid ?? true, issues: overrides.issues ?? [], modifiedAt: overrides.modifiedAt ?? 0, }; } describe('buildSlashCommandSuggestions', () => { it('keeps built-ins and adds valid skills in a separate suggestion type', () => { const suggestions = buildSlashCommandSuggestions( KNOWN_SLASH_COMMANDS, [createSkill({ id: 'project-skill', folderName: 'review-skill', scope: 'project' })], [] ); expect(suggestions[0]?.type).toBe('command'); expect(suggestions.some((suggestion) => suggestion.type === 'skill')).toBe(true); expect(suggestions.find((suggestion) => suggestion.id === 'skill:project-skill')).toMatchObject( { name: 'review-skill', command: '/review-skill', subtitle: 'Project skill', type: 'skill', } ); }); it('filters slash-unsafe names and built-in collisions', () => { const suggestions = buildSlashCommandSuggestions( KNOWN_SLASH_COMMANDS, [ createSkill({ id: 'unsafe', folderName: 'bad skill' }), createSkill({ id: 'collision', folderName: 'plan' }), ], [] ); expect(suggestions.find((suggestion) => suggestion.id === 'skill:unsafe')).toBeUndefined(); expect(suggestions.find((suggestion) => suggestion.id === 'skill:collision')).toBeUndefined(); }); it('prefers project skills when user and project skills share the same slash name', () => { const suggestions = buildSlashCommandSuggestions( KNOWN_SLASH_COMMANDS, [createSkill({ id: 'project', folderName: 'shared-skill', scope: 'project' })], [createSkill({ id: 'user', folderName: 'shared-skill', scope: 'user' })] ); expect(suggestions.filter((suggestion) => suggestion.command === '/shared-skill')).toHaveLength( 1 ); expect(suggestions.find((suggestion) => suggestion.command === '/shared-skill')?.id).toBe( 'skill:project' ); }); it('uses the provided built-in set when filtering skill collisions', () => { const suggestions = buildSlashCommandSuggestions( [ { name: 'custom-cmd', command: '/custom-cmd', description: 'Custom command', }, ], [createSkill({ id: 'collision', folderName: 'custom-cmd' })], [] ); expect(suggestions.find((suggestion) => suggestion.id === 'skill:collision')).toBeUndefined(); }); });