Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions src/cli/commands/plugin-skills.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1365,9 +1365,13 @@ const addCmd = command({
// skill search (GitHub Code Search)
// =============================================================================

export function formatSkillSearchSummary(count: number, query: string, truncated: boolean): string {
return `Showing ${count} skill${count !== 1 ? 's' : ''} matching "${query}"${truncated ? ' (truncated)' : ''}`;
}

/** Print results in gh-compatible tabular format: repo, skillName, description, stars. */
function printSearchResults(items: SkillSearchItem[], query: string, truncated: boolean): void {
console.log(`\nShowing ${items.length} result${items.length !== 1 ? 's' : ''} for "${query}"${truncated ? ' (truncated)' : ''}\n`);
console.log(`\n${formatSkillSearchSummary(items.length, query, truncated)}\n`);
for (const item of items) {
const repoCol = item.repo.padEnd(30);
const nameCol = qualifiedName(item).padEnd(24);
Expand Down Expand Up @@ -1522,9 +1526,9 @@ const searchCmd = command({
}

// Interactive mode: filter-as-you-type select with install support
const { autocomplete, isCancel } = await import('@clack/prompts');
const { autocomplete, isCancel, log } = await import('@clack/prompts');

printSearchResults(result.items, query, result.truncated);
log.success(formatSkillSearchSummary(result.items.length, query, result.truncated));

const options = result.items.map((item) => ({
label: `${qualifiedName(item)} ${chalk.dim(item.repo)}`,
Expand All @@ -1534,7 +1538,7 @@ const searchCmd = command({
options.push({ label: 'Cancel', value: '__cancel__', hint: '' });

const selected = await autocomplete({
message: `Select a skill to install (type to filter ${result.items.length} results)`,
message: 'Select a skill to install',
options,
placeholder: 'Type to filter...',
});
Expand Down
22 changes: 22 additions & 0 deletions tests/unit/cli/skill-search-summary.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { describe, expect, it } from 'bun:test';
import { formatSkillSearchSummary } from '../../../src/cli/commands/plugin-skills.js';

describe('formatSkillSearchSummary', () => {
it('uses singular skill wording for one match', () => {
expect(formatSkillSearchSummary(1, 'skill-source-mapping', false)).toBe(
'Showing 1 skill matching "skill-source-mapping"',
);
});

it('uses plural skills wording for multiple matches', () => {
expect(formatSkillSearchSummary(2, 'mapping', false)).toBe(
'Showing 2 skills matching "mapping"',
);
});

it('includes truncated marker when applicable', () => {
expect(formatSkillSearchSummary(15, 'mapping', true)).toBe(
'Showing 15 skills matching "mapping" (truncated)',
);
});
});