@agents-inc/cli 0.74.1 → 0.74.3
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 +24 -0
- package/dist/{chunk-JWZLVWTX.js → chunk-23OJO4JS.js} +4 -4
- package/dist/{chunk-NTVY4G35.js → chunk-2NWQS7N4.js} +2 -2
- package/dist/{chunk-KTF5RKKP.js → chunk-ALCUVCY5.js} +3 -3
- package/dist/{chunk-QJUPZPXO.js → chunk-AV5KJHP2.js} +2 -2
- package/dist/{chunk-WQRFVEAA.js → chunk-DUF4UVJB.js} +2 -2
- package/dist/{chunk-ANUYSHQA.js → chunk-GJLM53PH.js} +2 -2
- package/dist/{chunk-ZCJ4YYWL.js → chunk-N2HO5IT2.js} +6 -4
- package/dist/chunk-N2HO5IT2.js.map +1 -0
- package/dist/{chunk-B7KVPY3Z.js → chunk-OLS55LVJ.js} +2 -2
- package/dist/{chunk-VOYGRNLS.js → chunk-SFZQL6DJ.js} +2 -2
- package/dist/{chunk-UFAP6GHD.js → chunk-TUILIOBW.js} +9 -9
- package/dist/{chunk-XP7BXHFG.js → chunk-UVNIFNIN.js} +2 -2
- package/dist/{chunk-ZO7C5WMJ.js → chunk-XYXDEODG.js} +3 -3
- package/dist/{chunk-ZLMKEYDF.js → chunk-ZD3U734W.js} +44 -23
- package/dist/chunk-ZD3U734W.js.map +1 -0
- package/dist/{chunk-J6SHWAS6.js → chunk-ZNXK2J6R.js} +14 -6
- package/dist/chunk-ZNXK2J6R.js.map +1 -0
- package/dist/{chunk-J5T7M2CS.js → chunk-ZWYCZ7BN.js} +2 -2
- package/dist/commands/build/plugins.js +2 -2
- package/dist/commands/build/stack.js +2 -2
- package/dist/commands/compile.js +2 -2
- package/dist/commands/config/index.js +2 -2
- package/dist/commands/config/path.js +1 -1
- package/dist/commands/config/show.js +2 -2
- package/dist/commands/diff.js +1 -1
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/edit.js +15 -13
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +1 -1
- package/dist/commands/import/skill.js +1 -1
- package/dist/commands/info.js +1 -1
- package/dist/commands/init.js +12 -12
- package/dist/commands/list.js +1 -1
- package/dist/commands/new/agent.js +2 -2
- package/dist/commands/new/marketplace.js +2 -2
- package/dist/commands/new/skill.js +2 -2
- package/dist/commands/outdated.js +1 -1
- package/dist/commands/search.js +1 -1
- package/dist/commands/uninstall.js +17 -8
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +2 -2
- package/dist/commands/validate.js +4 -2
- package/dist/commands/validate.js.map +1 -1
- package/dist/components/wizard/category-grid.test.js +2 -2
- package/dist/components/wizard/domain-selection.js +3 -3
- package/dist/components/wizard/source-grid.test.js +2 -2
- package/dist/components/wizard/stack-selection.js +3 -3
- package/dist/components/wizard/step-agents.js +3 -3
- package/dist/components/wizard/step-agents.test.js +3 -3
- package/dist/components/wizard/step-build.js +3 -3
- package/dist/components/wizard/step-build.test.js +3 -3
- package/dist/components/wizard/step-confirm.test.js +2 -2
- package/dist/components/wizard/step-settings.js +2 -2
- package/dist/components/wizard/step-settings.test.js +5 -5
- package/dist/components/wizard/step-sources.js +3 -3
- package/dist/components/wizard/step-sources.test.js +3 -3
- package/dist/components/wizard/step-stack.js +5 -5
- package/dist/components/wizard/step-stack.test.js +5 -5
- package/dist/components/wizard/wizard-layout.js +3 -3
- package/dist/components/wizard/wizard.js +11 -11
- package/dist/hooks/init.js +12 -12
- package/dist/{source-loader-RTG42MWG.js → source-loader-VTNIFSL6.js} +2 -2
- package/dist/{source-manager-NCOFHYHD.js → source-manager-FWAJVMYS.js} +2 -2
- package/dist/stores/wizard-store.js +2 -2
- package/dist/stores/wizard-store.test.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-J6SHWAS6.js.map +0 -1
- package/dist/chunk-ZCJ4YYWL.js.map +0 -1
- package/dist/chunk-ZLMKEYDF.js.map +0 -1
- package/dist/plugins/dummy-skill/.claude-plugin/.content-hash +0 -1
- package/dist/plugins/dummy-skill/.claude-plugin/plugin.json +0 -13
- /package/dist/{chunk-JWZLVWTX.js.map → chunk-23OJO4JS.js.map} +0 -0
- /package/dist/{chunk-NTVY4G35.js.map → chunk-2NWQS7N4.js.map} +0 -0
- /package/dist/{chunk-KTF5RKKP.js.map → chunk-ALCUVCY5.js.map} +0 -0
- /package/dist/{chunk-QJUPZPXO.js.map → chunk-AV5KJHP2.js.map} +0 -0
- /package/dist/{chunk-WQRFVEAA.js.map → chunk-DUF4UVJB.js.map} +0 -0
- /package/dist/{chunk-ANUYSHQA.js.map → chunk-GJLM53PH.js.map} +0 -0
- /package/dist/{chunk-B7KVPY3Z.js.map → chunk-OLS55LVJ.js.map} +0 -0
- /package/dist/{chunk-VOYGRNLS.js.map → chunk-SFZQL6DJ.js.map} +0 -0
- /package/dist/{chunk-UFAP6GHD.js.map → chunk-TUILIOBW.js.map} +0 -0
- /package/dist/{chunk-XP7BXHFG.js.map → chunk-UVNIFNIN.js.map} +0 -0
- /package/dist/{chunk-ZO7C5WMJ.js.map → chunk-XYXDEODG.js.map} +0 -0
- /package/dist/{chunk-J5T7M2CS.js.map → chunk-ZWYCZ7BN.js.map} +0 -0
- /package/dist/{source-loader-RTG42MWG.js.map → source-loader-VTNIFSL6.js.map} +0 -0
- /package/dist/{source-manager-NCOFHYHD.js.map → source-manager-FWAJVMYS.js.map} +0 -0
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
listPluginNames,
|
|
14
14
|
loadProjectSourceConfig,
|
|
15
15
|
readForkedFromMetadata
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-ZD3U734W.js";
|
|
17
17
|
import "../chunk-RRBWNEG3.js";
|
|
18
18
|
import "../chunk-EMX7PA2I.js";
|
|
19
19
|
import "../chunk-E74Q7GUE.js";
|
|
@@ -57,6 +57,10 @@ function collectConfiguredAgents(config) {
|
|
|
57
57
|
if (!config?.agents) return [];
|
|
58
58
|
return config.agents.map((a) => a.name);
|
|
59
59
|
}
|
|
60
|
+
function getCliInstalledPluginKeys(config) {
|
|
61
|
+
if (!config?.skills) return /* @__PURE__ */ new Set();
|
|
62
|
+
return new Set(config.skills.map((skill) => `${skill.id}@${skill.source}`));
|
|
63
|
+
}
|
|
60
64
|
async function detectUninstallTarget(projectDir) {
|
|
61
65
|
const pluginsDir = getProjectPluginsDir(projectDir);
|
|
62
66
|
const skillsDir = path.join(projectDir, CLAUDE_DIR, "skills");
|
|
@@ -79,9 +83,12 @@ async function detectUninstallTarget(projectDir) {
|
|
|
79
83
|
}
|
|
80
84
|
const configuredSources = collectConfiguredSources(config);
|
|
81
85
|
const configuredAgents = collectConfiguredAgents(config);
|
|
86
|
+
const cliInstalledKeys = getCliInstalledPluginKeys(config);
|
|
87
|
+
const cliPluginNames = pluginNames.filter((name) => cliInstalledKeys.has(name));
|
|
82
88
|
return {
|
|
83
|
-
hasPlugins:
|
|
89
|
+
hasPlugins: cliPluginNames.length > 0,
|
|
84
90
|
pluginNames,
|
|
91
|
+
cliPluginNames,
|
|
85
92
|
hasLocalSkills,
|
|
86
93
|
hasLocalAgents,
|
|
87
94
|
hasClaudeDir,
|
|
@@ -108,10 +115,10 @@ var UninstallConfirm = ({
|
|
|
108
115
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
109
116
|
target.hasPlugins && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
110
117
|
/* @__PURE__ */ jsx(Text, { color: CLI_COLORS.ERROR, children: " Plugins:" }),
|
|
111
|
-
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
118
|
+
target.cliPluginNames.map((name) => /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
112
119
|
" ",
|
|
113
|
-
|
|
114
|
-
] })
|
|
120
|
+
name
|
|
121
|
+
] }, name))
|
|
115
122
|
] }),
|
|
116
123
|
(target.hasLocalSkills || target.hasLocalAgents) && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
117
124
|
/* @__PURE__ */ jsx(Text, { color: CLI_COLORS.ERROR, children: " CLI-managed files:" }),
|
|
@@ -229,7 +236,9 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
229
236
|
this.log("");
|
|
230
237
|
if (target.hasPlugins) {
|
|
231
238
|
this.log(" Plugins:");
|
|
232
|
-
|
|
239
|
+
for (const pluginName of target.cliPluginNames) {
|
|
240
|
+
this.log(` ${pluginName}`);
|
|
241
|
+
}
|
|
233
242
|
}
|
|
234
243
|
if (target.hasLocalSkills || target.hasLocalAgents) {
|
|
235
244
|
this.log(" CLI-managed files:");
|
|
@@ -250,7 +259,7 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
250
259
|
this.log("Uninstalling plugins...");
|
|
251
260
|
try {
|
|
252
261
|
const cliAvailable = await isClaudeCLIAvailable();
|
|
253
|
-
for (const pluginName of target.
|
|
262
|
+
for (const pluginName of target.cliPluginNames) {
|
|
254
263
|
if (cliAvailable) {
|
|
255
264
|
try {
|
|
256
265
|
const pluginScope = projectDir === os.homedir() ? "user" : "project";
|
|
@@ -263,7 +272,7 @@ var Uninstall = class _Uninstall extends BaseCommand {
|
|
|
263
272
|
this.log(` Uninstalled plugin '${pluginName}'`);
|
|
264
273
|
}
|
|
265
274
|
this.logSuccess(
|
|
266
|
-
`Uninstalled ${target.
|
|
275
|
+
`Uninstalled ${target.cliPluginNames.length} ${target.cliPluginNames.length === 1 ? "plugin" : "plugins"}`
|
|
267
276
|
);
|
|
268
277
|
} catch (error) {
|
|
269
278
|
this.log("Plugin uninstall failed");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/commands/uninstall.tsx"],"sourcesContent":["import React from \"react\";\n\nimport { Flags } from \"@oclif/core\";\nimport { render, Box, Text, useApp } from \"ink\";\nimport path from \"path\";\nimport os from \"os\";\n\nimport { BaseCommand } from \"../base-command\";\nimport { Confirm } from \"../components/common/confirm\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport { directoryExists, listDirectories, remove } from \"../utils/fs\";\nimport { claudePluginUninstall, isClaudeCLIAvailable } from \"../utils/exec\";\nimport { listPluginNames, getProjectPluginsDir } from \"../lib/plugins\";\nimport { readForkedFromMetadata } from \"../lib/skills\";\nimport { loadProjectSourceConfig } from \"../lib/configuration/config\";\nimport type { ProjectConfig } from \"../types\";\nimport { CLAUDE_DIR, CLAUDE_SRC_DIR, CLI_COLORS, DEFAULT_BRANDING } from \"../consts\";\nimport { EXIT_CODES } from \"../lib/exit-codes\";\nimport { SUCCESS_MESSAGES, INFO_MESSAGES } from \"../utils/messages\";\n\ntype UninstallTarget = {\n hasPlugins: boolean;\n pluginNames: string[];\n hasLocalSkills: boolean;\n hasLocalAgents: boolean;\n hasClaudeDir: boolean;\n hasClaudeSrcDir: boolean;\n pluginsDir: string;\n skillsDir: string;\n agentsDir: string;\n claudeDir: string;\n claudeSrcDir: string;\n /** Resolved project source config from .claude-src/config.ts */\n config: Partial<ProjectConfig> | null;\n /** All configured source URLs (primary + extras) */\n configuredSources: string[];\n /** Agent names from the generated config (e.g., [\"web-developer\"]) */\n configuredAgents: string[];\n};\n\nfunction collectConfiguredSources(config: Partial<ProjectConfig> | null): string[] {\n if (!config) return [];\n return [\n ...(config.source ? [config.source] : []),\n ...(config.sources?.map((entry) => entry.url) ?? []),\n ];\n}\n\nfunction collectConfiguredAgents(config: Partial<ProjectConfig> | null): string[] {\n if (!config?.agents) return [];\n return config.agents.map((a) => a.name);\n}\n\nasync function detectUninstallTarget(projectDir: string): Promise<UninstallTarget> {\n const pluginsDir = getProjectPluginsDir(projectDir);\n const skillsDir = path.join(projectDir, CLAUDE_DIR, \"skills\");\n const agentsDir = path.join(projectDir, CLAUDE_DIR, \"agents\");\n const claudeDir = path.join(projectDir, CLAUDE_DIR);\n const claudeSrcDir = path.join(projectDir, CLAUDE_SRC_DIR);\n\n const [hasLocalSkills, hasLocalAgents, hasClaudeDir, hasClaudeSrcDir, config] = await Promise.all(\n [\n directoryExists(skillsDir),\n directoryExists(agentsDir),\n directoryExists(claudeDir),\n directoryExists(claudeSrcDir),\n loadProjectSourceConfig(projectDir),\n ],\n );\n\n let pluginNames: string[] = [];\n try {\n pluginNames = await listPluginNames(projectDir);\n } catch {\n // Best-effort: plugin detection may fail\n }\n\n const configuredSources = collectConfiguredSources(config);\n const configuredAgents = collectConfiguredAgents(config);\n\n return {\n hasPlugins: pluginNames.length > 0,\n pluginNames,\n hasLocalSkills,\n hasLocalAgents,\n hasClaudeDir,\n hasClaudeSrcDir,\n pluginsDir,\n skillsDir,\n agentsDir,\n claudeDir,\n claudeSrcDir,\n config,\n configuredSources,\n configuredAgents,\n };\n}\n\ntype UninstallConfirmProps = {\n target: UninstallTarget;\n removeAll: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n};\n\nconst UninstallConfirm: React.FC<UninstallConfirmProps> = ({\n target,\n removeAll,\n onConfirm,\n onCancel,\n}) => {\n const { exit } = useApp();\n\n return (\n <Box flexDirection=\"column\">\n <Text bold>The following will be removed:</Text>\n <Text> </Text>\n\n {target.hasPlugins && (\n <Box flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> Plugins:</Text>\n <Text dimColor> {target.pluginsDir}</Text>\n </Box>\n )}\n\n {(target.hasLocalSkills || target.hasLocalAgents) && (\n <Box flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> CLI-managed files:</Text>\n {target.hasLocalSkills && <Text dimColor> {target.skillsDir}/ (matching sources)</Text>}\n {target.hasLocalAgents && <Text dimColor> {target.agentsDir}/ (CLI-compiled)</Text>}\n </Box>\n )}\n\n {removeAll && target.hasClaudeSrcDir && (\n <Box flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> Config:</Text>\n <Text dimColor> {target.claudeSrcDir}/</Text>\n </Box>\n )}\n\n <Text> </Text>\n <Confirm\n message=\"Are you sure you want to uninstall?\"\n onConfirm={() => {\n onConfirm();\n exit();\n }}\n onCancel={() => {\n onCancel();\n exit();\n }}\n defaultValue={false}\n />\n </Box>\n );\n};\n\nasync function isDirectoryEmpty(dirPath: string): Promise<boolean> {\n const { readdir } = await import(\"fs/promises\");\n try {\n const allEntries = await readdir(dirPath);\n return allEntries.length === 0;\n } catch {\n return true;\n }\n}\n\nfunction skillMatchesConfiguredSource(\n forkedFromSource: string | undefined,\n configuredSources: string[],\n): boolean {\n if (!forkedFromSource || configuredSources.length === 0) return false;\n return configuredSources.includes(forkedFromSource);\n}\n\nfunction shouldRemoveSkill(\n forkedFrom: { source?: string } | null,\n configuredSources: string[],\n hasConfig: boolean,\n): boolean {\n return (\n forkedFrom !== null &&\n (skillMatchesConfiguredSource(forkedFrom.source, configuredSources) ||\n (!forkedFrom.source && hasConfig))\n );\n}\n\nexport default class Uninstall extends BaseCommand {\n static summary = `Remove ${DEFAULT_BRANDING.NAME} from this project`;\n\n static description = `Uninstall ${DEFAULT_BRANDING.NAME} from this project. Removes CLI-managed skills (matched by source), compiled agents, and plugins. User-created content is preserved.`;\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> --yes\",\n \"<%= config.bin %> <%= command.id %> --all\",\n ];\n\n static flags = {\n ...BaseCommand.baseFlags,\n yes: Flags.boolean({\n char: \"y\",\n description: \"Skip confirmation prompt\",\n default: false,\n }),\n all: Flags.boolean({\n description: \"Also remove .claude-src/ config directory\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Uninstall);\n const projectDir = process.cwd();\n\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} Uninstall`);\n this.log(\"\");\n\n const target = await detectUninstallTarget(projectDir);\n\n const hasAnythingToRemove =\n target.hasPlugins ||\n target.hasLocalSkills ||\n target.hasLocalAgents ||\n (flags.all && target.hasClaudeSrcDir);\n\n if (!hasAnythingToRemove) {\n this.warn(\"Nothing to uninstall.\");\n this.log(\"\");\n this.log(INFO_MESSAGES.NOT_INSTALLED);\n this.log(\"\");\n this.log(INFO_MESSAGES.NO_CHANGES_MADE);\n return;\n }\n\n if (!flags.yes) {\n const confirmed = await new Promise<boolean>((resolve) => {\n const { waitUntilExit } = render(\n <UninstallConfirm\n target={target}\n removeAll={flags.all}\n onConfirm={() => resolve(true)}\n onCancel={() => resolve(false)}\n />,\n );\n\n waitUntilExit().catch(() => resolve(false));\n });\n\n if (!confirmed) {\n this.log(\"\");\n this.log(\"Uninstall cancelled\");\n this.exit(EXIT_CODES.CANCELLED);\n }\n } else {\n this.log(\"The following will be removed:\");\n this.log(\"\");\n\n if (target.hasPlugins) {\n this.log(\" Plugins:\");\n this.log(` ${target.pluginsDir}`);\n }\n\n if (target.hasLocalSkills || target.hasLocalAgents) {\n this.log(\" CLI-managed files:\");\n if (target.hasLocalSkills) {\n this.log(` ${target.skillsDir}/ (matching sources)`);\n }\n if (target.hasLocalAgents) {\n this.log(` ${target.agentsDir}/ (CLI-compiled)`);\n }\n }\n\n if (flags.all && target.hasClaudeSrcDir) {\n this.log(\" Config:\");\n this.log(` ${target.claudeSrcDir}/`);\n }\n\n this.log(\"\");\n }\n\n if (target.hasPlugins) {\n this.log(\"Uninstalling plugins...\");\n\n try {\n const cliAvailable = await isClaudeCLIAvailable();\n\n for (const pluginName of target.pluginNames) {\n if (cliAvailable) {\n try {\n const pluginScope = projectDir === os.homedir() ? \"user\" : \"project\";\n await claudePluginUninstall(pluginName, pluginScope, projectDir);\n } catch {\n // Best-effort: plugin may not be registered with Claude CLI\n }\n }\n\n const pluginPath = path.join(target.pluginsDir, pluginName);\n await remove(pluginPath);\n this.log(` Uninstalled plugin '${pluginName}'`);\n }\n\n this.logSuccess(\n `Uninstalled ${target.pluginNames.length} ${target.pluginNames.length === 1 ? \"plugin\" : \"plugins\"}`,\n );\n } catch (error) {\n this.log(\"Plugin uninstall failed\");\n this.error(getErrorMessage(error), {\n exit: EXIT_CODES.ERROR,\n });\n }\n }\n\n try {\n await this.removeLocalFiles(target, flags.all);\n } catch (error) {\n this.log(\"Failed to remove local files\");\n this.error(getErrorMessage(error), {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} has been uninstalled.`);\n this.log(\"\");\n this.logSuccess(SUCCESS_MESSAGES.UNINSTALL_COMPLETE);\n this.log(\"\");\n }\n\n private async removeLocalFiles(target: UninstallTarget, removeAll: boolean): Promise<void> {\n await this.removeMatchingSkills(target);\n await this.removeMatchingAgents(target);\n\n if (removeAll && target.hasClaudeSrcDir) {\n await remove(target.claudeSrcDir);\n this.logSuccess(`Removed ${CLAUDE_SRC_DIR}/`);\n }\n\n await this.removeEmptyClaudeDir(target);\n }\n\n private async removeMatchingSkills(target: UninstallTarget): Promise<void> {\n if (!target.hasLocalSkills) return;\n\n const skillDirNames = await listDirectories(target.skillsDir);\n let removedCount = 0;\n let skippedCount = 0;\n\n for (const skillDirName of skillDirNames) {\n const skillDir = path.join(target.skillsDir, skillDirName);\n const forkedFrom = await readForkedFromMetadata(skillDir);\n\n if (shouldRemoveSkill(forkedFrom, target.configuredSources, target.config !== null)) {\n await remove(skillDir);\n removedCount++;\n this.log(` Uninstalled skill '${skillDirName}'`);\n } else {\n this.warn(`Skipping '${skillDirName}': not created by ${DEFAULT_BRANDING.NAME} CLI`);\n skippedCount++;\n }\n }\n\n if (removedCount > 0) {\n this.logSuccess(\n `Removed ${removedCount} CLI-installed ${removedCount === 1 ? \"skill\" : \"skills\"}`,\n );\n }\n\n if (skippedCount > 0) return;\n if (!(await directoryExists(target.skillsDir))) return;\n if (await isDirectoryEmpty(target.skillsDir)) {\n await remove(target.skillsDir);\n }\n }\n\n private async removeMatchingAgents(target: UninstallTarget): Promise<void> {\n if (!target.hasLocalAgents) return;\n if (target.configuredAgents.length === 0) return;\n\n const agentFiles = await this.listAgentFiles(target.agentsDir);\n let removedCount = 0;\n\n for (const agentFile of agentFiles) {\n const agentName = agentFile.replace(/\\.md$/, \"\");\n if (!target.configuredAgents.includes(agentName)) continue;\n\n await remove(path.join(target.agentsDir, agentFile));\n this.log(` Uninstalled agent '${agentName}'`);\n removedCount++;\n }\n\n if (removedCount > 0) {\n this.logSuccess(\n `Removed ${removedCount} compiled ${removedCount === 1 ? \"agent\" : \"agents\"}`,\n );\n }\n\n if (!(await directoryExists(target.agentsDir))) return;\n if (await isDirectoryEmpty(target.agentsDir)) {\n await remove(target.agentsDir);\n }\n }\n\n private async listAgentFiles(agentsDir: string): Promise<string[]> {\n try {\n const { readdir } = await import(\"fs/promises\");\n return (await readdir(agentsDir)).filter((f) => f.endsWith(\".md\"));\n } catch {\n return [];\n }\n }\n\n private async removeEmptyClaudeDir(target: UninstallTarget): Promise<void> {\n if (!target.hasClaudeDir) return;\n if (!(await directoryExists(target.claudeDir))) return;\n\n if (await isDirectoryEmpty(target.claudeDir)) {\n await remove(target.claudeDir);\n this.logSuccess(`Removed ${CLAUDE_DIR}/`);\n } else {\n this.log(`Kept ${CLAUDE_DIR}/ (contains user content)`);\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/uninstall.tsx"],"sourcesContent":["import React from \"react\";\n\nimport { Flags } from \"@oclif/core\";\nimport { render, Box, Text, useApp } from \"ink\";\nimport path from \"path\";\nimport os from \"os\";\n\nimport { BaseCommand } from \"../base-command\";\nimport { Confirm } from \"../components/common/confirm\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport { directoryExists, listDirectories, remove } from \"../utils/fs\";\nimport { claudePluginUninstall, isClaudeCLIAvailable } from \"../utils/exec\";\nimport { listPluginNames, getProjectPluginsDir } from \"../lib/plugins\";\nimport { readForkedFromMetadata } from \"../lib/skills\";\nimport { loadProjectSourceConfig } from \"../lib/configuration/config\";\nimport type { ProjectConfig } from \"../types\";\nimport { CLAUDE_DIR, CLAUDE_SRC_DIR, CLI_COLORS, DEFAULT_BRANDING } from \"../consts\";\nimport { EXIT_CODES } from \"../lib/exit-codes\";\nimport { SUCCESS_MESSAGES, INFO_MESSAGES } from \"../utils/messages\";\n\ntype UninstallTarget = {\n hasPlugins: boolean;\n pluginNames: string[];\n /** Plugin names filtered to only those installed by this CLI (matched against config skills) */\n cliPluginNames: string[];\n hasLocalSkills: boolean;\n hasLocalAgents: boolean;\n hasClaudeDir: boolean;\n hasClaudeSrcDir: boolean;\n pluginsDir: string;\n skillsDir: string;\n agentsDir: string;\n claudeDir: string;\n claudeSrcDir: string;\n /** Resolved project source config from .claude-src/config.ts */\n config: Partial<ProjectConfig> | null;\n /** All configured source URLs (primary + extras) */\n configuredSources: string[];\n /** Agent names from the generated config (e.g., [\"web-developer\"]) */\n configuredAgents: string[];\n};\n\nfunction collectConfiguredSources(config: Partial<ProjectConfig> | null): string[] {\n if (!config) return [];\n return [\n ...(config.source ? [config.source] : []),\n ...(config.sources?.map((entry) => entry.url) ?? []),\n ];\n}\n\nfunction collectConfiguredAgents(config: Partial<ProjectConfig> | null): string[] {\n if (!config?.agents) return [];\n return config.agents.map((a) => a.name);\n}\n\nfunction getCliInstalledPluginKeys(config: Partial<ProjectConfig> | null): Set<string> {\n if (!config?.skills) return new Set();\n return new Set(config.skills.map((skill) => `${skill.id}@${skill.source}`));\n}\n\nasync function detectUninstallTarget(projectDir: string): Promise<UninstallTarget> {\n const pluginsDir = getProjectPluginsDir(projectDir);\n const skillsDir = path.join(projectDir, CLAUDE_DIR, \"skills\");\n const agentsDir = path.join(projectDir, CLAUDE_DIR, \"agents\");\n const claudeDir = path.join(projectDir, CLAUDE_DIR);\n const claudeSrcDir = path.join(projectDir, CLAUDE_SRC_DIR);\n\n const [hasLocalSkills, hasLocalAgents, hasClaudeDir, hasClaudeSrcDir, config] = await Promise.all(\n [\n directoryExists(skillsDir),\n directoryExists(agentsDir),\n directoryExists(claudeDir),\n directoryExists(claudeSrcDir),\n loadProjectSourceConfig(projectDir),\n ],\n );\n\n let pluginNames: string[] = [];\n try {\n pluginNames = await listPluginNames(projectDir);\n } catch {\n // Best-effort: plugin detection may fail\n }\n\n const configuredSources = collectConfiguredSources(config);\n const configuredAgents = collectConfiguredAgents(config);\n const cliInstalledKeys = getCliInstalledPluginKeys(config);\n const cliPluginNames = pluginNames.filter((name) => cliInstalledKeys.has(name));\n\n return {\n hasPlugins: cliPluginNames.length > 0,\n pluginNames,\n cliPluginNames,\n hasLocalSkills,\n hasLocalAgents,\n hasClaudeDir,\n hasClaudeSrcDir,\n pluginsDir,\n skillsDir,\n agentsDir,\n claudeDir,\n claudeSrcDir,\n config,\n configuredSources,\n configuredAgents,\n };\n}\n\ntype UninstallConfirmProps = {\n target: UninstallTarget;\n removeAll: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n};\n\nconst UninstallConfirm: React.FC<UninstallConfirmProps> = ({\n target,\n removeAll,\n onConfirm,\n onCancel,\n}) => {\n const { exit } = useApp();\n\n return (\n <Box flexDirection=\"column\">\n <Text bold>The following will be removed:</Text>\n <Text> </Text>\n\n {target.hasPlugins && (\n <Box flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> Plugins:</Text>\n {target.cliPluginNames.map((name) => (\n <Text key={name} dimColor>\n {\" \"}\n {name}\n </Text>\n ))}\n </Box>\n )}\n\n {(target.hasLocalSkills || target.hasLocalAgents) && (\n <Box flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> CLI-managed files:</Text>\n {target.hasLocalSkills && <Text dimColor> {target.skillsDir}/ (matching sources)</Text>}\n {target.hasLocalAgents && <Text dimColor> {target.agentsDir}/ (CLI-compiled)</Text>}\n </Box>\n )}\n\n {removeAll && target.hasClaudeSrcDir && (\n <Box flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> Config:</Text>\n <Text dimColor> {target.claudeSrcDir}/</Text>\n </Box>\n )}\n\n <Text> </Text>\n <Confirm\n message=\"Are you sure you want to uninstall?\"\n onConfirm={() => {\n onConfirm();\n exit();\n }}\n onCancel={() => {\n onCancel();\n exit();\n }}\n defaultValue={false}\n />\n </Box>\n );\n};\n\nasync function isDirectoryEmpty(dirPath: string): Promise<boolean> {\n const { readdir } = await import(\"fs/promises\");\n try {\n const allEntries = await readdir(dirPath);\n return allEntries.length === 0;\n } catch {\n return true;\n }\n}\n\nfunction skillMatchesConfiguredSource(\n forkedFromSource: string | undefined,\n configuredSources: string[],\n): boolean {\n if (!forkedFromSource || configuredSources.length === 0) return false;\n return configuredSources.includes(forkedFromSource);\n}\n\nfunction shouldRemoveSkill(\n forkedFrom: { source?: string } | null,\n configuredSources: string[],\n hasConfig: boolean,\n): boolean {\n return (\n forkedFrom !== null &&\n (skillMatchesConfiguredSource(forkedFrom.source, configuredSources) ||\n (!forkedFrom.source && hasConfig))\n );\n}\n\nexport default class Uninstall extends BaseCommand {\n static summary = `Remove ${DEFAULT_BRANDING.NAME} from this project`;\n\n static description = `Uninstall ${DEFAULT_BRANDING.NAME} from this project. Removes CLI-managed skills (matched by source), compiled agents, and plugins. User-created content is preserved.`;\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> --yes\",\n \"<%= config.bin %> <%= command.id %> --all\",\n ];\n\n static flags = {\n ...BaseCommand.baseFlags,\n yes: Flags.boolean({\n char: \"y\",\n description: \"Skip confirmation prompt\",\n default: false,\n }),\n all: Flags.boolean({\n description: \"Also remove .claude-src/ config directory\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Uninstall);\n const projectDir = process.cwd();\n\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} Uninstall`);\n this.log(\"\");\n\n const target = await detectUninstallTarget(projectDir);\n\n const hasAnythingToRemove =\n target.hasPlugins ||\n target.hasLocalSkills ||\n target.hasLocalAgents ||\n (flags.all && target.hasClaudeSrcDir);\n\n if (!hasAnythingToRemove) {\n this.warn(\"Nothing to uninstall.\");\n this.log(\"\");\n this.log(INFO_MESSAGES.NOT_INSTALLED);\n this.log(\"\");\n this.log(INFO_MESSAGES.NO_CHANGES_MADE);\n return;\n }\n\n if (!flags.yes) {\n const confirmed = await new Promise<boolean>((resolve) => {\n const { waitUntilExit } = render(\n <UninstallConfirm\n target={target}\n removeAll={flags.all}\n onConfirm={() => resolve(true)}\n onCancel={() => resolve(false)}\n />,\n );\n\n waitUntilExit().catch(() => resolve(false));\n });\n\n if (!confirmed) {\n this.log(\"\");\n this.log(\"Uninstall cancelled\");\n this.exit(EXIT_CODES.CANCELLED);\n }\n } else {\n this.log(\"The following will be removed:\");\n this.log(\"\");\n\n if (target.hasPlugins) {\n this.log(\" Plugins:\");\n for (const pluginName of target.cliPluginNames) {\n this.log(` ${pluginName}`);\n }\n }\n\n if (target.hasLocalSkills || target.hasLocalAgents) {\n this.log(\" CLI-managed files:\");\n if (target.hasLocalSkills) {\n this.log(` ${target.skillsDir}/ (matching sources)`);\n }\n if (target.hasLocalAgents) {\n this.log(` ${target.agentsDir}/ (CLI-compiled)`);\n }\n }\n\n if (flags.all && target.hasClaudeSrcDir) {\n this.log(\" Config:\");\n this.log(` ${target.claudeSrcDir}/`);\n }\n\n this.log(\"\");\n }\n\n if (target.hasPlugins) {\n this.log(\"Uninstalling plugins...\");\n\n try {\n const cliAvailable = await isClaudeCLIAvailable();\n\n for (const pluginName of target.cliPluginNames) {\n if (cliAvailable) {\n try {\n const pluginScope = projectDir === os.homedir() ? \"user\" : \"project\";\n await claudePluginUninstall(pluginName, pluginScope, projectDir);\n } catch {\n // Best-effort: plugin may not be registered with Claude CLI\n }\n }\n\n const pluginPath = path.join(target.pluginsDir, pluginName);\n await remove(pluginPath);\n this.log(` Uninstalled plugin '${pluginName}'`);\n }\n\n this.logSuccess(\n `Uninstalled ${target.cliPluginNames.length} ${target.cliPluginNames.length === 1 ? \"plugin\" : \"plugins\"}`,\n );\n } catch (error) {\n this.log(\"Plugin uninstall failed\");\n this.error(getErrorMessage(error), {\n exit: EXIT_CODES.ERROR,\n });\n }\n }\n\n try {\n await this.removeLocalFiles(target, flags.all);\n } catch (error) {\n this.log(\"Failed to remove local files\");\n this.error(getErrorMessage(error), {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} has been uninstalled.`);\n this.log(\"\");\n this.logSuccess(SUCCESS_MESSAGES.UNINSTALL_COMPLETE);\n this.log(\"\");\n }\n\n private async removeLocalFiles(target: UninstallTarget, removeAll: boolean): Promise<void> {\n await this.removeMatchingSkills(target);\n await this.removeMatchingAgents(target);\n\n if (removeAll && target.hasClaudeSrcDir) {\n await remove(target.claudeSrcDir);\n this.logSuccess(`Removed ${CLAUDE_SRC_DIR}/`);\n }\n\n await this.removeEmptyClaudeDir(target);\n }\n\n private async removeMatchingSkills(target: UninstallTarget): Promise<void> {\n if (!target.hasLocalSkills) return;\n\n const skillDirNames = await listDirectories(target.skillsDir);\n let removedCount = 0;\n let skippedCount = 0;\n\n for (const skillDirName of skillDirNames) {\n const skillDir = path.join(target.skillsDir, skillDirName);\n const forkedFrom = await readForkedFromMetadata(skillDir);\n\n if (shouldRemoveSkill(forkedFrom, target.configuredSources, target.config !== null)) {\n await remove(skillDir);\n removedCount++;\n this.log(` Uninstalled skill '${skillDirName}'`);\n } else {\n this.warn(`Skipping '${skillDirName}': not created by ${DEFAULT_BRANDING.NAME} CLI`);\n skippedCount++;\n }\n }\n\n if (removedCount > 0) {\n this.logSuccess(\n `Removed ${removedCount} CLI-installed ${removedCount === 1 ? \"skill\" : \"skills\"}`,\n );\n }\n\n if (skippedCount > 0) return;\n if (!(await directoryExists(target.skillsDir))) return;\n if (await isDirectoryEmpty(target.skillsDir)) {\n await remove(target.skillsDir);\n }\n }\n\n private async removeMatchingAgents(target: UninstallTarget): Promise<void> {\n if (!target.hasLocalAgents) return;\n if (target.configuredAgents.length === 0) return;\n\n const agentFiles = await this.listAgentFiles(target.agentsDir);\n let removedCount = 0;\n\n for (const agentFile of agentFiles) {\n const agentName = agentFile.replace(/\\.md$/, \"\");\n if (!target.configuredAgents.includes(agentName)) continue;\n\n await remove(path.join(target.agentsDir, agentFile));\n this.log(` Uninstalled agent '${agentName}'`);\n removedCount++;\n }\n\n if (removedCount > 0) {\n this.logSuccess(\n `Removed ${removedCount} compiled ${removedCount === 1 ? \"agent\" : \"agents\"}`,\n );\n }\n\n if (!(await directoryExists(target.agentsDir))) return;\n if (await isDirectoryEmpty(target.agentsDir)) {\n await remove(target.agentsDir);\n }\n }\n\n private async listAgentFiles(agentsDir: string): Promise<string[]> {\n try {\n const { readdir } = await import(\"fs/promises\");\n return (await readdir(agentsDir)).filter((f) => f.endsWith(\".md\"));\n } catch {\n return [];\n }\n }\n\n private async removeEmptyClaudeDir(target: UninstallTarget): Promise<void> {\n if (!target.hasClaudeDir) return;\n if (!(await directoryExists(target.claudeDir))) return;\n\n if (await isDirectoryEmpty(target.claudeDir)) {\n await remove(target.claudeDir);\n this.logSuccess(`Removed ${CLAUDE_DIR}/`);\n } else {\n this.log(`Kept ${CLAUDE_DIR}/ (contains user content)`);\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/commands/update.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "../chunk-N6S7ZRIL.js";
|
|
5
5
|
import {
|
|
6
6
|
recompileAgents
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-ZNXK2J6R.js";
|
|
8
8
|
import {
|
|
9
9
|
ERROR_MESSAGES,
|
|
10
10
|
INFO_MESSAGES,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
compareLocalSkillsWithSource,
|
|
16
16
|
injectForkedFromMetadata,
|
|
17
17
|
loadSkillsMatrixFromSource
|
|
18
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-ZD3U734W.js";
|
|
19
19
|
import "../chunk-RRBWNEG3.js";
|
|
20
20
|
import "../chunk-EMX7PA2I.js";
|
|
21
21
|
import {
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
validateAllPlugins,
|
|
12
12
|
validateAllSchemas,
|
|
13
13
|
validatePlugin
|
|
14
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-ZD3U734W.js";
|
|
15
15
|
import {
|
|
16
16
|
parseFrontmatter
|
|
17
17
|
} from "../chunk-RRBWNEG3.js";
|
|
@@ -30,7 +30,8 @@ import {
|
|
|
30
30
|
getErrorMessage,
|
|
31
31
|
glob,
|
|
32
32
|
metadataValidationSchema,
|
|
33
|
-
readFile
|
|
33
|
+
readFile,
|
|
34
|
+
setVerbose
|
|
34
35
|
} from "../chunk-4CRWKTNQ.js";
|
|
35
36
|
import "../chunk-SRIH4U5Y.js";
|
|
36
37
|
import {
|
|
@@ -254,6 +255,7 @@ var Validate = class _Validate extends BaseCommand {
|
|
|
254
255
|
async run() {
|
|
255
256
|
const { args, flags } = await this.parse(_Validate);
|
|
256
257
|
if (flags.source) {
|
|
258
|
+
setVerbose(flags.verbose);
|
|
257
259
|
await this.validateSkillsSource(flags.source);
|
|
258
260
|
} else if (args.path || flags.plugins) {
|
|
259
261
|
await this.validatePlugins(args.path, flags.verbose, flags.all);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/commands/validate.ts","../../src/cli/lib/source-validator.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport { BaseCommand } from \"../base-command.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { ERROR_MESSAGES } from \"../utils/messages.js\";\nimport { validateAllSchemas, printValidationResults } from \"../lib/schema-validator.js\";\nimport {\n validatePlugin,\n validateAllPlugins,\n printPluginValidationResult,\n} from \"../lib/plugins/index.js\";\nimport { validateSource } from \"../lib/source-validator.js\";\n\nexport default class Validate extends BaseCommand {\n static summary =\n \"Validate YAML files against schemas, validate compiled plugins, or validate a skills source\";\n static description =\n \"Validates skill/agent YAML files against JSON schemas, validates compiled plugin structure and content, \" +\n \"or validates a skills source repository for metadata correctness. \" +\n \"Without arguments, validates all YAML files in the current directory against their schemas. \" +\n \"With --source, validates all skills in the source for schema compliance, cross-references, and conventions. \" +\n \"With a path argument or --plugins flag, validates plugin(s) instead.\";\n\n static examples = [\n {\n description: \"Validate all YAML schemas\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n {\n description: \"Validate a skills source repository\",\n command: \"<%= config.bin %> <%= command.id %> --source .\",\n },\n {\n description: \"Validate a remote skills source\",\n command: \"<%= config.bin %> <%= command.id %> --source github:acme-corp/skills\",\n },\n {\n description: \"Validate a specific plugin\",\n command: \"<%= config.bin %> <%= command.id %> ./path/to/plugin\",\n },\n {\n description: \"Validate all plugins in a directory\",\n command: \"<%= config.bin %> <%= command.id %> ./plugins --all\",\n },\n {\n description: \"Validate plugins with verbose output\",\n command: \"<%= config.bin %> <%= command.id %> --plugins --verbose\",\n },\n ];\n\n static args = {\n path: Args.string({\n description: \"Path to plugin or plugins directory to validate\",\n required: false,\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n verbose: Flags.boolean({\n char: \"v\",\n description: \"Enable verbose logging\",\n default: false,\n }),\n all: Flags.boolean({\n char: \"a\",\n description: \"Validate all plugins in directory\",\n default: false,\n }),\n plugins: Flags.boolean({\n char: \"p\",\n description: \"Validate plugins instead of schemas\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Validate);\n\n if (flags.source) {\n await this.validateSkillsSource(flags.source);\n } else if (args.path || flags.plugins) {\n await this.validatePlugins(args.path, flags.verbose, flags.all);\n } else {\n await this.validateSchemas();\n }\n }\n\n private async validateSchemas(): Promise<void> {\n this.log(\"\");\n this.log(\"Validating all schemas\");\n this.log(\"\");\n\n try {\n const result = await validateAllSchemas();\n\n const summary = result.valid\n ? `Done: ${result.summary.validFiles}/${result.summary.totalFiles} files valid`\n : `Done: ${result.summary.invalidFiles} invalid files`;\n\n this.log(summary);\n printValidationResults(result);\n\n if (!result.valid) {\n this.exit(EXIT_CODES.ERROR);\n }\n } catch (error) {\n const message = getErrorMessage(error);\n this.error(`${ERROR_MESSAGES.VALIDATION_FAILED}: ${message}`, { exit: EXIT_CODES.ERROR });\n }\n }\n\n private async validatePlugins(\n pluginPath: string | undefined,\n verbose: boolean,\n all: boolean,\n ): Promise<void> {\n const targetPath = pluginPath ? path.resolve(pluginPath) : process.cwd();\n\n if (all) {\n await this.validateAllPluginsInDirectory(targetPath, verbose);\n } else {\n await this.validateSinglePlugin(targetPath, verbose);\n }\n }\n\n private async validateAllPluginsInDirectory(targetPath: string, verbose: boolean): Promise<void> {\n this.log(\"\");\n this.log(`Validating all plugins in: ${targetPath}`);\n this.log(\"\");\n\n try {\n const result = await validateAllPlugins(targetPath);\n\n const summary = result.valid\n ? `Done: ${result.summary.valid}/${result.summary.total} plugins valid`\n : `Done: ${result.summary.invalid} invalid plugins`;\n\n this.log(summary);\n\n this.log(\"\");\n this.log(\" Plugin Validation Summary:\");\n this.log(\" -------------------------\");\n this.log(` Total plugins: ${result.summary.total}`);\n this.log(` Valid: ${result.summary.valid}`);\n this.log(` Invalid: ${result.summary.invalid}`);\n this.log(` With warnings: ${result.summary.withWarnings}`);\n\n for (const { name, result: pluginResult } of result.results) {\n printPluginValidationResult(name, pluginResult, verbose);\n }\n\n if (result.valid) {\n this.log(\"\");\n this.logSuccess(\"All plugins validated successfully\");\n this.log(\"\");\n } else {\n this.log(\"\");\n this.error(ERROR_MESSAGES.VALIDATION_FAILED, { exit: EXIT_CODES.ERROR });\n }\n } catch (error) {\n const message = getErrorMessage(error);\n this.error(`${ERROR_MESSAGES.VALIDATION_FAILED}: ${message}`, { exit: EXIT_CODES.ERROR });\n }\n }\n\n private async validateSinglePlugin(targetPath: string, _verbose: boolean): Promise<void> {\n this.log(\"\");\n this.log(`Validating plugin: ${targetPath}`);\n this.log(\"\");\n\n try {\n const result = await validatePlugin(targetPath);\n\n const summary = result.valid ? \"Done: Plugin is valid\" : \"Done: Plugin has errors\";\n\n this.log(summary);\n\n printPluginValidationResult(path.basename(targetPath), result, true);\n\n if (result.valid && result.warnings.length === 0) {\n this.log(\"\");\n this.logSuccess(\"Plugin validated successfully\");\n this.log(\"\");\n } else if (result.valid) {\n this.log(\"\");\n this.logWarning(\"Plugin valid with warnings\");\n this.log(\"\");\n } else {\n this.log(\"\");\n this.error(ERROR_MESSAGES.VALIDATION_FAILED, { exit: EXIT_CODES.ERROR });\n }\n } catch (error) {\n const message = getErrorMessage(error);\n this.error(`${ERROR_MESSAGES.VALIDATION_FAILED}: ${message}`, { exit: EXIT_CODES.ERROR });\n }\n }\n\n private async validateSkillsSource(source: string): Promise<void> {\n this.log(\"\");\n this.log(`Validating source: ${source}`);\n this.log(\"\");\n\n try {\n const result = await validateSource(source);\n\n this.log(`Checked ${result.skillCount} skill(s)`);\n this.log(\"\");\n\n for (const issue of result.issues) {\n const prefix = issue.severity === \"error\" ? \"ERROR\" : \"WARN\";\n this.log(` [${prefix}] ${issue.file}: ${issue.message}`);\n }\n\n if (result.issues.length > 0) {\n this.log(\"\");\n }\n\n this.log(`Result: ${result.errorCount} error(s), ${result.warningCount} warning(s)`);\n\n if (result.errorCount > 0) {\n this.log(\"\");\n this.error(ERROR_MESSAGES.VALIDATION_FAILED, { exit: EXIT_CODES.ERROR });\n } else if (result.warningCount > 0) {\n this.log(\"\");\n this.logWarning(\"Source valid with warnings\");\n this.log(\"\");\n } else {\n this.log(\"\");\n this.logSuccess(\"Source validated successfully\");\n this.log(\"\");\n }\n } catch (error) {\n const message = getErrorMessage(error);\n this.error(`${ERROR_MESSAGES.VALIDATION_FAILED}: ${message}`, { exit: EXIT_CODES.ERROR });\n }\n }\n}\n","import path from \"path\";\nimport { parse as parseYaml } from \"yaml\";\nimport { glob, readFile, fileExists, directoryExists } from \"../utils/fs\";\nimport { verbose } from \"../utils/logger\";\nimport { SKILL_CATEGORIES_PATH, SKILLS_DIR_PATH, STANDARD_FILES } from \"../consts\";\nimport { metadataValidationSchema, SKILL_ID_PATTERN } from \"./schemas\";\nimport { parseFrontmatter } from \"./loading/loader\";\nimport { loadProjectSourceConfig } from \"./configuration\";\nimport { checkMatrixHealth } from \"./matrix\";\nimport { loadSkillsMatrixFromSource } from \"./loading/source-loader\";\nimport { matrix } from \"./matrix/matrix-provider\";\n\nexport type SourceValidationIssue = {\n severity: \"error\" | \"warning\";\n file: string;\n message: string;\n};\n\nexport type SourceValidationResult = {\n issues: SourceValidationIssue[];\n skillCount: number;\n errorCount: number;\n warningCount: number;\n};\n\n/** Checks if a key uses snake_case (has underscore between lowercase letters) */\nfunction isSnakeCase(key: string): boolean {\n return /[a-z]_[a-z]/.test(key);\n}\n\n/**\n * Validates a skills source repository for metadata correctness.\n *\n * Checks:\n * 1. Every metadata.yaml against the strict validation schema\n * 2. displayName format and directory name consistency\n * 3. category values against known domain-prefixed patterns\n * 4. Cross-references resolve to existing skill IDs (via checkMatrixHealth)\n * 5. camelCase key convention (no snake_case)\n * 7. Every skill directory has both SKILL.md and metadata.yaml\n */\nexport async function validateSource(sourcePath: string): Promise<SourceValidationResult> {\n const issues: SourceValidationIssue[] = [];\n\n const resolvedPath = path.isAbsolute(sourcePath) ? sourcePath : path.resolve(sourcePath);\n\n if (!(await directoryExists(resolvedPath))) {\n issues.push({\n severity: \"error\",\n file: resolvedPath,\n message: \"Source directory does not exist\",\n });\n return buildResult(issues, 0);\n }\n\n const sourceProjectConfig = await loadProjectSourceConfig(resolvedPath);\n const skillsDirRelPath = sourceProjectConfig?.skillsDir ?? SKILLS_DIR_PATH;\n const skillsDir = path.join(resolvedPath, skillsDirRelPath);\n\n if (!(await directoryExists(skillsDir))) {\n issues.push({\n severity: \"error\",\n file: skillsDir,\n message: \"Skills directory does not exist\",\n });\n return buildResult(issues, 0);\n }\n\n // Phase 1: Check every skill directory has both SKILL.md and metadata.yaml\n const skillMdFiles = await glob(`**/${STANDARD_FILES.SKILL_MD}`, skillsDir);\n const metadataFiles = await glob(`**/${STANDARD_FILES.METADATA_YAML}`, skillsDir);\n\n const skillMdDirs = new Set(skillMdFiles.map((f) => path.dirname(f)));\n const metadataDirs = new Set(metadataFiles.map((f) => path.dirname(f)));\n\n // Dirs with SKILL.md but no metadata.yaml\n for (const dir of skillMdDirs) {\n if (!metadataDirs.has(dir)) {\n issues.push({\n severity: \"error\",\n file: path.join(skillsDir, dir),\n message: `Missing ${STANDARD_FILES.METADATA_YAML} — skill directory has ${STANDARD_FILES.SKILL_MD} but no metadata`,\n });\n }\n }\n\n // Dirs with metadata.yaml but no SKILL.md\n for (const dir of metadataDirs) {\n if (!skillMdDirs.has(dir)) {\n issues.push({\n severity: \"error\",\n file: path.join(skillsDir, dir),\n message: `Missing ${STANDARD_FILES.SKILL_MD} — skill directory has ${STANDARD_FILES.METADATA_YAML} but no SKILL.md`,\n });\n }\n }\n\n // Phase 2: Validate each metadata.yaml against strict schema and conventions\n let skillCount = 0;\n for (const metadataFile of metadataFiles) {\n const metadataPath = path.join(skillsDir, metadataFile);\n const skillDir = path.dirname(metadataFile);\n const skillMdPath = path.join(skillsDir, skillDir, STANDARD_FILES.SKILL_MD);\n\n if (!(await fileExists(skillMdPath))) {\n // Already reported above\n continue;\n }\n\n skillCount++;\n const relPath = path.join(skillsDirRelPath, metadataFile);\n\n // Read and parse metadata.yaml\n let rawMetadata: unknown;\n try {\n const metadataContent = await readFile(metadataPath);\n rawMetadata = parseYaml(metadataContent);\n } catch (error) {\n issues.push({\n severity: \"error\",\n file: relPath,\n message: \"Failed to parse YAML\",\n });\n continue;\n }\n\n // Check for snake_case keys\n if (rawMetadata && typeof rawMetadata === \"object\" && !Array.isArray(rawMetadata)) {\n for (const key of Object.keys(rawMetadata as Record<string, unknown>)) {\n if (isSnakeCase(key)) {\n issues.push({\n severity: \"error\",\n file: relPath,\n message: `Key '${key}' uses snake_case — use camelCase instead`,\n });\n }\n }\n }\n\n // Validate against strict metadata schema\n const result = metadataValidationSchema.safeParse(rawMetadata);\n if (!result.success) {\n for (const issue of result.error.issues) {\n const fieldPath = issue.path.join(\".\");\n issues.push({\n severity: \"error\",\n file: relPath,\n message: `${fieldPath}: ${issue.message}`,\n });\n }\n continue;\n }\n\n const metadata = result.data;\n\n // Check displayName matches directory name\n const dirName = path.basename(skillDir);\n if (metadata.displayName !== dirName) {\n issues.push({\n severity: \"warning\",\n file: relPath,\n message: `displayName '${metadata.displayName}' does not match directory name '${dirName}'`,\n });\n }\n\n // Parse SKILL.md frontmatter and check name matches displayName\n const skillMdContent = await readFile(skillMdPath);\n const frontmatter = parseFrontmatter(skillMdContent, skillMdPath);\n if (frontmatter) {\n if (!SKILL_ID_PATTERN.test(frontmatter.name)) {\n issues.push({\n severity: \"warning\",\n file: path.join(skillsDirRelPath, skillDir, STANDARD_FILES.SKILL_MD),\n message: `SKILL.md name '${frontmatter.name}' does not match expected skill ID pattern (domain-category-name)`,\n });\n }\n }\n\n // Check category follows domain-prefixed pattern\n if (\n metadata.category &&\n !/^(web|api|cli|mobile|infra|meta|security|shared)-.+$/.test(metadata.category)\n ) {\n issues.push({\n severity: \"warning\",\n file: relPath,\n message: `Category '${metadata.category}' does not follow domain-prefixed pattern (e.g., 'web-framework', 'api-database')`,\n });\n }\n }\n\n // Phase 3: Cross-reference validation via matrix health check\n try {\n await loadSkillsMatrixFromSource({ sourceFlag: resolvedPath, skipExtraSources: true });\n const healthIssues = checkMatrixHealth(matrix);\n\n for (const healthIssue of healthIssues) {\n issues.push({\n severity: healthIssue.severity,\n file: SKILL_CATEGORIES_PATH,\n message: healthIssue.details,\n });\n }\n } catch (error) {\n issues.push({\n severity: \"warning\",\n file: SKILL_CATEGORIES_PATH,\n message: `Cross-reference validation skipped: failed to load categories/rules`,\n });\n }\n\n return buildResult(issues, skillCount);\n}\n\nfunction buildResult(issues: SourceValidationIssue[], skillCount: number): SourceValidationResult {\n const errorCount = issues.filter((i) => i.severity === \"error\").length;\n const warningCount = issues.filter((i) => i.severity === \"warning\").length;\n return { issues, skillCount, errorCount, warningCount };\n}\n"],"mappings":"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","names":["path","path"]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/validate.ts","../../src/cli/lib/source-validator.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport { BaseCommand } from \"../base-command.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { ERROR_MESSAGES } from \"../utils/messages.js\";\nimport { validateAllSchemas, printValidationResults } from \"../lib/schema-validator.js\";\nimport {\n validatePlugin,\n validateAllPlugins,\n printPluginValidationResult,\n} from \"../lib/plugins/index.js\";\nimport { validateSource } from \"../lib/source-validator.js\";\nimport { setVerbose } from \"../utils/logger.js\";\n\nexport default class Validate extends BaseCommand {\n static summary =\n \"Validate YAML files against schemas, validate compiled plugins, or validate a skills source\";\n static description =\n \"Validates skill/agent YAML files against JSON schemas, validates compiled plugin structure and content, \" +\n \"or validates a skills source repository for metadata correctness. \" +\n \"Without arguments, validates all YAML files in the current directory against their schemas. \" +\n \"With --source, validates all skills in the source for schema compliance, cross-references, and conventions. \" +\n \"With a path argument or --plugins flag, validates plugin(s) instead.\";\n\n static examples = [\n {\n description: \"Validate all YAML schemas\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n {\n description: \"Validate a skills source repository\",\n command: \"<%= config.bin %> <%= command.id %> --source .\",\n },\n {\n description: \"Validate a remote skills source\",\n command: \"<%= config.bin %> <%= command.id %> --source github:acme-corp/skills\",\n },\n {\n description: \"Validate a specific plugin\",\n command: \"<%= config.bin %> <%= command.id %> ./path/to/plugin\",\n },\n {\n description: \"Validate all plugins in a directory\",\n command: \"<%= config.bin %> <%= command.id %> ./plugins --all\",\n },\n {\n description: \"Validate plugins with verbose output\",\n command: \"<%= config.bin %> <%= command.id %> --plugins --verbose\",\n },\n ];\n\n static args = {\n path: Args.string({\n description: \"Path to plugin or plugins directory to validate\",\n required: false,\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n verbose: Flags.boolean({\n char: \"v\",\n description: \"Enable verbose logging\",\n default: false,\n }),\n all: Flags.boolean({\n char: \"a\",\n description: \"Validate all plugins in directory\",\n default: false,\n }),\n plugins: Flags.boolean({\n char: \"p\",\n description: \"Validate plugins instead of schemas\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Validate);\n\n if (flags.source) {\n setVerbose(flags.verbose);\n await this.validateSkillsSource(flags.source);\n } else if (args.path || flags.plugins) {\n await this.validatePlugins(args.path, flags.verbose, flags.all);\n } else {\n await this.validateSchemas();\n }\n }\n\n private async validateSchemas(): Promise<void> {\n this.log(\"\");\n this.log(\"Validating all schemas\");\n this.log(\"\");\n\n try {\n const result = await validateAllSchemas();\n\n const summary = result.valid\n ? `Done: ${result.summary.validFiles}/${result.summary.totalFiles} files valid`\n : `Done: ${result.summary.invalidFiles} invalid files`;\n\n this.log(summary);\n printValidationResults(result);\n\n if (!result.valid) {\n this.exit(EXIT_CODES.ERROR);\n }\n } catch (error) {\n const message = getErrorMessage(error);\n this.error(`${ERROR_MESSAGES.VALIDATION_FAILED}: ${message}`, { exit: EXIT_CODES.ERROR });\n }\n }\n\n private async validatePlugins(\n pluginPath: string | undefined,\n verbose: boolean,\n all: boolean,\n ): Promise<void> {\n const targetPath = pluginPath ? path.resolve(pluginPath) : process.cwd();\n\n if (all) {\n await this.validateAllPluginsInDirectory(targetPath, verbose);\n } else {\n await this.validateSinglePlugin(targetPath, verbose);\n }\n }\n\n private async validateAllPluginsInDirectory(targetPath: string, verbose: boolean): Promise<void> {\n this.log(\"\");\n this.log(`Validating all plugins in: ${targetPath}`);\n this.log(\"\");\n\n try {\n const result = await validateAllPlugins(targetPath);\n\n const summary = result.valid\n ? `Done: ${result.summary.valid}/${result.summary.total} plugins valid`\n : `Done: ${result.summary.invalid} invalid plugins`;\n\n this.log(summary);\n\n this.log(\"\");\n this.log(\" Plugin Validation Summary:\");\n this.log(\" -------------------------\");\n this.log(` Total plugins: ${result.summary.total}`);\n this.log(` Valid: ${result.summary.valid}`);\n this.log(` Invalid: ${result.summary.invalid}`);\n this.log(` With warnings: ${result.summary.withWarnings}`);\n\n for (const { name, result: pluginResult } of result.results) {\n printPluginValidationResult(name, pluginResult, verbose);\n }\n\n if (result.valid) {\n this.log(\"\");\n this.logSuccess(\"All plugins validated successfully\");\n this.log(\"\");\n } else {\n this.log(\"\");\n this.error(ERROR_MESSAGES.VALIDATION_FAILED, { exit: EXIT_CODES.ERROR });\n }\n } catch (error) {\n const message = getErrorMessage(error);\n this.error(`${ERROR_MESSAGES.VALIDATION_FAILED}: ${message}`, { exit: EXIT_CODES.ERROR });\n }\n }\n\n private async validateSinglePlugin(targetPath: string, _verbose: boolean): Promise<void> {\n this.log(\"\");\n this.log(`Validating plugin: ${targetPath}`);\n this.log(\"\");\n\n try {\n const result = await validatePlugin(targetPath);\n\n const summary = result.valid ? \"Done: Plugin is valid\" : \"Done: Plugin has errors\";\n\n this.log(summary);\n\n printPluginValidationResult(path.basename(targetPath), result, true);\n\n if (result.valid && result.warnings.length === 0) {\n this.log(\"\");\n this.logSuccess(\"Plugin validated successfully\");\n this.log(\"\");\n } else if (result.valid) {\n this.log(\"\");\n this.logWarning(\"Plugin valid with warnings\");\n this.log(\"\");\n } else {\n this.log(\"\");\n this.error(ERROR_MESSAGES.VALIDATION_FAILED, { exit: EXIT_CODES.ERROR });\n }\n } catch (error) {\n const message = getErrorMessage(error);\n this.error(`${ERROR_MESSAGES.VALIDATION_FAILED}: ${message}`, { exit: EXIT_CODES.ERROR });\n }\n }\n\n private async validateSkillsSource(source: string): Promise<void> {\n this.log(\"\");\n this.log(`Validating source: ${source}`);\n this.log(\"\");\n\n try {\n const result = await validateSource(source);\n\n this.log(`Checked ${result.skillCount} skill(s)`);\n this.log(\"\");\n\n for (const issue of result.issues) {\n const prefix = issue.severity === \"error\" ? \"ERROR\" : \"WARN\";\n this.log(` [${prefix}] ${issue.file}: ${issue.message}`);\n }\n\n if (result.issues.length > 0) {\n this.log(\"\");\n }\n\n this.log(`Result: ${result.errorCount} error(s), ${result.warningCount} warning(s)`);\n\n if (result.errorCount > 0) {\n this.log(\"\");\n this.error(ERROR_MESSAGES.VALIDATION_FAILED, { exit: EXIT_CODES.ERROR });\n } else if (result.warningCount > 0) {\n this.log(\"\");\n this.logWarning(\"Source valid with warnings\");\n this.log(\"\");\n } else {\n this.log(\"\");\n this.logSuccess(\"Source validated successfully\");\n this.log(\"\");\n }\n } catch (error) {\n const message = getErrorMessage(error);\n this.error(`${ERROR_MESSAGES.VALIDATION_FAILED}: ${message}`, { exit: EXIT_CODES.ERROR });\n }\n }\n}\n","import path from \"path\";\nimport { parse as parseYaml } from \"yaml\";\nimport { glob, readFile, fileExists, directoryExists } from \"../utils/fs\";\nimport { verbose } from \"../utils/logger\";\nimport { SKILL_CATEGORIES_PATH, SKILLS_DIR_PATH, STANDARD_FILES } from \"../consts\";\nimport { metadataValidationSchema, SKILL_ID_PATTERN } from \"./schemas\";\nimport { parseFrontmatter } from \"./loading/loader\";\nimport { loadProjectSourceConfig } from \"./configuration\";\nimport { checkMatrixHealth } from \"./matrix\";\nimport { loadSkillsMatrixFromSource } from \"./loading/source-loader\";\nimport { matrix } from \"./matrix/matrix-provider\";\n\nexport type SourceValidationIssue = {\n severity: \"error\" | \"warning\";\n file: string;\n message: string;\n};\n\nexport type SourceValidationResult = {\n issues: SourceValidationIssue[];\n skillCount: number;\n errorCount: number;\n warningCount: number;\n};\n\n/** Checks if a key uses snake_case (has underscore between lowercase letters) */\nfunction isSnakeCase(key: string): boolean {\n return /[a-z]_[a-z]/.test(key);\n}\n\n/**\n * Validates a skills source repository for metadata correctness.\n *\n * Checks:\n * 1. Every metadata.yaml against the strict validation schema\n * 2. displayName format and directory name consistency\n * 3. category values against known domain-prefixed patterns\n * 4. Cross-references resolve to existing skill IDs (via checkMatrixHealth)\n * 5. camelCase key convention (no snake_case)\n * 7. Every skill directory has both SKILL.md and metadata.yaml\n */\nexport async function validateSource(sourcePath: string): Promise<SourceValidationResult> {\n const issues: SourceValidationIssue[] = [];\n\n const resolvedPath = path.isAbsolute(sourcePath) ? sourcePath : path.resolve(sourcePath);\n\n if (!(await directoryExists(resolvedPath))) {\n issues.push({\n severity: \"error\",\n file: resolvedPath,\n message: \"Source directory does not exist\",\n });\n return buildResult(issues, 0);\n }\n\n const sourceProjectConfig = await loadProjectSourceConfig(resolvedPath);\n const skillsDirRelPath = sourceProjectConfig?.skillsDir ?? SKILLS_DIR_PATH;\n const skillsDir = path.join(resolvedPath, skillsDirRelPath);\n\n if (!(await directoryExists(skillsDir))) {\n issues.push({\n severity: \"error\",\n file: skillsDir,\n message: \"Skills directory does not exist\",\n });\n return buildResult(issues, 0);\n }\n\n // Phase 1: Check every skill directory has both SKILL.md and metadata.yaml\n const skillMdFiles = await glob(`**/${STANDARD_FILES.SKILL_MD}`, skillsDir);\n const metadataFiles = await glob(`**/${STANDARD_FILES.METADATA_YAML}`, skillsDir);\n\n const skillMdDirs = new Set(skillMdFiles.map((f) => path.dirname(f)));\n const metadataDirs = new Set(metadataFiles.map((f) => path.dirname(f)));\n\n // Dirs with SKILL.md but no metadata.yaml\n for (const dir of skillMdDirs) {\n if (!metadataDirs.has(dir)) {\n issues.push({\n severity: \"error\",\n file: path.join(skillsDir, dir),\n message: `Missing ${STANDARD_FILES.METADATA_YAML} — skill directory has ${STANDARD_FILES.SKILL_MD} but no metadata`,\n });\n }\n }\n\n // Dirs with metadata.yaml but no SKILL.md\n for (const dir of metadataDirs) {\n if (!skillMdDirs.has(dir)) {\n issues.push({\n severity: \"error\",\n file: path.join(skillsDir, dir),\n message: `Missing ${STANDARD_FILES.SKILL_MD} — skill directory has ${STANDARD_FILES.METADATA_YAML} but no SKILL.md`,\n });\n }\n }\n\n // Phase 2: Validate each metadata.yaml against strict schema and conventions\n let skillCount = 0;\n for (const metadataFile of metadataFiles) {\n const metadataPath = path.join(skillsDir, metadataFile);\n const skillDir = path.dirname(metadataFile);\n const skillMdPath = path.join(skillsDir, skillDir, STANDARD_FILES.SKILL_MD);\n\n if (!(await fileExists(skillMdPath))) {\n // Already reported above\n continue;\n }\n\n skillCount++;\n const relPath = path.join(skillsDirRelPath, metadataFile);\n\n // Read and parse metadata.yaml\n let rawMetadata: unknown;\n try {\n const metadataContent = await readFile(metadataPath);\n rawMetadata = parseYaml(metadataContent);\n } catch (error) {\n issues.push({\n severity: \"error\",\n file: relPath,\n message: \"Failed to parse YAML\",\n });\n continue;\n }\n\n // Check for snake_case keys\n if (rawMetadata && typeof rawMetadata === \"object\" && !Array.isArray(rawMetadata)) {\n for (const key of Object.keys(rawMetadata as Record<string, unknown>)) {\n if (isSnakeCase(key)) {\n issues.push({\n severity: \"error\",\n file: relPath,\n message: `Key '${key}' uses snake_case — use camelCase instead`,\n });\n }\n }\n }\n\n // Validate against strict metadata schema\n const result = metadataValidationSchema.safeParse(rawMetadata);\n if (!result.success) {\n for (const issue of result.error.issues) {\n const fieldPath = issue.path.join(\".\");\n issues.push({\n severity: \"error\",\n file: relPath,\n message: `${fieldPath}: ${issue.message}`,\n });\n }\n continue;\n }\n\n const metadata = result.data;\n\n // Check displayName matches directory name\n const dirName = path.basename(skillDir);\n if (metadata.displayName !== dirName) {\n issues.push({\n severity: \"warning\",\n file: relPath,\n message: `displayName '${metadata.displayName}' does not match directory name '${dirName}'`,\n });\n }\n\n // Parse SKILL.md frontmatter and check name matches displayName\n const skillMdContent = await readFile(skillMdPath);\n const frontmatter = parseFrontmatter(skillMdContent, skillMdPath);\n if (frontmatter) {\n if (!SKILL_ID_PATTERN.test(frontmatter.name)) {\n issues.push({\n severity: \"warning\",\n file: path.join(skillsDirRelPath, skillDir, STANDARD_FILES.SKILL_MD),\n message: `SKILL.md name '${frontmatter.name}' does not match expected skill ID pattern (domain-category-name)`,\n });\n }\n }\n\n // Check category follows domain-prefixed pattern\n if (\n metadata.category &&\n !/^(web|api|cli|mobile|infra|meta|security|shared)-.+$/.test(metadata.category)\n ) {\n issues.push({\n severity: \"warning\",\n file: relPath,\n message: `Category '${metadata.category}' does not follow domain-prefixed pattern (e.g., 'web-framework', 'api-database')`,\n });\n }\n }\n\n // Phase 3: Cross-reference validation via matrix health check\n try {\n await loadSkillsMatrixFromSource({ sourceFlag: resolvedPath, skipExtraSources: true });\n const healthIssues = checkMatrixHealth(matrix);\n\n for (const healthIssue of healthIssues) {\n issues.push({\n severity: healthIssue.severity,\n file: SKILL_CATEGORIES_PATH,\n message: healthIssue.details,\n });\n }\n } catch (error) {\n issues.push({\n severity: \"warning\",\n file: SKILL_CATEGORIES_PATH,\n message: `Cross-reference validation skipped: failed to load categories/rules`,\n });\n }\n\n return buildResult(issues, skillCount);\n}\n\nfunction buildResult(issues: SourceValidationIssue[], skillCount: number): SourceValidationResult {\n const errorCount = issues.filter((i) => i.severity === \"error\").length;\n const warningCount = issues.filter((i) => i.severity === \"warning\").length;\n return { issues, skillCount, errorCount, warningCount };\n}\n"],"mappings":"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","names":["path","path"]}
|
|
@@ -30,9 +30,9 @@ import {
|
|
|
30
30
|
} from "../../chunk-KSMT5FVM.js";
|
|
31
31
|
import "../../chunk-GG4BSB6S.js";
|
|
32
32
|
import "../../chunk-AUNBGZS4.js";
|
|
33
|
-
import "../../chunk-
|
|
33
|
+
import "../../chunk-OLS55LVJ.js";
|
|
34
34
|
import "../../chunk-6VIOO74O.js";
|
|
35
|
-
import "../../chunk-
|
|
35
|
+
import "../../chunk-ZD3U734W.js";
|
|
36
36
|
import "../../chunk-RRBWNEG3.js";
|
|
37
37
|
import "../../chunk-EMX7PA2I.js";
|
|
38
38
|
import {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
DomainSelection
|
|
4
|
-
} from "../../chunk-
|
|
4
|
+
} from "../../chunk-GJLM53PH.js";
|
|
5
5
|
import "../../chunk-BH4LN7XV.js";
|
|
6
6
|
import "../../chunk-OV5UJWS5.js";
|
|
7
7
|
import "../../chunk-XMLCXRTS.js";
|
|
8
8
|
import "../../chunk-AQYAVLZK.js";
|
|
9
9
|
import "../../chunk-AUNBGZS4.js";
|
|
10
|
-
import "../../chunk-
|
|
11
|
-
import "../../chunk-
|
|
10
|
+
import "../../chunk-OLS55LVJ.js";
|
|
11
|
+
import "../../chunk-ZD3U734W.js";
|
|
12
12
|
import "../../chunk-RRBWNEG3.js";
|
|
13
13
|
import "../../chunk-EMX7PA2I.js";
|
|
14
14
|
import "../../chunk-E74Q7GUE.js";
|
|
@@ -39,9 +39,9 @@ import "../../chunk-GG4BSB6S.js";
|
|
|
39
39
|
import "../../chunk-AUNBGZS4.js";
|
|
40
40
|
import "../../chunk-WF5PMBIR.js";
|
|
41
41
|
import "../../chunk-KUV24B5M.js";
|
|
42
|
-
import "../../chunk-
|
|
42
|
+
import "../../chunk-OLS55LVJ.js";
|
|
43
43
|
import "../../chunk-6VIOO74O.js";
|
|
44
|
-
import "../../chunk-
|
|
44
|
+
import "../../chunk-ZD3U734W.js";
|
|
45
45
|
import "../../chunk-RRBWNEG3.js";
|
|
46
46
|
import "../../chunk-EMX7PA2I.js";
|
|
47
47
|
import {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
StackSelection
|
|
4
|
-
} from "../../chunk-
|
|
4
|
+
} from "../../chunk-SFZQL6DJ.js";
|
|
5
5
|
import "../../chunk-MWGDG4QN.js";
|
|
6
6
|
import "../../chunk-AUNBGZS4.js";
|
|
7
|
-
import "../../chunk-
|
|
8
|
-
import "../../chunk-
|
|
7
|
+
import "../../chunk-OLS55LVJ.js";
|
|
8
|
+
import "../../chunk-ZD3U734W.js";
|
|
9
9
|
import "../../chunk-RRBWNEG3.js";
|
|
10
10
|
import "../../chunk-EMX7PA2I.js";
|
|
11
11
|
import "../../chunk-E74Q7GUE.js";
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
StepAgents
|
|
4
|
-
} from "../../chunk-
|
|
4
|
+
} from "../../chunk-UVNIFNIN.js";
|
|
5
5
|
import "../../chunk-K77I4XGL.js";
|
|
6
6
|
import "../../chunk-BH4LN7XV.js";
|
|
7
7
|
import "../../chunk-XMLCXRTS.js";
|
|
8
8
|
import "../../chunk-AQYAVLZK.js";
|
|
9
9
|
import "../../chunk-AUNBGZS4.js";
|
|
10
|
-
import "../../chunk-
|
|
11
|
-
import "../../chunk-
|
|
10
|
+
import "../../chunk-OLS55LVJ.js";
|
|
11
|
+
import "../../chunk-ZD3U734W.js";
|
|
12
12
|
import "../../chunk-RRBWNEG3.js";
|
|
13
13
|
import "../../chunk-EMX7PA2I.js";
|
|
14
14
|
import "../../chunk-E74Q7GUE.js";
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
} from "../../chunk-XY3XDVMI.js";
|
|
26
26
|
import {
|
|
27
27
|
StepAgents
|
|
28
|
-
} from "../../chunk-
|
|
28
|
+
} from "../../chunk-UVNIFNIN.js";
|
|
29
29
|
import "../../chunk-K77I4XGL.js";
|
|
30
30
|
import "../../chunk-BH4LN7XV.js";
|
|
31
31
|
import "../../chunk-XMLCXRTS.js";
|
|
@@ -33,8 +33,8 @@ import "../../chunk-AQYAVLZK.js";
|
|
|
33
33
|
import "../../chunk-AUNBGZS4.js";
|
|
34
34
|
import {
|
|
35
35
|
useWizardStore
|
|
36
|
-
} from "../../chunk-
|
|
37
|
-
import "../../chunk-
|
|
36
|
+
} from "../../chunk-OLS55LVJ.js";
|
|
37
|
+
import "../../chunk-ZD3U734W.js";
|
|
38
38
|
import "../../chunk-RRBWNEG3.js";
|
|
39
39
|
import "../../chunk-EMX7PA2I.js";
|
|
40
40
|
import {
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
StepBuild
|
|
4
|
-
} from "../../chunk-
|
|
4
|
+
} from "../../chunk-XYXDEODG.js";
|
|
5
5
|
import "../../chunk-K77I4XGL.js";
|
|
6
6
|
import "../../chunk-KSMT5FVM.js";
|
|
7
7
|
import "../../chunk-GG4BSB6S.js";
|
|
8
8
|
import "../../chunk-BH4LN7XV.js";
|
|
9
9
|
import "../../chunk-AQYAVLZK.js";
|
|
10
10
|
import "../../chunk-AUNBGZS4.js";
|
|
11
|
-
import "../../chunk-
|
|
11
|
+
import "../../chunk-OLS55LVJ.js";
|
|
12
12
|
import "../../chunk-6VIOO74O.js";
|
|
13
|
-
import "../../chunk-
|
|
13
|
+
import "../../chunk-ZD3U734W.js";
|
|
14
14
|
import "../../chunk-RRBWNEG3.js";
|
|
15
15
|
import "../../chunk-EMX7PA2I.js";
|
|
16
16
|
import "../../chunk-E74Q7GUE.js";
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
import {
|
|
34
34
|
StepBuild,
|
|
35
35
|
validateBuildStep
|
|
36
|
-
} from "../../chunk-
|
|
36
|
+
} from "../../chunk-XYXDEODG.js";
|
|
37
37
|
import "../../chunk-K77I4XGL.js";
|
|
38
38
|
import "../../chunk-KSMT5FVM.js";
|
|
39
39
|
import "../../chunk-GG4BSB6S.js";
|
|
@@ -42,9 +42,9 @@ import {
|
|
|
42
42
|
} from "../../chunk-BH4LN7XV.js";
|
|
43
43
|
import "../../chunk-AQYAVLZK.js";
|
|
44
44
|
import "../../chunk-AUNBGZS4.js";
|
|
45
|
-
import "../../chunk-
|
|
45
|
+
import "../../chunk-OLS55LVJ.js";
|
|
46
46
|
import "../../chunk-6VIOO74O.js";
|
|
47
|
-
import "../../chunk-
|
|
47
|
+
import "../../chunk-ZD3U734W.js";
|
|
48
48
|
import "../../chunk-RRBWNEG3.js";
|
|
49
49
|
import "../../chunk-EMX7PA2I.js";
|
|
50
50
|
import {
|
|
@@ -23,9 +23,9 @@ import {
|
|
|
23
23
|
} from "../../chunk-NUJHWYCR.js";
|
|
24
24
|
import "../../chunk-BH4LN7XV.js";
|
|
25
25
|
import "../../chunk-AQYAVLZK.js";
|
|
26
|
-
import "../../chunk-
|
|
26
|
+
import "../../chunk-OLS55LVJ.js";
|
|
27
27
|
import "../../chunk-6VIOO74O.js";
|
|
28
|
-
import "../../chunk-
|
|
28
|
+
import "../../chunk-ZD3U734W.js";
|
|
29
29
|
import "../../chunk-RRBWNEG3.js";
|
|
30
30
|
import "../../chunk-EMX7PA2I.js";
|
|
31
31
|
import "../../chunk-E74Q7GUE.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
StepSettings
|
|
4
|
-
} from "../../chunk-
|
|
4
|
+
} from "../../chunk-DUF4UVJB.js";
|
|
5
5
|
import "../../chunk-7SOPVGDV.js";
|
|
6
6
|
import "../../chunk-XMLCXRTS.js";
|
|
7
7
|
import "../../chunk-AQYAVLZK.js";
|
|
@@ -9,7 +9,7 @@ import "../../chunk-AUNBGZS4.js";
|
|
|
9
9
|
import "../../chunk-KUV24B5M.js";
|
|
10
10
|
import "../../chunk-U3IGFMCY.js";
|
|
11
11
|
import "../../chunk-6VIOO74O.js";
|
|
12
|
-
import "../../chunk-
|
|
12
|
+
import "../../chunk-ZD3U734W.js";
|
|
13
13
|
import "../../chunk-RRBWNEG3.js";
|
|
14
14
|
import "../../chunk-EMX7PA2I.js";
|
|
15
15
|
import "../../chunk-E74Q7GUE.js";
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
} from "../../chunk-XY3XDVMI.js";
|
|
20
20
|
import {
|
|
21
21
|
StepSettings
|
|
22
|
-
} from "../../chunk-
|
|
22
|
+
} from "../../chunk-DUF4UVJB.js";
|
|
23
23
|
import "../../chunk-7SOPVGDV.js";
|
|
24
24
|
import "../../chunk-XMLCXRTS.js";
|
|
25
25
|
import "../../chunk-AQYAVLZK.js";
|
|
@@ -27,7 +27,7 @@ import "../../chunk-AUNBGZS4.js";
|
|
|
27
27
|
import "../../chunk-KUV24B5M.js";
|
|
28
28
|
import "../../chunk-U3IGFMCY.js";
|
|
29
29
|
import "../../chunk-6VIOO74O.js";
|
|
30
|
-
import "../../chunk-
|
|
30
|
+
import "../../chunk-ZD3U734W.js";
|
|
31
31
|
import "../../chunk-RRBWNEG3.js";
|
|
32
32
|
import "../../chunk-EMX7PA2I.js";
|
|
33
33
|
import "../../chunk-E74Q7GUE.js";
|
|
@@ -64,7 +64,7 @@ describe("StepSettings component", () => {
|
|
|
64
64
|
let cleanup;
|
|
65
65
|
beforeEach(async () => {
|
|
66
66
|
vi.resetAllMocks();
|
|
67
|
-
const { getSourceSummary } = await import("../../source-manager-
|
|
67
|
+
const { getSourceSummary } = await import("../../source-manager-FWAJVMYS.js");
|
|
68
68
|
vi.mocked(getSourceSummary).mockResolvedValue({
|
|
69
69
|
sources: [
|
|
70
70
|
{ name: "public", url: "github:agents-inc/skills", enabled: true },
|
|
@@ -225,7 +225,7 @@ describe("StepSettings component", () => {
|
|
|
225
225
|
});
|
|
226
226
|
describe("edge cases", () => {
|
|
227
227
|
it("should handle empty sources list gracefully", async () => {
|
|
228
|
-
const { getSourceSummary } = await import("../../source-manager-
|
|
228
|
+
const { getSourceSummary } = await import("../../source-manager-FWAJVMYS.js");
|
|
229
229
|
vi.mocked(getSourceSummary).mockResolvedValue({
|
|
230
230
|
sources: [{ name: "public", url: "github:agents-inc/skills", enabled: true }],
|
|
231
231
|
localSkillCount: 0,
|
|
@@ -239,7 +239,7 @@ describe("StepSettings component", () => {
|
|
|
239
239
|
globalExpect(output).toContain("0");
|
|
240
240
|
});
|
|
241
241
|
it("should handle getSourceSummary failure gracefully", async () => {
|
|
242
|
-
const { getSourceSummary } = await import("../../source-manager-
|
|
242
|
+
const { getSourceSummary } = await import("../../source-manager-FWAJVMYS.js");
|
|
243
243
|
vi.mocked(getSourceSummary).mockRejectedValue(new Error("Config read failed"));
|
|
244
244
|
const { lastFrame, unmount } = renderStepSettings();
|
|
245
245
|
cleanup = unmount;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
StepSources
|
|
4
|
-
} from "../../chunk-
|
|
4
|
+
} from "../../chunk-ALCUVCY5.js";
|
|
5
5
|
import "../../chunk-HGTC76BX.js";
|
|
6
6
|
import "../../chunk-K77I4XGL.js";
|
|
7
7
|
import "../../chunk-MWGDG4QN.js";
|
|
@@ -13,9 +13,9 @@ import "../../chunk-AQYAVLZK.js";
|
|
|
13
13
|
import "../../chunk-AUNBGZS4.js";
|
|
14
14
|
import "../../chunk-WF5PMBIR.js";
|
|
15
15
|
import "../../chunk-KUV24B5M.js";
|
|
16
|
-
import "../../chunk-
|
|
16
|
+
import "../../chunk-OLS55LVJ.js";
|
|
17
17
|
import "../../chunk-6VIOO74O.js";
|
|
18
|
-
import "../../chunk-
|
|
18
|
+
import "../../chunk-ZD3U734W.js";
|
|
19
19
|
import "../../chunk-RRBWNEG3.js";
|
|
20
20
|
import "../../chunk-EMX7PA2I.js";
|
|
21
21
|
import "../../chunk-E74Q7GUE.js";
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
} from "../../chunk-XY3XDVMI.js";
|
|
27
27
|
import {
|
|
28
28
|
StepSources
|
|
29
|
-
} from "../../chunk-
|
|
29
|
+
} from "../../chunk-ALCUVCY5.js";
|
|
30
30
|
import "../../chunk-HGTC76BX.js";
|
|
31
31
|
import "../../chunk-K77I4XGL.js";
|
|
32
32
|
import "../../chunk-MWGDG4QN.js";
|
|
@@ -40,9 +40,9 @@ import "../../chunk-WF5PMBIR.js";
|
|
|
40
40
|
import "../../chunk-KUV24B5M.js";
|
|
41
41
|
import {
|
|
42
42
|
useWizardStore
|
|
43
|
-
} from "../../chunk-
|
|
43
|
+
} from "../../chunk-OLS55LVJ.js";
|
|
44
44
|
import "../../chunk-6VIOO74O.js";
|
|
45
|
-
import "../../chunk-
|
|
45
|
+
import "../../chunk-ZD3U734W.js";
|
|
46
46
|
import "../../chunk-RRBWNEG3.js";
|
|
47
47
|
import "../../chunk-EMX7PA2I.js";
|
|
48
48
|
import {
|