@claude-collective/cli 0.26.0 → 0.29.4
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 +125 -0
- package/README.md +47 -13
- package/config/stacks.yaml +330 -93
- package/dist/chunk-56ERY7H7.js +29 -0
- package/dist/chunk-56ERY7H7.js.map +1 -0
- package/dist/{chunk-OBXAY23Y.js → chunk-5I6VY2E7.js} +5 -5
- package/dist/chunk-5I6VY2E7.js.map +1 -0
- package/dist/{chunk-ZDREFYD2.js → chunk-5WIHSJRO.js} +234 -59
- package/dist/chunk-5WIHSJRO.js.map +1 -0
- package/dist/{chunk-GGFOD5PK.js → chunk-6F3ZKDVE.js} +122 -66
- package/dist/chunk-6F3ZKDVE.js.map +1 -0
- package/dist/{chunk-DBRUQQUF.js → chunk-7GHTQSWI.js} +5 -1
- package/dist/{chunk-DBRUQQUF.js.map → chunk-7GHTQSWI.js.map} +1 -1
- package/dist/chunk-7ICBJZV2.js +63 -0
- package/dist/chunk-7ICBJZV2.js.map +1 -0
- package/dist/{chunk-3X5D7RM5.js → chunk-7UKQZSWT.js} +15 -4
- package/dist/chunk-7UKQZSWT.js.map +1 -0
- package/dist/{chunk-F4RD5FYM.js → chunk-A4T4YSV4.js} +5 -2
- package/dist/chunk-A4T4YSV4.js.map +1 -0
- package/dist/{chunk-VVYNZZUX.js → chunk-AG5YGYJT.js} +9 -5
- package/dist/chunk-AG5YGYJT.js.map +1 -0
- package/dist/chunk-AJFSCLJ7.js +81 -0
- package/dist/chunk-AJFSCLJ7.js.map +1 -0
- package/dist/{chunk-NQJ47R4N.js → chunk-CQZAKMPJ.js} +66 -14
- package/dist/chunk-CQZAKMPJ.js.map +1 -0
- package/dist/chunk-DIRH4PDF.js +24 -0
- package/dist/chunk-DIRH4PDF.js.map +1 -0
- package/dist/{chunk-R7B63JAP.js → chunk-DUIYVKFK.js} +123 -86
- package/dist/chunk-DUIYVKFK.js.map +1 -0
- package/dist/chunk-EP6J44I4.js +142 -0
- package/dist/chunk-EP6J44I4.js.map +1 -0
- package/dist/{chunk-TDZE4TDG.js → chunk-EUPMWSM3.js} +92 -29
- package/dist/chunk-EUPMWSM3.js.map +1 -0
- package/dist/chunk-FUPBGSRA.js +66 -0
- package/dist/chunk-FUPBGSRA.js.map +1 -0
- package/dist/{chunk-U7HFKR74.js → chunk-FY5D4KIC.js} +5 -2
- package/dist/chunk-FY5D4KIC.js.map +1 -0
- package/dist/chunk-G5WXKKQM.js +233 -0
- package/dist/chunk-G5WXKKQM.js.map +1 -0
- package/dist/{chunk-KWYO3M5Q.js → chunk-GVVEPVR7.js} +25 -24
- package/dist/chunk-GVVEPVR7.js.map +1 -0
- package/dist/chunk-IFODQTCX.js +162 -0
- package/dist/chunk-IFODQTCX.js.map +1 -0
- package/dist/chunk-IQUBOWWU.js +366 -0
- package/dist/chunk-IQUBOWWU.js.map +1 -0
- package/dist/{chunk-ETCVEV3S.js → chunk-IRG52AN5.js} +242 -155
- package/dist/chunk-IRG52AN5.js.map +1 -0
- package/dist/chunk-MQAYAISQ.js +88 -0
- package/dist/chunk-MQAYAISQ.js.map +1 -0
- package/dist/{chunk-4357L7VK.js → chunk-N73GQTCK.js} +37 -104
- package/dist/chunk-N73GQTCK.js.map +1 -0
- package/dist/{chunk-H7SSBSPR.js → chunk-OA5RCL2L.js} +8 -5
- package/dist/chunk-OA5RCL2L.js.map +1 -0
- package/dist/{chunk-I3YYG5IO.js → chunk-PNXFJPXF.js} +3 -3
- package/dist/{chunk-MCTSHLAF.js → chunk-RI5QEK5W.js} +41 -14
- package/dist/chunk-RI5QEK5W.js.map +1 -0
- package/dist/chunk-RXC7AF7N.js +31 -0
- package/dist/chunk-RXC7AF7N.js.map +1 -0
- package/dist/{chunk-ETQ3BPGU.js → chunk-SSHG7MEE.js} +1252 -728
- package/dist/chunk-SSHG7MEE.js.map +1 -0
- package/dist/{chunk-4S4FCAA2.js → chunk-VTUPUKFD.js} +26 -31
- package/dist/chunk-VTUPUKFD.js.map +1 -0
- package/dist/{chunk-XENOESJZ.js → chunk-WLQUQXWO.js} +10 -67
- package/dist/chunk-WLQUQXWO.js.map +1 -0
- package/dist/chunk-WPED6CL3.js +105 -0
- package/dist/chunk-WPED6CL3.js.map +1 -0
- package/dist/{chunk-R5KJVI54.js → chunk-XPMEGGJK.js} +97 -76
- package/dist/chunk-XPMEGGJK.js.map +1 -0
- package/dist/chunk-XZKVOPCR.js +75 -0
- package/dist/chunk-XZKVOPCR.js.map +1 -0
- package/dist/{chunk-ZW2PELOH.js → chunk-ZX5DM4D5.js} +106 -69
- package/dist/chunk-ZX5DM4D5.js.map +1 -0
- package/dist/commands/build/marketplace.js +21 -20
- package/dist/commands/build/marketplace.js.map +1 -1
- package/dist/commands/build/plugins.js +7 -11
- package/dist/commands/build/plugins.js.map +1 -1
- package/dist/commands/build/stack.js +8 -13
- package/dist/commands/build/stack.js.map +1 -1
- package/dist/commands/compile.js +109 -135
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/config/get.js +4 -5
- package/dist/commands/config/get.js.map +1 -1
- package/dist/commands/config/index.js +5 -6
- package/dist/commands/config/index.js.map +1 -1
- package/dist/commands/config/path.js +4 -5
- package/dist/commands/config/path.js.map +1 -1
- package/dist/commands/config/set-project.js +4 -5
- package/dist/commands/config/set-project.js.map +1 -1
- package/dist/commands/config/show.js +5 -6
- package/dist/commands/config/unset-project.js +4 -5
- package/dist/commands/config/unset-project.js.map +1 -1
- package/dist/commands/diff.js +26 -11
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/doctor.js +13 -16
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +71 -42
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +34 -14
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/import/skill.js +93 -52
- package/dist/commands/import/skill.js.map +1 -1
- package/dist/commands/info.js +27 -9
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/init.js +98 -48
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/list.js +10 -5
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/agent.js +8 -11
- package/dist/commands/new/agent.js.map +1 -1
- package/dist/commands/new/skill.js +17 -18
- package/dist/commands/new/skill.js.map +1 -1
- package/dist/commands/outdated.js +23 -9
- package/dist/commands/outdated.js.map +1 -1
- package/dist/commands/search.js +23 -20
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/uninstall.js +28 -21
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +30 -22
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/validate.js +103 -39
- package/dist/commands/validate.js.map +1 -1
- package/dist/commands/version/bump.js +4 -5
- package/dist/commands/version/bump.js.map +1 -1
- package/dist/commands/version/index.js +4 -5
- package/dist/commands/version/index.js.map +1 -1
- package/dist/commands/version/set.js +4 -5
- package/dist/commands/version/set.js.map +1 -1
- package/dist/commands/version/show.js +4 -5
- package/dist/commands/version/show.js.map +1 -1
- package/dist/components/common/confirm.test.js +2 -2
- package/dist/components/common/confirm.test.js.map +1 -1
- package/dist/components/skill-search/skill-search.js +4 -2
- package/dist/components/wizard/category-grid.js +3 -1
- package/dist/components/wizard/category-grid.test.js +63 -64
- package/dist/components/wizard/category-grid.test.js.map +1 -1
- package/dist/components/wizard/domain-selection.js +13 -0
- package/dist/components/wizard/help-modal.js +10 -0
- package/dist/components/wizard/help-modal.js.map +1 -0
- package/dist/components/wizard/menu-item.js +2 -1
- package/dist/components/wizard/search-modal.js +3 -1
- package/dist/components/wizard/search-modal.test.js +4 -2
- package/dist/components/wizard/search-modal.test.js.map +1 -1
- package/dist/components/wizard/section-progress.js +2 -1
- package/dist/components/wizard/section-progress.test.js +2 -1
- package/dist/components/wizard/section-progress.test.js.map +1 -1
- package/dist/components/wizard/source-grid.js +6 -2
- package/dist/components/wizard/source-grid.test.js +49 -45
- package/dist/components/wizard/source-grid.test.js.map +1 -1
- package/dist/components/wizard/stack-selection.js +15 -0
- package/dist/components/wizard/stack-selection.js.map +1 -0
- package/dist/components/wizard/step-approach.js +8 -6
- package/dist/components/wizard/step-approach.test.js +11 -9
- package/dist/components/wizard/step-approach.test.js.map +1 -1
- package/dist/components/wizard/step-build.js +9 -13
- package/dist/components/wizard/step-build.test.js +27 -45
- package/dist/components/wizard/step-build.test.js.map +1 -1
- package/dist/components/wizard/step-confirm.js +2 -1
- package/dist/components/wizard/step-confirm.test.js +6 -5
- package/dist/components/wizard/step-confirm.test.js.map +1 -1
- package/dist/components/wizard/step-refine.js +2 -1
- package/dist/components/wizard/step-refine.test.js +3 -2
- package/dist/components/wizard/step-refine.test.js.map +1 -1
- package/dist/components/wizard/step-settings.js +8 -6
- package/dist/components/wizard/step-settings.test.js +12 -10
- package/dist/components/wizard/step-settings.test.js.map +1 -1
- package/dist/components/wizard/step-sources.js +11 -9
- package/dist/components/wizard/step-sources.test.js +16 -15
- package/dist/components/wizard/step-sources.test.js.map +1 -1
- package/dist/components/wizard/step-stack.js +9 -6
- package/dist/components/wizard/step-stack.test.js +15 -12
- package/dist/components/wizard/step-stack.test.js.map +1 -1
- package/dist/components/wizard/view-title.js +2 -1
- package/dist/components/wizard/wizard-layout.js +7 -9
- package/dist/components/wizard/wizard-tabs.js +2 -1
- package/dist/components/wizard/wizard-tabs.test.js +2 -1
- package/dist/components/wizard/wizard-tabs.test.js.map +1 -1
- package/dist/components/wizard/wizard.js +26 -20
- package/dist/config/stacks.yaml +330 -93
- package/dist/hooks/init.js +3 -4
- package/dist/hooks/init.js.map +1 -1
- package/dist/source-manager-TV2YGPAN.js +15 -0
- package/dist/source-manager-TV2YGPAN.js.map +1 -0
- package/dist/stores/wizard-store.js +4 -3
- package/dist/stores/wizard-store.test.js +272 -25
- package/dist/stores/wizard-store.test.js.map +1 -1
- package/package.json +2 -1
- package/src/schemas/agent-frontmatter.schema.json +84 -0
- package/src/schemas/agent.schema.json +93 -0
- package/src/schemas/hooks.schema.json +47 -0
- package/src/schemas/marketplace.schema.json +119 -0
- package/src/schemas/metadata.schema.json +113 -0
- package/src/schemas/plugin.schema.json +130 -0
- package/src/schemas/project-config.schema.json +125 -0
- package/src/schemas/project-source-config.schema.json +81 -0
- package/src/schemas/skill-frontmatter.schema.json +42 -0
- package/src/schemas/skills-matrix.schema.json +467 -0
- package/src/schemas/stack.schema.json +191 -0
- package/src/schemas/stacks.schema.json +111 -0
- package/dist/chunk-3X5D7RM5.js.map +0 -1
- package/dist/chunk-4357L7VK.js.map +0 -1
- package/dist/chunk-4S4FCAA2.js.map +0 -1
- package/dist/chunk-7UPXT32F.js +0 -197
- package/dist/chunk-7UPXT32F.js.map +0 -1
- package/dist/chunk-ETCVEV3S.js.map +0 -1
- package/dist/chunk-ETQ3BPGU.js.map +0 -1
- package/dist/chunk-F4RD5FYM.js.map +0 -1
- package/dist/chunk-GGFOD5PK.js.map +0 -1
- package/dist/chunk-H7SSBSPR.js.map +0 -1
- package/dist/chunk-HWD32NP7.js +0 -19
- package/dist/chunk-HWD32NP7.js.map +0 -1
- package/dist/chunk-KWYO3M5Q.js.map +0 -1
- package/dist/chunk-MCTSHLAF.js.map +0 -1
- package/dist/chunk-NQJ47R4N.js.map +0 -1
- package/dist/chunk-O6ZTD7ZI.js +0 -70
- package/dist/chunk-O6ZTD7ZI.js.map +0 -1
- package/dist/chunk-OBXAY23Y.js.map +0 -1
- package/dist/chunk-R5KJVI54.js.map +0 -1
- package/dist/chunk-R7B63JAP.js.map +0 -1
- package/dist/chunk-TDZE4TDG.js.map +0 -1
- package/dist/chunk-TMED5DQ2.js +0 -210
- package/dist/chunk-TMED5DQ2.js.map +0 -1
- package/dist/chunk-U7HFKR74.js.map +0 -1
- package/dist/chunk-UEMRJI2K.js +0 -146
- package/dist/chunk-UEMRJI2K.js.map +0 -1
- package/dist/chunk-UNN7523L.js +0 -78
- package/dist/chunk-UNN7523L.js.map +0 -1
- package/dist/chunk-VVYNZZUX.js.map +0 -1
- package/dist/chunk-XENOESJZ.js.map +0 -1
- package/dist/chunk-ZDREFYD2.js.map +0 -1
- package/dist/chunk-ZW2PELOH.js.map +0 -1
- package/dist/source-manager-EYO3F2DV.js +0 -16
- /package/dist/{chunk-I3YYG5IO.js.map → chunk-PNXFJPXF.js.map} +0 -0
- /package/dist/{source-manager-EYO3F2DV.js.map → components/wizard/domain-selection.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/commands/uninstall.tsx"],"sourcesContent":["import React from \"react\";\nimport { Flags } from \"@oclif/core\";\nimport { render, Box, Text, useApp } from \"ink\";\nimport path from \"path\";\nimport { BaseCommand } from \"../base-command\";\nimport { Confirm } from \"../components/common/confirm\";\nimport { directoryExists, fileExists, remove } from \"../utils/fs\";\nimport { claudePluginUninstall, isClaudeCLIAvailable } from \"../utils/exec\";\nimport { getCollectivePluginDir } from \"../lib/plugins\";\nimport { CLAUDE_DIR, CLAUDE_SRC_DIR } from \"../consts\";\nimport { EXIT_CODES } from \"../lib/exit-codes\";\n\nconst PLUGIN_NAME = \"claude-collective\";\n\ntype UninstallTarget = {\n hasPlugin: boolean;\n hasLocalSkills: boolean;\n hasLocalAgents: boolean;\n hasLocalConfig: boolean;\n hasClaudeDir: boolean;\n hasClaudeSrcDir: boolean;\n pluginDir: string;\n skillsDir: string;\n agentsDir: string;\n configPath: string;\n claudeDir: string;\n claudeSrcDir: string;\n};\n\nasync function detectInstallation(projectDir: string): Promise<UninstallTarget> {\n const pluginDir = getCollectivePluginDir(projectDir);\n const skillsDir = path.join(projectDir, CLAUDE_DIR, \"skills\");\n const agentsDir = path.join(projectDir, CLAUDE_DIR, \"agents\");\n const configPath = path.join(projectDir, CLAUDE_DIR, \"config.yaml\");\n const claudeDir = path.join(projectDir, CLAUDE_DIR);\n const claudeSrcDir = path.join(projectDir, CLAUDE_SRC_DIR);\n\n const [hasPlugin, hasLocalSkills, hasLocalAgents, hasLocalConfig, hasClaudeDir, hasClaudeSrcDir] =\n await Promise.all([\n directoryExists(pluginDir),\n directoryExists(skillsDir),\n directoryExists(agentsDir),\n fileExists(configPath),\n directoryExists(claudeDir),\n directoryExists(claudeSrcDir),\n ]);\n\n return {\n hasPlugin,\n hasLocalSkills,\n hasLocalAgents,\n hasLocalConfig,\n hasClaudeDir,\n hasClaudeSrcDir,\n pluginDir,\n skillsDir,\n agentsDir,\n configPath,\n claudeDir,\n claudeSrcDir,\n };\n}\n\ntype UninstallConfirmProps = {\n target: UninstallTarget;\n uninstallPlugin: boolean;\n uninstallLocal: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n};\n\nconst UninstallConfirm: React.FC<UninstallConfirmProps> = ({\n target,\n uninstallPlugin,\n uninstallLocal,\n onConfirm,\n onCancel,\n}) => {\n const { exit } = useApp();\n const hasPluginToRemove = uninstallPlugin && target.hasPlugin;\n const hasLocalToRemove = uninstallLocal && (target.hasClaudeDir || target.hasClaudeSrcDir);\n\n return (\n <Box flexDirection=\"column\">\n <Text bold>The following will be removed:</Text>\n <Text> </Text>\n\n {hasPluginToRemove && (\n <Box flexDirection=\"column\">\n <Text color=\"red\"> Plugin:</Text>\n <Text dimColor> {target.pluginDir}</Text>\n </Box>\n )}\n\n {hasLocalToRemove && (\n <Box flexDirection=\"column\">\n <Text color=\"red\"> Local directories:</Text>\n {target.hasClaudeDir && <Text dimColor> {target.claudeDir}/</Text>}\n {target.hasClaudeSrcDir && <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\nexport default class Uninstall extends BaseCommand {\n static summary = \"Remove Claude Collective from this project\";\n\n static description =\n \"Uninstall the Claude Collective plugin and/or local directories (.claude/ and .claude-src/). By default, removes everything.\";\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> --yes\",\n \"<%= config.bin %> <%= command.id %> --plugin\",\n \"<%= config.bin %> <%= command.id %> --local\",\n \"<%= config.bin %> <%= command.id %> --dry-run\",\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 plugin: Flags.boolean({\n description: \"Only uninstall the plugin (not local files)\",\n default: false,\n }),\n local: Flags.boolean({\n description: \"Only remove local files (not the plugin)\",\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(\"Claude Collective Uninstall\");\n this.log(\"\");\n\n if (flags[\"dry-run\"]) {\n this.log(\"[dry-run] Preview mode - no files will be removed\");\n this.log(\"\");\n }\n\n const target = await detectInstallation(projectDir);\n\n const uninstallPlugin = !flags.local;\n const uninstallLocal = !flags.plugin;\n\n const hasPluginToRemove = uninstallPlugin && target.hasPlugin;\n const hasLocalToRemove = uninstallLocal && (target.hasClaudeDir || target.hasClaudeSrcDir);\n\n if (!hasPluginToRemove && !hasLocalToRemove) {\n this.warn(\"Nothing to uninstall.\");\n this.log(\"\");\n\n if (flags.plugin && !target.hasPlugin) {\n this.log(\"No plugin installation found.\");\n }\n if (flags.local && !target.hasClaudeDir && !target.hasClaudeSrcDir) {\n this.log(\"No local installation found.\");\n }\n if (!flags.plugin && !flags.local) {\n this.log(\"Claude Collective is not installed in this project.\");\n }\n\n this.log(\"\");\n this.log(\"No changes made.\");\n return;\n }\n\n if (!flags.yes && !flags[\"dry-run\"]) {\n const confirmed = await new Promise<boolean>((resolve) => {\n const { waitUntilExit } = render(\n <UninstallConfirm\n target={target}\n uninstallPlugin={uninstallPlugin}\n uninstallLocal={uninstallLocal}\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 (hasPluginToRemove) {\n this.log(\" Plugin:\");\n this.log(` ${target.pluginDir}`);\n }\n\n if (hasLocalToRemove) {\n this.log(\" Local directories:\");\n if (target.hasClaudeDir) {\n this.log(` ${target.claudeDir}/`);\n }\n if (target.hasClaudeSrcDir) {\n this.log(` ${target.claudeSrcDir}/`);\n }\n }\n\n this.log(\"\");\n }\n\n if (flags[\"dry-run\"]) {\n if (hasPluginToRemove) {\n this.log(`[dry-run] Would uninstall plugin \"${PLUGIN_NAME}\"`);\n this.log(`[dry-run] Would remove ${target.pluginDir}`);\n }\n if (hasLocalToRemove) {\n if (target.hasClaudeDir) {\n this.log(`[dry-run] Would remove ${target.claudeDir}/`);\n }\n if (target.hasClaudeSrcDir) {\n this.log(`[dry-run] Would remove ${target.claudeSrcDir}/`);\n }\n }\n this.log(\"\");\n this.log(\"[dry-run] Preview complete - no files were removed\");\n this.log(\"\");\n return;\n }\n\n if (hasPluginToRemove) {\n this.log(\"Uninstalling plugin...\");\n\n try {\n const cliAvailable = await isClaudeCLIAvailable();\n if (cliAvailable) {\n try {\n await claudePluginUninstall(PLUGIN_NAME, \"project\", projectDir);\n } catch {\n // Best-effort: Claude CLI plugin unregister may fail (e.g., plugin\n // not registered). We still proceed to remove the plugin directory.\n }\n }\n\n await remove(target.pluginDir);\n\n this.logSuccess(\"Plugin uninstalled\");\n } catch (error) {\n this.log(\"Plugin uninstall failed\");\n this.error(error instanceof Error ? error.message : \"Unknown error occurred\", {\n exit: EXIT_CODES.ERROR,\n });\n }\n }\n\n if (hasLocalToRemove) {\n this.log(\"Removing local directories...\");\n\n try {\n const removed: string[] = [];\n\n if (target.hasClaudeDir) {\n await remove(target.claudeDir);\n removed.push(CLAUDE_DIR);\n }\n\n if (target.hasClaudeSrcDir) {\n await remove(target.claudeSrcDir);\n removed.push(CLAUDE_SRC_DIR);\n }\n\n this.logSuccess(\n `Removed ${removed.length} ${removed.length === 1 ? \"directory\" : \"directories\"}: ${removed.join(\", \")}`,\n );\n } catch (error) {\n this.log(\"Failed to remove local directories\");\n this.error(error instanceof Error ? error.message : \"Unknown error occurred\", {\n exit: EXIT_CODES.ERROR,\n });\n }\n }\n\n this.log(\"\");\n this.log(\"Claude Collective has been uninstalled.\");\n\n this.log(\"\");\n this.logSuccess(\"Uninstall complete!\");\n this.log(\"\");\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\";\n\nimport { BaseCommand } from \"../base-command\";\nimport { Confirm } from \"../components/common/confirm\";\nimport { directoryExists, fileExists, remove } from \"../utils/fs\";\nimport { claudePluginUninstall, isClaudeCLIAvailable } from \"../utils/exec\";\nimport { getCollectivePluginDir } from \"../lib/plugins\";\nimport {\n CLAUDE_DIR,\n CLAUDE_SRC_DIR,\n CLI_COLORS,\n DEFAULT_PLUGIN_NAME,\n STANDARD_FILES,\n} from \"../consts\";\nimport { EXIT_CODES } from \"../lib/exit-codes\";\nimport {\n ERROR_MESSAGES,\n SUCCESS_MESSAGES,\n INFO_MESSAGES,\n DRY_RUN_MESSAGES,\n} from \"../utils/messages\";\n\ntype UninstallTarget = {\n hasPlugin: boolean;\n hasLocalSkills: boolean;\n hasLocalAgents: boolean;\n hasLocalConfig: boolean;\n hasClaudeDir: boolean;\n hasClaudeSrcDir: boolean;\n pluginDir: string;\n skillsDir: string;\n agentsDir: string;\n configPath: string;\n claudeDir: string;\n claudeSrcDir: string;\n};\n\nasync function detectInstallation(projectDir: string): Promise<UninstallTarget> {\n const pluginDir = getCollectivePluginDir(projectDir);\n const skillsDir = path.join(projectDir, CLAUDE_DIR, \"skills\");\n const agentsDir = path.join(projectDir, CLAUDE_DIR, \"agents\");\n const configPath = path.join(projectDir, CLAUDE_DIR, STANDARD_FILES.CONFIG_YAML);\n const claudeDir = path.join(projectDir, CLAUDE_DIR);\n const claudeSrcDir = path.join(projectDir, CLAUDE_SRC_DIR);\n\n const [hasPlugin, hasLocalSkills, hasLocalAgents, hasLocalConfig, hasClaudeDir, hasClaudeSrcDir] =\n await Promise.all([\n directoryExists(pluginDir),\n directoryExists(skillsDir),\n directoryExists(agentsDir),\n fileExists(configPath),\n directoryExists(claudeDir),\n directoryExists(claudeSrcDir),\n ]);\n\n return {\n hasPlugin,\n hasLocalSkills,\n hasLocalAgents,\n hasLocalConfig,\n hasClaudeDir,\n hasClaudeSrcDir,\n pluginDir,\n skillsDir,\n agentsDir,\n configPath,\n claudeDir,\n claudeSrcDir,\n };\n}\n\ntype UninstallConfirmProps = {\n target: UninstallTarget;\n uninstallPlugin: boolean;\n uninstallLocal: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n};\n\nconst UninstallConfirm: React.FC<UninstallConfirmProps> = ({\n target,\n uninstallPlugin,\n uninstallLocal,\n onConfirm,\n onCancel,\n}) => {\n const { exit } = useApp();\n const hasPluginToRemove = uninstallPlugin && target.hasPlugin;\n const hasLocalToRemove = uninstallLocal && (target.hasClaudeDir || target.hasClaudeSrcDir);\n\n return (\n <Box flexDirection=\"column\">\n <Text bold>The following will be removed:</Text>\n <Text> </Text>\n\n {hasPluginToRemove && (\n <Box flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> Plugin:</Text>\n <Text dimColor> {target.pluginDir}</Text>\n </Box>\n )}\n\n {hasLocalToRemove && (\n <Box flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> Local directories:</Text>\n {target.hasClaudeDir && <Text dimColor> {target.claudeDir}/</Text>}\n {target.hasClaudeSrcDir && <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\nexport default class Uninstall extends BaseCommand {\n static summary = \"Remove Claude Collective from this project\";\n\n static description =\n \"Uninstall the Claude Collective plugin and/or local directories (.claude/ and .claude-src/). By default, removes everything.\";\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> --yes\",\n \"<%= config.bin %> <%= command.id %> --plugin\",\n \"<%= config.bin %> <%= command.id %> --local\",\n \"<%= config.bin %> <%= command.id %> --dry-run\",\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 plugin: Flags.boolean({\n description: \"Only uninstall the plugin (not local files)\",\n default: false,\n }),\n local: Flags.boolean({\n description: \"Only remove local files (not the plugin)\",\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(\"Claude Collective Uninstall\");\n this.log(\"\");\n\n if (flags[\"dry-run\"]) {\n this.log(DRY_RUN_MESSAGES.PREVIEW_NO_FILES_REMOVED);\n this.log(\"\");\n }\n\n const target = await detectInstallation(projectDir);\n\n const uninstallPlugin = !flags.local;\n const uninstallLocal = !flags.plugin;\n\n const hasPluginToRemove = uninstallPlugin && target.hasPlugin;\n const hasLocalToRemove = uninstallLocal && (target.hasClaudeDir || target.hasClaudeSrcDir);\n\n if (!hasPluginToRemove && !hasLocalToRemove) {\n this.warn(\"Nothing to uninstall.\");\n this.log(\"\");\n\n if (flags.plugin && !target.hasPlugin) {\n this.log(INFO_MESSAGES.NO_PLUGIN_INSTALLATION);\n }\n if (flags.local && !target.hasClaudeDir && !target.hasClaudeSrcDir) {\n this.log(INFO_MESSAGES.NO_LOCAL_INSTALLATION);\n }\n if (!flags.plugin && !flags.local) {\n this.log(INFO_MESSAGES.NOT_INSTALLED);\n }\n\n this.log(\"\");\n this.log(INFO_MESSAGES.NO_CHANGES_MADE);\n return;\n }\n\n if (!flags.yes && !flags[\"dry-run\"]) {\n const confirmed = await new Promise<boolean>((resolve) => {\n const { waitUntilExit } = render(\n <UninstallConfirm\n target={target}\n uninstallPlugin={uninstallPlugin}\n uninstallLocal={uninstallLocal}\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 (hasPluginToRemove) {\n this.log(\" Plugin:\");\n this.log(` ${target.pluginDir}`);\n }\n\n if (hasLocalToRemove) {\n this.log(\" Local directories:\");\n if (target.hasClaudeDir) {\n this.log(` ${target.claudeDir}/`);\n }\n if (target.hasClaudeSrcDir) {\n this.log(` ${target.claudeSrcDir}/`);\n }\n }\n\n this.log(\"\");\n }\n\n if (flags[\"dry-run\"]) {\n if (hasPluginToRemove) {\n this.log(`[dry-run] Would uninstall plugin \"${DEFAULT_PLUGIN_NAME}\"`);\n this.log(`[dry-run] Would remove ${target.pluginDir}`);\n }\n if (hasLocalToRemove) {\n if (target.hasClaudeDir) {\n this.log(`[dry-run] Would remove ${target.claudeDir}/`);\n }\n if (target.hasClaudeSrcDir) {\n this.log(`[dry-run] Would remove ${target.claudeSrcDir}/`);\n }\n }\n this.log(\"\");\n this.log(DRY_RUN_MESSAGES.COMPLETE_NO_FILES_REMOVED);\n this.log(\"\");\n return;\n }\n\n if (hasPluginToRemove) {\n this.log(\"Uninstalling plugin...\");\n\n try {\n const cliAvailable = await isClaudeCLIAvailable();\n if (cliAvailable) {\n try {\n await claudePluginUninstall(DEFAULT_PLUGIN_NAME, \"project\", projectDir);\n } catch {\n // Best-effort: Claude CLI plugin unregister may fail (e.g., plugin\n // not registered). We still proceed to remove the plugin directory.\n }\n }\n\n await remove(target.pluginDir);\n\n this.logSuccess(\"Plugin uninstalled\");\n } catch (error) {\n this.log(\"Plugin uninstall failed\");\n this.error(error instanceof Error ? error.message : ERROR_MESSAGES.UNKNOWN_ERROR, {\n exit: EXIT_CODES.ERROR,\n });\n }\n }\n\n if (hasLocalToRemove) {\n this.log(\"Removing local directories...\");\n\n try {\n const removed: string[] = [];\n\n if (target.hasClaudeDir) {\n await remove(target.claudeDir);\n removed.push(CLAUDE_DIR);\n }\n\n if (target.hasClaudeSrcDir) {\n await remove(target.claudeSrcDir);\n removed.push(CLAUDE_SRC_DIR);\n }\n\n this.logSuccess(\n `Removed ${removed.length} ${removed.length === 1 ? \"directory\" : \"directories\"}: ${removed.join(\", \")}`,\n );\n } catch (error) {\n this.log(\"Failed to remove local directories\");\n this.error(error instanceof Error ? error.message : ERROR_MESSAGES.UNKNOWN_ERROR, {\n exit: EXIT_CODES.ERROR,\n });\n }\n }\n\n this.log(\"\");\n this.log(\"Claude Collective has been uninstalled.\");\n\n this.log(\"\");\n this.logSuccess(SUCCESS_MESSAGES.UNINSTALL_COMPLETE);\n this.log(\"\");\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/commands/update.js
CHANGED
|
@@ -4,34 +4,40 @@ import {
|
|
|
4
4
|
} from "../chunk-IXBCRT3F.js";
|
|
5
5
|
import {
|
|
6
6
|
recompileAgents
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-XPMEGGJK.js";
|
|
8
|
+
import {
|
|
9
|
+
ERROR_MESSAGES,
|
|
10
|
+
INFO_MESSAGES,
|
|
11
|
+
STATUS_MESSAGES,
|
|
12
|
+
SUCCESS_MESSAGES
|
|
13
|
+
} from "../chunk-FUPBGSRA.js";
|
|
8
14
|
import {
|
|
9
15
|
BaseCommand,
|
|
10
16
|
EXIT_CODES
|
|
11
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-5I6VY2E7.js";
|
|
12
18
|
import {
|
|
13
|
-
|
|
19
|
+
compareLocalSkillsWithSource,
|
|
14
20
|
getCollectivePluginDir,
|
|
15
21
|
injectForkedFromMetadata,
|
|
16
22
|
loadSkillsMatrixFromSource
|
|
17
|
-
} from "../chunk-
|
|
23
|
+
} from "../chunk-SSHG7MEE.js";
|
|
18
24
|
import {
|
|
19
25
|
copy,
|
|
20
|
-
fileExists
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
fileExists,
|
|
27
|
+
getErrorMessage
|
|
28
|
+
} from "../chunk-5WIHSJRO.js";
|
|
23
29
|
import {
|
|
24
30
|
LOCAL_SKILLS_PATH
|
|
25
|
-
} from "../chunk-
|
|
31
|
+
} from "../chunk-IFODQTCX.js";
|
|
26
32
|
import {
|
|
27
33
|
init_esm_shims
|
|
28
34
|
} from "../chunk-AWKZ5BDL.js";
|
|
29
35
|
|
|
30
36
|
// src/cli/commands/update.tsx
|
|
31
37
|
init_esm_shims();
|
|
32
|
-
import { render } from "ink";
|
|
33
38
|
import { Flags, Args } from "@oclif/core";
|
|
34
39
|
import { printTable } from "@oclif/table";
|
|
40
|
+
import { render } from "ink";
|
|
35
41
|
import path from "path";
|
|
36
42
|
import { jsx } from "react/jsx-runtime";
|
|
37
43
|
async function updateSkill(skill, projectDir, sourceResult) {
|
|
@@ -49,7 +55,7 @@ async function updateSkill(skill, projectDir, sourceResult) {
|
|
|
49
55
|
return {
|
|
50
56
|
success: false,
|
|
51
57
|
newHash: null,
|
|
52
|
-
error:
|
|
58
|
+
error: getErrorMessage(error)
|
|
53
59
|
};
|
|
54
60
|
}
|
|
55
61
|
}
|
|
@@ -119,10 +125,10 @@ var Update = class _Update extends BaseCommand {
|
|
|
119
125
|
try {
|
|
120
126
|
const localSkillsPath = path.join(projectDir, LOCAL_SKILLS_PATH);
|
|
121
127
|
if (!await fileExists(localSkillsPath)) {
|
|
122
|
-
this.warn(
|
|
128
|
+
this.warn(ERROR_MESSAGES.NO_LOCAL_SKILLS);
|
|
123
129
|
return;
|
|
124
130
|
}
|
|
125
|
-
this.log(
|
|
131
|
+
this.log(STATUS_MESSAGES.LOADING_SKILLS);
|
|
126
132
|
const sourceResult = await loadSkillsMatrixFromSource({
|
|
127
133
|
sourceFlag: flags.source,
|
|
128
134
|
projectDir
|
|
@@ -137,7 +143,11 @@ var Update = class _Update extends BaseCommand {
|
|
|
137
143
|
sourceSkills[skillId] = { path: skill.path };
|
|
138
144
|
}
|
|
139
145
|
}
|
|
140
|
-
const allResults = await
|
|
146
|
+
const allResults = await compareLocalSkillsWithSource(
|
|
147
|
+
projectDir,
|
|
148
|
+
sourceResult.sourcePath,
|
|
149
|
+
sourceSkills
|
|
150
|
+
);
|
|
141
151
|
let outdatedSkills = allResults.filter((r) => r.status === "outdated");
|
|
142
152
|
if (args.skill) {
|
|
143
153
|
const foundSkill = findSkillByPartialMatch(args.skill, allResults);
|
|
@@ -155,7 +165,7 @@ var Update = class _Update extends BaseCommand {
|
|
|
155
165
|
}
|
|
156
166
|
this.log(`Run \`cc search ${args.skill}\` to search available skills.`);
|
|
157
167
|
this.log("");
|
|
158
|
-
this.error(
|
|
168
|
+
this.error(ERROR_MESSAGES.SKILL_NOT_FOUND, { exit: EXIT_CODES.ERROR });
|
|
159
169
|
}
|
|
160
170
|
if (foundSkill.status === "current") {
|
|
161
171
|
this.log("");
|
|
@@ -177,7 +187,7 @@ var Update = class _Update extends BaseCommand {
|
|
|
177
187
|
}
|
|
178
188
|
if (outdatedSkills.length === 0) {
|
|
179
189
|
this.log("");
|
|
180
|
-
this.logSuccess(
|
|
190
|
+
this.logSuccess(SUCCESS_MESSAGES.ALL_SKILLS_UP_TO_DATE);
|
|
181
191
|
this.log("");
|
|
182
192
|
return;
|
|
183
193
|
}
|
|
@@ -222,7 +232,7 @@ var Update = class _Update extends BaseCommand {
|
|
|
222
232
|
this.exit(EXIT_CODES.CANCELLED);
|
|
223
233
|
}
|
|
224
234
|
if (!confirmed) {
|
|
225
|
-
this.log(
|
|
235
|
+
this.log(INFO_MESSAGES.NO_CHANGES_MADE);
|
|
226
236
|
return;
|
|
227
237
|
}
|
|
228
238
|
}
|
|
@@ -243,7 +253,7 @@ var Update = class _Update extends BaseCommand {
|
|
|
243
253
|
let recompiledAgents = [];
|
|
244
254
|
if (shouldRecompile && updated.length > 0) {
|
|
245
255
|
this.log("");
|
|
246
|
-
this.log(
|
|
256
|
+
this.log(STATUS_MESSAGES.RECOMPILING_AGENTS);
|
|
247
257
|
try {
|
|
248
258
|
const pluginDir = getCollectivePluginDir(projectDir);
|
|
249
259
|
const recompileResult = await recompileAgents({
|
|
@@ -258,7 +268,7 @@ var Update = class _Update extends BaseCommand {
|
|
|
258
268
|
this.log(` Recompiled: ${agent}`);
|
|
259
269
|
}
|
|
260
270
|
} else {
|
|
261
|
-
this.log(
|
|
271
|
+
this.log(INFO_MESSAGES.NO_AGENTS_TO_RECOMPILE);
|
|
262
272
|
}
|
|
263
273
|
if (recompileResult.warnings.length > 0) {
|
|
264
274
|
for (const warning of recompileResult.warnings) {
|
|
@@ -267,9 +277,7 @@ var Update = class _Update extends BaseCommand {
|
|
|
267
277
|
}
|
|
268
278
|
} catch (error) {
|
|
269
279
|
this.warn("Agent recompilation failed");
|
|
270
|
-
this.warn(
|
|
271
|
-
`Could not recompile agents: ${error instanceof Error ? error.message : String(error)}`
|
|
272
|
-
);
|
|
280
|
+
this.warn(`Could not recompile agents: ${getErrorMessage(error)}`);
|
|
273
281
|
}
|
|
274
282
|
}
|
|
275
283
|
this.log("");
|
|
@@ -286,7 +294,7 @@ var Update = class _Update extends BaseCommand {
|
|
|
286
294
|
this.error("Some updates failed", { exit: EXIT_CODES.ERROR });
|
|
287
295
|
}
|
|
288
296
|
} catch (error) {
|
|
289
|
-
const message =
|
|
297
|
+
const message = getErrorMessage(error);
|
|
290
298
|
this.error(`Update failed: ${message}`, { exit: EXIT_CODES.ERROR });
|
|
291
299
|
}
|
|
292
300
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/commands/update.tsx"],"sourcesContent":["import React from \"react\";\nimport { render } from \"ink\";\nimport { Flags, Args } from \"@oclif/core\";\nimport { printTable } from \"@oclif/table\";\nimport path from \"path\";\nimport { BaseCommand } from \"../base-command.js\";\nimport { loadSkillsMatrixFromSource, type SourceLoadResult } from \"../lib/loading/index.js\";\nimport { recompileAgents } from \"../lib/agents/index.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport {\n compareSkills,\n injectForkedFromMetadata,\n type SkillComparisonResult,\n} from \"../lib/skills/index.js\";\nimport { fileExists, copy } from \"../utils/fs.js\";\nimport { LOCAL_SKILLS_PATH } from \"../consts.js\";\nimport { getCollectivePluginDir } from \"../lib/plugins/index.js\";\nimport { Confirm } from \"../components/common/confirm.js\";\n\nasync function updateSkill(\n skill: SkillComparisonResult,\n projectDir: string,\n sourceResult: SourceLoadResult,\n): Promise<{ success: boolean; newHash: string | null; error?: string }> {\n if (!skill.sourcePath || !skill.sourceHash) {\n return { success: false, newHash: null, error: \"No source path available\" };\n }\n\n const localSkillsPath = path.join(projectDir, LOCAL_SKILLS_PATH);\n const destPath = path.join(localSkillsPath, skill.dirName);\n const srcPath = path.join(sourceResult.sourcePath, \"src\", skill.sourcePath);\n\n try {\n await copy(srcPath, destPath);\n await injectForkedFromMetadata(destPath, skill.id, skill.sourceHash);\n\n return { success: true, newHash: skill.sourceHash };\n } catch (error) {\n return {\n success: false,\n newHash: null,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nfunction findSkillByPartialMatch(\n skillName: string,\n results: SkillComparisonResult[],\n): SkillComparisonResult | null {\n const exact = results.find((r) => r.id === skillName);\n if (exact) return exact;\n\n const partial = results.find((r) => {\n const nameWithoutAuthor = r.id.replace(/\\s*\\(@\\w+\\)$/, \"\").toLowerCase();\n return nameWithoutAuthor === skillName.toLowerCase();\n });\n if (partial) return partial;\n\n const byDir = results.find((r) => r.dirName.toLowerCase() === skillName.toLowerCase());\n if (byDir) return byDir;\n\n return null;\n}\n\nfunction findSimilarSkills(skillName: string, results: SkillComparisonResult[]): string[] {\n const lowered = skillName.toLowerCase();\n return results\n .filter((r) => {\n const name = r.id.toLowerCase();\n const dir = r.dirName.toLowerCase();\n return (\n name.includes(lowered) || dir.includes(lowered) || lowered.includes(name.split(\" \")[0])\n );\n })\n .map((r) => r.id)\n .slice(0, 3);\n}\n\ntype UpdateConfirmProps = {\n onConfirm: () => void;\n onCancel: () => void;\n};\n\nconst UpdateConfirm: React.FC<UpdateConfirmProps> = ({ onConfirm, onCancel }) => {\n return (\n <Confirm\n message=\"Proceed with update?\"\n onConfirm={onConfirm}\n onCancel={onCancel}\n defaultValue={false}\n />\n );\n};\n\nexport default class Update extends BaseCommand {\n static summary = \"Update local skills from source\";\n\n static description =\n \"Update local skills from the source repository. By default, checks all skills for updates. Specify a skill name to update only that skill.\";\n\n static args = {\n skill: Args.string({\n description: \"Specific skill to update (optional)\",\n required: false,\n }),\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 \"no-recompile\": Flags.boolean({\n description: \"Skip agent recompilation after update\",\n default: false,\n }),\n };\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> my-skill\",\n \"<%= config.bin %> <%= command.id %> --yes\",\n \"<%= config.bin %> <%= command.id %> --source /path/to/marketplace\",\n \"<%= config.bin %> <%= command.id %> --no-recompile\",\n ];\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Update);\n const projectDir = process.cwd();\n const shouldRecompile = !flags[\"no-recompile\"];\n\n try {\n const localSkillsPath = path.join(projectDir, LOCAL_SKILLS_PATH);\n if (!(await fileExists(localSkillsPath))) {\n this.warn(\"No local skills found. Run `cc init` or `cc edit` first.\");\n return;\n }\n\n this.log(\"Loading skills...\");\n\n const sourceResult = await loadSkillsMatrixFromSource({\n sourceFlag: flags.source,\n projectDir,\n });\n\n this.log(\n `Loaded from ${sourceResult.isLocal ? \"local\" : \"remote\"}: ${sourceResult.sourcePath}`,\n );\n\n const sourceSkills: Record<string, { path: string }> = {};\n for (const [skillId, skill] of Object.entries(sourceResult.matrix.skills)) {\n if (!skill) continue;\n if (!skill.local) {\n sourceSkills[skillId] = { path: skill.path };\n }\n }\n\n const allResults = await compareSkills(projectDir, sourceResult.sourcePath, sourceSkills);\n\n let outdatedSkills = allResults.filter((r) => r.status === \"outdated\");\n\n if (args.skill) {\n const foundSkill = findSkillByPartialMatch(args.skill, allResults);\n\n if (!foundSkill) {\n this.log(\"\");\n this.log(`Error: Skill \"${args.skill}\" not found.`);\n this.log(\"\");\n\n const similar = findSimilarSkills(args.skill, allResults);\n if (similar.length > 0) {\n this.log(\"Did you mean one of these?\");\n for (const name of similar) {\n this.log(` - ${name}`);\n }\n this.log(\"\");\n }\n\n this.log(`Run \\`cc search ${args.skill}\\` to search available skills.`);\n this.log(\"\");\n this.error(\"Skill not found\", { exit: EXIT_CODES.ERROR });\n }\n\n if (foundSkill.status === \"current\") {\n this.log(\"\");\n this.log(`Skill \"${foundSkill.id}\" is already up to date.`);\n this.log(\"\");\n this.log(` Local hash: ${foundSkill.localHash}`);\n this.log(` Source hash: ${foundSkill.sourceHash}`);\n this.log(\"\");\n return;\n }\n\n if (foundSkill.status === \"local-only\") {\n this.log(\"\");\n this.log(`Skill \"${foundSkill.id}\" is a local-only skill (not forked from source).`);\n this.log(\"Cannot update local-only skills.\");\n this.log(\"\");\n return;\n }\n\n outdatedSkills = [foundSkill];\n }\n\n if (outdatedSkills.length === 0) {\n this.log(\"\");\n this.logSuccess(\"All skills are up to date.\");\n this.log(\"\");\n return;\n }\n\n this.log(\"\");\n this.log(\"The following skills will be updated:\");\n this.log(\"\");\n\n printTable({\n data: outdatedSkills.map((skill) => ({\n skill: skill.id,\n localHash: skill.localHash ?? \"-\",\n sourceHash: skill.sourceHash ?? \"-\",\n })),\n columns: [\n { key: \"skill\", name: \"Skill\" },\n { key: \"localHash\", name: \"Local Hash\" },\n { key: \"sourceHash\", name: \"Source Hash\" },\n ],\n headerOptions: { bold: true },\n });\n\n this.log(\"\");\n this.log(`${outdatedSkills.length} skill(s) will be updated.`);\n this.log(\"\");\n\n if (!flags.yes) {\n let confirmed = false;\n let cancelled = false;\n\n const { waitUntilExit } = render(\n <UpdateConfirm\n onConfirm={() => {\n confirmed = true;\n }}\n onCancel={() => {\n cancelled = true;\n }}\n />,\n );\n\n await waitUntilExit();\n\n if (cancelled) {\n this.log(\"Update cancelled\");\n this.exit(EXIT_CODES.CANCELLED);\n }\n\n if (!confirmed) {\n this.log(\"No changes made.\");\n return;\n }\n }\n\n this.log(\"\");\n\n const updated: string[] = [];\n const failed: string[] = [];\n\n for (const skill of outdatedSkills) {\n this.log(`Updating ${skill.id}...`);\n\n const result = await updateSkill(skill, projectDir, sourceResult);\n\n if (result.success) {\n this.log(` Updated ${skill.id}`);\n updated.push(skill.id);\n } else {\n this.log(` Failed to update ${skill.id}: ${result.error}`);\n failed.push(skill.id);\n }\n }\n\n let recompiledAgents: string[] = [];\n\n if (shouldRecompile && updated.length > 0) {\n this.log(\"\");\n this.log(\"Recompiling agents...\");\n\n try {\n const pluginDir = getCollectivePluginDir(projectDir);\n const recompileResult = await recompileAgents({\n pluginDir,\n sourcePath: sourceResult.sourcePath,\n projectDir,\n });\n\n recompiledAgents = recompileResult.compiled;\n\n if (recompiledAgents.length > 0) {\n this.log(\"Agents recompiled\");\n for (const agent of recompiledAgents) {\n this.log(` Recompiled: ${agent}`);\n }\n } else {\n this.log(\"No agents to recompile\");\n }\n\n if (recompileResult.warnings.length > 0) {\n for (const warning of recompileResult.warnings) {\n this.warn(warning);\n }\n }\n } catch (error) {\n this.warn(\"Agent recompilation failed\");\n this.warn(\n `Could not recompile agents: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n this.log(\"\");\n if (failed.length === 0) {\n const agentMsg =\n recompiledAgents.length > 0 ? `, ${recompiledAgents.length} agent(s) recompiled` : \"\";\n this.logSuccess(`Update complete! ${updated.length} skill(s) updated${agentMsg}.`);\n } else {\n this.warn(\n `Update finished with errors: ${updated.length} updated, ${failed.length} failed.`,\n );\n }\n this.log(\"\");\n\n if (failed.length > 0) {\n this.error(\"Some updates failed\", { exit: EXIT_CODES.ERROR });\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n this.error(`Update failed: ${message}`, { exit: EXIT_CODES.ERROR });\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/update.tsx"],"sourcesContent":["import React from \"react\";\n\nimport { Flags, Args } from \"@oclif/core\";\nimport { printTable } from \"@oclif/table\";\nimport { render } from \"ink\";\nimport path from \"path\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { loadSkillsMatrixFromSource, type SourceLoadResult } from \"../lib/loading/index.js\";\nimport { recompileAgents } from \"../lib/agents/index.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport {\n compareLocalSkillsWithSource,\n injectForkedFromMetadata,\n type SkillComparisonResult,\n} from \"../lib/skills/index.js\";\nimport { fileExists, copy } from \"../utils/fs.js\";\nimport { LOCAL_SKILLS_PATH } from \"../consts.js\";\nimport { getCollectivePluginDir } from \"../lib/plugins/index.js\";\nimport {\n ERROR_MESSAGES,\n SUCCESS_MESSAGES,\n STATUS_MESSAGES,\n INFO_MESSAGES,\n} from \"../utils/messages.js\";\nimport { Confirm } from \"../components/common/confirm.js\";\n\nasync function updateSkill(\n skill: SkillComparisonResult,\n projectDir: string,\n sourceResult: SourceLoadResult,\n): Promise<{ success: boolean; newHash: string | null; error?: string }> {\n if (!skill.sourcePath || !skill.sourceHash) {\n return { success: false, newHash: null, error: \"No source path available\" };\n }\n\n const localSkillsPath = path.join(projectDir, LOCAL_SKILLS_PATH);\n const destPath = path.join(localSkillsPath, skill.dirName);\n const srcPath = path.join(sourceResult.sourcePath, \"src\", skill.sourcePath);\n\n try {\n await copy(srcPath, destPath);\n await injectForkedFromMetadata(destPath, skill.id, skill.sourceHash);\n\n return { success: true, newHash: skill.sourceHash };\n } catch (error) {\n return {\n success: false,\n newHash: null,\n error: getErrorMessage(error),\n };\n }\n}\n\nfunction findSkillByPartialMatch(\n skillName: string,\n results: SkillComparisonResult[],\n): SkillComparisonResult | null {\n const exact = results.find((r) => r.id === skillName);\n if (exact) return exact;\n\n const partial = results.find((r) => {\n const nameWithoutAuthor = r.id.replace(/\\s*\\(@\\w+\\)$/, \"\").toLowerCase();\n return nameWithoutAuthor === skillName.toLowerCase();\n });\n if (partial) return partial;\n\n const byDir = results.find((r) => r.dirName.toLowerCase() === skillName.toLowerCase());\n if (byDir) return byDir;\n\n return null;\n}\n\nfunction findSimilarSkills(skillName: string, results: SkillComparisonResult[]): string[] {\n const lowered = skillName.toLowerCase();\n return results\n .filter((r) => {\n const name = r.id.toLowerCase();\n const dir = r.dirName.toLowerCase();\n return (\n name.includes(lowered) || dir.includes(lowered) || lowered.includes(name.split(\" \")[0])\n );\n })\n .map((r) => r.id)\n .slice(0, 3);\n}\n\ntype UpdateConfirmProps = {\n onConfirm: () => void;\n onCancel: () => void;\n};\n\nconst UpdateConfirm: React.FC<UpdateConfirmProps> = ({ onConfirm, onCancel }) => {\n return (\n <Confirm\n message=\"Proceed with update?\"\n onConfirm={onConfirm}\n onCancel={onCancel}\n defaultValue={false}\n />\n );\n};\n\nexport default class Update extends BaseCommand {\n static summary = \"Update local skills from source\";\n\n static description =\n \"Update local skills from the source repository. By default, checks all skills for updates. Specify a skill name to update only that skill.\";\n\n static args = {\n skill: Args.string({\n description: \"Specific skill to update (optional)\",\n required: false,\n }),\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 \"no-recompile\": Flags.boolean({\n description: \"Skip agent recompilation after update\",\n default: false,\n }),\n };\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> my-skill\",\n \"<%= config.bin %> <%= command.id %> --yes\",\n \"<%= config.bin %> <%= command.id %> --source /path/to/marketplace\",\n \"<%= config.bin %> <%= command.id %> --no-recompile\",\n ];\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Update);\n const projectDir = process.cwd();\n const shouldRecompile = !flags[\"no-recompile\"];\n\n try {\n const localSkillsPath = path.join(projectDir, LOCAL_SKILLS_PATH);\n if (!(await fileExists(localSkillsPath))) {\n this.warn(ERROR_MESSAGES.NO_LOCAL_SKILLS);\n return;\n }\n\n this.log(STATUS_MESSAGES.LOADING_SKILLS);\n\n const sourceResult = await loadSkillsMatrixFromSource({\n sourceFlag: flags.source,\n projectDir,\n });\n\n this.log(\n `Loaded from ${sourceResult.isLocal ? \"local\" : \"remote\"}: ${sourceResult.sourcePath}`,\n );\n\n const sourceSkills: Record<string, { path: string }> = {};\n for (const [skillId, skill] of Object.entries(sourceResult.matrix.skills)) {\n if (!skill) continue;\n if (!skill.local) {\n sourceSkills[skillId] = { path: skill.path };\n }\n }\n\n const allResults = await compareLocalSkillsWithSource(\n projectDir,\n sourceResult.sourcePath,\n sourceSkills,\n );\n\n let outdatedSkills = allResults.filter((r) => r.status === \"outdated\");\n\n if (args.skill) {\n const foundSkill = findSkillByPartialMatch(args.skill, allResults);\n\n if (!foundSkill) {\n this.log(\"\");\n this.log(`Error: Skill \"${args.skill}\" not found.`);\n this.log(\"\");\n\n const similar = findSimilarSkills(args.skill, allResults);\n if (similar.length > 0) {\n this.log(\"Did you mean one of these?\");\n for (const name of similar) {\n this.log(` - ${name}`);\n }\n this.log(\"\");\n }\n\n this.log(`Run \\`cc search ${args.skill}\\` to search available skills.`);\n this.log(\"\");\n this.error(ERROR_MESSAGES.SKILL_NOT_FOUND, { exit: EXIT_CODES.ERROR });\n }\n\n if (foundSkill.status === \"current\") {\n this.log(\"\");\n this.log(`Skill \"${foundSkill.id}\" is already up to date.`);\n this.log(\"\");\n this.log(` Local hash: ${foundSkill.localHash}`);\n this.log(` Source hash: ${foundSkill.sourceHash}`);\n this.log(\"\");\n return;\n }\n\n if (foundSkill.status === \"local-only\") {\n this.log(\"\");\n this.log(`Skill \"${foundSkill.id}\" is a local-only skill (not forked from source).`);\n this.log(\"Cannot update local-only skills.\");\n this.log(\"\");\n return;\n }\n\n outdatedSkills = [foundSkill];\n }\n\n if (outdatedSkills.length === 0) {\n this.log(\"\");\n this.logSuccess(SUCCESS_MESSAGES.ALL_SKILLS_UP_TO_DATE);\n this.log(\"\");\n return;\n }\n\n this.log(\"\");\n this.log(\"The following skills will be updated:\");\n this.log(\"\");\n\n printTable({\n data: outdatedSkills.map((skill) => ({\n skill: skill.id,\n localHash: skill.localHash ?? \"-\",\n sourceHash: skill.sourceHash ?? \"-\",\n })),\n columns: [\n { key: \"skill\", name: \"Skill\" },\n { key: \"localHash\", name: \"Local Hash\" },\n { key: \"sourceHash\", name: \"Source Hash\" },\n ],\n headerOptions: { bold: true },\n });\n\n this.log(\"\");\n this.log(`${outdatedSkills.length} skill(s) will be updated.`);\n this.log(\"\");\n\n if (!flags.yes) {\n let confirmed = false;\n let cancelled = false;\n\n const { waitUntilExit } = render(\n <UpdateConfirm\n onConfirm={() => {\n confirmed = true;\n }}\n onCancel={() => {\n cancelled = true;\n }}\n />,\n );\n\n await waitUntilExit();\n\n if (cancelled) {\n this.log(\"Update cancelled\");\n this.exit(EXIT_CODES.CANCELLED);\n }\n\n if (!confirmed) {\n this.log(INFO_MESSAGES.NO_CHANGES_MADE);\n return;\n }\n }\n\n this.log(\"\");\n\n const updated: string[] = [];\n const failed: string[] = [];\n\n for (const skill of outdatedSkills) {\n this.log(`Updating ${skill.id}...`);\n\n const result = await updateSkill(skill, projectDir, sourceResult);\n\n if (result.success) {\n this.log(` Updated ${skill.id}`);\n updated.push(skill.id);\n } else {\n this.log(` Failed to update ${skill.id}: ${result.error}`);\n failed.push(skill.id);\n }\n }\n\n let recompiledAgents: string[] = [];\n\n if (shouldRecompile && updated.length > 0) {\n this.log(\"\");\n this.log(STATUS_MESSAGES.RECOMPILING_AGENTS);\n\n try {\n const pluginDir = getCollectivePluginDir(projectDir);\n const recompileResult = await recompileAgents({\n pluginDir,\n sourcePath: sourceResult.sourcePath,\n projectDir,\n });\n\n recompiledAgents = recompileResult.compiled;\n\n if (recompiledAgents.length > 0) {\n this.log(\"Agents recompiled\");\n for (const agent of recompiledAgents) {\n this.log(` Recompiled: ${agent}`);\n }\n } else {\n this.log(INFO_MESSAGES.NO_AGENTS_TO_RECOMPILE);\n }\n\n if (recompileResult.warnings.length > 0) {\n for (const warning of recompileResult.warnings) {\n this.warn(warning);\n }\n }\n } catch (error) {\n this.warn(\"Agent recompilation failed\");\n this.warn(`Could not recompile agents: ${getErrorMessage(error)}`);\n }\n }\n\n this.log(\"\");\n if (failed.length === 0) {\n const agentMsg =\n recompiledAgents.length > 0 ? `, ${recompiledAgents.length} agent(s) recompiled` : \"\";\n this.logSuccess(`Update complete! ${updated.length} skill(s) updated${agentMsg}.`);\n } else {\n this.warn(\n `Update finished with errors: ${updated.length} updated, ${failed.length} failed.`,\n );\n }\n this.log(\"\");\n\n if (failed.length > 0) {\n this.error(\"Some updates failed\", { exit: EXIT_CODES.ERROR });\n }\n } catch (error) {\n const message = getErrorMessage(error);\n this.error(`Update failed: ${message}`, { exit: EXIT_CODES.ERROR });\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,25 +1,37 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
ERROR_MESSAGES
|
|
4
|
+
} from "../chunk-FUPBGSRA.js";
|
|
2
5
|
import {
|
|
3
6
|
BaseCommand,
|
|
4
7
|
EXIT_CODES
|
|
5
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-5I6VY2E7.js";
|
|
6
9
|
import {
|
|
7
10
|
extractFrontmatter,
|
|
8
11
|
printPluginValidationResult,
|
|
9
12
|
validateAllPlugins,
|
|
10
13
|
validatePlugin
|
|
11
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-SSHG7MEE.js";
|
|
12
15
|
import {
|
|
16
|
+
agentFrontmatterValidationSchema,
|
|
13
17
|
agentYamlGenerationSchema,
|
|
14
18
|
fileExists,
|
|
19
|
+
getErrorMessage,
|
|
20
|
+
log,
|
|
15
21
|
metadataValidationSchema,
|
|
22
|
+
pluginManifestSchema,
|
|
23
|
+
projectSourceConfigSchema,
|
|
16
24
|
readFile,
|
|
17
25
|
skillFrontmatterValidationSchema,
|
|
18
26
|
skillsMatrixConfigSchema,
|
|
19
|
-
stackConfigValidationSchema
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
import
|
|
27
|
+
stackConfigValidationSchema,
|
|
28
|
+
stacksConfigSchema
|
|
29
|
+
} from "../chunk-5WIHSJRO.js";
|
|
30
|
+
import {
|
|
31
|
+
CLAUDE_DIR,
|
|
32
|
+
CLAUDE_SRC_DIR,
|
|
33
|
+
STANDARD_FILES
|
|
34
|
+
} from "../chunk-IFODQTCX.js";
|
|
23
35
|
import {
|
|
24
36
|
init_esm_shims
|
|
25
37
|
} from "../chunk-AWKZ5BDL.js";
|
|
@@ -39,46 +51,85 @@ var VALIDATION_TARGETS = [
|
|
|
39
51
|
{
|
|
40
52
|
name: "Skills Matrix",
|
|
41
53
|
schema: skillsMatrixConfigSchema,
|
|
42
|
-
pattern:
|
|
54
|
+
pattern: STANDARD_FILES.SKILLS_MATRIX_YAML,
|
|
43
55
|
baseDir: "src/config"
|
|
44
56
|
},
|
|
45
57
|
{
|
|
46
58
|
name: "Skill Metadata",
|
|
47
59
|
schema: metadataValidationSchema,
|
|
48
|
-
pattern:
|
|
60
|
+
pattern: `**/${STANDARD_FILES.METADATA_YAML}`,
|
|
49
61
|
baseDir: "src/skills"
|
|
50
62
|
},
|
|
51
63
|
{
|
|
52
64
|
name: "Stack Skill Metadata",
|
|
53
65
|
schema: metadataValidationSchema,
|
|
54
|
-
pattern:
|
|
66
|
+
pattern: `**/skills/**/${STANDARD_FILES.METADATA_YAML}`,
|
|
55
67
|
baseDir: "src/stacks"
|
|
56
68
|
},
|
|
57
69
|
{
|
|
58
70
|
name: "Stack Config",
|
|
59
71
|
schema: stackConfigValidationSchema,
|
|
60
|
-
pattern:
|
|
72
|
+
pattern: `*/${STANDARD_FILES.CONFIG_YAML}`,
|
|
61
73
|
baseDir: "src/stacks"
|
|
62
74
|
},
|
|
63
75
|
{
|
|
64
76
|
name: "Agent Definition",
|
|
65
77
|
schema: agentYamlGenerationSchema,
|
|
66
|
-
pattern:
|
|
78
|
+
pattern: `**/${STANDARD_FILES.AGENT_YAML}`,
|
|
67
79
|
baseDir: "src/agents"
|
|
68
80
|
},
|
|
69
81
|
{
|
|
70
82
|
name: "Skill Frontmatter",
|
|
71
83
|
schema: skillFrontmatterValidationSchema,
|
|
72
|
-
pattern:
|
|
84
|
+
pattern: `**/${STANDARD_FILES.SKILL_MD}`,
|
|
73
85
|
baseDir: "src/skills",
|
|
74
86
|
extractor: extractFrontmatter
|
|
75
87
|
},
|
|
76
88
|
{
|
|
77
89
|
name: "Stack Skill Frontmatter",
|
|
78
90
|
schema: skillFrontmatterValidationSchema,
|
|
79
|
-
pattern:
|
|
91
|
+
pattern: `**/skills/**/${STANDARD_FILES.SKILL_MD}`,
|
|
80
92
|
baseDir: "src/stacks",
|
|
81
93
|
extractor: extractFrontmatter
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: "Stacks Config",
|
|
97
|
+
schema: stacksConfigSchema,
|
|
98
|
+
pattern: "stacks.yaml",
|
|
99
|
+
baseDir: "config"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: "Project Source Config",
|
|
103
|
+
schema: projectSourceConfigSchema,
|
|
104
|
+
pattern: STANDARD_FILES.CONFIG_YAML,
|
|
105
|
+
baseDir: CLAUDE_SRC_DIR
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: "Project Skill Metadata",
|
|
109
|
+
schema: metadataValidationSchema,
|
|
110
|
+
pattern: `*/${STANDARD_FILES.METADATA_YAML}`,
|
|
111
|
+
baseDir: `${CLAUDE_DIR}/skills`
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: "Project Skill Frontmatter",
|
|
115
|
+
schema: skillFrontmatterValidationSchema,
|
|
116
|
+
pattern: `*/${STANDARD_FILES.SKILL_MD}`,
|
|
117
|
+
baseDir: `${CLAUDE_DIR}/skills`,
|
|
118
|
+
extractor: extractFrontmatter
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: "Project Agent Frontmatter",
|
|
122
|
+
schema: agentFrontmatterValidationSchema,
|
|
123
|
+
pattern: "*.md",
|
|
124
|
+
baseDir: `${CLAUDE_DIR}/agents`,
|
|
125
|
+
extractor: extractFrontmatter
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: "Plugin Manifest",
|
|
129
|
+
schema: pluginManifestSchema,
|
|
130
|
+
pattern: `*/${STANDARD_FILES.PLUGIN_JSON}`,
|
|
131
|
+
baseDir: `${CLAUDE_DIR}/plugins`,
|
|
132
|
+
extractor: (content) => JSON.parse(content)
|
|
82
133
|
}
|
|
83
134
|
];
|
|
84
135
|
function formatZodErrors(error) {
|
|
@@ -114,7 +165,7 @@ async function validateFile(filePath, schema, extractor) {
|
|
|
114
165
|
}
|
|
115
166
|
return { valid: false, errors: formatZodErrors(result.error) };
|
|
116
167
|
} catch (error) {
|
|
117
|
-
const message =
|
|
168
|
+
const message = getErrorMessage(error);
|
|
118
169
|
return { valid: false, errors: [`Failed to parse content: ${message}`] };
|
|
119
170
|
}
|
|
120
171
|
}
|
|
@@ -166,36 +217,31 @@ async function validateAllSchemas(rootDir = process.cwd()) {
|
|
|
166
217
|
};
|
|
167
218
|
}
|
|
168
219
|
function printValidationResults(result) {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
console.log(` Invalid: ${result.summary.invalidFiles}`);
|
|
220
|
+
log("\n Schema Validation Summary:");
|
|
221
|
+
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");
|
|
222
|
+
log(` Total schemas checked: ${result.summary.totalSchemas}`);
|
|
223
|
+
log(` Total files: ${result.summary.totalFiles}`);
|
|
224
|
+
log(` Valid: ${result.summary.validFiles}`);
|
|
225
|
+
log(` Invalid: ${result.summary.invalidFiles}`);
|
|
176
226
|
for (const schemaResult of result.results) {
|
|
177
227
|
if (schemaResult.totalFiles === 0) continue;
|
|
178
228
|
const status = schemaResult.valid ? "\u2713" : "\u2717";
|
|
179
|
-
|
|
229
|
+
log(
|
|
180
230
|
`
|
|
181
231
|
${status} ${schemaResult.schemaName}: ${schemaResult.validFiles}/${schemaResult.totalFiles} valid`
|
|
182
232
|
);
|
|
183
233
|
if (schemaResult.invalidFiles.length > 0) {
|
|
184
234
|
for (const file of schemaResult.invalidFiles) {
|
|
185
|
-
|
|
235
|
+
log(`
|
|
186
236
|
${file.file}:`);
|
|
187
|
-
file.errors.forEach((e) =>
|
|
237
|
+
file.errors.forEach((e) => log(` - ${e}`));
|
|
188
238
|
}
|
|
189
239
|
}
|
|
190
240
|
}
|
|
191
241
|
if (result.valid) {
|
|
192
|
-
|
|
193
|
-
\u2713 All schemas validated successfully
|
|
194
|
-
`);
|
|
242
|
+
log("\n \u2713 All schemas validated successfully\n");
|
|
195
243
|
} else {
|
|
196
|
-
|
|
197
|
-
\u2717 Validation failed
|
|
198
|
-
`);
|
|
244
|
+
log("\n \u2717 Validation failed\n");
|
|
199
245
|
}
|
|
200
246
|
}
|
|
201
247
|
|
|
@@ -203,6 +249,24 @@ function printValidationResults(result) {
|
|
|
203
249
|
var Validate = class _Validate extends BaseCommand {
|
|
204
250
|
static summary = "Validate YAML files against schemas or validate compiled plugins";
|
|
205
251
|
static description = "Validates skill/agent YAML files against JSON schemas, or validates compiled plugin structure and content. Without arguments, validates all YAML files in the current directory against their schemas. With a path argument or --plugins flag, validates plugin(s) instead.";
|
|
252
|
+
static examples = [
|
|
253
|
+
{
|
|
254
|
+
description: "Validate all YAML schemas",
|
|
255
|
+
command: "<%= config.bin %> <%= command.id %>"
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
description: "Validate a specific plugin",
|
|
259
|
+
command: "<%= config.bin %> <%= command.id %> ./path/to/plugin"
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
description: "Validate all plugins in a directory",
|
|
263
|
+
command: "<%= config.bin %> <%= command.id %> ./plugins --all"
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
description: "Validate plugins with verbose output",
|
|
267
|
+
command: "<%= config.bin %> <%= command.id %> --plugins --verbose"
|
|
268
|
+
}
|
|
269
|
+
];
|
|
206
270
|
static args = {
|
|
207
271
|
path: Args.string({
|
|
208
272
|
description: "Path to plugin or plugins directory to validate",
|
|
@@ -248,8 +312,8 @@ var Validate = class _Validate extends BaseCommand {
|
|
|
248
312
|
this.exit(EXIT_CODES.ERROR);
|
|
249
313
|
}
|
|
250
314
|
} catch (error) {
|
|
251
|
-
const message =
|
|
252
|
-
this.error(
|
|
315
|
+
const message = getErrorMessage(error);
|
|
316
|
+
this.error(`${ERROR_MESSAGES.VALIDATION_FAILED}: ${message}`, { exit: EXIT_CODES.ERROR });
|
|
253
317
|
}
|
|
254
318
|
}
|
|
255
319
|
async validatePlugins(pluginPath, verbose, all) {
|
|
@@ -284,14 +348,14 @@ var Validate = class _Validate extends BaseCommand {
|
|
|
284
348
|
this.log("");
|
|
285
349
|
} else {
|
|
286
350
|
this.log("");
|
|
287
|
-
this.error(
|
|
351
|
+
this.error(ERROR_MESSAGES.VALIDATION_FAILED, { exit: EXIT_CODES.ERROR });
|
|
288
352
|
}
|
|
289
353
|
} catch (error) {
|
|
290
|
-
const message =
|
|
291
|
-
this.error(
|
|
354
|
+
const message = getErrorMessage(error);
|
|
355
|
+
this.error(`${ERROR_MESSAGES.VALIDATION_FAILED}: ${message}`, { exit: EXIT_CODES.ERROR });
|
|
292
356
|
}
|
|
293
357
|
}
|
|
294
|
-
async validateSinglePlugin(targetPath,
|
|
358
|
+
async validateSinglePlugin(targetPath, _verbose) {
|
|
295
359
|
this.log("");
|
|
296
360
|
this.log(`Validating plugin: ${targetPath}`);
|
|
297
361
|
this.log("");
|
|
@@ -310,11 +374,11 @@ var Validate = class _Validate extends BaseCommand {
|
|
|
310
374
|
this.log("");
|
|
311
375
|
} else {
|
|
312
376
|
this.log("");
|
|
313
|
-
this.error(
|
|
377
|
+
this.error(ERROR_MESSAGES.VALIDATION_FAILED, { exit: EXIT_CODES.ERROR });
|
|
314
378
|
}
|
|
315
379
|
} catch (error) {
|
|
316
|
-
const message =
|
|
317
|
-
this.error(
|
|
380
|
+
const message = getErrorMessage(error);
|
|
381
|
+
this.error(`${ERROR_MESSAGES.VALIDATION_FAILED}: ${message}`, { exit: EXIT_CODES.ERROR });
|
|
318
382
|
}
|
|
319
383
|
}
|
|
320
384
|
};
|