Files
claudecodeui/server/modules/providers/list/gemini/gemini-skills.provider.ts
Haile c5fe127958 feat(skills): add provider skill management (#909)
* feat(skills): add provider skill management

Users need one settings surface to discover and install skills without manually navigating provider-specific directories.

Add provider-backed global skill installation for Claude, Codex, Gemini, and Cursor, while keeping OpenCode read-only because it reuses other providers' skill locations.

Add a responsive Skills settings tab with scoped discovery, search, refresh controls, markdown and folder uploads, upload feedback, and overflow-safe layouts.

Validate bundled skill files and paths before writing them, preserve scripts and assets, and cover provider discovery and installation behavior with tests.

* fix(skills): preserve uploaded skill folders

Folder drops discarded supporting scripts and assets.

Keep relative paths and upload every file from the selected skill folder.

Use the selected folder name for installation and cover it in provider tests.

* fix(skills): restrict standalone skill uploads

Only show Markdown files when selecting standalone skills.

Normalize browser file paths so SKILL.md is not mistaken for a folder named dot.

* fix(skills): validate installs before writing

Preserve bundled files and normalize fallback names across skill installation paths.

Validate complete batches before writing and reject existing targets to avoid partial installs.

Keep project metadata and make folder selection tolerant of casing and cancelled dialogs.

* fix(skills): overwrite existing installations

Replace an existing skill directory instead of rejecting a duplicate installation.

Remove stale supporting files so the installed directory exactly matches the new upload.
2026-06-22 22:45:27 +02:00

45 lines
1.1 KiB
TypeScript

import os from 'node:os';
import path from 'node:path';
import { SkillsProvider } from '@/modules/providers/shared/skills/skills.provider.js';
import type { ProviderSkillSource } from '@/shared/types.js';
export class GeminiSkillsProvider extends SkillsProvider {
constructor() {
super('gemini');
}
protected async getSkillSources(workspacePath: string): Promise<ProviderSkillSource[]> {
return [
{
scope: 'user',
rootDir: path.join(os.homedir(), '.gemini', 'skills'),
commandPrefix: '/',
},
{
scope: 'user',
rootDir: path.join(os.homedir(), '.agents', 'skills'),
commandPrefix: '/',
},
{
scope: 'project',
rootDir: path.join(workspacePath, '.gemini', 'skills'),
commandPrefix: '/',
},
{
scope: 'project',
rootDir: path.join(workspacePath, '.agents', 'skills'),
commandPrefix: '/',
},
];
}
protected async getGlobalSkillSource(): Promise<ProviderSkillSource> {
return {
scope: 'user',
rootDir: path.join(os.homedir(), '.gemini', 'skills'),
commandPrefix: '/',
};
}
}