mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-06-22 01:01:56 +08:00
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.
This commit is contained in:
@@ -957,9 +957,25 @@ export async function readProviderSkillMarkdownDefinition(
|
||||
skillPath: string,
|
||||
): Promise<{ name: string; description: string }> {
|
||||
const content = await readFile(skillPath, 'utf8');
|
||||
return readProviderSkillMarkdownDefinitionFromContent(
|
||||
content,
|
||||
path.basename(path.dirname(skillPath)),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the `name` and `description` fields from raw skill markdown content.
|
||||
*
|
||||
* This keeps filesystem discovery and newly uploaded skill creation aligned on
|
||||
* the same front matter parsing rules. `fallbackName` is used when the markdown
|
||||
* omits a `name` field so callers still get a stable, non-empty skill id.
|
||||
*/
|
||||
export function readProviderSkillMarkdownDefinitionFromContent(
|
||||
content: string,
|
||||
fallbackName: string,
|
||||
): { name: string; description: string } {
|
||||
const parsed = parseFrontMatter(content);
|
||||
const data = readObjectRecord(parsed.data) ?? {};
|
||||
const fallbackName = path.basename(path.dirname(skillPath));
|
||||
|
||||
return {
|
||||
name: readOptionalString(data.name) ?? fallbackName,
|
||||
|
||||
Reference in New Issue
Block a user