mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-03 00:14:28 -07:00
Agent Skills: Extension Support & Security Disclosure (#15834)
This commit is contained in:
@@ -9,6 +9,7 @@ import * as fs from 'node:fs/promises';
|
||||
import * as os from 'node:os';
|
||||
import * as path from 'node:path';
|
||||
import { loadSkillsFromDir } from './skillLoader.js';
|
||||
import { coreEvents } from '../utils/events.js';
|
||||
|
||||
describe('skillLoader', () => {
|
||||
let testRootDir: string;
|
||||
@@ -17,6 +18,7 @@ describe('skillLoader', () => {
|
||||
testRootDir = await fs.mkdtemp(
|
||||
path.join(os.tmpdir(), 'skill-loader-test-'),
|
||||
);
|
||||
vi.spyOn(coreEvents, 'emitFeedback');
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
@@ -40,18 +42,45 @@ describe('skillLoader', () => {
|
||||
expect(skills[0].description).toBe('A test skill');
|
||||
expect(skills[0].location).toBe(skillFile);
|
||||
expect(skills[0].body).toBe('# Instructions\nDo something.');
|
||||
expect(coreEvents.emitFeedback).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should emit feedback when no valid skills are found in a non-empty directory', async () => {
|
||||
const notASkillDir = path.join(testRootDir, 'not-a-skill');
|
||||
await fs.mkdir(notASkillDir, { recursive: true });
|
||||
await fs.writeFile(path.join(notASkillDir, 'some-file.txt'), 'hello');
|
||||
|
||||
const skills = await loadSkillsFromDir(testRootDir);
|
||||
|
||||
expect(skills).toHaveLength(0);
|
||||
expect(coreEvents.emitFeedback).toHaveBeenCalledWith(
|
||||
'warning',
|
||||
expect.stringContaining('Failed to load skills from'),
|
||||
);
|
||||
});
|
||||
|
||||
it('should ignore empty directories and not emit feedback', async () => {
|
||||
const skills = await loadSkillsFromDir(testRootDir);
|
||||
|
||||
expect(skills).toHaveLength(0);
|
||||
expect(coreEvents.emitFeedback).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should ignore directories without SKILL.md', async () => {
|
||||
const notASkillDir = path.join(testRootDir, 'not-a-skill');
|
||||
await fs.mkdir(notASkillDir, { recursive: true });
|
||||
|
||||
// With a subdirectory, even if empty, it might still trigger readdir
|
||||
// But my current logic is if discoveredSkills.length === 0, then check readdir
|
||||
// If readdir is empty, it's fine.
|
||||
|
||||
const skills = await loadSkillsFromDir(testRootDir);
|
||||
|
||||
expect(skills).toHaveLength(0);
|
||||
// If notASkillDir is empty, no warning.
|
||||
});
|
||||
|
||||
it('should ignore SKILL.md without valid frontmatter', async () => {
|
||||
it('should ignore SKILL.md without valid frontmatter and emit warning if directory is not empty', async () => {
|
||||
const skillDir = path.join(testRootDir, 'invalid-skill');
|
||||
await fs.mkdir(skillDir, { recursive: true });
|
||||
const skillFile = path.join(skillDir, 'SKILL.md');
|
||||
@@ -60,10 +89,15 @@ describe('skillLoader', () => {
|
||||
const skills = await loadSkillsFromDir(testRootDir);
|
||||
|
||||
expect(skills).toHaveLength(0);
|
||||
expect(coreEvents.emitFeedback).toHaveBeenCalledWith(
|
||||
'warning',
|
||||
expect.stringContaining('Failed to load skills from'),
|
||||
);
|
||||
});
|
||||
|
||||
it('should return empty array for non-existent directory', async () => {
|
||||
const skills = await loadSkillsFromDir('/non/existent/path');
|
||||
expect(skills).toEqual([]);
|
||||
expect(coreEvents.emitFeedback).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user