@agents-inc/cli 0.48.0 → 0.50.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 +1 -2
- package/config/stacks.yaml +0 -1
- package/dist/{chunk-YDASDMTH.js → chunk-26MXZUHU.js} +2 -2
- package/dist/{chunk-WSGKCBY5.js → chunk-2BWCR762.js} +2 -3
- package/dist/chunk-2BWCR762.js.map +1 -0
- package/dist/chunk-3VOL4WEG.js +31 -0
- package/dist/chunk-3VOL4WEG.js.map +1 -0
- package/dist/chunk-4QWDB2MD.js +571 -0
- package/dist/chunk-4QWDB2MD.js.map +1 -0
- package/dist/{chunk-ZML3OCYA.js → chunk-4R52TQ3K.js} +2 -2
- package/dist/{chunk-KPJJOLAQ.js → chunk-5FCHJLM7.js} +34 -16
- package/dist/chunk-5FCHJLM7.js.map +1 -0
- package/dist/chunk-5FPIKTSA.js +40 -0
- package/dist/chunk-5FPIKTSA.js.map +1 -0
- package/dist/{chunk-SPVSWDFM.js → chunk-5L724R4C.js} +5 -6
- package/dist/{chunk-SPVSWDFM.js.map → chunk-5L724R4C.js.map} +1 -1
- package/dist/{chunk-AXV7NFFJ.js → chunk-7LV4V6A4.js} +4 -4
- package/dist/{chunk-LESHL6SM.js → chunk-AWP5A6IM.js} +9 -3
- package/dist/chunk-AWP5A6IM.js.map +1 -0
- package/dist/chunk-C3Q43WLC.js +118 -0
- package/dist/chunk-C3Q43WLC.js.map +1 -0
- package/dist/{chunk-U2AEK4ZL.js → chunk-CMNKHDOX.js} +2 -2
- package/dist/{chunk-X3SZIBVW.js → chunk-D72AFYQR.js} +2 -2
- package/dist/chunk-D72AFYQR.js.map +1 -0
- package/dist/{chunk-FPTUCWBY.js → chunk-DCE423KO.js} +46 -30
- package/dist/chunk-DCE423KO.js.map +1 -0
- package/dist/chunk-GBOW6FUW.js +74 -0
- package/dist/chunk-GBOW6FUW.js.map +1 -0
- package/dist/{chunk-P2SFRDWI.js → chunk-HMSHB5EQ.js} +437 -185
- package/dist/chunk-HMSHB5EQ.js.map +1 -0
- package/dist/{chunk-GSPPOXMG.js → chunk-HYEUETIC.js} +2 -2
- package/dist/{chunk-IS7GP6XC.js → chunk-I6IOGZSZ.js} +61 -52
- package/dist/chunk-I6IOGZSZ.js.map +1 -0
- package/dist/{chunk-OTTITQ7C.js → chunk-JFF7P4LC.js} +30 -93
- package/dist/chunk-JFF7P4LC.js.map +1 -0
- package/dist/{chunk-FHKNG3UA.js → chunk-JWYRXE6C.js} +2 -2
- package/dist/{chunk-W62XVWXB.js → chunk-KAO3LKB5.js} +3 -3
- package/dist/{chunk-AMNCCZSG.js → chunk-KQOU4POU.js} +26 -28
- package/dist/chunk-KQOU4POU.js.map +1 -0
- package/dist/{chunk-VBAAATPU.js → chunk-M3GQ2R3E.js} +29 -28
- package/dist/chunk-M3GQ2R3E.js.map +1 -0
- package/dist/{chunk-2BVZOYJP.js → chunk-PGY5XROM.js} +2 -2
- package/dist/chunk-PGY5XROM.js.map +1 -0
- package/dist/{chunk-5MN5S3DV.js → chunk-QB5HHTAA.js} +8 -19
- package/dist/chunk-QB5HHTAA.js.map +1 -0
- package/dist/{chunk-34BP5BC4.js → chunk-QYLCINGC.js} +2 -2
- package/dist/{chunk-I52THVF6.js → chunk-RA2IPRO2.js} +2 -2
- package/dist/{chunk-G5OZQ376.js → chunk-RDWGYKDY.js} +4 -4
- package/dist/{chunk-7IAKVZL5.js → chunk-RFKDGJAJ.js} +26 -57
- package/dist/chunk-RFKDGJAJ.js.map +1 -0
- package/dist/{chunk-5O6GKXAN.js → chunk-SPFHPHYL.js} +7 -7
- package/dist/{chunk-NJVJ7VO5.js → chunk-U2W5SENM.js} +3 -3
- package/dist/{chunk-37QYD33C.js → chunk-U7X4V4HE.js} +2 -2
- package/dist/{chunk-C7DLY64D.js → chunk-UAD3SC27.js} +4 -12
- package/dist/chunk-UAD3SC27.js.map +1 -0
- package/dist/{chunk-YMUWTPOM.js → chunk-WBHPCBVN.js} +31 -11
- package/dist/chunk-WBHPCBVN.js.map +1 -0
- package/dist/chunk-WFFV254H.js +314 -0
- package/dist/chunk-WFFV254H.js.map +1 -0
- package/dist/{chunk-F7KTUFGU.js → chunk-WJHFV6RI.js} +3 -2
- package/dist/chunk-WJHFV6RI.js.map +1 -0
- package/dist/{chunk-DG2U2WY3.js → chunk-WLZHCM7O.js} +2 -2
- package/dist/{chunk-OHDEJEYB.js → chunk-XDSVV5GZ.js} +4 -4
- package/dist/{chunk-2DNDAXF6.js → chunk-YDYRAXSY.js} +57 -27
- package/dist/chunk-YDYRAXSY.js.map +1 -0
- 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 +11 -9
- package/dist/commands/compile.js.map +1 -1
- 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 +58 -52
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +4 -4
- package/dist/commands/import/skill.js +5 -5
- package/dist/commands/info.js +5 -5
- package/dist/commands/init.js +40 -435
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/list.js +4 -4
- package/dist/commands/new/agent.js +11 -10
- package/dist/commands/new/agent.js.map +1 -1
- package/dist/commands/new/marketplace.js +24 -5
- package/dist/commands/new/marketplace.js.map +1 -1
- package/dist/commands/new/skill.js +15 -208
- package/dist/commands/new/skill.js.map +1 -1
- package/dist/commands/outdated.js +11 -7
- package/dist/commands/outdated.js.map +1 -1
- package/dist/commands/search.js +7 -7
- package/dist/commands/uninstall.js +6 -6
- package/dist/commands/update.js +6 -6
- package/dist/commands/validate.js +26 -247
- 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 +3 -2
- package/dist/components/wizard/category-grid.test.js +112 -58
- package/dist/components/wizard/category-grid.test.js.map +1 -1
- package/dist/components/wizard/checkbox-grid.js +5 -3
- package/dist/components/wizard/checkbox-grid.test.js +5 -4
- package/dist/components/wizard/checkbox-grid.test.js.map +1 -1
- package/dist/components/wizard/domain-selection.js +11 -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 +4 -3
- package/dist/components/wizard/source-grid.test.js +4 -3
- package/dist/components/wizard/source-grid.test.js.map +1 -1
- package/dist/components/wizard/stack-selection.js +8 -8
- package/dist/components/wizard/step-agents.js +10 -8
- package/dist/components/wizard/step-agents.test.js +18 -17
- package/dist/components/wizard/step-agents.test.js.map +1 -1
- package/dist/components/wizard/step-build.js +9 -8
- package/dist/components/wizard/step-build.test.js +11 -25
- 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 +7 -5
- package/dist/components/wizard/step-settings.test.js +10 -8
- package/dist/components/wizard/step-settings.test.js.map +1 -1
- package/dist/components/wizard/step-sources.js +11 -10
- package/dist/components/wizard/step-sources.test.js +12 -11
- package/dist/components/wizard/step-sources.test.js.map +1 -1
- package/dist/components/wizard/step-stack.js +15 -12
- package/dist/components/wizard/step-stack.test.js +16 -13
- package/dist/components/wizard/step-stack.test.js.map +1 -1
- 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 +27 -25
- package/dist/config/stacks.yaml +0 -1
- package/dist/hooks/init.js +55 -3
- package/dist/hooks/init.js.map +1 -1
- package/dist/{source-manager-Y7R6WPOW.js → source-manager-BVB2SG73.js} +4 -4
- package/dist/src/agents/meta/agent-summoner/critical-reminders.md +1 -1
- package/dist/src/agents/meta/agent-summoner/critical-requirements.md +1 -1
- package/dist/src/agents/meta/agent-summoner/examples.md +2 -2
- package/dist/src/agents/meta/agent-summoner/output-format.md +1 -1
- package/dist/src/agents/meta/agent-summoner/workflow.md +5 -7
- package/{src/agents/meta/documentor/agent.yaml → dist/src/agents/meta/documentor/metadata.yaml} +1 -0
- package/dist/stores/wizard-store.js +5 -5
- package/dist/stores/wizard-store.test.js +79 -27
- package/dist/stores/wizard-store.test.js.map +1 -1
- package/package.json +1 -1
- package/src/agents/meta/agent-summoner/critical-reminders.md +1 -1
- package/src/agents/meta/agent-summoner/critical-requirements.md +1 -1
- package/src/agents/meta/agent-summoner/examples.md +2 -2
- package/src/agents/meta/agent-summoner/output-format.md +1 -1
- package/src/agents/meta/agent-summoner/workflow.md +5 -7
- package/{dist/src/agents/meta/documentor/agent.yaml → src/agents/meta/documentor/metadata.yaml} +1 -0
- package/src/schemas/agent.schema.json +1 -1
- package/src/schemas/project-config.schema.json +0 -3
- package/dist/chunk-2BVZOYJP.js.map +0 -1
- package/dist/chunk-2DNDAXF6.js.map +0 -1
- package/dist/chunk-5MN5S3DV.js.map +0 -1
- package/dist/chunk-7IAKVZL5.js.map +0 -1
- package/dist/chunk-AMNCCZSG.js.map +0 -1
- package/dist/chunk-AXZNJ5PN.js +0 -99
- package/dist/chunk-AXZNJ5PN.js.map +0 -1
- package/dist/chunk-C7DLY64D.js.map +0 -1
- package/dist/chunk-F7KTUFGU.js.map +0 -1
- package/dist/chunk-FPTUCWBY.js.map +0 -1
- package/dist/chunk-IS7GP6XC.js.map +0 -1
- package/dist/chunk-KPJJOLAQ.js.map +0 -1
- package/dist/chunk-LESHL6SM.js.map +0 -1
- package/dist/chunk-OTTITQ7C.js.map +0 -1
- package/dist/chunk-P2SFRDWI.js.map +0 -1
- package/dist/chunk-PY2XZUBF.js +0 -29
- package/dist/chunk-PY2XZUBF.js.map +0 -1
- package/dist/chunk-VBAAATPU.js.map +0 -1
- package/dist/chunk-WSGKCBY5.js.map +0 -1
- package/dist/chunk-X3SZIBVW.js.map +0 -1
- package/dist/chunk-YMUWTPOM.js.map +0 -1
- package/dist/src/agents/migration/cli-migrator/agent.yaml +0 -12
- package/dist/src/agents/migration/cli-migrator/anti-patterns.md +0 -158
- package/dist/src/agents/migration/cli-migrator/conversion-mappings.md +0 -63
- package/dist/src/agents/migration/cli-migrator/critical-reminders.md +0 -17
- package/dist/src/agents/migration/cli-migrator/critical-requirements.md +0 -13
- package/dist/src/agents/migration/cli-migrator/intro.md +0 -15
- package/dist/src/agents/migration/cli-migrator/output-format.md +0 -164
- package/dist/src/agents/migration/cli-migrator/workflow.md +0 -230
- package/src/agents/migration/cli-migrator/agent.yaml +0 -12
- package/src/agents/migration/cli-migrator/anti-patterns.md +0 -158
- package/src/agents/migration/cli-migrator/conversion-mappings.md +0 -63
- package/src/agents/migration/cli-migrator/critical-reminders.md +0 -17
- package/src/agents/migration/cli-migrator/critical-requirements.md +0 -13
- package/src/agents/migration/cli-migrator/intro.md +0 -15
- package/src/agents/migration/cli-migrator/output-format.md +0 -164
- package/src/agents/migration/cli-migrator/workflow.md +0 -230
- /package/dist/{chunk-YDASDMTH.js.map → chunk-26MXZUHU.js.map} +0 -0
- /package/dist/{chunk-ZML3OCYA.js.map → chunk-4R52TQ3K.js.map} +0 -0
- /package/dist/{chunk-AXV7NFFJ.js.map → chunk-7LV4V6A4.js.map} +0 -0
- /package/dist/{chunk-U2AEK4ZL.js.map → chunk-CMNKHDOX.js.map} +0 -0
- /package/dist/{chunk-GSPPOXMG.js.map → chunk-HYEUETIC.js.map} +0 -0
- /package/dist/{chunk-FHKNG3UA.js.map → chunk-JWYRXE6C.js.map} +0 -0
- /package/dist/{chunk-W62XVWXB.js.map → chunk-KAO3LKB5.js.map} +0 -0
- /package/dist/{chunk-34BP5BC4.js.map → chunk-QYLCINGC.js.map} +0 -0
- /package/dist/{chunk-I52THVF6.js.map → chunk-RA2IPRO2.js.map} +0 -0
- /package/dist/{chunk-G5OZQ376.js.map → chunk-RDWGYKDY.js.map} +0 -0
- /package/dist/{chunk-5O6GKXAN.js.map → chunk-SPFHPHYL.js.map} +0 -0
- /package/dist/{chunk-NJVJ7VO5.js.map → chunk-U2W5SENM.js.map} +0 -0
- /package/dist/{chunk-37QYD33C.js.map → chunk-U7X4V4HE.js.map} +0 -0
- /package/dist/{chunk-DG2U2WY3.js.map → chunk-WLZHCM7O.js.map} +0 -0
- /package/dist/{chunk-OHDEJEYB.js.map → chunk-XDSVV5GZ.js.map} +0 -0
- /package/dist/{source-manager-Y7R6WPOW.js.map → source-manager-BVB2SG73.js.map} +0 -0
- /package/dist/src/agents/developer/api-developer/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/developer/cli-developer/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/developer/web-architecture/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/developer/web-developer/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/meta/agent-summoner/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/meta/skill-summoner/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/pattern/pattern-scout/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/pattern/web-pattern-critique/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/planning/web-pm/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/researcher/api-researcher/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/researcher/web-researcher/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/reviewer/api-reviewer/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/reviewer/cli-reviewer/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/reviewer/web-reviewer/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/tester/cli-tester/{agent.yaml → metadata.yaml} +0 -0
- /package/dist/src/agents/tester/web-tester/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/developer/api-developer/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/developer/cli-developer/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/developer/web-architecture/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/developer/web-developer/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/meta/agent-summoner/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/meta/skill-summoner/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/pattern/pattern-scout/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/pattern/web-pattern-critique/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/planning/web-pm/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/researcher/api-researcher/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/researcher/web-researcher/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/reviewer/api-reviewer/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/reviewer/cli-reviewer/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/reviewer/web-reviewer/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/tester/cli-tester/{agent.yaml → metadata.yaml} +0 -0
- /package/src/agents/tester/web-tester/{agent.yaml → metadata.yaml} +0 -0
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
agentFrontmatterValidationSchema,
|
|
10
10
|
agentNameSchema,
|
|
11
11
|
agentYamlConfigSchema,
|
|
12
|
+
agentYamlGenerationSchema,
|
|
12
13
|
categoryPathSchema,
|
|
13
14
|
copy,
|
|
14
15
|
directoryExists,
|
|
@@ -26,6 +27,7 @@ import {
|
|
|
26
27
|
localSkillMetadataSchema,
|
|
27
28
|
log,
|
|
28
29
|
marketplaceSchema,
|
|
30
|
+
metadataValidationSchema,
|
|
29
31
|
pluginAuthorSchema,
|
|
30
32
|
pluginManifestSchema,
|
|
31
33
|
projectConfigLoaderSchema,
|
|
@@ -41,13 +43,14 @@ import {
|
|
|
41
43
|
skillIdSchema,
|
|
42
44
|
skillMetadataLoaderSchema,
|
|
43
45
|
skillRulesFileSchema,
|
|
46
|
+
stackConfigValidationSchema,
|
|
44
47
|
stacksConfigSchema,
|
|
45
48
|
validateNestingDepth,
|
|
46
49
|
verbose,
|
|
47
50
|
warn,
|
|
48
51
|
warnUnknownFields,
|
|
49
52
|
writeFile
|
|
50
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-WBHPCBVN.js";
|
|
51
54
|
import {
|
|
52
55
|
ARCHIVED_SKILLS_DIR_NAME,
|
|
53
56
|
CACHE_DIR,
|
|
@@ -82,7 +85,7 @@ import {
|
|
|
82
85
|
STANDARD_FILES,
|
|
83
86
|
YAML_FORMATTING,
|
|
84
87
|
yamlSchemaComment
|
|
85
|
-
} from "./chunk-
|
|
88
|
+
} from "./chunk-AWP5A6IM.js";
|
|
86
89
|
import {
|
|
87
90
|
init_esm_shims
|
|
88
91
|
} from "./chunk-DHET7RCE.js";
|
|
@@ -92,6 +95,7 @@ init_esm_shims();
|
|
|
92
95
|
|
|
93
96
|
// src/cli/lib/configuration/config.ts
|
|
94
97
|
init_esm_shims();
|
|
98
|
+
import os from "os";
|
|
95
99
|
import path from "path";
|
|
96
100
|
import { stringify as stringifyYaml } from "yaml";
|
|
97
101
|
|
|
@@ -139,6 +143,18 @@ async function loadProjectSourceConfig(projectDir) {
|
|
|
139
143
|
verbose(`Loaded project config from ${configPath}`);
|
|
140
144
|
return data;
|
|
141
145
|
}
|
|
146
|
+
async function loadGlobalSourceConfig() {
|
|
147
|
+
const homeDir = os.homedir();
|
|
148
|
+
const globalConfigPath = path.join(homeDir, CLAUDE_SRC_DIR, PROJECT_CONFIG_FILE);
|
|
149
|
+
if (!await fileExists(globalConfigPath)) {
|
|
150
|
+
verbose(`Global config not found at ${globalConfigPath}`);
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
const data = await safeLoadYamlFile(globalConfigPath, projectSourceConfigSchema);
|
|
154
|
+
if (!data) return null;
|
|
155
|
+
verbose(`Loaded global config from ${globalConfigPath}`);
|
|
156
|
+
return data;
|
|
157
|
+
}
|
|
142
158
|
async function saveProjectConfig(projectDir, config) {
|
|
143
159
|
const configPath = getProjectConfigPath(projectDir);
|
|
144
160
|
await ensureDir(path.join(projectDir, CLAUDE_SRC_DIR));
|
|
@@ -148,9 +164,13 @@ async function saveProjectConfig(projectDir, config) {
|
|
|
148
164
|
await writeFile(configPath, `${schemaComment}${content}`);
|
|
149
165
|
verbose(`Saved project config to ${configPath}`);
|
|
150
166
|
}
|
|
151
|
-
async function
|
|
167
|
+
async function loadEffectiveSourceConfig(projectDir) {
|
|
152
168
|
const projectConfig = projectDir ? await loadProjectSourceConfig(projectDir) : null;
|
|
153
|
-
|
|
169
|
+
return projectConfig ?? await loadGlobalSourceConfig();
|
|
170
|
+
}
|
|
171
|
+
async function resolveSource(flagValue, projectDir) {
|
|
172
|
+
const effectiveConfig = await loadEffectiveSourceConfig(projectDir);
|
|
173
|
+
const marketplace = effectiveConfig?.marketplace;
|
|
154
174
|
if (flagValue !== void 0) {
|
|
155
175
|
if (flagValue === "" || flagValue.trim() === "") {
|
|
156
176
|
throw new Error(
|
|
@@ -180,10 +200,10 @@ ${message}`
|
|
|
180
200
|
}
|
|
181
201
|
}
|
|
182
202
|
}
|
|
183
|
-
if (
|
|
184
|
-
verbose(`Source from project config: ${
|
|
203
|
+
if (effectiveConfig?.source) {
|
|
204
|
+
verbose(`Source from project config: ${effectiveConfig.source}`);
|
|
185
205
|
return {
|
|
186
|
-
source:
|
|
206
|
+
source: effectiveConfig.source,
|
|
187
207
|
sourceOrigin: "project",
|
|
188
208
|
marketplace
|
|
189
209
|
};
|
|
@@ -202,11 +222,11 @@ async function resolveAgentsSource(flagValue, projectDir) {
|
|
|
202
222
|
verbose(`Agents source from --agent-source flag: ${flagValue}`);
|
|
203
223
|
return { agentsSource: flagValue, agentsSourceOrigin: "flag" };
|
|
204
224
|
}
|
|
205
|
-
const
|
|
206
|
-
if (
|
|
207
|
-
verbose(`Agents source from project config: ${
|
|
225
|
+
const effectiveConfig = await loadEffectiveSourceConfig(projectDir);
|
|
226
|
+
if (effectiveConfig?.agentsSource) {
|
|
227
|
+
verbose(`Agents source from project config: ${effectiveConfig.agentsSource}`);
|
|
208
228
|
return {
|
|
209
|
-
agentsSource:
|
|
229
|
+
agentsSource: effectiveConfig.agentsSource,
|
|
210
230
|
agentsSourceOrigin: "project"
|
|
211
231
|
};
|
|
212
232
|
}
|
|
@@ -239,11 +259,11 @@ function formatOrigin(type, origin) {
|
|
|
239
259
|
return origin;
|
|
240
260
|
}
|
|
241
261
|
async function resolveAuthor(projectDir) {
|
|
242
|
-
const
|
|
243
|
-
return
|
|
262
|
+
const effectiveConfig = await loadEffectiveSourceConfig(projectDir);
|
|
263
|
+
return effectiveConfig?.author;
|
|
244
264
|
}
|
|
245
265
|
async function resolveAllSources(projectDir) {
|
|
246
|
-
const
|
|
266
|
+
const effectiveConfig = await loadEffectiveSourceConfig(projectDir);
|
|
247
267
|
const resolvedConfig = await resolveSource(void 0, projectDir);
|
|
248
268
|
const primary = {
|
|
249
269
|
name: "marketplace",
|
|
@@ -252,8 +272,8 @@ async function resolveAllSources(projectDir) {
|
|
|
252
272
|
};
|
|
253
273
|
const extras = [];
|
|
254
274
|
const seenNames = /* @__PURE__ */ new Set();
|
|
255
|
-
if (
|
|
256
|
-
for (const source of
|
|
275
|
+
if (effectiveConfig?.sources) {
|
|
276
|
+
for (const source of effectiveConfig.sources) {
|
|
257
277
|
if (!seenNames.has(source.name)) {
|
|
258
278
|
seenNames.add(source.name);
|
|
259
279
|
extras.push(source);
|
|
@@ -420,7 +440,7 @@ function isLocalSource(source) {
|
|
|
420
440
|
init_esm_shims();
|
|
421
441
|
import { createHash } from "crypto";
|
|
422
442
|
import { downloadTemplate } from "giget";
|
|
423
|
-
import
|
|
443
|
+
import os3 from "os";
|
|
424
444
|
import path4 from "path";
|
|
425
445
|
|
|
426
446
|
// src/cli/lib/configuration/index.ts
|
|
@@ -535,6 +555,7 @@ import { difference } from "remeda";
|
|
|
535
555
|
|
|
536
556
|
// src/cli/lib/configuration/project-config.ts
|
|
537
557
|
init_esm_shims();
|
|
558
|
+
import os2 from "os";
|
|
538
559
|
import path3 from "path";
|
|
539
560
|
|
|
540
561
|
// src/cli/lib/stacks/stacks-loader.ts
|
|
@@ -631,7 +652,7 @@ function getStackSkillIds(stack) {
|
|
|
631
652
|
// src/cli/lib/configuration/project-config.ts
|
|
632
653
|
var CONFIG_PATH = `${CLAUDE_SRC_DIR}/config.yaml`;
|
|
633
654
|
var LEGACY_CONFIG_PATH = `${CLAUDE_DIR}/config.yaml`;
|
|
634
|
-
async function
|
|
655
|
+
async function loadProjectConfigFromDir(projectDir) {
|
|
635
656
|
const srcConfigPath = path3.join(projectDir, CONFIG_PATH);
|
|
636
657
|
const legacyConfigPath = path3.join(projectDir, LEGACY_CONFIG_PATH);
|
|
637
658
|
let configPath = srcConfigPath;
|
|
@@ -668,6 +689,15 @@ async function loadProjectConfig(projectDir) {
|
|
|
668
689
|
configPath
|
|
669
690
|
};
|
|
670
691
|
}
|
|
692
|
+
async function loadProjectConfig(projectDir) {
|
|
693
|
+
const projectResult = await loadProjectConfigFromDir(projectDir);
|
|
694
|
+
if (projectResult) return projectResult;
|
|
695
|
+
const homeDir = os2.homedir();
|
|
696
|
+
if (projectDir !== homeDir) {
|
|
697
|
+
return loadProjectConfigFromDir(homeDir);
|
|
698
|
+
}
|
|
699
|
+
return null;
|
|
700
|
+
}
|
|
671
701
|
function validateProjectConfig(config) {
|
|
672
702
|
const errors = [];
|
|
673
703
|
const warnings = [];
|
|
@@ -805,7 +835,7 @@ function getGigetCacheDir(source) {
|
|
|
805
835
|
return void 0;
|
|
806
836
|
}
|
|
807
837
|
const templateName = uriMatch.groups.repo.replace("/", "-").replace(/[^\da-z-]/gi, "-");
|
|
808
|
-
const gigetCacheRoot = process.env.XDG_CACHE_HOME ? path4.resolve(process.env.XDG_CACHE_HOME, "giget") : path4.resolve(
|
|
838
|
+
const gigetCacheRoot = process.env.XDG_CACHE_HOME ? path4.resolve(process.env.XDG_CACHE_HOME, "giget") : path4.resolve(os3.homedir(), ".cache", "giget");
|
|
809
839
|
return path4.join(gigetCacheRoot, providerName, templateName);
|
|
810
840
|
}
|
|
811
841
|
async function clearGigetCache(source) {
|
|
@@ -979,8 +1009,8 @@ Too many plugins: ${marketplace.plugins.length} (limit: ${MAX_MARKETPLACE_PLUGIN
|
|
|
979
1009
|
|
|
980
1010
|
// src/cli/lib/skills/local-skill-loader.ts
|
|
981
1011
|
init_esm_shims();
|
|
982
|
-
import { parse as
|
|
983
|
-
import
|
|
1012
|
+
import { parse as parseYaml9 } from "yaml";
|
|
1013
|
+
import path23 from "path";
|
|
984
1014
|
|
|
985
1015
|
// src/cli/lib/loading/index.ts
|
|
986
1016
|
init_esm_shims();
|
|
@@ -1006,7 +1036,7 @@ function parseFrontmatter(content, filePath) {
|
|
|
1006
1036
|
async function loadAllAgents(projectRoot) {
|
|
1007
1037
|
const agents = {};
|
|
1008
1038
|
const agentSourcesDir = path5.join(projectRoot, DIRS.agents);
|
|
1009
|
-
const files = await glob(
|
|
1039
|
+
const files = await glob(`**/${STANDARD_FILES.AGENT_METADATA_YAML}`, agentSourcesDir);
|
|
1010
1040
|
for (const file of files) {
|
|
1011
1041
|
const fullPath = path5.join(agentSourcesDir, file);
|
|
1012
1042
|
try {
|
|
@@ -1024,7 +1054,7 @@ async function loadAllAgents(projectRoot) {
|
|
|
1024
1054
|
};
|
|
1025
1055
|
verbose(`Loaded agent: ${config.id} from ${file}`);
|
|
1026
1056
|
} catch (error) {
|
|
1027
|
-
warn(`Skipping invalid
|
|
1057
|
+
warn(`Skipping invalid metadata.yaml at '${fullPath}': ${getErrorMessage(error)}`);
|
|
1028
1058
|
}
|
|
1029
1059
|
}
|
|
1030
1060
|
return agents;
|
|
@@ -1036,7 +1066,7 @@ async function loadProjectAgents(projectRoot) {
|
|
|
1036
1066
|
verbose(`No project agents directory at ${projectAgentsDir}`);
|
|
1037
1067
|
return agents;
|
|
1038
1068
|
}
|
|
1039
|
-
const files = await glob(
|
|
1069
|
+
const files = await glob(`**/${STANDARD_FILES.AGENT_METADATA_YAML}`, projectAgentsDir);
|
|
1040
1070
|
for (const file of files) {
|
|
1041
1071
|
const fullPath = path5.join(projectAgentsDir, file);
|
|
1042
1072
|
try {
|
|
@@ -1056,7 +1086,7 @@ async function loadProjectAgents(projectRoot) {
|
|
|
1056
1086
|
};
|
|
1057
1087
|
verbose(`Loaded project agent: ${config.id} from ${file}`);
|
|
1058
1088
|
} catch (error) {
|
|
1059
|
-
warn(`Skipping invalid
|
|
1089
|
+
warn(`Skipping invalid metadata.yaml at '${fullPath}': ${getErrorMessage(error)}`);
|
|
1060
1090
|
}
|
|
1061
1091
|
}
|
|
1062
1092
|
return agents;
|
|
@@ -1161,7 +1191,8 @@ async function loadPluginSkills(pluginDir) {
|
|
|
1161
1191
|
|
|
1162
1192
|
// src/cli/lib/loading/source-loader.ts
|
|
1163
1193
|
init_esm_shims();
|
|
1164
|
-
import
|
|
1194
|
+
import os6 from "os";
|
|
1195
|
+
import path22 from "path";
|
|
1165
1196
|
import { unique as unique4 } from "remeda";
|
|
1166
1197
|
|
|
1167
1198
|
// src/cli/lib/metadata-keys.ts
|
|
@@ -1293,6 +1324,10 @@ async function writeContentHash(pluginDir, contentHash, getManifestPath) {
|
|
|
1293
1324
|
|
|
1294
1325
|
// src/cli/lib/skills/skill-metadata.ts
|
|
1295
1326
|
async function readForkedFromMetadata(skillDir) {
|
|
1327
|
+
const metadata = await readLocalSkillMetadata(skillDir);
|
|
1328
|
+
return metadata?.forkedFrom ?? null;
|
|
1329
|
+
}
|
|
1330
|
+
async function readLocalSkillMetadata(skillDir) {
|
|
1296
1331
|
const metadataPath = path7.join(skillDir, STANDARD_FILES.METADATA_YAML);
|
|
1297
1332
|
if (!await fileExists(metadataPath)) {
|
|
1298
1333
|
return null;
|
|
@@ -1303,7 +1338,7 @@ async function readForkedFromMetadata(skillDir) {
|
|
|
1303
1338
|
warn(`Invalid metadata.yaml at ${metadataPath}: ${formatZodErrors(result.error.issues)}`);
|
|
1304
1339
|
return null;
|
|
1305
1340
|
}
|
|
1306
|
-
return result.data
|
|
1341
|
+
return result.data;
|
|
1307
1342
|
}
|
|
1308
1343
|
async function getLocalSkillsWithMetadata(projectDir) {
|
|
1309
1344
|
const localSkillsPath = path7.join(projectDir, LOCAL_SKILLS_PATH);
|
|
@@ -1476,8 +1511,8 @@ async function copySkillsToLocalFlattened(selectedSkillIds, localSkillsDir, matr
|
|
|
1476
1511
|
|
|
1477
1512
|
// src/cli/lib/skills/skill-plugin-compiler.ts
|
|
1478
1513
|
init_esm_shims();
|
|
1479
|
-
import
|
|
1480
|
-
import { parse as
|
|
1514
|
+
import path18 from "path";
|
|
1515
|
+
import { parse as parseYaml7 } from "yaml";
|
|
1481
1516
|
|
|
1482
1517
|
// src/cli/lib/plugins/index.ts
|
|
1483
1518
|
init_esm_shims();
|
|
@@ -1584,19 +1619,21 @@ init_esm_shims();
|
|
|
1584
1619
|
|
|
1585
1620
|
// src/cli/lib/installation/installation.ts
|
|
1586
1621
|
init_esm_shims();
|
|
1622
|
+
import os4 from "os";
|
|
1587
1623
|
import path11 from "path";
|
|
1588
|
-
async function
|
|
1624
|
+
async function detectProjectInstallation(projectDir) {
|
|
1589
1625
|
const srcConfigPath = path11.join(projectDir, CLAUDE_SRC_DIR, STANDARD_FILES.CONFIG_YAML);
|
|
1590
1626
|
const legacyConfigPath = path11.join(projectDir, CLAUDE_DIR, STANDARD_FILES.CONFIG_YAML);
|
|
1591
1627
|
const localConfigPath = await fileExists(srcConfigPath) ? srcConfigPath : await fileExists(legacyConfigPath) ? legacyConfigPath : null;
|
|
1592
1628
|
if (!localConfigPath) {
|
|
1593
1629
|
return null;
|
|
1594
1630
|
}
|
|
1595
|
-
const loaded = await
|
|
1631
|
+
const loaded = await loadProjectConfigFromDir(projectDir);
|
|
1596
1632
|
const mode = loaded?.config?.installMode ?? "local";
|
|
1597
1633
|
if (mode === "local") {
|
|
1598
1634
|
return {
|
|
1599
1635
|
mode: "local",
|
|
1636
|
+
scope: "project",
|
|
1600
1637
|
configPath: localConfigPath,
|
|
1601
1638
|
agentsDir: path11.join(projectDir, CLAUDE_DIR, "agents"),
|
|
1602
1639
|
skillsDir: path11.join(projectDir, CLAUDE_DIR, "skills"),
|
|
@@ -1605,12 +1642,45 @@ async function detectInstallation(projectDir = process.cwd()) {
|
|
|
1605
1642
|
}
|
|
1606
1643
|
return {
|
|
1607
1644
|
mode: "plugin",
|
|
1645
|
+
scope: "project",
|
|
1608
1646
|
configPath: localConfigPath,
|
|
1609
1647
|
agentsDir: path11.join(projectDir, CLAUDE_DIR, "agents"),
|
|
1610
1648
|
skillsDir: path11.join(projectDir, CLAUDE_DIR, PLUGINS_SUBDIR),
|
|
1611
1649
|
projectDir
|
|
1612
1650
|
};
|
|
1613
1651
|
}
|
|
1652
|
+
async function detectGlobalInstallation() {
|
|
1653
|
+
const homeDir = os4.homedir();
|
|
1654
|
+
const srcConfigPath = path11.join(homeDir, CLAUDE_SRC_DIR, STANDARD_FILES.CONFIG_YAML);
|
|
1655
|
+
if (!await fileExists(srcConfigPath)) {
|
|
1656
|
+
return null;
|
|
1657
|
+
}
|
|
1658
|
+
const loaded = await loadProjectConfigFromDir(homeDir);
|
|
1659
|
+
const mode = loaded?.config?.installMode ?? "local";
|
|
1660
|
+
if (mode === "local") {
|
|
1661
|
+
return {
|
|
1662
|
+
mode: "local",
|
|
1663
|
+
scope: "global",
|
|
1664
|
+
configPath: srcConfigPath,
|
|
1665
|
+
agentsDir: path11.join(homeDir, CLAUDE_DIR, "agents"),
|
|
1666
|
+
skillsDir: path11.join(homeDir, CLAUDE_DIR, "skills"),
|
|
1667
|
+
projectDir: homeDir
|
|
1668
|
+
};
|
|
1669
|
+
}
|
|
1670
|
+
return {
|
|
1671
|
+
mode: "plugin",
|
|
1672
|
+
scope: "global",
|
|
1673
|
+
configPath: srcConfigPath,
|
|
1674
|
+
agentsDir: path11.join(homeDir, CLAUDE_DIR, "agents"),
|
|
1675
|
+
skillsDir: path11.join(homeDir, CLAUDE_DIR, PLUGINS_SUBDIR),
|
|
1676
|
+
projectDir: homeDir
|
|
1677
|
+
};
|
|
1678
|
+
}
|
|
1679
|
+
async function detectInstallation(projectDir = process.cwd()) {
|
|
1680
|
+
const projectInstallation = await detectProjectInstallation(projectDir);
|
|
1681
|
+
if (projectInstallation) return projectInstallation;
|
|
1682
|
+
return detectGlobalInstallation();
|
|
1683
|
+
}
|
|
1614
1684
|
|
|
1615
1685
|
// src/cli/lib/installation/local-installer.ts
|
|
1616
1686
|
init_esm_shims();
|
|
@@ -1686,7 +1756,7 @@ async function resolveAgents(agents, skills, compileConfig, _projectRoot, stack)
|
|
|
1686
1756
|
const availableAgents = typedKeys(agents);
|
|
1687
1757
|
const agentList = availableAgents.length > 0 ? `Available agents: ${availableAgents.slice(0, 5).join(", ")}${availableAgents.length > 5 ? ` (and ${availableAgents.length - 5} more)` : ""}` : "No agents found in scanned directories";
|
|
1688
1758
|
throw new Error(
|
|
1689
|
-
`Agent '${agentName}' referenced in compile config but not found in scanned agents. ${agentList}. Check that src/agents/${agentName}/
|
|
1759
|
+
`Agent '${agentName}' referenced in compile config but not found in scanned agents. ${agentList}. Check that src/agents/${agentName}/metadata.yaml exists.`
|
|
1690
1760
|
);
|
|
1691
1761
|
}
|
|
1692
1762
|
const agentConfig = compileConfig.agents[agentName];
|
|
@@ -2183,9 +2253,6 @@ async function buildLocalConfig(wizardResult, sourceResult) {
|
|
|
2183
2253
|
}
|
|
2184
2254
|
function setConfigMetadata(config, wizardResult, sourceResult, sourceFlag) {
|
|
2185
2255
|
config.installMode = wizardResult.installMode;
|
|
2186
|
-
if (wizardResult.expertMode) {
|
|
2187
|
-
config.expertMode = true;
|
|
2188
|
-
}
|
|
2189
2256
|
if (wizardResult.selectedDomains && wizardResult.selectedDomains.length > 0) {
|
|
2190
2257
|
config.domains = wizardResult.selectedDomains;
|
|
2191
2258
|
}
|
|
@@ -2362,7 +2429,7 @@ init_esm_shims();
|
|
|
2362
2429
|
// src/cli/lib/plugins/plugin-settings.ts
|
|
2363
2430
|
init_esm_shims();
|
|
2364
2431
|
import path15 from "path";
|
|
2365
|
-
import
|
|
2432
|
+
import os5 from "os";
|
|
2366
2433
|
import { z } from "zod";
|
|
2367
2434
|
var pluginSettingsSchema = z.object({
|
|
2368
2435
|
enabledPlugins: z.record(z.string(), z.unknown()).optional()
|
|
@@ -2413,7 +2480,7 @@ async function resolvePluginInstallPaths(pluginKeys, projectDir) {
|
|
|
2413
2480
|
if (pluginKeys.length === 0) {
|
|
2414
2481
|
return [];
|
|
2415
2482
|
}
|
|
2416
|
-
const registryPath = path15.join(
|
|
2483
|
+
const registryPath = path15.join(os5.homedir(), CLAUDE_DIR, PLUGINS_SUBDIR, INSTALLED_PLUGINS_FILE);
|
|
2417
2484
|
if (!await fileExists(registryPath)) {
|
|
2418
2485
|
verbose(`Plugin registry not found at '${registryPath}'`);
|
|
2419
2486
|
return [];
|
|
@@ -2588,9 +2655,221 @@ function formatInstallationDisplay(info) {
|
|
|
2588
2655
|
// src/cli/lib/plugins/plugin-validator.ts
|
|
2589
2656
|
init_esm_shims();
|
|
2590
2657
|
import { z as z2 } from "zod";
|
|
2658
|
+
import path17 from "path";
|
|
2659
|
+
import fg2 from "fast-glob";
|
|
2660
|
+
import { countBy } from "remeda";
|
|
2661
|
+
|
|
2662
|
+
// src/cli/lib/schema-validator.ts
|
|
2663
|
+
init_esm_shims();
|
|
2664
|
+
import { sumBy } from "remeda";
|
|
2591
2665
|
import path16 from "path";
|
|
2666
|
+
import { parse as parseYaml6 } from "yaml";
|
|
2592
2667
|
import fg from "fast-glob";
|
|
2593
|
-
|
|
2668
|
+
var VALIDATION_TARGETS = [
|
|
2669
|
+
{
|
|
2670
|
+
name: "Skill Categories",
|
|
2671
|
+
schema: skillCategoriesFileSchema,
|
|
2672
|
+
pattern: STANDARD_FILES.SKILL_CATEGORIES_YAML,
|
|
2673
|
+
baseDir: "config"
|
|
2674
|
+
},
|
|
2675
|
+
{
|
|
2676
|
+
name: "Skill Rules",
|
|
2677
|
+
schema: skillRulesFileSchema,
|
|
2678
|
+
pattern: STANDARD_FILES.SKILL_RULES_YAML,
|
|
2679
|
+
baseDir: "config"
|
|
2680
|
+
},
|
|
2681
|
+
{
|
|
2682
|
+
name: "Skill Metadata",
|
|
2683
|
+
schema: metadataValidationSchema,
|
|
2684
|
+
pattern: `**/${STANDARD_FILES.METADATA_YAML}`,
|
|
2685
|
+
baseDir: "src/skills"
|
|
2686
|
+
},
|
|
2687
|
+
{
|
|
2688
|
+
name: "Stack Skill Metadata",
|
|
2689
|
+
schema: metadataValidationSchema,
|
|
2690
|
+
pattern: `**/skills/**/${STANDARD_FILES.METADATA_YAML}`,
|
|
2691
|
+
baseDir: "src/stacks"
|
|
2692
|
+
},
|
|
2693
|
+
{
|
|
2694
|
+
name: "Stack Config",
|
|
2695
|
+
schema: stackConfigValidationSchema,
|
|
2696
|
+
pattern: `*/${STANDARD_FILES.CONFIG_YAML}`,
|
|
2697
|
+
baseDir: "src/stacks"
|
|
2698
|
+
},
|
|
2699
|
+
{
|
|
2700
|
+
name: "Agent Definition",
|
|
2701
|
+
schema: agentYamlGenerationSchema,
|
|
2702
|
+
pattern: `**/${STANDARD_FILES.AGENT_METADATA_YAML}`,
|
|
2703
|
+
baseDir: "src/agents"
|
|
2704
|
+
},
|
|
2705
|
+
{
|
|
2706
|
+
name: "Skill Frontmatter",
|
|
2707
|
+
schema: skillFrontmatterValidationSchema,
|
|
2708
|
+
pattern: `**/${STANDARD_FILES.SKILL_MD}`,
|
|
2709
|
+
baseDir: "src/skills",
|
|
2710
|
+
extractor: extractFrontmatter
|
|
2711
|
+
},
|
|
2712
|
+
{
|
|
2713
|
+
name: "Stack Skill Frontmatter",
|
|
2714
|
+
schema: skillFrontmatterValidationSchema,
|
|
2715
|
+
pattern: `**/skills/**/${STANDARD_FILES.SKILL_MD}`,
|
|
2716
|
+
baseDir: "src/stacks",
|
|
2717
|
+
extractor: extractFrontmatter
|
|
2718
|
+
},
|
|
2719
|
+
{
|
|
2720
|
+
name: "Stacks Config",
|
|
2721
|
+
schema: stacksConfigSchema,
|
|
2722
|
+
pattern: "stacks.yaml",
|
|
2723
|
+
baseDir: "config"
|
|
2724
|
+
},
|
|
2725
|
+
{
|
|
2726
|
+
name: "Project Source Config",
|
|
2727
|
+
schema: projectSourceConfigSchema,
|
|
2728
|
+
pattern: STANDARD_FILES.CONFIG_YAML,
|
|
2729
|
+
baseDir: CLAUDE_SRC_DIR
|
|
2730
|
+
},
|
|
2731
|
+
{
|
|
2732
|
+
name: "Project Skill Metadata",
|
|
2733
|
+
schema: metadataValidationSchema,
|
|
2734
|
+
pattern: `*/${STANDARD_FILES.METADATA_YAML}`,
|
|
2735
|
+
baseDir: `${CLAUDE_DIR}/skills`
|
|
2736
|
+
},
|
|
2737
|
+
{
|
|
2738
|
+
name: "Project Skill Frontmatter",
|
|
2739
|
+
schema: skillFrontmatterValidationSchema,
|
|
2740
|
+
pattern: `*/${STANDARD_FILES.SKILL_MD}`,
|
|
2741
|
+
baseDir: `${CLAUDE_DIR}/skills`,
|
|
2742
|
+
extractor: extractFrontmatter
|
|
2743
|
+
},
|
|
2744
|
+
{
|
|
2745
|
+
name: "Project Agent Frontmatter",
|
|
2746
|
+
schema: agentFrontmatterValidationSchema,
|
|
2747
|
+
pattern: "*.md",
|
|
2748
|
+
baseDir: `${CLAUDE_DIR}/agents`,
|
|
2749
|
+
extractor: extractFrontmatter
|
|
2750
|
+
},
|
|
2751
|
+
{
|
|
2752
|
+
name: "Plugin Manifest",
|
|
2753
|
+
schema: pluginManifestSchema,
|
|
2754
|
+
pattern: `*/${STANDARD_FILES.PLUGIN_JSON}`,
|
|
2755
|
+
baseDir: `${CLAUDE_DIR}/plugins`,
|
|
2756
|
+
extractor: (content) => JSON.parse(content)
|
|
2757
|
+
}
|
|
2758
|
+
];
|
|
2759
|
+
function formatZodErrors2(error) {
|
|
2760
|
+
return error.issues.map((issue) => {
|
|
2761
|
+
const path24 = issue.path.join(".");
|
|
2762
|
+
if (issue.code === "unrecognized_keys") {
|
|
2763
|
+
return `Unrecognized key: "${issue.keys.join('", "')}"`;
|
|
2764
|
+
}
|
|
2765
|
+
return path24 ? `${path24}: ${issue.message}` : issue.message;
|
|
2766
|
+
});
|
|
2767
|
+
}
|
|
2768
|
+
async function validateFile(filePath, schema, extractor) {
|
|
2769
|
+
try {
|
|
2770
|
+
if (!await fileExists(filePath)) {
|
|
2771
|
+
return { valid: false, errors: [`File not found: ${filePath}`] };
|
|
2772
|
+
}
|
|
2773
|
+
const content = await readFile(filePath);
|
|
2774
|
+
let parsed;
|
|
2775
|
+
if (extractor) {
|
|
2776
|
+
parsed = extractor(content);
|
|
2777
|
+
if (parsed === null) {
|
|
2778
|
+
return {
|
|
2779
|
+
valid: false,
|
|
2780
|
+
errors: ["Failed to extract content (no valid frontmatter found)"]
|
|
2781
|
+
};
|
|
2782
|
+
}
|
|
2783
|
+
} else {
|
|
2784
|
+
parsed = parseYaml6(content);
|
|
2785
|
+
}
|
|
2786
|
+
const result = schema.safeParse(parsed);
|
|
2787
|
+
if (result.success) {
|
|
2788
|
+
return { valid: true, errors: [] };
|
|
2789
|
+
}
|
|
2790
|
+
return { valid: false, errors: formatZodErrors2(result.error) };
|
|
2791
|
+
} catch (error) {
|
|
2792
|
+
const message = getErrorMessage(error);
|
|
2793
|
+
return { valid: false, errors: [`Failed to parse content: ${message}`] };
|
|
2794
|
+
}
|
|
2795
|
+
}
|
|
2796
|
+
async function validateTarget(target, rootDir = process.cwd()) {
|
|
2797
|
+
const baseDir = path16.join(rootDir, target.baseDir);
|
|
2798
|
+
const pattern = path16.join(baseDir, target.pattern);
|
|
2799
|
+
const files = await fg(pattern, { absolute: true });
|
|
2800
|
+
const result = {
|
|
2801
|
+
schemaName: target.name,
|
|
2802
|
+
valid: true,
|
|
2803
|
+
totalFiles: files.length,
|
|
2804
|
+
validFiles: 0,
|
|
2805
|
+
invalidFiles: []
|
|
2806
|
+
};
|
|
2807
|
+
if (files.length === 0) {
|
|
2808
|
+
return result;
|
|
2809
|
+
}
|
|
2810
|
+
for (const file of files) {
|
|
2811
|
+
const validation = await validateFile(file, target.schema, target.extractor);
|
|
2812
|
+
const relativePath = path16.relative(rootDir, file);
|
|
2813
|
+
if (validation.valid) {
|
|
2814
|
+
result.validFiles++;
|
|
2815
|
+
} else {
|
|
2816
|
+
result.valid = false;
|
|
2817
|
+
result.invalidFiles.push({
|
|
2818
|
+
file: relativePath,
|
|
2819
|
+
errors: validation.errors
|
|
2820
|
+
});
|
|
2821
|
+
}
|
|
2822
|
+
}
|
|
2823
|
+
return result;
|
|
2824
|
+
}
|
|
2825
|
+
async function validateAllSchemas(rootDir = process.cwd()) {
|
|
2826
|
+
const results = [];
|
|
2827
|
+
for (const target of VALIDATION_TARGETS) {
|
|
2828
|
+
const result = await validateTarget(target, rootDir);
|
|
2829
|
+
results.push(result);
|
|
2830
|
+
}
|
|
2831
|
+
const summary = {
|
|
2832
|
+
totalSchemas: results.length,
|
|
2833
|
+
totalFiles: sumBy(results, (r) => r.totalFiles),
|
|
2834
|
+
validFiles: sumBy(results, (r) => r.validFiles),
|
|
2835
|
+
invalidFiles: sumBy(results, (r) => r.invalidFiles.length)
|
|
2836
|
+
};
|
|
2837
|
+
return {
|
|
2838
|
+
valid: results.every((r) => r.valid),
|
|
2839
|
+
results,
|
|
2840
|
+
summary
|
|
2841
|
+
};
|
|
2842
|
+
}
|
|
2843
|
+
function printValidationResults(result) {
|
|
2844
|
+
log("\n Schema Validation Summary:");
|
|
2845
|
+
log(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
2846
|
+
log(` Total schemas checked: ${result.summary.totalSchemas}`);
|
|
2847
|
+
log(` Total files: ${result.summary.totalFiles}`);
|
|
2848
|
+
log(` Valid: ${result.summary.validFiles}`);
|
|
2849
|
+
log(` Invalid: ${result.summary.invalidFiles}`);
|
|
2850
|
+
for (const schemaResult of result.results) {
|
|
2851
|
+
if (schemaResult.totalFiles === 0) continue;
|
|
2852
|
+
const status = schemaResult.valid ? "\u2713" : "\u2717";
|
|
2853
|
+
log(
|
|
2854
|
+
`
|
|
2855
|
+
${status} ${schemaResult.schemaName}: ${schemaResult.validFiles}/${schemaResult.totalFiles} valid`
|
|
2856
|
+
);
|
|
2857
|
+
if (schemaResult.invalidFiles.length > 0) {
|
|
2858
|
+
for (const file of schemaResult.invalidFiles) {
|
|
2859
|
+
log(`
|
|
2860
|
+
${file.file}:`);
|
|
2861
|
+
file.errors.forEach((e) => log(` - ${e}`));
|
|
2862
|
+
}
|
|
2863
|
+
}
|
|
2864
|
+
}
|
|
2865
|
+
if (result.valid) {
|
|
2866
|
+
log("\n \u2713 All schemas validated successfully\n");
|
|
2867
|
+
} else {
|
|
2868
|
+
log("\n \u2717 Validation failed\n");
|
|
2869
|
+
}
|
|
2870
|
+
}
|
|
2871
|
+
|
|
2872
|
+
// src/cli/lib/plugins/plugin-validator.ts
|
|
2594
2873
|
var PLUGIN_DIR = PLUGIN_MANIFEST_DIR;
|
|
2595
2874
|
var PLUGIN_MANIFEST = STANDARD_FILES.PLUGIN_JSON;
|
|
2596
2875
|
var KEBAB_CASE_REGEX = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
|
|
@@ -2606,15 +2885,6 @@ var pluginManifestValidationSchema = z2.object({
|
|
|
2606
2885
|
skills: z2.union([z2.string(), z2.array(z2.string())]).optional(),
|
|
2607
2886
|
hooks: z2.union([z2.string(), hooksRecordSchema]).optional()
|
|
2608
2887
|
}).strict();
|
|
2609
|
-
function formatZodErrors2(error) {
|
|
2610
|
-
return error.issues.map((issue) => {
|
|
2611
|
-
const path23 = issue.path.join(".");
|
|
2612
|
-
if (issue.code === "unrecognized_keys") {
|
|
2613
|
-
return `Unrecognized key: "${issue.keys.join('", "')}"`;
|
|
2614
|
-
}
|
|
2615
|
-
return path23 ? `${path23}: ${issue.message}` : issue.message;
|
|
2616
|
-
});
|
|
2617
|
-
}
|
|
2618
2888
|
function isKebabCase(str) {
|
|
2619
2889
|
return KEBAB_CASE_REGEX.test(str);
|
|
2620
2890
|
}
|
|
@@ -2631,15 +2901,15 @@ async function validatePluginStructure(pluginPath) {
|
|
|
2631
2901
|
warnings: []
|
|
2632
2902
|
};
|
|
2633
2903
|
}
|
|
2634
|
-
const pluginDir =
|
|
2904
|
+
const pluginDir = path17.join(pluginPath, PLUGIN_DIR);
|
|
2635
2905
|
if (!await directoryExists(pluginDir)) {
|
|
2636
2906
|
errors.push(`Missing ${PLUGIN_DIR}/ directory`);
|
|
2637
2907
|
}
|
|
2638
|
-
const manifestPath =
|
|
2908
|
+
const manifestPath = path17.join(pluginDir, PLUGIN_MANIFEST);
|
|
2639
2909
|
if (!await fileExists(manifestPath)) {
|
|
2640
2910
|
errors.push(`Missing ${PLUGIN_DIR}/${PLUGIN_MANIFEST}`);
|
|
2641
2911
|
}
|
|
2642
|
-
const readmePath =
|
|
2912
|
+
const readmePath = path17.join(pluginPath, "README.md");
|
|
2643
2913
|
if (!await fileExists(readmePath)) {
|
|
2644
2914
|
warnings.push("Missing README.md (recommended for documentation)");
|
|
2645
2915
|
}
|
|
@@ -2689,15 +2959,15 @@ async function validatePluginManifest(manifestPath) {
|
|
|
2689
2959
|
if (!manifest.description) {
|
|
2690
2960
|
warnings.push("Missing description field (recommended for discoverability)");
|
|
2691
2961
|
}
|
|
2692
|
-
const pluginDir =
|
|
2962
|
+
const pluginDir = path17.dirname(path17.dirname(manifestPath));
|
|
2693
2963
|
if (manifest.skills && typeof manifest.skills === "string") {
|
|
2694
|
-
const skillsPath =
|
|
2964
|
+
const skillsPath = path17.join(pluginDir, manifest.skills);
|
|
2695
2965
|
if (!await directoryExists(skillsPath)) {
|
|
2696
2966
|
errors.push(`Skills path does not exist: ${manifest.skills}`);
|
|
2697
2967
|
}
|
|
2698
2968
|
}
|
|
2699
2969
|
if (manifest.agents && typeof manifest.agents === "string") {
|
|
2700
|
-
const agentsPath =
|
|
2970
|
+
const agentsPath = path17.join(pluginDir, manifest.agents);
|
|
2701
2971
|
if (!await directoryExists(agentsPath)) {
|
|
2702
2972
|
errors.push(`Agents path does not exist: ${manifest.agents}`);
|
|
2703
2973
|
}
|
|
@@ -2786,9 +3056,9 @@ function prefixResult(result, prefix) {
|
|
|
2786
3056
|
};
|
|
2787
3057
|
}
|
|
2788
3058
|
async function validatePluginSkillFiles(pluginPath, skillsRelPath) {
|
|
2789
|
-
const skillsDir =
|
|
3059
|
+
const skillsDir = path17.join(pluginPath, skillsRelPath);
|
|
2790
3060
|
if (!await directoryExists(skillsDir)) return EMPTY_RESULT;
|
|
2791
|
-
const files = await
|
|
3061
|
+
const files = await fg2("**/SKILL.md", { cwd: skillsDir, absolute: true });
|
|
2792
3062
|
if (files.length === 0) {
|
|
2793
3063
|
return {
|
|
2794
3064
|
valid: true,
|
|
@@ -2798,15 +3068,15 @@ async function validatePluginSkillFiles(pluginPath, skillsRelPath) {
|
|
|
2798
3068
|
}
|
|
2799
3069
|
const results = await Promise.all(
|
|
2800
3070
|
files.map(
|
|
2801
|
-
async (f) => prefixResult(await validateSkillFrontmatter(f),
|
|
3071
|
+
async (f) => prefixResult(await validateSkillFrontmatter(f), path17.relative(pluginPath, f))
|
|
2802
3072
|
)
|
|
2803
3073
|
);
|
|
2804
3074
|
return mergeResults(results);
|
|
2805
3075
|
}
|
|
2806
3076
|
async function validatePluginAgentFiles(pluginPath, agentsRelPath) {
|
|
2807
|
-
const agentsDir =
|
|
3077
|
+
const agentsDir = path17.join(pluginPath, agentsRelPath);
|
|
2808
3078
|
if (!await directoryExists(agentsDir)) return EMPTY_RESULT;
|
|
2809
|
-
const files = await
|
|
3079
|
+
const files = await fg2("*.md", { cwd: agentsDir, absolute: true });
|
|
2810
3080
|
if (files.length === 0) {
|
|
2811
3081
|
return {
|
|
2812
3082
|
valid: true,
|
|
@@ -2816,7 +3086,7 @@ async function validatePluginAgentFiles(pluginPath, agentsRelPath) {
|
|
|
2816
3086
|
}
|
|
2817
3087
|
const results = await Promise.all(
|
|
2818
3088
|
files.map(
|
|
2819
|
-
async (f) => prefixResult(await validateAgentFrontmatter(f),
|
|
3089
|
+
async (f) => prefixResult(await validateAgentFrontmatter(f), path17.relative(pluginPath, f))
|
|
2820
3090
|
)
|
|
2821
3091
|
);
|
|
2822
3092
|
return mergeResults(results);
|
|
@@ -2832,7 +3102,7 @@ async function loadManifestForValidation(manifestPath) {
|
|
|
2832
3102
|
async function validatePlugin(pluginPath) {
|
|
2833
3103
|
const structureResult = await validatePluginStructure(pluginPath);
|
|
2834
3104
|
if (!structureResult.valid) return structureResult;
|
|
2835
|
-
const manifestPath =
|
|
3105
|
+
const manifestPath = path17.join(pluginPath, PLUGIN_DIR, PLUGIN_MANIFEST);
|
|
2836
3106
|
const manifestResult = await validatePluginManifest(manifestPath);
|
|
2837
3107
|
const manifest = await loadManifestForValidation(manifestPath);
|
|
2838
3108
|
const skillsResult = manifest?.skills && typeof manifest.skills === "string" ? await validatePluginSkillFiles(pluginPath, manifest.skills) : EMPTY_RESULT;
|
|
@@ -2860,7 +3130,7 @@ async function validateAllPlugins(pluginsDir) {
|
|
|
2860
3130
|
const allDirs = await listDirectories(pluginsDir);
|
|
2861
3131
|
const pluginDirs = [];
|
|
2862
3132
|
for (const dirName of allDirs) {
|
|
2863
|
-
const potentialPluginDir =
|
|
3133
|
+
const potentialPluginDir = path17.join(pluginsDir, dirName, PLUGIN_DIR);
|
|
2864
3134
|
if (await directoryExists(potentialPluginDir)) {
|
|
2865
3135
|
pluginDirs.push(dirName);
|
|
2866
3136
|
}
|
|
@@ -2884,7 +3154,7 @@ async function validateAllPlugins(pluginsDir) {
|
|
|
2884
3154
|
};
|
|
2885
3155
|
}
|
|
2886
3156
|
for (const pluginName of pluginDirs) {
|
|
2887
|
-
const pluginPath =
|
|
3157
|
+
const pluginPath = path17.join(pluginsDir, pluginName);
|
|
2888
3158
|
const result = await validatePlugin(pluginPath);
|
|
2889
3159
|
results.push({ name: pluginName, result });
|
|
2890
3160
|
}
|
|
@@ -2922,7 +3192,7 @@ function sanitizeSkillName(name) {
|
|
|
2922
3192
|
return name.replace(/\+/g, "-");
|
|
2923
3193
|
}
|
|
2924
3194
|
async function readSkillMetadata(skillPath) {
|
|
2925
|
-
const metadataPath =
|
|
3195
|
+
const metadataPath = path18.join(skillPath, STANDARD_FILES.METADATA_YAML);
|
|
2926
3196
|
if (!await fileExists(metadataPath)) {
|
|
2927
3197
|
return null;
|
|
2928
3198
|
}
|
|
@@ -2930,7 +3200,7 @@ async function readSkillMetadata(skillPath) {
|
|
|
2930
3200
|
const content = await readFile(metadataPath);
|
|
2931
3201
|
const lines = content.split("\n");
|
|
2932
3202
|
const yamlContent = lines[0]?.startsWith("# yaml-language-server:") ? lines.slice(1).join("\n") : content;
|
|
2933
|
-
const result = skillMetadataLoaderSchema.safeParse(
|
|
3203
|
+
const result = skillMetadataLoaderSchema.safeParse(parseYaml7(yamlContent));
|
|
2934
3204
|
if (!result.success) {
|
|
2935
3205
|
warn(`Invalid metadata.yaml at '${skillPath}': ${formatZodErrors(result.error.issues)}`);
|
|
2936
3206
|
return null;
|
|
@@ -2979,8 +3249,8 @@ function generateReadme(skillName, frontmatter, metadata) {
|
|
|
2979
3249
|
}
|
|
2980
3250
|
async function compileSkillPlugin(options) {
|
|
2981
3251
|
const { skillPath, outputDir, skillName: overrideName } = options;
|
|
2982
|
-
const dirBasename =
|
|
2983
|
-
const skillMdPath =
|
|
3252
|
+
const dirBasename = path18.basename(skillPath);
|
|
3253
|
+
const skillMdPath = path18.join(skillPath, STANDARD_FILES.SKILL_MD);
|
|
2984
3254
|
if (!await fileExists(skillMdPath)) {
|
|
2985
3255
|
throw new Error(
|
|
2986
3256
|
`Skill '${dirBasename}' is missing required ${STANDARD_FILES.SKILL_MD} file. Expected at: ${skillMdPath}`
|
|
@@ -2996,8 +3266,8 @@ async function compileSkillPlugin(options) {
|
|
|
2996
3266
|
const skillName = overrideName ?? sanitizeSkillName(frontmatter.name);
|
|
2997
3267
|
verbose(`Compiling skill plugin: ${skillName} from ${skillPath}`);
|
|
2998
3268
|
const metadata = await readSkillMetadata(skillPath);
|
|
2999
|
-
const pluginDir =
|
|
3000
|
-
const skillsDir =
|
|
3269
|
+
const pluginDir = path18.join(outputDir, skillName);
|
|
3270
|
+
const skillsDir = path18.join(pluginDir, "skills", skillName);
|
|
3001
3271
|
await ensureDir(pluginDir);
|
|
3002
3272
|
await ensureDir(skillsDir);
|
|
3003
3273
|
const newHash = await computeSkillFolderHash(skillPath);
|
|
@@ -3016,26 +3286,26 @@ async function compileSkillPlugin(options) {
|
|
|
3016
3286
|
await writePluginManifest(pluginDir, manifest);
|
|
3017
3287
|
await writeContentHash(pluginDir, contentHash, getPluginManifestPath);
|
|
3018
3288
|
verbose(` Wrote plugin.json for ${skillName} (v${version})`);
|
|
3019
|
-
await writeFile(
|
|
3289
|
+
await writeFile(path18.join(skillsDir, STANDARD_FILES.SKILL_MD), skillMdContent);
|
|
3020
3290
|
verbose(` Copied ${STANDARD_FILES.SKILL_MD}`);
|
|
3021
3291
|
for (const fileName of SKILL_CONTENT_FILES) {
|
|
3022
3292
|
if (fileName === STANDARD_FILES.SKILL_MD) continue;
|
|
3023
|
-
const sourcePath =
|
|
3293
|
+
const sourcePath = path18.join(skillPath, fileName);
|
|
3024
3294
|
if (await fileExists(sourcePath)) {
|
|
3025
3295
|
const content = await readFile(sourcePath);
|
|
3026
|
-
await writeFile(
|
|
3296
|
+
await writeFile(path18.join(skillsDir, fileName), content);
|
|
3027
3297
|
verbose(` Copied ${fileName}`);
|
|
3028
3298
|
}
|
|
3029
3299
|
}
|
|
3030
3300
|
for (const dirName of SKILL_CONTENT_DIRS) {
|
|
3031
|
-
const sourceDir =
|
|
3301
|
+
const sourceDir = path18.join(skillPath, dirName);
|
|
3032
3302
|
if (await fileExists(sourceDir)) {
|
|
3033
|
-
await copy(sourceDir,
|
|
3303
|
+
await copy(sourceDir, path18.join(skillsDir, dirName));
|
|
3034
3304
|
verbose(` Copied ${dirName}/`);
|
|
3035
3305
|
}
|
|
3036
3306
|
}
|
|
3037
3307
|
const readme = generateReadme(skillName, frontmatter, metadata);
|
|
3038
|
-
await writeFile(
|
|
3308
|
+
await writeFile(path18.join(pluginDir, "README.md"), readme);
|
|
3039
3309
|
verbose(" Generated README.md");
|
|
3040
3310
|
return {
|
|
3041
3311
|
pluginPath: pluginDir,
|
|
@@ -3047,7 +3317,7 @@ async function compileAllSkillPlugins(skillsDir, outputDir) {
|
|
|
3047
3317
|
const results = [];
|
|
3048
3318
|
const skillMdFiles = await glob(`**/${STANDARD_FILES.SKILL_MD}`, skillsDir);
|
|
3049
3319
|
for (const skillMdFile of skillMdFiles) {
|
|
3050
|
-
const skillPath =
|
|
3320
|
+
const skillPath = path18.join(skillsDir, path18.dirname(skillMdFile));
|
|
3051
3321
|
try {
|
|
3052
3322
|
const result = await compileSkillPlugin({
|
|
3053
3323
|
skillPath,
|
|
@@ -3057,7 +3327,7 @@ async function compileAllSkillPlugins(skillsDir, outputDir) {
|
|
|
3057
3327
|
log(` [OK] ${result.skillName}`);
|
|
3058
3328
|
} catch (error) {
|
|
3059
3329
|
const errorMessage = getErrorMessage(error);
|
|
3060
|
-
const dirBasename =
|
|
3330
|
+
const dirBasename = path18.basename(skillPath);
|
|
3061
3331
|
warn(`Failed to compile skill from '${dirBasename}': ${errorMessage}`);
|
|
3062
3332
|
}
|
|
3063
3333
|
}
|
|
@@ -3073,7 +3343,7 @@ Compiled ${results.length} skill plugins:`);
|
|
|
3073
3343
|
|
|
3074
3344
|
// src/cli/lib/skills/source-switcher.ts
|
|
3075
3345
|
init_esm_shims();
|
|
3076
|
-
import
|
|
3346
|
+
import path19 from "path";
|
|
3077
3347
|
function validateSkillId(skillId) {
|
|
3078
3348
|
if (!isValidSkillId(skillId)) {
|
|
3079
3349
|
return false;
|
|
@@ -3081,19 +3351,19 @@ function validateSkillId(skillId) {
|
|
|
3081
3351
|
return !(skillId.includes("\0") || skillId.includes("..") || skillId.includes("/") || skillId.includes("\\"));
|
|
3082
3352
|
}
|
|
3083
3353
|
function validatePathBoundary(resolvedPath, expectedParent) {
|
|
3084
|
-
const normalizedPath =
|
|
3085
|
-
const normalizedParent =
|
|
3086
|
-
return normalizedPath.startsWith(normalizedParent +
|
|
3354
|
+
const normalizedPath = path19.resolve(resolvedPath);
|
|
3355
|
+
const normalizedParent = path19.resolve(expectedParent);
|
|
3356
|
+
return normalizedPath.startsWith(normalizedParent + path19.sep);
|
|
3087
3357
|
}
|
|
3088
3358
|
async function archiveLocalSkill(projectDir, skillId) {
|
|
3089
3359
|
if (!validateSkillId(skillId)) {
|
|
3090
3360
|
warn(`Invalid skill ID for archiving: '${skillId}'`);
|
|
3091
3361
|
return;
|
|
3092
3362
|
}
|
|
3093
|
-
const skillsDir =
|
|
3094
|
-
const skillPath =
|
|
3095
|
-
const archivedDir =
|
|
3096
|
-
const archivedSkillPath =
|
|
3363
|
+
const skillsDir = path19.resolve(path19.join(projectDir, LOCAL_SKILLS_PATH));
|
|
3364
|
+
const skillPath = path19.resolve(path19.join(skillsDir, skillId));
|
|
3365
|
+
const archivedDir = path19.resolve(path19.join(skillsDir, ARCHIVED_SKILLS_DIR_NAME));
|
|
3366
|
+
const archivedSkillPath = path19.resolve(path19.join(archivedDir, skillId));
|
|
3097
3367
|
if (!validatePathBoundary(skillPath, skillsDir) || !validatePathBoundary(archivedSkillPath, archivedDir)) {
|
|
3098
3368
|
warn(`Skill ID '${skillId}' resolves outside the skills directory.`);
|
|
3099
3369
|
return;
|
|
@@ -3113,10 +3383,10 @@ async function restoreArchivedSkill(projectDir, skillId) {
|
|
|
3113
3383
|
warn(`Invalid skill ID for restoring: '${skillId}'`);
|
|
3114
3384
|
return false;
|
|
3115
3385
|
}
|
|
3116
|
-
const skillsDir =
|
|
3117
|
-
const skillPath =
|
|
3118
|
-
const archivedDir =
|
|
3119
|
-
const archivedSkillPath =
|
|
3386
|
+
const skillsDir = path19.resolve(path19.join(projectDir, LOCAL_SKILLS_PATH));
|
|
3387
|
+
const skillPath = path19.resolve(path19.join(skillsDir, skillId));
|
|
3388
|
+
const archivedDir = path19.resolve(path19.join(skillsDir, ARCHIVED_SKILLS_DIR_NAME));
|
|
3389
|
+
const archivedSkillPath = path19.resolve(path19.join(archivedDir, skillId));
|
|
3120
3390
|
if (!validatePathBoundary(skillPath, skillsDir) || !validatePathBoundary(archivedSkillPath, archivedDir)) {
|
|
3121
3391
|
warn(`Skill ID '${skillId}' resolves outside the skills directory.`);
|
|
3122
3392
|
return false;
|
|
@@ -3136,8 +3406,8 @@ init_esm_shims();
|
|
|
3136
3406
|
|
|
3137
3407
|
// src/cli/lib/matrix/matrix-loader.ts
|
|
3138
3408
|
init_esm_shims();
|
|
3139
|
-
import { parse as
|
|
3140
|
-
import
|
|
3409
|
+
import { parse as parseYaml8 } from "yaml";
|
|
3410
|
+
import path20 from "path";
|
|
3141
3411
|
import { z as z3 } from "zod";
|
|
3142
3412
|
var rawMetadataSchema = z3.object({
|
|
3143
3413
|
category: categoryPathSchema,
|
|
@@ -3168,7 +3438,7 @@ function synthesizeCategory(categoryPath, skillDomain) {
|
|
|
3168
3438
|
}
|
|
3169
3439
|
async function loadSkillCategories(configPath) {
|
|
3170
3440
|
const content = await readFile(configPath);
|
|
3171
|
-
const raw =
|
|
3441
|
+
const raw = parseYaml8(content);
|
|
3172
3442
|
const result = skillCategoriesFileSchema.safeParse(raw);
|
|
3173
3443
|
if (!result.success) {
|
|
3174
3444
|
throw new Error(
|
|
@@ -3180,7 +3450,7 @@ async function loadSkillCategories(configPath) {
|
|
|
3180
3450
|
}
|
|
3181
3451
|
async function loadSkillRules(configPath) {
|
|
3182
3452
|
const content = await readFile(configPath);
|
|
3183
|
-
const raw =
|
|
3453
|
+
const raw = parseYaml8(content);
|
|
3184
3454
|
const result = skillRulesFileSchema.safeParse(raw);
|
|
3185
3455
|
if (!result.success) {
|
|
3186
3456
|
throw new Error(
|
|
@@ -3207,15 +3477,15 @@ async function extractAllSkills(skillsDir) {
|
|
|
3207
3477
|
const skills = [];
|
|
3208
3478
|
const metadataFiles = await glob(`**/${STANDARD_FILES.METADATA_YAML}`, skillsDir);
|
|
3209
3479
|
for (const metadataFile of metadataFiles) {
|
|
3210
|
-
const skillDir =
|
|
3211
|
-
const skillMdPath =
|
|
3212
|
-
const metadataPath =
|
|
3480
|
+
const skillDir = path20.dirname(metadataFile);
|
|
3481
|
+
const skillMdPath = path20.join(skillsDir, skillDir, STANDARD_FILES.SKILL_MD);
|
|
3482
|
+
const metadataPath = path20.join(skillsDir, metadataFile);
|
|
3213
3483
|
if (!await fileExists(skillMdPath)) {
|
|
3214
3484
|
verbose(`Skipping ${metadataFile}: No ${STANDARD_FILES.SKILL_MD} found`);
|
|
3215
3485
|
continue;
|
|
3216
3486
|
}
|
|
3217
3487
|
const metadataContent = await readFile(metadataPath);
|
|
3218
|
-
const rawMetadata =
|
|
3488
|
+
const rawMetadata = parseYaml8(metadataContent);
|
|
3219
3489
|
const metadataResult = rawMetadataSchema.safeParse(rawMetadata);
|
|
3220
3490
|
if (!metadataResult.success) {
|
|
3221
3491
|
warn(
|
|
@@ -3475,26 +3745,31 @@ function initializeSelectionContext(currentSelections, matrix) {
|
|
|
3475
3745
|
const selectedSet = new Set(resolvedSelections);
|
|
3476
3746
|
return { resolvedSelections, selectedSet };
|
|
3477
3747
|
}
|
|
3478
|
-
function
|
|
3479
|
-
if (options?.expertMode) {
|
|
3480
|
-
return false;
|
|
3481
|
-
}
|
|
3748
|
+
function isDiscouraged(skillId, currentSelections, matrix) {
|
|
3482
3749
|
const fullId = resolveAlias(skillId, matrix);
|
|
3483
3750
|
const skill = matrix.skills[fullId];
|
|
3484
3751
|
if (!skill) {
|
|
3485
3752
|
return false;
|
|
3486
3753
|
}
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3754
|
+
const { resolvedSelections, selectedSet } = initializeSelectionContext(currentSelections, matrix);
|
|
3755
|
+
for (const selectedId of resolvedSelections) {
|
|
3756
|
+
const selectedSkill = matrix.skills[selectedId];
|
|
3757
|
+
if (selectedSkill?.discourages.some((d) => d.skillId === fullId)) {
|
|
3490
3758
|
return true;
|
|
3491
3759
|
}
|
|
3492
|
-
|
|
3760
|
+
if (skill.discourages.some((d) => d.skillId === selectedId)) {
|
|
3761
|
+
return true;
|
|
3762
|
+
}
|
|
3763
|
+
}
|
|
3764
|
+
for (const selectedId of resolvedSelections) {
|
|
3765
|
+
if (skill.conflictsWith.some((c) => c.skillId === selectedId)) {
|
|
3766
|
+
return true;
|
|
3767
|
+
}
|
|
3768
|
+
const selectedSkill = matrix.skills[selectedId];
|
|
3493
3769
|
if (selectedSkill?.conflictsWith.some((c) => c.skillId === fullId)) {
|
|
3494
3770
|
return true;
|
|
3495
3771
|
}
|
|
3496
3772
|
}
|
|
3497
|
-
const { selectedSet } = initializeSelectionContext(currentSelections, matrix);
|
|
3498
3773
|
for (const requirement of skill.requires) {
|
|
3499
3774
|
if (requirement.needsAny) {
|
|
3500
3775
|
const hasAny = requirement.skillIds.some((reqId) => selectedSet.has(reqId));
|
|
@@ -3510,13 +3785,26 @@ function isDisabled(skillId, currentSelections, matrix, options) {
|
|
|
3510
3785
|
}
|
|
3511
3786
|
return false;
|
|
3512
3787
|
}
|
|
3513
|
-
function
|
|
3788
|
+
function getDiscourageReason(skillId, currentSelections, matrix) {
|
|
3514
3789
|
const fullId = resolveAlias(skillId, matrix);
|
|
3515
3790
|
const skill = matrix.skills[fullId];
|
|
3516
3791
|
if (!skill) {
|
|
3517
3792
|
return void 0;
|
|
3518
3793
|
}
|
|
3519
3794
|
const { resolvedSelections, selectedSet } = initializeSelectionContext(currentSelections, matrix);
|
|
3795
|
+
for (const selectedId of resolvedSelections) {
|
|
3796
|
+
const selectedSkill = matrix.skills[selectedId];
|
|
3797
|
+
if (selectedSkill) {
|
|
3798
|
+
const discourage = selectedSkill.discourages.find((d) => d.skillId === fullId);
|
|
3799
|
+
if (discourage) {
|
|
3800
|
+
return discourage.reason;
|
|
3801
|
+
}
|
|
3802
|
+
}
|
|
3803
|
+
const reverseDiscourage = skill.discourages.find((d) => d.skillId === selectedId);
|
|
3804
|
+
if (reverseDiscourage) {
|
|
3805
|
+
return reverseDiscourage.reason;
|
|
3806
|
+
}
|
|
3807
|
+
}
|
|
3520
3808
|
for (const selectedId of resolvedSelections) {
|
|
3521
3809
|
const conflict = skill.conflictsWith.find((c) => c.skillId === selectedId);
|
|
3522
3810
|
if (conflict) {
|
|
@@ -3548,46 +3836,6 @@ function getDisableReason(skillId, currentSelections, matrix) {
|
|
|
3548
3836
|
}
|
|
3549
3837
|
return void 0;
|
|
3550
3838
|
}
|
|
3551
|
-
function isDiscouraged(skillId, currentSelections, matrix) {
|
|
3552
|
-
const fullId = resolveAlias(skillId, matrix);
|
|
3553
|
-
const skill = matrix.skills[fullId];
|
|
3554
|
-
if (!skill) {
|
|
3555
|
-
return false;
|
|
3556
|
-
}
|
|
3557
|
-
const { resolvedSelections } = initializeSelectionContext(currentSelections, matrix);
|
|
3558
|
-
for (const selectedId of resolvedSelections) {
|
|
3559
|
-
const selectedSkill = matrix.skills[selectedId];
|
|
3560
|
-
if (selectedSkill?.discourages.some((d) => d.skillId === fullId)) {
|
|
3561
|
-
return true;
|
|
3562
|
-
}
|
|
3563
|
-
if (skill.discourages.some((d) => d.skillId === selectedId)) {
|
|
3564
|
-
return true;
|
|
3565
|
-
}
|
|
3566
|
-
}
|
|
3567
|
-
return false;
|
|
3568
|
-
}
|
|
3569
|
-
function getDiscourageReason(skillId, currentSelections, matrix) {
|
|
3570
|
-
const fullId = resolveAlias(skillId, matrix);
|
|
3571
|
-
const skill = matrix.skills[fullId];
|
|
3572
|
-
if (!skill) {
|
|
3573
|
-
return void 0;
|
|
3574
|
-
}
|
|
3575
|
-
const { resolvedSelections } = initializeSelectionContext(currentSelections, matrix);
|
|
3576
|
-
for (const selectedId of resolvedSelections) {
|
|
3577
|
-
const selectedSkill = matrix.skills[selectedId];
|
|
3578
|
-
if (selectedSkill) {
|
|
3579
|
-
const discourage = selectedSkill.discourages.find((d) => d.skillId === fullId);
|
|
3580
|
-
if (discourage) {
|
|
3581
|
-
return discourage.reason;
|
|
3582
|
-
}
|
|
3583
|
-
}
|
|
3584
|
-
const reverseDiscourage = skill.discourages.find((d) => d.skillId === selectedId);
|
|
3585
|
-
if (reverseDiscourage) {
|
|
3586
|
-
return reverseDiscourage.reason;
|
|
3587
|
-
}
|
|
3588
|
-
}
|
|
3589
|
-
return void 0;
|
|
3590
|
-
}
|
|
3591
3839
|
function isRecommended(skillId, currentSelections, matrix) {
|
|
3592
3840
|
const fullId = resolveAlias(skillId, matrix);
|
|
3593
3841
|
const skill = matrix.skills[fullId];
|
|
@@ -3750,7 +3998,7 @@ function validateSelection(selections, matrix) {
|
|
|
3750
3998
|
warnings
|
|
3751
3999
|
};
|
|
3752
4000
|
}
|
|
3753
|
-
function getAvailableSkills(categoryId, currentSelections, matrix
|
|
4001
|
+
function getAvailableSkills(categoryId, currentSelections, matrix) {
|
|
3754
4002
|
const skillOptions = [];
|
|
3755
4003
|
const { selectedSet } = initializeSelectionContext(currentSelections, matrix);
|
|
3756
4004
|
for (const skill of Object.values(matrix.skills)) {
|
|
@@ -3758,15 +4006,12 @@ function getAvailableSkills(categoryId, currentSelections, matrix, options) {
|
|
|
3758
4006
|
if (skill.category !== categoryId) {
|
|
3759
4007
|
continue;
|
|
3760
4008
|
}
|
|
3761
|
-
const
|
|
3762
|
-
const
|
|
3763
|
-
const recommended = !disabled && !discouraged && isRecommended(skill.id, currentSelections, matrix);
|
|
4009
|
+
const discouraged = isDiscouraged(skill.id, currentSelections, matrix);
|
|
4010
|
+
const recommended = !discouraged && isRecommended(skill.id, currentSelections, matrix);
|
|
3764
4011
|
skillOptions.push({
|
|
3765
4012
|
id: skill.id,
|
|
3766
4013
|
displayName: skill.displayName,
|
|
3767
4014
|
description: skill.description,
|
|
3768
|
-
disabled,
|
|
3769
|
-
disabledReason: disabled ? getDisableReason(skill.id, currentSelections, matrix) : void 0,
|
|
3770
4015
|
discouraged,
|
|
3771
4016
|
discouragedReason: discouraged ? getDiscourageReason(skill.id, currentSelections, matrix) : void 0,
|
|
3772
4017
|
recommended,
|
|
@@ -3861,7 +4106,7 @@ function checkSkillRelationRefs(matrix, issues) {
|
|
|
3861
4106
|
|
|
3862
4107
|
// src/cli/lib/loading/multi-source-loader.ts
|
|
3863
4108
|
init_esm_shims();
|
|
3864
|
-
import
|
|
4109
|
+
import path21 from "path";
|
|
3865
4110
|
async function loadSkillsFromAllSources(primaryMatrix, sourceConfig, projectDir, forceRefresh = false, marketplace) {
|
|
3866
4111
|
const resolvedMarketplace = marketplace ?? sourceConfig.marketplace;
|
|
3867
4112
|
const isDefaultPublicSource = sourceConfig.source === DEFAULT_SOURCE;
|
|
@@ -3950,7 +4195,7 @@ async function tagPublicSourceSkills(matrix, forceRefresh) {
|
|
|
3950
4195
|
}
|
|
3951
4196
|
try {
|
|
3952
4197
|
const fetchResult = await fetchFromSource(DEFAULT_SOURCE, { forceRefresh });
|
|
3953
|
-
const skillsDir =
|
|
4198
|
+
const skillsDir = path21.join(fetchResult.path, SKILLS_DIR_PATH);
|
|
3954
4199
|
const publicSkills = await extractAllSkills(skillsDir);
|
|
3955
4200
|
let matchCount = 0;
|
|
3956
4201
|
for (const publicSkill of publicSkills) {
|
|
@@ -3988,7 +4233,7 @@ async function tagExtraSources(matrix, projectDir, forceRefresh) {
|
|
|
3988
4233
|
verbose(`Loading extra source: ${extraSource.name} (${extraSource.url})`);
|
|
3989
4234
|
try {
|
|
3990
4235
|
const fetchResult = await fetchFromSource(extraSource.url, { forceRefresh });
|
|
3991
|
-
const skillsDir =
|
|
4236
|
+
const skillsDir = path21.join(fetchResult.path, SKILLS_DIR_PATH);
|
|
3992
4237
|
const skills = await extractAllSkills(skillsDir);
|
|
3993
4238
|
let matchCount = 0;
|
|
3994
4239
|
for (const extractedSkill of skills) {
|
|
@@ -4031,7 +4276,7 @@ async function searchExtraSources(alias, configuredSources) {
|
|
|
4031
4276
|
for (const source of configuredSources) {
|
|
4032
4277
|
try {
|
|
4033
4278
|
const fetchResult = await fetchFromSource(source.url, { forceRefresh: false });
|
|
4034
|
-
const skillsDir =
|
|
4279
|
+
const skillsDir = path21.join(fetchResult.path, SKILLS_DIR_PATH);
|
|
4035
4280
|
const skills = await extractAllSkills(skillsDir);
|
|
4036
4281
|
for (const skill of skills) {
|
|
4037
4282
|
const segments = skill.directoryPath.split("/");
|
|
@@ -4069,7 +4314,11 @@ async function loadSkillsMatrixFromSource(options = {}) {
|
|
|
4069
4314
|
result = await loadFromRemote(source, sourceConfig, forceRefresh);
|
|
4070
4315
|
}
|
|
4071
4316
|
const resolvedProjectDir = projectDir || process.cwd();
|
|
4072
|
-
|
|
4317
|
+
let localSkillsResult = await discoverLocalSkills(resolvedProjectDir);
|
|
4318
|
+
const homeDir = os6.homedir();
|
|
4319
|
+
if ((!localSkillsResult || localSkillsResult.skills.length === 0) && resolvedProjectDir !== homeDir) {
|
|
4320
|
+
localSkillsResult = await discoverLocalSkills(homeDir);
|
|
4321
|
+
}
|
|
4073
4322
|
if (localSkillsResult && localSkillsResult.skills.length > 0) {
|
|
4074
4323
|
verbose(
|
|
4075
4324
|
`Found ${localSkillsResult.skills.length} local skill(s) in ${localSkillsResult.localSkillsPath}`
|
|
@@ -4089,7 +4338,7 @@ async function loadSkillsMatrixFromSource(options = {}) {
|
|
|
4089
4338
|
async function loadFromLocal(source, sourceConfig) {
|
|
4090
4339
|
let skillsPath;
|
|
4091
4340
|
if (isLocalSource(source)) {
|
|
4092
|
-
skillsPath =
|
|
4341
|
+
skillsPath = path22.isAbsolute(source) ? source : path22.resolve(process.cwd(), source);
|
|
4093
4342
|
} else {
|
|
4094
4343
|
skillsPath = PROJECT_ROOT;
|
|
4095
4344
|
}
|
|
@@ -4130,8 +4379,8 @@ async function loadAndMergeFromBasePath(basePath) {
|
|
|
4130
4379
|
const sourceProjectConfig = await loadProjectSourceConfig(basePath);
|
|
4131
4380
|
const skillsDirRelPath = sourceProjectConfig?.skillsDir ?? SKILLS_DIR_PATH;
|
|
4132
4381
|
const stacksRelFile = sourceProjectConfig?.stacksFile;
|
|
4133
|
-
const cliCategoriesPath =
|
|
4134
|
-
const cliRulesPath =
|
|
4382
|
+
const cliCategoriesPath = path22.join(PROJECT_ROOT, SKILL_CATEGORIES_YAML_PATH);
|
|
4383
|
+
const cliRulesPath = path22.join(PROJECT_ROOT, SKILL_RULES_YAML_PATH);
|
|
4135
4384
|
const cliCategories = await loadSkillCategories(cliCategoriesPath);
|
|
4136
4385
|
const cliRules = await loadSkillRules(cliRulesPath);
|
|
4137
4386
|
let categories = cliCategories;
|
|
@@ -4139,8 +4388,8 @@ async function loadAndMergeFromBasePath(basePath) {
|
|
|
4139
4388
|
let aliases = cliRules.aliases;
|
|
4140
4389
|
let perSkillRules = cliRules.perSkill;
|
|
4141
4390
|
await discoverAndExtendFromSource(basePath);
|
|
4142
|
-
const sourceCategoriesPath =
|
|
4143
|
-
const sourceRulesPath =
|
|
4391
|
+
const sourceCategoriesPath = path22.join(basePath, SKILL_CATEGORIES_YAML_PATH);
|
|
4392
|
+
const sourceRulesPath = path22.join(basePath, SKILL_RULES_YAML_PATH);
|
|
4144
4393
|
const hasSourceCategories = await fileExists(sourceCategoriesPath);
|
|
4145
4394
|
const hasSourceRules = await fileExists(sourceRulesPath);
|
|
4146
4395
|
if (hasSourceCategories || hasSourceRules) {
|
|
@@ -4174,7 +4423,7 @@ async function loadAndMergeFromBasePath(basePath) {
|
|
|
4174
4423
|
} else {
|
|
4175
4424
|
verbose(`Matrix from CLI only (source has no categories/rules files)`);
|
|
4176
4425
|
}
|
|
4177
|
-
const skillsDir =
|
|
4426
|
+
const skillsDir = path22.join(basePath, skillsDirRelPath);
|
|
4178
4427
|
verbose(`Skills from source: ${skillsDir}`);
|
|
4179
4428
|
const skills = await extractAllSkills(skillsDir);
|
|
4180
4429
|
const mergedMatrix = await mergeMatrixWithSkills(
|
|
@@ -4261,9 +4510,9 @@ function getMarketplaceLabel(sourceResult) {
|
|
|
4261
4510
|
}
|
|
4262
4511
|
return marketplace;
|
|
4263
4512
|
}
|
|
4264
|
-
async function discoverCustomAgentValues(agentsDir, file,
|
|
4265
|
-
const content = await readFile(
|
|
4266
|
-
const raw =
|
|
4513
|
+
async function discoverCustomAgentValues(agentsDir, file, parseYaml10, builtinDomains) {
|
|
4514
|
+
const content = await readFile(path22.join(agentsDir, file));
|
|
4515
|
+
const raw = parseYaml10(content);
|
|
4267
4516
|
if (raw?.custom !== true) return {};
|
|
4268
4517
|
const result = {};
|
|
4269
4518
|
if (typeof raw?.id === "string" && !agentNameSchema.safeParse(raw.id).success) {
|
|
@@ -4274,16 +4523,16 @@ async function discoverCustomAgentValues(agentsDir, file, parseYaml9, builtinDom
|
|
|
4274
4523
|
}
|
|
4275
4524
|
return result;
|
|
4276
4525
|
}
|
|
4277
|
-
async function discoverCustomSkillValues(skillsDir, file,
|
|
4278
|
-
const content = await readFile(
|
|
4526
|
+
async function discoverCustomSkillValues(skillsDir, file, parseYaml10, builtinSubcategories, builtinDomains) {
|
|
4527
|
+
const content = await readFile(path22.join(skillsDir, file));
|
|
4279
4528
|
const frontmatter = parseFrontmatter(content);
|
|
4280
4529
|
if (!frontmatter) return {};
|
|
4281
4530
|
const skillId = frontmatter.name;
|
|
4282
|
-
const skillDir =
|
|
4283
|
-
const metadataPath =
|
|
4531
|
+
const skillDir = path22.dirname(path22.join(skillsDir, file));
|
|
4532
|
+
const metadataPath = path22.join(skillDir, STANDARD_FILES.METADATA_YAML);
|
|
4284
4533
|
if (!await fileExists(metadataPath)) return {};
|
|
4285
4534
|
const metadataContent = await readFile(metadataPath);
|
|
4286
|
-
const metadataRaw =
|
|
4535
|
+
const metadataRaw = parseYaml10(metadataContent);
|
|
4287
4536
|
if (metadataRaw?.custom !== true) return {};
|
|
4288
4537
|
const result = {};
|
|
4289
4538
|
result.skillId = skillId;
|
|
@@ -4298,26 +4547,26 @@ async function discoverCustomSkillValues(skillsDir, file, parseYaml9, builtinSub
|
|
|
4298
4547
|
return result;
|
|
4299
4548
|
}
|
|
4300
4549
|
async function discoverAndExtendFromSource(basePath) {
|
|
4301
|
-
const { parse:
|
|
4550
|
+
const { parse: parseYaml10 } = await import("yaml");
|
|
4302
4551
|
const builtinSubcategories = new Set(SUBCATEGORY_VALUES);
|
|
4303
4552
|
const builtinDomains = new Set(DOMAIN_VALUES);
|
|
4304
4553
|
const customCategories = [];
|
|
4305
4554
|
const customDomains = [];
|
|
4306
4555
|
const customAgentNames = [];
|
|
4307
4556
|
const customSkillIds = [];
|
|
4308
|
-
const agentsDir =
|
|
4557
|
+
const agentsDir = path22.join(basePath, DIRS.agents);
|
|
4309
4558
|
if (await directoryExists(agentsDir)) {
|
|
4310
|
-
const agentFiles = await glob(`**/${STANDARD_FILES.
|
|
4559
|
+
const agentFiles = await glob(`**/${STANDARD_FILES.AGENT_METADATA_YAML}`, agentsDir);
|
|
4311
4560
|
for (const file of agentFiles) {
|
|
4312
4561
|
try {
|
|
4313
|
-
const result = await discoverCustomAgentValues(agentsDir, file,
|
|
4562
|
+
const result = await discoverCustomAgentValues(agentsDir, file, parseYaml10, builtinDomains);
|
|
4314
4563
|
if (result.agentName) customAgentNames.push(result.agentName);
|
|
4315
4564
|
if (result.domain) customDomains.push(result.domain);
|
|
4316
4565
|
} catch {
|
|
4317
4566
|
}
|
|
4318
4567
|
}
|
|
4319
4568
|
}
|
|
4320
|
-
const skillsDir =
|
|
4569
|
+
const skillsDir = path22.join(basePath, DIRS.skills);
|
|
4321
4570
|
if (await directoryExists(skillsDir)) {
|
|
4322
4571
|
const skillFiles = await glob(`**/${STANDARD_FILES.SKILL_MD}`, skillsDir);
|
|
4323
4572
|
for (const file of skillFiles) {
|
|
@@ -4325,7 +4574,7 @@ async function discoverAndExtendFromSource(basePath) {
|
|
|
4325
4574
|
const result = await discoverCustomSkillValues(
|
|
4326
4575
|
skillsDir,
|
|
4327
4576
|
file,
|
|
4328
|
-
|
|
4577
|
+
parseYaml10,
|
|
4329
4578
|
builtinSubcategories,
|
|
4330
4579
|
builtinDomains
|
|
4331
4580
|
);
|
|
@@ -4382,7 +4631,7 @@ function mergeLocalSkillsIntoMatrix(matrix, localResult) {
|
|
|
4382
4631
|
|
|
4383
4632
|
// src/cli/lib/skills/local-skill-loader.ts
|
|
4384
4633
|
async function discoverLocalSkills(projectDir) {
|
|
4385
|
-
const localSkillsPath =
|
|
4634
|
+
const localSkillsPath = path23.join(projectDir, LOCAL_SKILLS_PATH);
|
|
4386
4635
|
if (!await directoryExists(localSkillsPath)) {
|
|
4387
4636
|
verbose(`Local skills directory not found: ${localSkillsPath}`);
|
|
4388
4637
|
return null;
|
|
@@ -4402,9 +4651,9 @@ async function discoverLocalSkills(projectDir) {
|
|
|
4402
4651
|
};
|
|
4403
4652
|
}
|
|
4404
4653
|
async function extractLocalSkill(localSkillsPath, skillDirName) {
|
|
4405
|
-
const skillDir =
|
|
4406
|
-
const metadataPath =
|
|
4407
|
-
const skillMdPath =
|
|
4654
|
+
const skillDir = path23.join(localSkillsPath, skillDirName);
|
|
4655
|
+
const metadataPath = path23.join(skillDir, STANDARD_FILES.METADATA_YAML);
|
|
4656
|
+
const skillMdPath = path23.join(skillDir, STANDARD_FILES.SKILL_MD);
|
|
4408
4657
|
if (!await fileExists(metadataPath)) {
|
|
4409
4658
|
verbose(`Skipping local skill '${skillDirName}': No metadata.yaml found`);
|
|
4410
4659
|
return null;
|
|
@@ -4414,9 +4663,9 @@ async function extractLocalSkill(localSkillsPath, skillDirName) {
|
|
|
4414
4663
|
return null;
|
|
4415
4664
|
}
|
|
4416
4665
|
const metadataContent = await readFile(metadataPath);
|
|
4417
|
-
const parsed = localRawMetadataSchema.safeParse(
|
|
4666
|
+
const parsed = localRawMetadataSchema.safeParse(parseYaml9(metadataContent));
|
|
4418
4667
|
if (!parsed.success) {
|
|
4419
|
-
|
|
4668
|
+
verbose(
|
|
4420
4669
|
`Skipping local skill '${skillDirName}': invalid metadata.yaml \u2014 ${formatZodErrors(parsed.error.issues)}`
|
|
4421
4670
|
);
|
|
4422
4671
|
return null;
|
|
@@ -4430,7 +4679,7 @@ async function extractLocalSkill(localSkillsPath, skillDirName) {
|
|
|
4430
4679
|
const skillMdContent = await readFile(skillMdPath);
|
|
4431
4680
|
const frontmatter = parseFrontmatter(skillMdContent, skillMdPath);
|
|
4432
4681
|
if (!frontmatter) {
|
|
4433
|
-
|
|
4682
|
+
verbose(`Skipping local skill '${skillDirName}': invalid SKILL.md frontmatter`);
|
|
4434
4683
|
return null;
|
|
4435
4684
|
}
|
|
4436
4685
|
const relativePath = `${LOCAL_SKILLS_PATH}/${skillDirName}/`;
|
|
@@ -4590,13 +4839,16 @@ export {
|
|
|
4590
4839
|
addSource,
|
|
4591
4840
|
removeSource,
|
|
4592
4841
|
getSourceSummary,
|
|
4842
|
+
detectProjectInstallation,
|
|
4593
4843
|
detectInstallation,
|
|
4594
4844
|
installPluginConfig,
|
|
4595
4845
|
installLocal,
|
|
4596
4846
|
getInstallationInfo,
|
|
4597
4847
|
formatInstallationDisplay,
|
|
4848
|
+
validateAllSchemas,
|
|
4849
|
+
printValidationResults,
|
|
4598
4850
|
validatePlugin,
|
|
4599
4851
|
validateAllPlugins,
|
|
4600
4852
|
printPluginValidationResult
|
|
4601
4853
|
};
|
|
4602
|
-
//# sourceMappingURL=chunk-
|
|
4854
|
+
//# sourceMappingURL=chunk-HMSHB5EQ.js.map
|