load skills from .claude directory
also put skills inside skills/ directory
This commit is contained in:
@@ -4,6 +4,10 @@ import {
|
|||||||
} from "@continuedev/config-yaml";
|
} from "@continuedev/config-yaml";
|
||||||
import z from "zod";
|
import z from "zod";
|
||||||
import { IDE, Skill } from "../..";
|
import { IDE, Skill } from "../..";
|
||||||
|
import { walkDir } from "../../indexing/walkDir";
|
||||||
|
import { localPathToUri } from "../../util/pathToUri";
|
||||||
|
import { getGlobalFolderWithName } from "../../util/paths";
|
||||||
|
import { joinPathsToUri } from "../../util/uri";
|
||||||
import { getAllDotContinueDefinitionFiles } from "../loadLocalAssistants";
|
import { getAllDotContinueDefinitionFiles } from "../loadLocalAssistants";
|
||||||
|
|
||||||
const skillFrontmatterSchema = z.object({
|
const skillFrontmatterSchema = z.object({
|
||||||
@@ -11,28 +15,61 @@ const skillFrontmatterSchema = z.object({
|
|||||||
description: z.string().min(1),
|
description: z.string().min(1),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const SKILLS_DIR = "skills";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get skills from .claude/skills directory
|
||||||
|
*/
|
||||||
|
async function getClaudeSkillsDir(ide: IDE) {
|
||||||
|
const fullDirs = (await ide.getWorkspaceDirs()).map((dir) =>
|
||||||
|
joinPathsToUri(dir, ".claude", SKILLS_DIR),
|
||||||
|
);
|
||||||
|
|
||||||
|
fullDirs.push(localPathToUri(getGlobalFolderWithName(SKILLS_DIR)));
|
||||||
|
|
||||||
|
return (
|
||||||
|
await Promise.all(
|
||||||
|
fullDirs.map(async (dir) => {
|
||||||
|
const exists = await ide.fileExists(dir);
|
||||||
|
if (!exists) return [];
|
||||||
|
const uris = await walkDir(dir, ide, {
|
||||||
|
source: "get claude skills files",
|
||||||
|
});
|
||||||
|
// filter markdown files only
|
||||||
|
return uris.filter((uri) => uri.endsWith(".md"));
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
).flat();
|
||||||
|
}
|
||||||
|
|
||||||
export async function loadMarkdownSkills(ide: IDE) {
|
export async function loadMarkdownSkills(ide: IDE) {
|
||||||
const errors: ConfigValidationError[] = [];
|
const errors: ConfigValidationError[] = [];
|
||||||
const skills: Skill[] = [];
|
const skills: Skill[] = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const yamlAndMarkdownFiles = await getAllDotContinueDefinitionFiles(
|
const yamlAndMarkdownFileUris = [
|
||||||
ide,
|
...(
|
||||||
{
|
await getAllDotContinueDefinitionFiles(
|
||||||
includeGlobal: true,
|
ide,
|
||||||
includeWorkspace: true,
|
{
|
||||||
fileExtType: "markdown",
|
includeGlobal: true,
|
||||||
},
|
includeWorkspace: true,
|
||||||
"", // SKILL.md can exist in any .continue subdirectory
|
fileExtType: "markdown",
|
||||||
);
|
},
|
||||||
|
SKILLS_DIR,
|
||||||
|
)
|
||||||
|
).map((file) => file.path),
|
||||||
|
...(await getClaudeSkillsDir(ide)),
|
||||||
|
];
|
||||||
|
|
||||||
const skillFiles = yamlAndMarkdownFiles.filter((file) =>
|
const skillFiles = yamlAndMarkdownFileUris.filter((path) =>
|
||||||
file.path.endsWith("SKILL.md"),
|
path.endsWith("SKILL.md"),
|
||||||
);
|
);
|
||||||
for (const file of skillFiles) {
|
for (const fileUri of skillFiles) {
|
||||||
try {
|
try {
|
||||||
|
const content = await ide.readFile(fileUri);
|
||||||
const { frontmatter, markdown } = parseMarkdownRule(
|
const { frontmatter, markdown } = parseMarkdownRule(
|
||||||
file.content,
|
content,
|
||||||
) as unknown as { frontmatter: Skill; markdown: string };
|
) as unknown as { frontmatter: Skill; markdown: string };
|
||||||
|
|
||||||
const validatedFrontmatter = skillFrontmatterSchema.parse(frontmatter);
|
const validatedFrontmatter = skillFrontmatterSchema.parse(frontmatter);
|
||||||
@@ -40,7 +77,7 @@ export async function loadMarkdownSkills(ide: IDE) {
|
|||||||
skills.push({
|
skills.push({
|
||||||
...validatedFrontmatter,
|
...validatedFrontmatter,
|
||||||
content: markdown,
|
content: markdown,
|
||||||
path: file.path.slice(7),
|
path: fileUri,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
errors.push({
|
errors.push({
|
||||||
|
|||||||
Reference in New Issue
Block a user