72 lines
3 KiB
TypeScript
72 lines
3 KiB
TypeScript
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>): 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 ?? '/tmp/project',
|
|
discoveryRoot: overrides.discoveryRoot ?? '/tmp/project/.claude/skills',
|
|
skillDir: overrides.skillDir ?? '/tmp/project/.claude/skills/skill-name',
|
|
skillFile: overrides.skillFile ?? '/tmp/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'
|
|
);
|
|
});
|
|
});
|