@agents-inc/cli 0.46.0 → 0.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/README.md +114 -118
- package/config/skill-categories.yaml +344 -0
- package/config/skill-rules.yaml +740 -0
- package/dist/{chunk-LFZXMQOH.js → chunk-2BVZOYJP.js} +2 -2
- package/dist/{chunk-4C7PDDLY.js → chunk-2DNDAXF6.js} +5 -5
- package/dist/{chunk-C7BO2ASM.js → chunk-34BP5BC4.js} +2 -2
- package/dist/{chunk-TOWP4T5L.js → chunk-37QYD33C.js} +2 -2
- package/dist/{chunk-YT7UHV67.js → chunk-5MN5S3DV.js} +11 -9
- package/dist/chunk-5MN5S3DV.js.map +1 -0
- package/dist/{chunk-72GS6PIH.js → chunk-5O6GKXAN.js} +7 -7
- package/dist/{chunk-KWQ2BQXF.js → chunk-7IAKVZL5.js} +3 -3
- package/dist/{chunk-CTQHZELA.js → chunk-AMNCCZSG.js} +14 -14
- package/dist/{chunk-PZLUO4OY.js → chunk-AXV7NFFJ.js} +4 -4
- package/dist/{chunk-ODQ2BKWU.js → chunk-AXZNJ5PN.js} +3 -3
- package/dist/{chunk-J64CA4V6.js → chunk-C7DLY64D.js} +2 -2
- package/dist/{chunk-G2WNOT3R.js → chunk-DG2U2WY3.js} +2 -2
- package/dist/{chunk-3WKFSTG6.js → chunk-F7KTUFGU.js} +2 -2
- package/dist/{chunk-5M6JI76P.js → chunk-FHKNG3UA.js} +2 -2
- package/dist/{chunk-I26YP2Q3.js → chunk-FPTUCWBY.js} +5 -5
- package/dist/{chunk-VH3PI43B.js → chunk-G5OZQ376.js} +4 -4
- package/dist/{chunk-RWR56UVK.js → chunk-GSPPOXMG.js} +11 -2
- package/dist/chunk-GSPPOXMG.js.map +1 -0
- package/dist/{chunk-YVMYQSED.js → chunk-I52THVF6.js} +2 -2
- package/dist/{chunk-FKBCYT7B.js → chunk-IS7GP6XC.js} +5 -5
- package/dist/{chunk-UK3AMBR7.js → chunk-KPJJOLAQ.js} +13 -6
- package/dist/{chunk-UK3AMBR7.js.map → chunk-KPJJOLAQ.js.map} +1 -1
- package/dist/{chunk-74HSA7C4.js → chunk-LESHL6SM.js} +9 -5
- package/dist/chunk-LESHL6SM.js.map +1 -0
- package/dist/{chunk-NMXNHRAK.js → chunk-NJVJ7VO5.js} +3 -3
- package/dist/{chunk-GVLYNP2I.js → chunk-OHDEJEYB.js} +4 -4
- package/dist/{chunk-CD64ZNYI.js → chunk-OTTITQ7C.js} +11 -3
- package/dist/chunk-OTTITQ7C.js.map +1 -0
- package/dist/{chunk-RT6IBH37.js → chunk-P2SFRDWI.js} +191 -109
- package/dist/chunk-P2SFRDWI.js.map +1 -0
- package/dist/{chunk-FUEZQ2H6.js → chunk-PY2XZUBF.js} +4 -4
- package/dist/{chunk-CDGHSTB6.js → chunk-SPVSWDFM.js} +7 -5
- package/dist/chunk-SPVSWDFM.js.map +1 -0
- package/dist/{chunk-DO5OZHSS.js → chunk-U2AEK4ZL.js} +2 -2
- package/dist/{chunk-HM3DHMW7.js → chunk-VBAAATPU.js} +8 -8
- package/dist/chunk-VBAAATPU.js.map +1 -0
- package/dist/{chunk-7LDSHHKN.js → chunk-W62XVWXB.js} +3 -3
- package/dist/{chunk-D7JTL3DJ.js → chunk-WSGKCBY5.js} +2 -2
- package/dist/{chunk-XE6RTHUD.js → chunk-X3SZIBVW.js} +34 -4
- package/dist/chunk-X3SZIBVW.js.map +1 -0
- package/dist/{chunk-QBUOZVNZ.js → chunk-YDASDMTH.js} +2 -2
- package/dist/{chunk-5QRJUBK7.js → chunk-YMUWTPOM.js} +41 -29
- package/dist/chunk-YMUWTPOM.js.map +1 -0
- package/dist/{chunk-SGXUMZWL.js → chunk-ZML3OCYA.js} +2 -2
- package/dist/commands/build/marketplace.js +4 -4
- package/dist/commands/build/plugins.js +5 -5
- package/dist/commands/build/stack.js +5 -5
- package/dist/commands/compile.js +6 -6
- package/dist/commands/config/get.js +4 -4
- package/dist/commands/config/index.js +5 -5
- package/dist/commands/config/path.js +4 -4
- package/dist/commands/config/set-project.js +4 -4
- package/dist/commands/config/show.js +5 -5
- package/dist/commands/config/unset-project.js +4 -4
- package/dist/commands/diff.js +4 -4
- package/dist/commands/doctor.js +4 -4
- package/dist/commands/edit.js +29 -29
- package/dist/commands/eject.js +4 -4
- package/dist/commands/import/skill.js +7 -8
- package/dist/commands/import/skill.js.map +1 -1
- package/dist/commands/info.js +5 -5
- package/dist/commands/init.js +28 -28
- package/dist/commands/list.js +4 -4
- package/dist/commands/new/agent.js +6 -6
- package/dist/commands/new/marketplace.js +5 -5
- package/dist/commands/new/skill.js +10 -8
- package/dist/commands/new/skill.js.map +1 -1
- package/dist/commands/outdated.js +4 -4
- package/dist/commands/search.js +7 -8
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/uninstall.js +6 -6
- package/dist/commands/update.js +6 -6
- package/dist/commands/validate.js +267 -24
- package/dist/commands/validate.js.map +1 -1
- package/dist/components/skill-search/skill-search.js +3 -3
- package/dist/components/wizard/category-grid.js +2 -2
- package/dist/components/wizard/category-grid.test.js +122 -2
- package/dist/components/wizard/category-grid.test.js.map +1 -1
- package/dist/components/wizard/checkbox-grid.js +3 -3
- package/dist/components/wizard/checkbox-grid.test.js +3 -3
- package/dist/components/wizard/domain-selection.js +9 -9
- package/dist/components/wizard/help-modal.js +2 -2
- package/dist/components/wizard/menu-item.js +1 -1
- package/dist/components/wizard/search-modal.js +2 -2
- package/dist/components/wizard/search-modal.test.js +2 -2
- package/dist/components/wizard/section-progress.js +2 -2
- package/dist/components/wizard/section-progress.test.js +2 -2
- package/dist/components/wizard/selection-card.js +2 -2
- package/dist/components/wizard/source-grid.js +3 -3
- package/dist/components/wizard/source-grid.test.js +3 -3
- package/dist/components/wizard/stack-selection.js +8 -8
- package/dist/components/wizard/step-agents.js +8 -8
- package/dist/components/wizard/step-agents.test.js +9 -9
- package/dist/components/wizard/step-build.js +8 -8
- package/dist/components/wizard/step-build.test.js +74 -46
- package/dist/components/wizard/step-build.test.js.map +1 -1
- package/dist/components/wizard/step-confirm.js +4 -4
- package/dist/components/wizard/step-confirm.test.js +8 -8
- package/dist/components/wizard/step-refine.js +2 -2
- package/dist/components/wizard/step-refine.test.js +2 -2
- package/dist/components/wizard/step-settings.js +5 -5
- package/dist/components/wizard/step-settings.test.js +8 -8
- package/dist/components/wizard/step-sources.js +10 -10
- package/dist/components/wizard/step-sources.test.js +11 -11
- package/dist/components/wizard/step-stack.js +12 -12
- package/dist/components/wizard/step-stack.test.js +13 -13
- package/dist/components/wizard/view-title.js +2 -2
- package/dist/components/wizard/wizard-layout.js +8 -8
- package/dist/components/wizard/wizard-tabs.js +2 -2
- package/dist/components/wizard/wizard-tabs.test.js +2 -2
- package/dist/components/wizard/wizard.js +25 -25
- package/dist/config/skill-categories.yaml +344 -0
- package/dist/config/skill-rules.yaml +740 -0
- package/dist/hooks/init.js +3 -3
- package/dist/{source-manager-6QZ2GDUA.js → source-manager-Y7R6WPOW.js} +4 -4
- package/dist/src/agents/meta/documentor/examples.md +35 -36
- package/dist/src/agents/meta/documentor/workflow.md +91 -105
- package/dist/stores/wizard-store.js +5 -5
- package/dist/stores/wizard-store.test.js +48 -6
- package/dist/stores/wizard-store.test.js.map +1 -1
- package/package.json +5 -1
- package/src/agents/meta/documentor/examples.md +35 -36
- package/src/agents/meta/documentor/workflow.md +91 -105
- package/src/schemas/agent.schema.json +3 -0
- package/src/schemas/metadata.schema.json +5 -5
- package/src/schemas/project-source-config.schema.json +4 -1
- package/config/skills-matrix.yaml +0 -918
- package/dist/chunk-5QRJUBK7.js.map +0 -1
- package/dist/chunk-74HSA7C4.js.map +0 -1
- package/dist/chunk-CD64ZNYI.js.map +0 -1
- package/dist/chunk-CDGHSTB6.js.map +0 -1
- package/dist/chunk-HM3DHMW7.js.map +0 -1
- package/dist/chunk-RT6IBH37.js.map +0 -1
- package/dist/chunk-RWR56UVK.js.map +0 -1
- package/dist/chunk-XE6RTHUD.js.map +0 -1
- package/dist/chunk-YT7UHV67.js.map +0 -1
- package/dist/config/skills-matrix.yaml +0 -918
- package/src/schemas/skills-matrix.schema.json +0 -179
- /package/dist/{chunk-LFZXMQOH.js.map → chunk-2BVZOYJP.js.map} +0 -0
- /package/dist/{chunk-4C7PDDLY.js.map → chunk-2DNDAXF6.js.map} +0 -0
- /package/dist/{chunk-C7BO2ASM.js.map → chunk-34BP5BC4.js.map} +0 -0
- /package/dist/{chunk-TOWP4T5L.js.map → chunk-37QYD33C.js.map} +0 -0
- /package/dist/{chunk-72GS6PIH.js.map → chunk-5O6GKXAN.js.map} +0 -0
- /package/dist/{chunk-KWQ2BQXF.js.map → chunk-7IAKVZL5.js.map} +0 -0
- /package/dist/{chunk-CTQHZELA.js.map → chunk-AMNCCZSG.js.map} +0 -0
- /package/dist/{chunk-PZLUO4OY.js.map → chunk-AXV7NFFJ.js.map} +0 -0
- /package/dist/{chunk-ODQ2BKWU.js.map → chunk-AXZNJ5PN.js.map} +0 -0
- /package/dist/{chunk-J64CA4V6.js.map → chunk-C7DLY64D.js.map} +0 -0
- /package/dist/{chunk-G2WNOT3R.js.map → chunk-DG2U2WY3.js.map} +0 -0
- /package/dist/{chunk-3WKFSTG6.js.map → chunk-F7KTUFGU.js.map} +0 -0
- /package/dist/{chunk-5M6JI76P.js.map → chunk-FHKNG3UA.js.map} +0 -0
- /package/dist/{chunk-I26YP2Q3.js.map → chunk-FPTUCWBY.js.map} +0 -0
- /package/dist/{chunk-VH3PI43B.js.map → chunk-G5OZQ376.js.map} +0 -0
- /package/dist/{chunk-YVMYQSED.js.map → chunk-I52THVF6.js.map} +0 -0
- /package/dist/{chunk-FKBCYT7B.js.map → chunk-IS7GP6XC.js.map} +0 -0
- /package/dist/{chunk-NMXNHRAK.js.map → chunk-NJVJ7VO5.js.map} +0 -0
- /package/dist/{chunk-GVLYNP2I.js.map → chunk-OHDEJEYB.js.map} +0 -0
- /package/dist/{chunk-FUEZQ2H6.js.map → chunk-PY2XZUBF.js.map} +0 -0
- /package/dist/{chunk-DO5OZHSS.js.map → chunk-U2AEK4ZL.js.map} +0 -0
- /package/dist/{chunk-7LDSHHKN.js.map → chunk-W62XVWXB.js.map} +0 -0
- /package/dist/{chunk-D7JTL3DJ.js.map → chunk-WSGKCBY5.js.map} +0 -0
- /package/dist/{chunk-QBUOZVNZ.js.map → chunk-YDASDMTH.js.map} +0 -0
- /package/dist/{chunk-SGXUMZWL.js.map → chunk-ZML3OCYA.js.map} +0 -0
- /package/dist/{source-manager-6QZ2GDUA.js.map → source-manager-Y7R6WPOW.js.map} +0 -0
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
import {
|
|
3
3
|
INFO_MESSAGES,
|
|
4
4
|
STATUS_MESSAGES
|
|
5
|
-
} from "../../chunk-
|
|
5
|
+
} from "../../chunk-DG2U2WY3.js";
|
|
6
6
|
import {
|
|
7
7
|
BaseCommand,
|
|
8
8
|
EXIT_CODES
|
|
9
|
-
} from "../../chunk-
|
|
9
|
+
} from "../../chunk-2BVZOYJP.js";
|
|
10
10
|
import {
|
|
11
11
|
IMPORT_DEFAULTS,
|
|
12
12
|
computeFileHash,
|
|
13
13
|
fetchFromSource,
|
|
14
14
|
getCurrentDate
|
|
15
|
-
} from "../../chunk-
|
|
15
|
+
} from "../../chunk-P2SFRDWI.js";
|
|
16
16
|
import "../../chunk-T4EXUIBY.js";
|
|
17
17
|
import {
|
|
18
18
|
copy,
|
|
@@ -24,14 +24,14 @@ import {
|
|
|
24
24
|
listDirectories,
|
|
25
25
|
readFile,
|
|
26
26
|
writeFile
|
|
27
|
-
} from "../../chunk-
|
|
27
|
+
} from "../../chunk-YMUWTPOM.js";
|
|
28
28
|
import {
|
|
29
29
|
DEFAULT_SKILLS_SUBDIR,
|
|
30
30
|
GITHUB_SOURCE,
|
|
31
31
|
LOCAL_SKILLS_PATH,
|
|
32
32
|
STANDARD_FILES,
|
|
33
33
|
YAML_FORMATTING
|
|
34
|
-
} from "../../chunk-
|
|
34
|
+
} from "../../chunk-LESHL6SM.js";
|
|
35
35
|
import {
|
|
36
36
|
init_esm_shims
|
|
37
37
|
} from "../../chunk-DHET7RCE.js";
|
|
@@ -309,7 +309,7 @@ Create one with:
|
|
|
309
309
|
this.warn(
|
|
310
310
|
`Malformed metadata.yaml at ${metadataYamlPath} \u2014 existing fields may be lost
|
|
311
311
|
Validation errors: ${parseResult.error.issues.map((i) => i.message).join(", ")}
|
|
312
|
-
Expected fields:
|
|
312
|
+
Expected fields: displayName (string), cliDescription (string), category (string)
|
|
313
313
|
Validate your YAML syntax at https://yamllint.com`
|
|
314
314
|
);
|
|
315
315
|
}
|
|
@@ -342,10 +342,9 @@ Create one with:
|
|
|
342
342
|
return;
|
|
343
343
|
}
|
|
344
344
|
const minimalMetadata = {
|
|
345
|
-
|
|
345
|
+
displayName: skillName.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" "),
|
|
346
346
|
cliDescription: "Imported from third-party repository",
|
|
347
347
|
category: IMPORT_DEFAULTS.CATEGORY,
|
|
348
|
-
categoryExclusive: false,
|
|
349
348
|
author: IMPORT_DEFAULTS.AUTHOR,
|
|
350
349
|
forkedFrom
|
|
351
350
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/import/skill.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { BaseCommand } from \"../../base-command.js\";\nimport { getErrorMessage } from \"../../utils/errors.js\";\nimport { EXIT_CODES } from \"../../lib/exit-codes.js\";\nimport { fetchFromSource } from \"../../lib/loading/index.js\";\nimport { importedSkillMetadataSchema } from \"../../lib/schemas.js\";\nimport { getCurrentDate, computeFileHash } from \"../../lib/versioning.js\";\nimport {\n copy,\n directoryExists,\n fileExists,\n listDirectories,\n readFile,\n writeFile,\n ensureDir,\n} from \"../../utils/fs.js\";\nimport {\n DEFAULT_SKILLS_SUBDIR,\n GITHUB_SOURCE,\n LOCAL_SKILLS_PATH,\n STANDARD_FILES,\n YAML_FORMATTING,\n} from \"../../consts.js\";\nimport { IMPORT_DEFAULTS } from \"../../lib/metadata-keys.js\";\nimport { STATUS_MESSAGES, INFO_MESSAGES } from \"../../utils/messages.js\";\n\n/**\n * Metadata for tracking third-party imports. Different from ForkedFromMetadata\n * in skill-metadata.ts which tracks internal fork lineage (uses skillId\n * instead of source/skillName).\n */\ntype ImportedForkedFromMetadata = {\n source: string;\n skillName: string;\n contentHash: string;\n date: string;\n};\n\ntype SkillMetadata = {\n forkedFrom?: ImportedForkedFromMetadata;\n [key: string]: unknown;\n};\n\nconst SKILL_MD_FILE = STANDARD_FILES.SKILL_MD;\nconst METADATA_YAML_FILE = STANDARD_FILES.METADATA_YAML;\nconst METADATA_JSON_FILE = STANDARD_FILES.METADATA_JSON;\n\nfunction parseGitHubSource(source: string): {\n gigetSource: string;\n displaySource: string;\n} {\n if (source.startsWith(GITHUB_SOURCE.HTTPS_PREFIX)) {\n const path = source.replace(GITHUB_SOURCE.HTTPS_PREFIX, \"\");\n return {\n gigetSource: `${GITHUB_SOURCE.GITHUB_PREFIX}${path}`,\n displaySource: source,\n };\n }\n\n if (\n source.startsWith(GITHUB_SOURCE.GITHUB_PREFIX) ||\n source.startsWith(GITHUB_SOURCE.GH_PREFIX)\n ) {\n const normalized = source.startsWith(GITHUB_SOURCE.GH_PREFIX)\n ? GITHUB_SOURCE.GITHUB_PREFIX + source.slice(GITHUB_SOURCE.GH_PREFIX.length)\n : source;\n return {\n gigetSource: normalized,\n displaySource: `${GITHUB_SOURCE.HTTPS_PREFIX}${normalized.replace(GITHUB_SOURCE.GITHUB_PREFIX, \"\")}`,\n };\n }\n\n if (source.includes(\"/\") && !source.includes(\":\")) {\n return {\n gigetSource: `${GITHUB_SOURCE.GITHUB_PREFIX}${source}`,\n displaySource: `${GITHUB_SOURCE.HTTPS_PREFIX}${source}`,\n };\n }\n\n return {\n gigetSource: source,\n displaySource: source,\n };\n}\n\nasync function discoverValidSkills(skillsDir: string, skillDirs: string[]): Promise<string[]> {\n const validSkills: string[] = [];\n\n for (const skillDir of skillDirs) {\n const skillMdPath = path.join(skillsDir, skillDir, SKILL_MD_FILE);\n if (await fileExists(skillMdPath)) {\n validSkills.push(skillDir);\n }\n }\n\n return validSkills.sort();\n}\n\nexport default class ImportSkill extends BaseCommand {\n static summary = \"Import a skill from a third-party GitHub repository\";\n static description =\n \"Download and import skills from external GitHub repositories into your local \" +\n \".claude/skills/ directory. Supports importing specific skills or listing available skills.\";\n\n static examples = [\n {\n description: \"List available skills from a repository\",\n command: \"<%= config.bin %> import skill github:vercel-labs/agent-skills --list\",\n },\n {\n description: \"Import a specific skill\",\n command:\n \"<%= config.bin %> import skill github:vercel-labs/agent-skills --skill react-best-practices\",\n },\n {\n description: \"Import all skills from a repository\",\n command: \"<%= config.bin %> import skill github:vercel-labs/agent-skills --all\",\n },\n {\n description: \"Import with custom skills directory\",\n command:\n \"<%= config.bin %> import skill github:owner/repo --skill my-skill --subdir custom-skills\",\n },\n ];\n\n static args = {\n source: Args.string({\n description:\n \"GitHub repository source (github:owner/repo, https://github.com/owner/repo, or owner/repo)\",\n required: true,\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n skill: Flags.string({\n char: \"n\",\n description: \"Name of the specific skill to import\",\n required: false,\n }),\n all: Flags.boolean({\n char: \"a\",\n description: \"Import all skills from the repository\",\n default: false,\n }),\n list: Flags.boolean({\n char: \"l\",\n description: \"List available skills without importing\",\n default: false,\n }),\n subdir: Flags.string({\n description: \"Subdirectory containing skills (default: skills)\",\n default: DEFAULT_SKILLS_SUBDIR,\n }),\n force: Flags.boolean({\n char: \"f\",\n description: \"Overwrite existing skills\",\n default: false,\n }),\n refresh: Flags.boolean({\n description: \"Force refresh from remote (ignore cache)\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(ImportSkill);\n const projectDir = process.cwd();\n\n this.log(\"\");\n this.log(\"Import Third-Party Skill\");\n this.log(\"\");\n\n if (!flags.list && !flags.skill && !flags.all) {\n this.error(\"Please specify --skill <name>, --all, or --list to list available skills\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (flags.skill && flags.all) {\n this.error(\"Cannot use --skill and --all together\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n const { gigetSource, displaySource } = parseGitHubSource(args.source);\n this.log(`Source: ${displaySource}`);\n\n this.log(STATUS_MESSAGES.FETCHING_REPOSITORY);\n\n let repoPath: string;\n try {\n const result = await fetchFromSource(gigetSource, {\n forceRefresh: flags.refresh,\n });\n repoPath = result.path;\n this.log(result.fromCache ? \"Using cached source\" : \"Downloaded fresh copy\");\n } catch (error) {\n this.error(error instanceof Error ? error.message : `Failed to fetch: ${args.source}`, {\n exit: EXIT_CODES.NETWORK_ERROR,\n });\n }\n\n // Validate --subdir to prevent path traversal outside repository boundary\n const subdir = flags.subdir;\n if (/\\0/.test(subdir)) {\n this.error(\"--subdir contains null bytes\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n if (path.isAbsolute(subdir)) {\n this.error(`--subdir must be a relative path, got: ${subdir}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n const skillsDir = path.resolve(path.join(repoPath, subdir));\n const resolvedRepoPath = path.resolve(repoPath);\n if (!skillsDir.startsWith(resolvedRepoPath + path.sep) && skillsDir !== resolvedRepoPath) {\n this.error(`--subdir path escapes repository boundary: ${subdir}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (!(await directoryExists(skillsDir))) {\n this.error(\n `Skills directory not found: ${flags.subdir}\\n` +\n `The repository doesn't have a '${flags.subdir}' directory.\\n` +\n `Use --subdir to specify a different location.`,\n { exit: EXIT_CODES.INVALID_ARGS },\n );\n }\n\n const skillDirs = await listDirectories(skillsDir);\n const availableSkills = await discoverValidSkills(skillsDir, skillDirs);\n\n if (availableSkills.length === 0) {\n this.error(`No valid skills found in ${flags.subdir}/\\nSkills must have a SKILL.md file.`, {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n if (flags.list) {\n this.log(\"\");\n this.log(`Available skills (${availableSkills.length}):`);\n this.log(\"\");\n for (const skill of availableSkills) {\n this.log(` - ${skill}`);\n }\n this.log(\"\");\n this.log(\"Use --skill <name> to import a specific skill, or --all to import all.\");\n return;\n }\n\n let skillsToImport: string[] = [];\n\n if (flags.all) {\n skillsToImport = availableSkills;\n } else if (flags.skill) {\n if (!availableSkills.includes(flags.skill)) {\n this.error(\n `Skill '${flags.skill}' not found in repository.\\n` +\n `Available skills: ${availableSkills.join(\", \")}\\n` +\n `Use --list to see all available skills.`,\n { exit: EXIT_CODES.INVALID_ARGS },\n );\n }\n skillsToImport = [flags.skill];\n }\n\n const destDir = path.join(projectDir, LOCAL_SKILLS_PATH);\n\n if (flags[\"dry-run\"]) {\n this.log(\"\");\n this.log(\"[DRY RUN] Would import the following skills:\");\n for (const skill of skillsToImport) {\n const destPath = path.join(destDir, skill);\n const exists = await directoryExists(destPath);\n this.log(` - ${skill} -> ${destPath}${exists ? \" (exists)\" : \"\"}`);\n }\n return;\n }\n\n this.log(\"\");\n this.log(`Importing ${skillsToImport.length} skill(s)...`);\n\n let imported = 0;\n let skipped = 0;\n\n for (const skillName of skillsToImport) {\n const sourcePath = path.join(skillsDir, skillName);\n const destPath = path.join(destDir, skillName);\n\n if (await directoryExists(destPath)) {\n if (!flags.force) {\n this.warn(`Skipping '${skillName}': already exists. Use --force to overwrite.`);\n skipped++;\n continue;\n }\n }\n\n try {\n await this.importSkill(sourcePath, destPath, skillName, displaySource);\n this.logSuccess(`Imported: ${skillName}`);\n imported++;\n } catch (error) {\n this.warn(`Failed to import '${skillName}': ${getErrorMessage(error)}`);\n skipped++;\n }\n }\n\n this.log(\"\");\n this.logSuccess(`Import complete: ${imported} imported, ${skipped} skipped`);\n this.log(`Skills location: ${destDir}`);\n this.log(\"\");\n this.log(INFO_MESSAGES.RUN_COMPILE);\n this.log(\"\");\n }\n\n private async importSkill(\n sourcePath: string,\n destPath: string,\n skillName: string,\n source: string,\n ): Promise<void> {\n const skillMdPath = path.join(sourcePath, SKILL_MD_FILE);\n if (!(await fileExists(skillMdPath))) {\n throw new Error(\n `Missing required SKILL.md file at ${skillMdPath}\\n` +\n `Every skill must have a SKILL.md file containing the skill's prompt content.\\n` +\n `Create one with:\\n` +\n ` echo \"# ${skillName}\" > ${path.join(sourcePath, SKILL_MD_FILE)}`,\n );\n }\n\n const contentHash = await computeFileHash(skillMdPath);\n\n await ensureDir(path.dirname(destPath));\n await copy(sourcePath, destPath);\n\n await this.injectForkedFromMetadata(destPath, skillName, source, contentHash);\n }\n\n private async injectForkedFromMetadata(\n destPath: string,\n skillName: string,\n source: string,\n contentHash: string,\n ): Promise<void> {\n const metadataYamlPath = path.join(destPath, METADATA_YAML_FILE);\n const metadataJsonPath = path.join(destPath, METADATA_JSON_FILE);\n\n const forkedFrom: ImportedForkedFromMetadata = {\n source,\n skillName: skillName,\n contentHash: contentHash,\n date: getCurrentDate(),\n };\n\n if (await fileExists(metadataYamlPath)) {\n const rawContent = await readFile(metadataYamlPath);\n const lines = rawContent.split(\"\\n\");\n let yamlContent = rawContent;\n let schemaComment = \"\";\n\n if (lines[0]?.startsWith(\"# yaml-language-server:\")) {\n schemaComment = `${lines[0]}\\n`;\n yamlContent = lines.slice(1).join(\"\\n\");\n }\n\n const raw = parseYaml(yamlContent);\n const parseResult = importedSkillMetadataSchema.safeParse(raw);\n if (!parseResult.success) {\n this.warn(\n `Malformed metadata.yaml at ${metadataYamlPath} — existing fields may be lost\\n` +\n ` Validation errors: ${parseResult.error.issues.map((i) => i.message).join(\", \")}\\n` +\n ` Expected fields: cliName (string), cliDescription (string), category (string)\\n` +\n ` Validate your YAML syntax at https://yamllint.com`,\n );\n }\n const metadata = parseResult.success\n ? (parseResult.data as SkillMetadata)\n : { forkedFrom: undefined };\n metadata.forkedFrom = forkedFrom;\n\n const newYamlContent = stringifyYaml(metadata, {\n lineWidth: YAML_FORMATTING.LINE_WIDTH_NONE,\n });\n await writeFile(metadataYamlPath, schemaComment + newYamlContent);\n return;\n }\n\n if (await fileExists(metadataJsonPath)) {\n const rawContent = await readFile(metadataJsonPath);\n let jsonParsed: unknown;\n try {\n jsonParsed = JSON.parse(rawContent);\n } catch {\n this.warn(\n `Malformed JSON in ${metadataJsonPath} — skipping metadata injection\\n` +\n ` Common issues: trailing commas, unquoted keys, single quotes instead of double quotes\\n` +\n ` Validate your JSON at https://jsonlint.com`,\n );\n return;\n }\n const jsonResult = importedSkillMetadataSchema.safeParse(jsonParsed);\n const metadata = jsonResult.success\n ? (jsonResult.data as SkillMetadata)\n : { forkedFrom: undefined };\n metadata.forkedFrom = forkedFrom;\n\n const yamlContent = stringifyYaml(metadata, { lineWidth: YAML_FORMATTING.LINE_WIDTH_NONE });\n await writeFile(metadataYamlPath, yamlContent);\n return;\n }\n\n const minimalMetadata: SkillMetadata = {\n cliName: skillName\n .split(\"-\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \"),\n cliDescription: \"Imported from third-party repository\",\n category: IMPORT_DEFAULTS.CATEGORY,\n categoryExclusive: false,\n author: IMPORT_DEFAULTS.AUTHOR,\n forkedFrom: forkedFrom,\n };\n\n const yamlContent = stringifyYaml(minimalMetadata, {\n lineWidth: YAML_FORMATTING.LINE_WIDTH_NONE,\n });\n await writeFile(metadataYamlPath, yamlContent);\n }\n}\n"],"mappings":"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","names":["path","yamlContent"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/import/skill.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { BaseCommand } from \"../../base-command.js\";\nimport { getErrorMessage } from \"../../utils/errors.js\";\nimport { EXIT_CODES } from \"../../lib/exit-codes.js\";\nimport { fetchFromSource } from \"../../lib/loading/index.js\";\nimport { importedSkillMetadataSchema } from \"../../lib/schemas.js\";\nimport { getCurrentDate, computeFileHash } from \"../../lib/versioning.js\";\nimport {\n copy,\n directoryExists,\n fileExists,\n listDirectories,\n readFile,\n writeFile,\n ensureDir,\n} from \"../../utils/fs.js\";\nimport {\n DEFAULT_SKILLS_SUBDIR,\n GITHUB_SOURCE,\n LOCAL_SKILLS_PATH,\n STANDARD_FILES,\n YAML_FORMATTING,\n} from \"../../consts.js\";\nimport { IMPORT_DEFAULTS } from \"../../lib/metadata-keys.js\";\nimport { STATUS_MESSAGES, INFO_MESSAGES } from \"../../utils/messages.js\";\n\n/**\n * Metadata for tracking third-party imports. Different from ForkedFromMetadata\n * in skill-metadata.ts which tracks internal fork lineage (uses skillId\n * instead of source/skillName).\n */\ntype ImportedForkedFromMetadata = {\n source: string;\n skillName: string;\n contentHash: string;\n date: string;\n};\n\ntype SkillMetadata = {\n forkedFrom?: ImportedForkedFromMetadata;\n [key: string]: unknown;\n};\n\nconst SKILL_MD_FILE = STANDARD_FILES.SKILL_MD;\nconst METADATA_YAML_FILE = STANDARD_FILES.METADATA_YAML;\nconst METADATA_JSON_FILE = STANDARD_FILES.METADATA_JSON;\n\nfunction parseGitHubSource(source: string): {\n gigetSource: string;\n displaySource: string;\n} {\n if (source.startsWith(GITHUB_SOURCE.HTTPS_PREFIX)) {\n const path = source.replace(GITHUB_SOURCE.HTTPS_PREFIX, \"\");\n return {\n gigetSource: `${GITHUB_SOURCE.GITHUB_PREFIX}${path}`,\n displaySource: source,\n };\n }\n\n if (\n source.startsWith(GITHUB_SOURCE.GITHUB_PREFIX) ||\n source.startsWith(GITHUB_SOURCE.GH_PREFIX)\n ) {\n const normalized = source.startsWith(GITHUB_SOURCE.GH_PREFIX)\n ? GITHUB_SOURCE.GITHUB_PREFIX + source.slice(GITHUB_SOURCE.GH_PREFIX.length)\n : source;\n return {\n gigetSource: normalized,\n displaySource: `${GITHUB_SOURCE.HTTPS_PREFIX}${normalized.replace(GITHUB_SOURCE.GITHUB_PREFIX, \"\")}`,\n };\n }\n\n if (source.includes(\"/\") && !source.includes(\":\")) {\n return {\n gigetSource: `${GITHUB_SOURCE.GITHUB_PREFIX}${source}`,\n displaySource: `${GITHUB_SOURCE.HTTPS_PREFIX}${source}`,\n };\n }\n\n return {\n gigetSource: source,\n displaySource: source,\n };\n}\n\nasync function discoverValidSkills(skillsDir: string, skillDirs: string[]): Promise<string[]> {\n const validSkills: string[] = [];\n\n for (const skillDir of skillDirs) {\n const skillMdPath = path.join(skillsDir, skillDir, SKILL_MD_FILE);\n if (await fileExists(skillMdPath)) {\n validSkills.push(skillDir);\n }\n }\n\n return validSkills.sort();\n}\n\nexport default class ImportSkill extends BaseCommand {\n static summary = \"Import a skill from a third-party GitHub repository\";\n static description =\n \"Download and import skills from external GitHub repositories into your local \" +\n \".claude/skills/ directory. Supports importing specific skills or listing available skills.\";\n\n static examples = [\n {\n description: \"List available skills from a repository\",\n command: \"<%= config.bin %> import skill github:vercel-labs/agent-skills --list\",\n },\n {\n description: \"Import a specific skill\",\n command:\n \"<%= config.bin %> import skill github:vercel-labs/agent-skills --skill react-best-practices\",\n },\n {\n description: \"Import all skills from a repository\",\n command: \"<%= config.bin %> import skill github:vercel-labs/agent-skills --all\",\n },\n {\n description: \"Import with custom skills directory\",\n command:\n \"<%= config.bin %> import skill github:owner/repo --skill my-skill --subdir custom-skills\",\n },\n ];\n\n static args = {\n source: Args.string({\n description:\n \"GitHub repository source (github:owner/repo, https://github.com/owner/repo, or owner/repo)\",\n required: true,\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n skill: Flags.string({\n char: \"n\",\n description: \"Name of the specific skill to import\",\n required: false,\n }),\n all: Flags.boolean({\n char: \"a\",\n description: \"Import all skills from the repository\",\n default: false,\n }),\n list: Flags.boolean({\n char: \"l\",\n description: \"List available skills without importing\",\n default: false,\n }),\n subdir: Flags.string({\n description: \"Subdirectory containing skills (default: skills)\",\n default: DEFAULT_SKILLS_SUBDIR,\n }),\n force: Flags.boolean({\n char: \"f\",\n description: \"Overwrite existing skills\",\n default: false,\n }),\n refresh: Flags.boolean({\n description: \"Force refresh from remote (ignore cache)\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(ImportSkill);\n const projectDir = process.cwd();\n\n this.log(\"\");\n this.log(\"Import Third-Party Skill\");\n this.log(\"\");\n\n if (!flags.list && !flags.skill && !flags.all) {\n this.error(\"Please specify --skill <name>, --all, or --list to list available skills\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (flags.skill && flags.all) {\n this.error(\"Cannot use --skill and --all together\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n const { gigetSource, displaySource } = parseGitHubSource(args.source);\n this.log(`Source: ${displaySource}`);\n\n this.log(STATUS_MESSAGES.FETCHING_REPOSITORY);\n\n let repoPath: string;\n try {\n const result = await fetchFromSource(gigetSource, {\n forceRefresh: flags.refresh,\n });\n repoPath = result.path;\n this.log(result.fromCache ? \"Using cached source\" : \"Downloaded fresh copy\");\n } catch (error) {\n this.error(error instanceof Error ? error.message : `Failed to fetch: ${args.source}`, {\n exit: EXIT_CODES.NETWORK_ERROR,\n });\n }\n\n // Validate --subdir to prevent path traversal outside repository boundary\n const subdir = flags.subdir;\n if (/\\0/.test(subdir)) {\n this.error(\"--subdir contains null bytes\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n if (path.isAbsolute(subdir)) {\n this.error(`--subdir must be a relative path, got: ${subdir}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n const skillsDir = path.resolve(path.join(repoPath, subdir));\n const resolvedRepoPath = path.resolve(repoPath);\n if (!skillsDir.startsWith(resolvedRepoPath + path.sep) && skillsDir !== resolvedRepoPath) {\n this.error(`--subdir path escapes repository boundary: ${subdir}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (!(await directoryExists(skillsDir))) {\n this.error(\n `Skills directory not found: ${flags.subdir}\\n` +\n `The repository doesn't have a '${flags.subdir}' directory.\\n` +\n `Use --subdir to specify a different location.`,\n { exit: EXIT_CODES.INVALID_ARGS },\n );\n }\n\n const skillDirs = await listDirectories(skillsDir);\n const availableSkills = await discoverValidSkills(skillsDir, skillDirs);\n\n if (availableSkills.length === 0) {\n this.error(`No valid skills found in ${flags.subdir}/\\nSkills must have a SKILL.md file.`, {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n if (flags.list) {\n this.log(\"\");\n this.log(`Available skills (${availableSkills.length}):`);\n this.log(\"\");\n for (const skill of availableSkills) {\n this.log(` - ${skill}`);\n }\n this.log(\"\");\n this.log(\"Use --skill <name> to import a specific skill, or --all to import all.\");\n return;\n }\n\n let skillsToImport: string[] = [];\n\n if (flags.all) {\n skillsToImport = availableSkills;\n } else if (flags.skill) {\n if (!availableSkills.includes(flags.skill)) {\n this.error(\n `Skill '${flags.skill}' not found in repository.\\n` +\n `Available skills: ${availableSkills.join(\", \")}\\n` +\n `Use --list to see all available skills.`,\n { exit: EXIT_CODES.INVALID_ARGS },\n );\n }\n skillsToImport = [flags.skill];\n }\n\n const destDir = path.join(projectDir, LOCAL_SKILLS_PATH);\n\n if (flags[\"dry-run\"]) {\n this.log(\"\");\n this.log(\"[DRY RUN] Would import the following skills:\");\n for (const skill of skillsToImport) {\n const destPath = path.join(destDir, skill);\n const exists = await directoryExists(destPath);\n this.log(` - ${skill} -> ${destPath}${exists ? \" (exists)\" : \"\"}`);\n }\n return;\n }\n\n this.log(\"\");\n this.log(`Importing ${skillsToImport.length} skill(s)...`);\n\n let imported = 0;\n let skipped = 0;\n\n for (const skillName of skillsToImport) {\n const sourcePath = path.join(skillsDir, skillName);\n const destPath = path.join(destDir, skillName);\n\n if (await directoryExists(destPath)) {\n if (!flags.force) {\n this.warn(`Skipping '${skillName}': already exists. Use --force to overwrite.`);\n skipped++;\n continue;\n }\n }\n\n try {\n await this.importSkill(sourcePath, destPath, skillName, displaySource);\n this.logSuccess(`Imported: ${skillName}`);\n imported++;\n } catch (error) {\n this.warn(`Failed to import '${skillName}': ${getErrorMessage(error)}`);\n skipped++;\n }\n }\n\n this.log(\"\");\n this.logSuccess(`Import complete: ${imported} imported, ${skipped} skipped`);\n this.log(`Skills location: ${destDir}`);\n this.log(\"\");\n this.log(INFO_MESSAGES.RUN_COMPILE);\n this.log(\"\");\n }\n\n private async importSkill(\n sourcePath: string,\n destPath: string,\n skillName: string,\n source: string,\n ): Promise<void> {\n const skillMdPath = path.join(sourcePath, SKILL_MD_FILE);\n if (!(await fileExists(skillMdPath))) {\n throw new Error(\n `Missing required SKILL.md file at ${skillMdPath}\\n` +\n `Every skill must have a SKILL.md file containing the skill's prompt content.\\n` +\n `Create one with:\\n` +\n ` echo \"# ${skillName}\" > ${path.join(sourcePath, SKILL_MD_FILE)}`,\n );\n }\n\n const contentHash = await computeFileHash(skillMdPath);\n\n await ensureDir(path.dirname(destPath));\n await copy(sourcePath, destPath);\n\n await this.injectForkedFromMetadata(destPath, skillName, source, contentHash);\n }\n\n private async injectForkedFromMetadata(\n destPath: string,\n skillName: string,\n source: string,\n contentHash: string,\n ): Promise<void> {\n const metadataYamlPath = path.join(destPath, METADATA_YAML_FILE);\n const metadataJsonPath = path.join(destPath, METADATA_JSON_FILE);\n\n const forkedFrom: ImportedForkedFromMetadata = {\n source,\n skillName: skillName,\n contentHash: contentHash,\n date: getCurrentDate(),\n };\n\n if (await fileExists(metadataYamlPath)) {\n const rawContent = await readFile(metadataYamlPath);\n const lines = rawContent.split(\"\\n\");\n let yamlContent = rawContent;\n let schemaComment = \"\";\n\n if (lines[0]?.startsWith(\"# yaml-language-server:\")) {\n schemaComment = `${lines[0]}\\n`;\n yamlContent = lines.slice(1).join(\"\\n\");\n }\n\n const raw = parseYaml(yamlContent);\n const parseResult = importedSkillMetadataSchema.safeParse(raw);\n if (!parseResult.success) {\n this.warn(\n `Malformed metadata.yaml at ${metadataYamlPath} — existing fields may be lost\\n` +\n ` Validation errors: ${parseResult.error.issues.map((i) => i.message).join(\", \")}\\n` +\n ` Expected fields: displayName (string), cliDescription (string), category (string)\\n` +\n ` Validate your YAML syntax at https://yamllint.com`,\n );\n }\n const metadata = parseResult.success\n ? (parseResult.data as SkillMetadata)\n : { forkedFrom: undefined };\n metadata.forkedFrom = forkedFrom;\n\n const newYamlContent = stringifyYaml(metadata, {\n lineWidth: YAML_FORMATTING.LINE_WIDTH_NONE,\n });\n await writeFile(metadataYamlPath, schemaComment + newYamlContent);\n return;\n }\n\n if (await fileExists(metadataJsonPath)) {\n const rawContent = await readFile(metadataJsonPath);\n let jsonParsed: unknown;\n try {\n jsonParsed = JSON.parse(rawContent);\n } catch {\n this.warn(\n `Malformed JSON in ${metadataJsonPath} — skipping metadata injection\\n` +\n ` Common issues: trailing commas, unquoted keys, single quotes instead of double quotes\\n` +\n ` Validate your JSON at https://jsonlint.com`,\n );\n return;\n }\n const jsonResult = importedSkillMetadataSchema.safeParse(jsonParsed);\n const metadata = jsonResult.success\n ? (jsonResult.data as SkillMetadata)\n : { forkedFrom: undefined };\n metadata.forkedFrom = forkedFrom;\n\n const yamlContent = stringifyYaml(metadata, { lineWidth: YAML_FORMATTING.LINE_WIDTH_NONE });\n await writeFile(metadataYamlPath, yamlContent);\n return;\n }\n\n const minimalMetadata: SkillMetadata = {\n displayName: skillName\n .split(\"-\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \"),\n cliDescription: \"Imported from third-party repository\",\n category: IMPORT_DEFAULTS.CATEGORY,\n author: IMPORT_DEFAULTS.AUTHOR,\n forkedFrom: forkedFrom,\n };\n\n const yamlContent = stringifyYaml(minimalMetadata, {\n lineWidth: YAML_FORMATTING.LINE_WIDTH_NONE,\n });\n await writeFile(metadataYamlPath, yamlContent);\n }\n}\n"],"mappings":"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","names":["path","yamlContent"]}
|
package/dist/commands/info.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
STATUS_MESSAGES
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-DG2U2WY3.js";
|
|
5
5
|
import {
|
|
6
6
|
BaseCommand,
|
|
7
7
|
EXIT_CODES
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-2BVZOYJP.js";
|
|
9
9
|
import {
|
|
10
10
|
discoverLocalSkills,
|
|
11
11
|
loadSkillsMatrixFromSource
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-P2SFRDWI.js";
|
|
13
13
|
import "../chunk-T4EXUIBY.js";
|
|
14
14
|
import {
|
|
15
15
|
fileExists,
|
|
16
16
|
readFile
|
|
17
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-YMUWTPOM.js";
|
|
18
18
|
import {
|
|
19
19
|
CLI_BIN_NAME,
|
|
20
20
|
STANDARD_FILES
|
|
21
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-LESHL6SM.js";
|
|
22
22
|
import {
|
|
23
23
|
init_esm_shims
|
|
24
24
|
} from "../chunk-DHET7RCE.js";
|
package/dist/commands/init.js
CHANGED
|
@@ -1,48 +1,48 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
Wizard
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
10
|
-
import "../chunk-
|
|
11
|
-
import "../chunk-
|
|
12
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-AMNCCZSG.js";
|
|
5
|
+
import "../chunk-IS7GP6XC.js";
|
|
6
|
+
import "../chunk-37QYD33C.js";
|
|
7
|
+
import "../chunk-2DNDAXF6.js";
|
|
8
|
+
import "../chunk-5O6GKXAN.js";
|
|
9
|
+
import "../chunk-PY2XZUBF.js";
|
|
10
|
+
import "../chunk-FPTUCWBY.js";
|
|
11
|
+
import "../chunk-VBAAATPU.js";
|
|
12
|
+
import "../chunk-5MN5S3DV.js";
|
|
13
13
|
import "../chunk-K77I4XGL.js";
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-
|
|
17
|
-
import "../chunk-
|
|
14
|
+
import "../chunk-OHDEJEYB.js";
|
|
15
|
+
import "../chunk-WSGKCBY5.js";
|
|
16
|
+
import "../chunk-F7KTUFGU.js";
|
|
17
|
+
import "../chunk-7IAKVZL5.js";
|
|
18
18
|
import "../chunk-7SOPVGDV.js";
|
|
19
|
-
import "../chunk-
|
|
19
|
+
import "../chunk-34BP5BC4.js";
|
|
20
20
|
import "../chunk-KUV24B5M.js";
|
|
21
|
-
import "../chunk-
|
|
21
|
+
import "../chunk-OTTITQ7C.js";
|
|
22
22
|
import "../chunk-GG4BSB6S.js";
|
|
23
|
-
import "../chunk-
|
|
24
|
-
import "../chunk-
|
|
25
|
-
import "../chunk-
|
|
26
|
-
import "../chunk-
|
|
27
|
-
import "../chunk-
|
|
23
|
+
import "../chunk-SPVSWDFM.js";
|
|
24
|
+
import "../chunk-GSPPOXMG.js";
|
|
25
|
+
import "../chunk-AXZNJ5PN.js";
|
|
26
|
+
import "../chunk-U2AEK4ZL.js";
|
|
27
|
+
import "../chunk-FHKNG3UA.js";
|
|
28
28
|
import "../chunk-U3IGFMCY.js";
|
|
29
29
|
import {
|
|
30
30
|
claudePluginInstall,
|
|
31
31
|
claudePluginMarketplaceAdd,
|
|
32
32
|
claudePluginMarketplaceExists
|
|
33
|
-
} from "../chunk-
|
|
34
|
-
import "../chunk-
|
|
35
|
-
import "../chunk-
|
|
33
|
+
} from "../chunk-YDASDMTH.js";
|
|
34
|
+
import "../chunk-KPJJOLAQ.js";
|
|
35
|
+
import "../chunk-C7DLY64D.js";
|
|
36
36
|
import {
|
|
37
37
|
DRY_RUN_MESSAGES,
|
|
38
38
|
INFO_MESSAGES,
|
|
39
39
|
STATUS_MESSAGES,
|
|
40
40
|
SUCCESS_MESSAGES
|
|
41
|
-
} from "../chunk-
|
|
41
|
+
} from "../chunk-DG2U2WY3.js";
|
|
42
42
|
import {
|
|
43
43
|
BaseCommand,
|
|
44
44
|
EXIT_CODES
|
|
45
|
-
} from "../chunk-
|
|
45
|
+
} from "../chunk-2BVZOYJP.js";
|
|
46
46
|
import {
|
|
47
47
|
detectInstallation,
|
|
48
48
|
getMarketplaceLabel,
|
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
installLocal,
|
|
51
51
|
installPluginConfig,
|
|
52
52
|
loadSkillsMatrixFromSource
|
|
53
|
-
} from "../chunk-
|
|
53
|
+
} from "../chunk-P2SFRDWI.js";
|
|
54
54
|
import "../chunk-T4EXUIBY.js";
|
|
55
55
|
import {
|
|
56
56
|
fileExists,
|
|
@@ -59,7 +59,7 @@ import {
|
|
|
59
59
|
settingsFileSchema,
|
|
60
60
|
warn,
|
|
61
61
|
warnUnknownFields
|
|
62
|
-
} from "../chunk-
|
|
62
|
+
} from "../chunk-YMUWTPOM.js";
|
|
63
63
|
import {
|
|
64
64
|
ASCII_LOGO,
|
|
65
65
|
CLAUDE_DIR,
|
|
@@ -68,7 +68,7 @@ import {
|
|
|
68
68
|
DEFAULT_BRANDING,
|
|
69
69
|
LOCAL_SKILLS_PATH,
|
|
70
70
|
MAX_CONFIG_FILE_SIZE
|
|
71
|
-
} from "../chunk-
|
|
71
|
+
} from "../chunk-LESHL6SM.js";
|
|
72
72
|
import {
|
|
73
73
|
init_esm_shims
|
|
74
74
|
} from "../chunk-DHET7RCE.js";
|
package/dist/commands/list.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
BaseCommand
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-2BVZOYJP.js";
|
|
5
5
|
import {
|
|
6
6
|
formatInstallationDisplay,
|
|
7
7
|
getInstallationInfo
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-P2SFRDWI.js";
|
|
9
9
|
import "../chunk-T4EXUIBY.js";
|
|
10
|
-
import "../chunk-
|
|
10
|
+
import "../chunk-YMUWTPOM.js";
|
|
11
11
|
import {
|
|
12
12
|
CLI_BIN_NAME,
|
|
13
13
|
DEFAULT_BRANDING
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-LESHL6SM.js";
|
|
15
15
|
import {
|
|
16
16
|
init_esm_shims
|
|
17
17
|
} from "../chunk-DHET7RCE.js";
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
getAgentDefinitions
|
|
4
|
-
} from "../../chunk-
|
|
4
|
+
} from "../../chunk-AXV7NFFJ.js";
|
|
5
5
|
import {
|
|
6
6
|
isClaudeCLIAvailable
|
|
7
|
-
} from "../../chunk-
|
|
7
|
+
} from "../../chunk-YDASDMTH.js";
|
|
8
8
|
import {
|
|
9
9
|
BaseCommand,
|
|
10
10
|
EXIT_CODES
|
|
11
|
-
} from "../../chunk-
|
|
11
|
+
} from "../../chunk-2BVZOYJP.js";
|
|
12
12
|
import {
|
|
13
13
|
resolveSource
|
|
14
|
-
} from "../../chunk-
|
|
14
|
+
} from "../../chunk-P2SFRDWI.js";
|
|
15
15
|
import "../../chunk-T4EXUIBY.js";
|
|
16
16
|
import {
|
|
17
17
|
fileExists,
|
|
18
18
|
readFile
|
|
19
|
-
} from "../../chunk-
|
|
19
|
+
} from "../../chunk-YMUWTPOM.js";
|
|
20
20
|
import {
|
|
21
21
|
CLAUDE_DIR,
|
|
22
22
|
CLI_COLORS
|
|
23
|
-
} from "../../chunk-
|
|
23
|
+
} from "../../chunk-LESHL6SM.js";
|
|
24
24
|
import {
|
|
25
25
|
init_esm_shims
|
|
26
26
|
} from "../../chunk-DHET7RCE.js";
|
|
@@ -2,21 +2,21 @@
|
|
|
2
2
|
import {
|
|
3
3
|
generateMarketplace,
|
|
4
4
|
writeMarketplace
|
|
5
|
-
} from "../../chunk-
|
|
5
|
+
} from "../../chunk-W62XVWXB.js";
|
|
6
6
|
import {
|
|
7
7
|
BaseCommand,
|
|
8
8
|
EXIT_CODES
|
|
9
|
-
} from "../../chunk-
|
|
9
|
+
} from "../../chunk-2BVZOYJP.js";
|
|
10
10
|
import {
|
|
11
11
|
compileAllSkillPlugins
|
|
12
|
-
} from "../../chunk-
|
|
12
|
+
} from "../../chunk-P2SFRDWI.js";
|
|
13
13
|
import "../../chunk-T4EXUIBY.js";
|
|
14
14
|
import {
|
|
15
15
|
directoryExists,
|
|
16
16
|
ensureDir,
|
|
17
17
|
getErrorMessage,
|
|
18
18
|
writeFile
|
|
19
|
-
} from "../../chunk-
|
|
19
|
+
} from "../../chunk-YMUWTPOM.js";
|
|
20
20
|
import {
|
|
21
21
|
CLI_BIN_NAME,
|
|
22
22
|
KEBAB_CASE_PATTERN,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
SKILLS_DIR_PATH,
|
|
25
25
|
STACKS_FILE_PATH,
|
|
26
26
|
STANDARD_FILES
|
|
27
|
-
} from "../../chunk-
|
|
27
|
+
} from "../../chunk-LESHL6SM.js";
|
|
28
28
|
import {
|
|
29
29
|
init_esm_shims
|
|
30
30
|
} from "../../chunk-DHET7RCE.js";
|
|
@@ -2,17 +2,18 @@
|
|
|
2
2
|
import {
|
|
3
3
|
BaseCommand,
|
|
4
4
|
EXIT_CODES
|
|
5
|
-
} from "../../chunk-
|
|
5
|
+
} from "../../chunk-2BVZOYJP.js";
|
|
6
6
|
import {
|
|
7
7
|
LOCAL_DEFAULTS,
|
|
8
|
+
computeSkillFolderHash,
|
|
8
9
|
resolveAuthor
|
|
9
|
-
} from "../../chunk-
|
|
10
|
+
} from "../../chunk-P2SFRDWI.js";
|
|
10
11
|
import "../../chunk-T4EXUIBY.js";
|
|
11
12
|
import {
|
|
12
13
|
directoryExists,
|
|
13
14
|
fileExists,
|
|
14
15
|
writeFile
|
|
15
|
-
} from "../../chunk-
|
|
16
|
+
} from "../../chunk-YMUWTPOM.js";
|
|
16
17
|
import {
|
|
17
18
|
CLI_BIN_NAME,
|
|
18
19
|
KEBAB_CASE_PATTERN,
|
|
@@ -20,7 +21,7 @@ import {
|
|
|
20
21
|
PLUGIN_MANIFEST_DIR,
|
|
21
22
|
SKILLS_DIR_PATH,
|
|
22
23
|
STANDARD_FILES
|
|
23
|
-
} from "../../chunk-
|
|
24
|
+
} from "../../chunk-LESHL6SM.js";
|
|
24
25
|
import {
|
|
25
26
|
init_esm_shims
|
|
26
27
|
} from "../../chunk-DHET7RCE.js";
|
|
@@ -95,15 +96,15 @@ Add your patterns here.
|
|
|
95
96
|
</critical_reminders>
|
|
96
97
|
`;
|
|
97
98
|
}
|
|
98
|
-
function generateMetadataYaml(name, author, category) {
|
|
99
|
+
function generateMetadataYaml(name, author, category, contentHash) {
|
|
99
100
|
const titleName = toTitleCase(name);
|
|
100
101
|
return `custom: true
|
|
101
102
|
category: ${category}
|
|
102
|
-
categoryExclusive: false
|
|
103
103
|
author: "${author}"
|
|
104
|
-
|
|
104
|
+
displayName: ${titleName}
|
|
105
105
|
cliDescription: Brief description
|
|
106
106
|
usageGuidance: Use when <guidance>.
|
|
107
|
+
contentHash: ${contentHash}
|
|
107
108
|
tags:
|
|
108
109
|
- local
|
|
109
110
|
- custom
|
|
@@ -189,10 +190,11 @@ Use --force to overwrite.`, {
|
|
|
189
190
|
this.log("Creating skill files...");
|
|
190
191
|
try {
|
|
191
192
|
const skillMdContent = generateSkillMd(args.name);
|
|
192
|
-
const metadataContent = generateMetadataYaml(args.name, author, category);
|
|
193
193
|
const skillMdPath = path.join(skillDir, STANDARD_FILES.SKILL_MD);
|
|
194
194
|
const metadataPath = path.join(skillDir, STANDARD_FILES.METADATA_YAML);
|
|
195
195
|
await writeFile(skillMdPath, skillMdContent);
|
|
196
|
+
const contentHash = await computeSkillFolderHash(skillDir);
|
|
197
|
+
const metadataContent = generateMetadataYaml(args.name, author, category, contentHash);
|
|
196
198
|
await writeFile(metadataPath, metadataContent);
|
|
197
199
|
this.log("");
|
|
198
200
|
this.logSuccess(`Created ${STANDARD_FILES.SKILL_MD} at ${skillMdPath}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/commands/new/skill.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport { BaseCommand } from \"../../base-command.js\";\nimport { resolveAuthor } from \"../../lib/configuration/index.js\";\nimport { writeFile, directoryExists, fileExists } from \"../../utils/fs.js\";\nimport {\n CLI_BIN_NAME,\n KEBAB_CASE_PATTERN,\n LOCAL_SKILLS_PATH,\n PLUGIN_MANIFEST_DIR,\n SKILLS_DIR_PATH,\n STANDARD_FILES,\n} from \"../../consts.js\";\nimport { EXIT_CODES } from \"../../lib/exit-codes.js\";\nimport { LOCAL_DEFAULTS } from \"../../lib/metadata-keys.js\";\nimport type { CategoryPath } from \"../../types/index.js\";\n\nexport function validateSkillName(name: string): string | null {\n if (!name || name.trim() === \"\") {\n return \"Skill name is required\";\n }\n\n if (!KEBAB_CASE_PATTERN.test(name)) {\n return \"Skill name must be kebab-case (lowercase letters, numbers, and hyphens, starting with a letter)\";\n }\n\n return null;\n}\n\nexport function toTitleCase(kebabCase: string): string {\n return kebabCase\n .split(\"-\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n}\n\nexport function generateSkillMd(name: string): string {\n const titleName = toTitleCase(name);\n\n return `---\nname: ${name}\ndescription: Brief description of this skill\n---\n\n# ${titleName}\n\n> **Quick Guide:** Add a brief summary of what this skill teaches.\n\n---\n\n<critical_requirements>\n\n## CRITICAL: Before Using This Skill\n\n**(Add critical requirements here)**\n\n</critical_requirements>\n\n---\n\n**When to use:**\n\n- Add use cases here\n\n**Key patterns covered:**\n\n- Add patterns here\n\n---\n\n<patterns>\n\n## Core Patterns\n\n### Pattern 1: Example Pattern\n\nAdd your patterns here.\n\n</patterns>\n\n---\n\n<critical_reminders>\n\n## CRITICAL REMINDERS\n\n**(Repeat critical requirements here)**\n\n</critical_reminders>\n`;\n}\n\nexport function generateMetadataYaml(name: string
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/new/skill.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport { BaseCommand } from \"../../base-command.js\";\nimport { resolveAuthor } from \"../../lib/configuration/index.js\";\nimport { writeFile, directoryExists, fileExists } from \"../../utils/fs.js\";\nimport {\n CLI_BIN_NAME,\n KEBAB_CASE_PATTERN,\n LOCAL_SKILLS_PATH,\n PLUGIN_MANIFEST_DIR,\n SKILLS_DIR_PATH,\n STANDARD_FILES,\n} from \"../../consts.js\";\nimport { EXIT_CODES } from \"../../lib/exit-codes.js\";\nimport { LOCAL_DEFAULTS } from \"../../lib/metadata-keys.js\";\nimport { computeSkillFolderHash } from \"../../lib/versioning.js\";\nimport type { CategoryPath } from \"../../types/index.js\";\n\nexport function validateSkillName(name: string): string | null {\n if (!name || name.trim() === \"\") {\n return \"Skill name is required\";\n }\n\n if (!KEBAB_CASE_PATTERN.test(name)) {\n return \"Skill name must be kebab-case (lowercase letters, numbers, and hyphens, starting with a letter)\";\n }\n\n return null;\n}\n\nexport function toTitleCase(kebabCase: string): string {\n return kebabCase\n .split(\"-\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n}\n\nexport function generateSkillMd(name: string): string {\n const titleName = toTitleCase(name);\n\n return `---\nname: ${name}\ndescription: Brief description of this skill\n---\n\n# ${titleName}\n\n> **Quick Guide:** Add a brief summary of what this skill teaches.\n\n---\n\n<critical_requirements>\n\n## CRITICAL: Before Using This Skill\n\n**(Add critical requirements here)**\n\n</critical_requirements>\n\n---\n\n**When to use:**\n\n- Add use cases here\n\n**Key patterns covered:**\n\n- Add patterns here\n\n---\n\n<patterns>\n\n## Core Patterns\n\n### Pattern 1: Example Pattern\n\nAdd your patterns here.\n\n</patterns>\n\n---\n\n<critical_reminders>\n\n## CRITICAL REMINDERS\n\n**(Repeat critical requirements here)**\n\n</critical_reminders>\n`;\n}\n\nexport function generateMetadataYaml(\n name: string,\n author: string,\n category: CategoryPath,\n contentHash: string,\n): string {\n const titleName = toTitleCase(name);\n\n return `custom: true\ncategory: ${category}\nauthor: \"${author}\"\ndisplayName: ${titleName}\ncliDescription: Brief description\nusageGuidance: Use when <guidance>.\ncontentHash: ${contentHash}\ntags:\n - local\n - custom\n`;\n}\n\nexport default class NewSkill extends BaseCommand {\n static summary = \"Create a new local skill with proper structure\";\n static description = \"Create a new local skill scaffold with SKILL.md and metadata.yaml files\";\n\n static args = {\n name: Args.string({\n description: \"Name of the skill to create (kebab-case)\",\n required: true,\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n author: Flags.string({\n char: \"a\",\n description: \"Author identifier (e.g., @myhandle)\",\n required: false,\n }),\n category: Flags.string({\n char: \"c\",\n description: \"Skill category\",\n default: LOCAL_DEFAULTS.CATEGORY,\n }),\n force: Flags.boolean({\n char: \"f\",\n description: \"Overwrite existing skill directory\",\n default: false,\n }),\n output: Flags.string({\n char: \"o\",\n description: \"Output directory for the skill (overrides marketplace detection)\",\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(NewSkill);\n const projectDir = process.cwd();\n\n this.log(\"\");\n this.log(\"Create New Skill\");\n this.log(\"\");\n\n const validationError = validateSkillName(args.name);\n if (validationError) {\n this.error(validationError, { exit: EXIT_CODES.INVALID_ARGS });\n }\n\n // Determine author: flag > project config > default\n let author = flags.author;\n if (!author) {\n author = (await resolveAuthor(projectDir)) || LOCAL_DEFAULTS.AUTHOR;\n }\n\n // CLI flag is an untyped string — cast at data boundary\n const category = flags.category as CategoryPath;\n\n // Determine skill output path: --output flag > marketplace detection > local default\n let skillsBasePath: string;\n if (flags.output) {\n skillsBasePath = path.resolve(flags.output);\n } else {\n const marketplacePath = path.join(projectDir, PLUGIN_MANIFEST_DIR, \"marketplace.json\");\n if (await fileExists(marketplacePath)) {\n this.log(`Detected marketplace context, creating skill in ${SKILLS_DIR_PATH}/`);\n skillsBasePath = path.join(projectDir, SKILLS_DIR_PATH);\n } else {\n skillsBasePath = path.join(projectDir, LOCAL_SKILLS_PATH);\n }\n }\n\n const skillDir = path.join(skillsBasePath, args.name);\n\n if (await directoryExists(skillDir)) {\n if (!flags.force) {\n this.error(`Skill directory already exists: ${skillDir}\\nUse --force to overwrite.`, {\n exit: EXIT_CODES.ERROR,\n });\n }\n this.warn(`Overwriting existing skill at ${skillDir}`);\n }\n\n this.log(`Skill name: ${args.name}`);\n this.log(`Author: ${author}`);\n this.log(`Category: ${category}`);\n this.log(`Directory: ${skillDir}`);\n this.log(\"\");\n\n if (flags[\"dry-run\"]) {\n this.log(\"[DRY RUN] Would create skill files\");\n return;\n }\n\n this.log(\"Creating skill files...\");\n\n try {\n const skillMdContent = generateSkillMd(args.name);\n\n const skillMdPath = path.join(skillDir, STANDARD_FILES.SKILL_MD);\n const metadataPath = path.join(skillDir, STANDARD_FILES.METADATA_YAML);\n\n await writeFile(skillMdPath, skillMdContent);\n\n const contentHash = await computeSkillFolderHash(skillDir);\n const metadataContent = generateMetadataYaml(args.name, author, category, contentHash);\n await writeFile(metadataPath, metadataContent);\n\n this.log(\"\");\n this.logSuccess(`Created ${STANDARD_FILES.SKILL_MD} at ${skillMdPath}`);\n this.logSuccess(`Created ${STANDARD_FILES.METADATA_YAML} at ${metadataPath}`);\n this.log(\"\");\n this.log(\n `Skill created successfully! Run '${CLI_BIN_NAME} compile' to include it in your agents.`,\n );\n this.log(\"\");\n } catch (error) {\n this.handleError(error);\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
import {
|
|
3
3
|
BaseCommand,
|
|
4
4
|
EXIT_CODES
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-2BVZOYJP.js";
|
|
6
6
|
import {
|
|
7
7
|
compareLocalSkillsWithSource,
|
|
8
8
|
loadSkillsMatrixFromSource
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-P2SFRDWI.js";
|
|
10
10
|
import "../chunk-T4EXUIBY.js";
|
|
11
11
|
import {
|
|
12
12
|
fileExists,
|
|
13
13
|
getErrorMessage
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-YMUWTPOM.js";
|
|
15
15
|
import {
|
|
16
16
|
CLI_BIN_NAME,
|
|
17
17
|
LOCAL_SKILLS_PATH
|
|
18
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-LESHL6SM.js";
|
|
19
19
|
import {
|
|
20
20
|
init_esm_shims
|
|
21
21
|
} from "../chunk-DHET7RCE.js";
|
package/dist/commands/search.js
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SkillSearch
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-NJVJ7VO5.js";
|
|
5
|
+
import "../chunk-FHKNG3UA.js";
|
|
6
6
|
import "../chunk-U3IGFMCY.js";
|
|
7
7
|
import {
|
|
8
8
|
INFO_MESSAGES,
|
|
9
9
|
STATUS_MESSAGES,
|
|
10
10
|
SUCCESS_MESSAGES
|
|
11
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-DG2U2WY3.js";
|
|
12
12
|
import {
|
|
13
13
|
BaseCommand,
|
|
14
14
|
EXIT_CODES
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-2BVZOYJP.js";
|
|
16
16
|
import {
|
|
17
17
|
fetchFromSource,
|
|
18
18
|
loadSkillsMatrixFromSource,
|
|
19
19
|
resolveAllSources
|
|
20
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-P2SFRDWI.js";
|
|
21
21
|
import "../chunk-T4EXUIBY.js";
|
|
22
22
|
import {
|
|
23
23
|
copy,
|
|
24
24
|
ensureDir,
|
|
25
25
|
fileExists,
|
|
26
26
|
listDirectories
|
|
27
|
-
} from "../chunk-
|
|
27
|
+
} from "../chunk-YMUWTPOM.js";
|
|
28
28
|
import {
|
|
29
29
|
DEFAULT_SKILLS_SUBDIR,
|
|
30
30
|
LOCAL_SKILLS_PATH,
|
|
31
31
|
STANDARD_FILES
|
|
32
|
-
} from "../chunk-
|
|
32
|
+
} from "../chunk-LESHL6SM.js";
|
|
33
33
|
import {
|
|
34
34
|
init_esm_shims
|
|
35
35
|
} from "../chunk-DHET7RCE.js";
|
|
@@ -89,7 +89,6 @@ async function fetchSkillsFromSource(source, forceRefresh) {
|
|
|
89
89
|
description: `Skill from ${source.name}`,
|
|
90
90
|
// Synthetic category for third-party sources — not in CategoryPath union
|
|
91
91
|
category: "imported",
|
|
92
|
-
categoryExclusive: false,
|
|
93
92
|
tags: [],
|
|
94
93
|
author: `@${source.name}`,
|
|
95
94
|
conflictsWith: [],
|