Support for Built-in Agent Skills (#16045)

This commit is contained in:
N. Taylor Mullen
2026-01-09 22:26:58 -08:00
committed by GitHub
parent b54e688c75
commit 461c277bf2
17 changed files with 755 additions and 451 deletions
@@ -6,7 +6,7 @@
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { skillsCommand } from './skillsCommand.js';
import { MessageType } from '../types.js';
import { MessageType, type HistoryItemSkillsList } from '../types.js';
import { createMockCommandContext } from '../../test-utils/mockCommandContext.js';
import type { CommandContext } from './types.js';
import type { Config, SkillDefinition } from '@google/gemini-cli-core';
@@ -136,6 +136,51 @@ describe('skillsCommand', () => {
);
});
it('should filter built-in skills by default and show them with "all"', async () => {
const skillManager = context.services.config!.getSkillManager();
const mockSkills = [
{
name: 'regular',
description: 'desc1',
location: '/loc1',
body: 'body1',
},
{
name: 'builtin',
description: 'desc2',
location: '/loc2',
body: 'body2',
isBuiltin: true,
},
];
vi.mocked(skillManager.getAllSkills).mockReturnValue(mockSkills);
const listCmd = skillsCommand.subCommands!.find((s) => s.name === 'list')!;
// By default, only regular skills
await listCmd.action!(context, '');
let lastCall = vi
.mocked(context.ui.addItem)
.mock.calls.at(-1)![0] as HistoryItemSkillsList;
expect(lastCall.skills).toHaveLength(1);
expect(lastCall.skills[0].name).toBe('regular');
// With "all", show both
await listCmd.action!(context, 'all');
lastCall = vi
.mocked(context.ui.addItem)
.mock.calls.at(-1)![0] as HistoryItemSkillsList;
expect(lastCall.skills).toHaveLength(2);
expect(lastCall.skills.map((s) => s.name)).toContain('builtin');
// With "--all", show both
await listCmd.action!(context, '--all');
lastCall = vi
.mocked(context.ui.addItem)
.mock.calls.at(-1)![0] as HistoryItemSkillsList;
expect(lastCall.skills).toHaveLength(2);
});
describe('disable/enable', () => {
beforeEach(() => {
context.services.settings.merged.skills = { disabled: [] };
+15 -5
View File
@@ -23,12 +23,18 @@ async function listAction(
context: CommandContext,
args: string,
): Promise<void | SlashCommandActionReturn> {
const subCommand = args.trim();
const subArgs = args.trim().split(/\s+/);
// Default to SHOWING descriptions. The user can hide them with 'nodesc'.
let useShowDescriptions = true;
if (subCommand === 'nodesc') {
useShowDescriptions = false;
let showAll = false;
for (const arg of subArgs) {
if (arg === 'nodesc' || arg === '--nodesc') {
useShowDescriptions = false;
} else if (arg === 'all' || arg === '--all') {
showAll = true;
}
}
const skillManager = context.services.config?.getSkillManager();
@@ -43,7 +49,9 @@ async function listAction(
return;
}
const skills = skillManager.getAllSkills();
const skills = showAll
? skillManager.getAllSkills()
: skillManager.getAllSkills().filter((s) => !s.isBuiltin);
const skillsListItem: HistoryItemSkillsList = {
type: MessageType.SKILLS_LIST,
@@ -53,6 +61,7 @@ async function listAction(
disabled: skill.disabled,
location: skill.location,
body: skill.body,
isBuiltin: skill.isBuiltin,
})),
showDescriptions: useShowDescriptions,
};
@@ -278,7 +287,8 @@ export const skillsCommand: SlashCommand = {
subCommands: [
{
name: 'list',
description: 'List available agent skills. Usage: /skills list [nodesc]',
description:
'List available agent skills. Usage: /skills list [nodesc] [all]',
kind: CommandKind.BUILT_IN,
action: listAction,
},