@claude-collective/cli 0.13.4 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +183 -0
- package/config/skills-matrix.yaml +180 -113
- package/config/stacks.yaml +6 -6
- package/dist/{chunk-K3NB6DSG.js → chunk-2LSGX6R4.js} +54 -114
- package/dist/chunk-2LSGX6R4.js.map +1 -0
- package/dist/chunk-2OKUEELH.js +32 -0
- package/dist/chunk-2OKUEELH.js.map +1 -0
- package/dist/{chunk-V46GGCCI.js → chunk-374JNMR6.js} +14 -96
- package/dist/chunk-374JNMR6.js.map +1 -0
- package/dist/chunk-3EHUF54X.js +133 -0
- package/dist/chunk-3EHUF54X.js.map +1 -0
- package/dist/{chunk-7Q44DMSP.js → chunk-3XR4PALU.js} +92 -145
- package/dist/chunk-3XR4PALU.js.map +1 -0
- package/dist/{chunk-IAUAQJQ2.js → chunk-5K2ZLUO5.js} +5 -5
- package/dist/{chunk-IAUAQJQ2.js.map → chunk-5K2ZLUO5.js.map} +1 -1
- package/dist/{chunk-ACNBKXXJ.js → chunk-5KXUDHAB.js} +8 -36
- package/dist/chunk-5KXUDHAB.js.map +1 -0
- package/dist/chunk-7SLV7CMF.js +615 -0
- package/dist/chunk-7SLV7CMF.js.map +1 -0
- package/dist/{chunk-CDX4W4DM.js → chunk-A46TPNBJ.js} +61 -32
- package/dist/chunk-A46TPNBJ.js.map +1 -0
- package/dist/{chunk-TKFPKEV3.js → chunk-AL74GBW4.js} +1 -1
- package/dist/chunk-AL74GBW4.js.map +1 -0
- package/dist/chunk-BQX23RBV.js +191 -0
- package/dist/chunk-BQX23RBV.js.map +1 -0
- package/dist/{chunk-IMDW5ZUP.js → chunk-CA4LH4LI.js} +5 -5
- package/dist/chunk-CA4LH4LI.js.map +1 -0
- package/dist/{chunk-D237EVNB.js → chunk-CBLPAMZO.js} +5 -8
- package/dist/chunk-CBLPAMZO.js.map +1 -0
- package/dist/{chunk-B7CCVP6Q.js → chunk-CKPQHGXR.js} +52 -274
- package/dist/chunk-CKPQHGXR.js.map +1 -0
- package/dist/{chunk-SVYPSDWY.js → chunk-CXOFOJCN.js} +6 -10
- package/dist/chunk-CXOFOJCN.js.map +1 -0
- package/dist/{chunk-UQTEPWU7.js → chunk-EHGD7HIE.js} +2 -6
- package/dist/chunk-EHGD7HIE.js.map +1 -0
- package/dist/{chunk-76DWXGQE.js → chunk-FJFEKPXF.js} +1 -1
- package/dist/chunk-FJFEKPXF.js.map +1 -0
- package/dist/{chunk-E3FJH4TF.js → chunk-HEOHU5EZ.js} +2 -13
- package/dist/chunk-HEOHU5EZ.js.map +1 -0
- package/dist/{chunk-JIPWV2FX.js → chunk-HGCBZUH5.js} +6 -27
- package/dist/chunk-HGCBZUH5.js.map +1 -0
- package/dist/{chunk-ED4E6Q2T.js → chunk-HPGFY5ZN.js} +4 -4
- package/dist/chunk-HPGFY5ZN.js.map +1 -0
- package/dist/chunk-INJ2EFRW.js +127 -0
- package/dist/chunk-INJ2EFRW.js.map +1 -0
- package/dist/{chunk-KAAEN2PO.js → chunk-IOBFMF6X.js} +6 -2
- package/dist/{chunk-KAAEN2PO.js.map → chunk-IOBFMF6X.js.map} +1 -1
- package/dist/{chunk-K7EVM5LY.js → chunk-KH3HA7J7.js} +8 -33
- package/dist/chunk-KH3HA7J7.js.map +1 -0
- package/dist/{chunk-4K4ZXQRM.js → chunk-N6JNE326.js} +38 -94
- package/dist/chunk-N6JNE326.js.map +1 -0
- package/dist/chunk-NAGU7TVZ.js +36 -0
- package/dist/chunk-NAGU7TVZ.js.map +1 -0
- package/dist/{chunk-Z7G4B5HJ.js → chunk-OQYYMQJR.js} +68 -142
- package/dist/chunk-OQYYMQJR.js.map +1 -0
- package/dist/{chunk-RFTSZDHV.js → chunk-PLZOUVDD.js} +159 -53
- package/dist/chunk-PLZOUVDD.js.map +1 -0
- package/dist/chunk-Q3J43SF3.js +21 -0
- package/dist/chunk-Q3J43SF3.js.map +1 -0
- package/dist/{chunk-3U3R4NCG.js → chunk-T25OEQFI.js} +6 -2
- package/dist/chunk-T25OEQFI.js.map +1 -0
- package/dist/chunk-UMORK7OK.js +29 -0
- package/dist/chunk-UMORK7OK.js.map +1 -0
- package/dist/{chunk-ZFPSUQOU.js → chunk-VFHWU7JU.js} +12 -121
- package/dist/chunk-VFHWU7JU.js.map +1 -0
- package/dist/{chunk-GDH553MV.js → chunk-VS4GVTZE.js} +3 -3
- package/dist/chunk-VS4GVTZE.js.map +1 -0
- package/dist/chunk-WFEFICFM.js +67 -0
- package/dist/chunk-WFEFICFM.js.map +1 -0
- package/dist/{chunk-P26A2K5N.js → chunk-WG6KIAPK.js} +6 -16
- package/dist/chunk-WG6KIAPK.js.map +1 -0
- package/dist/{chunk-X6QONICW.js → chunk-ZEI3ZUDU.js} +3 -7
- package/dist/chunk-ZEI3ZUDU.js.map +1 -0
- package/dist/chunk-ZNIDWLL5.js +68 -0
- package/dist/chunk-ZNIDWLL5.js.map +1 -0
- package/dist/chunk-ZSVMS677.js +45 -0
- package/dist/chunk-ZSVMS677.js.map +1 -0
- package/dist/cli/defaults/agent-mappings.yaml +13 -13
- package/dist/commands/build/marketplace.js +8 -14
- package/dist/commands/build/marketplace.js.map +1 -1
- package/dist/commands/build/plugins.js +10 -21
- package/dist/commands/build/plugins.js.map +1 -1
- package/dist/commands/build/stack.js +13 -18
- package/dist/commands/build/stack.js.map +1 -1
- package/dist/commands/compile.js +25 -40
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/config/get.js +7 -7
- package/dist/commands/config/get.js.map +1 -1
- package/dist/commands/config/index.js +6 -6
- package/dist/commands/config/index.js.map +1 -1
- package/dist/commands/config/path.js +5 -7
- package/dist/commands/config/path.js.map +1 -1
- package/dist/commands/config/set-project.js +8 -9
- package/dist/commands/config/set-project.js.map +1 -1
- package/dist/commands/config/show.js +5 -5
- package/dist/commands/config/unset-project.js +8 -9
- package/dist/commands/config/unset-project.js.map +1 -1
- package/dist/commands/diff.js +17 -40
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/doctor.js +14 -25
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +41 -54
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +24 -44
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/import/skill.js +19 -39
- package/dist/commands/import/skill.js.map +1 -1
- package/dist/commands/info.js +10 -15
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/init.js +452 -451
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/list.js +85 -9
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/agent.js +9 -10
- package/dist/commands/new/agent.js.map +1 -1
- package/dist/commands/new/skill.js +12 -16
- package/dist/commands/new/skill.js.map +1 -1
- package/dist/commands/outdated.js +12 -89
- package/dist/commands/outdated.js.map +1 -1
- package/dist/commands/search.js +12 -18
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/uninstall.js +12 -21
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +26 -146
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/validate.js +407 -15
- package/dist/commands/validate.js.map +1 -1
- package/dist/commands/version/bump.js +7 -23
- package/dist/commands/version/bump.js.map +1 -1
- package/dist/commands/version/index.js +6 -21
- package/dist/commands/version/index.js.map +1 -1
- package/dist/commands/version/set.js +6 -23
- package/dist/commands/version/set.js.map +1 -1
- package/dist/commands/version/show.js +6 -21
- package/dist/commands/version/show.js.map +1 -1
- package/dist/components/common/message.js +2 -6
- package/dist/components/common/message.js.map +1 -1
- package/dist/components/common/spinner.js.map +1 -1
- package/dist/components/skill-search/skill-search.js +1 -1
- package/dist/components/wizard/category-grid.js +1 -1
- package/dist/components/wizard/category-grid.test.js +20 -92
- package/dist/components/wizard/category-grid.test.js.map +1 -1
- package/dist/components/wizard/menu-item.js +9 -0
- package/dist/components/wizard/section-progress.js +1 -1
- package/dist/components/wizard/section-progress.test.js +13 -103
- package/dist/components/wizard/section-progress.test.js.map +1 -1
- package/dist/components/wizard/step-approach.js +5 -4
- package/dist/components/wizard/step-build.js +3 -4
- package/dist/components/wizard/step-build.test.js +81 -186
- package/dist/components/wizard/step-build.test.js.map +1 -1
- package/dist/components/wizard/step-confirm.js +1 -2
- package/dist/components/wizard/step-refine.js +1 -2
- package/dist/components/wizard/step-refine.test.js +6 -14
- package/dist/components/wizard/step-refine.test.js.map +1 -1
- package/dist/components/wizard/step-stack.js +5 -3
- package/dist/components/wizard/view-title.js +9 -0
- package/dist/components/wizard/wizard-layout.js +16 -0
- package/dist/components/wizard/wizard-layout.js.map +1 -0
- package/dist/components/wizard/wizard-tabs.js +1 -1
- package/dist/components/wizard/wizard.js +12 -13
- package/dist/config/skills-matrix.yaml +180 -113
- package/dist/config/stacks.yaml +6 -6
- package/dist/hooks/init.js +5 -7
- package/dist/hooks/init.js.map +1 -1
- package/dist/src/agents/developer/web-developer/examples.md +1 -6
- package/dist/src/agents/meta/documentor/workflow.md +1 -5
- package/dist/src/agents/migration/cli-migrator/anti-patterns.md +1 -3
- package/dist/src/agents/tester/web-tester/output-format.md +1 -3
- package/dist/stores/wizard-store.js +2 -2
- package/dist/stores/wizard-store.test.js +60 -23
- package/dist/stores/wizard-store.test.js.map +1 -1
- package/package.json +1 -1
- package/src/agents/developer/web-developer/examples.md +1 -6
- package/src/agents/meta/documentor/workflow.md +1 -5
- package/src/agents/migration/cli-migrator/anti-patterns.md +1 -3
- package/src/agents/tester/web-tester/output-format.md +1 -3
- package/dist/chunk-3U3R4NCG.js.map +0 -1
- package/dist/chunk-4K4ZXQRM.js.map +0 -1
- package/dist/chunk-76DWXGQE.js.map +0 -1
- package/dist/chunk-7Q44DMSP.js.map +0 -1
- package/dist/chunk-ACNBKXXJ.js.map +0 -1
- package/dist/chunk-B7CCVP6Q.js.map +0 -1
- package/dist/chunk-BDLUZVKU.js +0 -54
- package/dist/chunk-BDLUZVKU.js.map +0 -1
- package/dist/chunk-CDX4W4DM.js.map +0 -1
- package/dist/chunk-D237EVNB.js.map +0 -1
- package/dist/chunk-DRXPNNPB.js +0 -393
- package/dist/chunk-DRXPNNPB.js.map +0 -1
- package/dist/chunk-E3FJH4TF.js.map +0 -1
- package/dist/chunk-ED4E6Q2T.js.map +0 -1
- package/dist/chunk-GDH553MV.js.map +0 -1
- package/dist/chunk-HLJX2FTL.js +0 -95
- package/dist/chunk-HLJX2FTL.js.map +0 -1
- package/dist/chunk-I2DSLOXZ.js +0 -75
- package/dist/chunk-I2DSLOXZ.js.map +0 -1
- package/dist/chunk-I4TPKIYX.js +0 -493
- package/dist/chunk-I4TPKIYX.js.map +0 -1
- package/dist/chunk-IBE7JIAG.js +0 -129
- package/dist/chunk-IBE7JIAG.js.map +0 -1
- package/dist/chunk-IMDW5ZUP.js.map +0 -1
- package/dist/chunk-JIPWV2FX.js.map +0 -1
- package/dist/chunk-K3NB6DSG.js.map +0 -1
- package/dist/chunk-K7EVM5LY.js.map +0 -1
- package/dist/chunk-NDY25DTL.js +0 -453
- package/dist/chunk-NDY25DTL.js.map +0 -1
- package/dist/chunk-P26A2K5N.js.map +0 -1
- package/dist/chunk-RFTSZDHV.js.map +0 -1
- package/dist/chunk-SVYPSDWY.js.map +0 -1
- package/dist/chunk-TKFPKEV3.js.map +0 -1
- package/dist/chunk-UQTEPWU7.js.map +0 -1
- package/dist/chunk-V46GGCCI.js.map +0 -1
- package/dist/chunk-X6QONICW.js.map +0 -1
- package/dist/chunk-Y2LW7R3Y.js +0 -23
- package/dist/chunk-Y2LW7R3Y.js.map +0 -1
- package/dist/chunk-Z7G4B5HJ.js.map +0 -1
- package/dist/chunk-ZENYS6KW.js +0 -90
- package/dist/chunk-ZENYS6KW.js.map +0 -1
- package/dist/chunk-ZFPSUQOU.js.map +0 -1
- package/dist/commands/config/set.js +0 -61
- package/dist/commands/config/set.js.map +0 -1
- package/dist/commands/config/unset.js +0 -57
- package/dist/commands/config/unset.js.map +0 -1
- package/dist/commands/test-imports.js +0 -92
- package/dist/commands/test-imports.js.map +0 -1
- package/dist/components/wizard/step-stack-options.js +0 -11
- package/dist/components/wizard/wizard-footer.js +0 -9
- /package/dist/components/wizard/{step-stack-options.js.map → menu-item.js.map} +0 -0
- /package/dist/components/wizard/{wizard-footer.js.map → view-title.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/plugin-finder\";\nimport { CLAUDE_DIR, CLAUDE_SRC_DIR } from \"../consts\";\nimport { EXIT_CODES } from \"../lib/exit-codes\";\n\nconst PLUGIN_NAME = \"claude-collective\";\n\ninterface 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(\n projectDir: string,\n): 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 [\n hasPlugin,\n hasLocalSkills,\n hasLocalAgents,\n hasLocalConfig,\n hasClaudeDir,\n 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\ninterface 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 =\n 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 && (\n <Text dimColor> {target.claudeSrcDir}/</Text>\n )}\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 // Detect what's installed\n const target = await detectInstallation(projectDir);\n\n // Determine what to uninstall based on flags\n const uninstallPlugin = !flags.local;\n const uninstallLocal = !flags.plugin;\n\n // Check if there's anything to uninstall\n const hasPluginToRemove = uninstallPlugin && target.hasPlugin;\n const hasLocalToRemove =\n 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 // Show what will be removed and get confirmation (unless --yes or --dry-run)\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 // In dry-run or --yes mode, just show what will be removed\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 // Dry run - show what would happen\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 // Uninstall plugin\n if (hasPluginToRemove) {\n this.log(\"Uninstalling plugin...\");\n\n try {\n // Try to use claude CLI to uninstall (handles settings.json)\n const cliAvailable = await isClaudeCLIAvailable();\n if (cliAvailable) {\n await claudePluginUninstall(PLUGIN_NAME, \"project\", projectDir);\n }\n\n // Remove plugin directory\n await remove(target.pluginDir);\n\n this.logSuccess(\"Plugin uninstalled\");\n } catch (error) {\n this.log(\"Plugin uninstall failed\");\n this.error(\n error instanceof Error ? error.message : \"Unknown error occurred\",\n { exit: EXIT_CODES.ERROR },\n );\n }\n }\n\n // Remove local directories\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(\n 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\";\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/plugin-finder\";\nimport { CLAUDE_DIR, CLAUDE_SRC_DIR } from \"../consts\";\nimport { EXIT_CODES } from \"../lib/exit-codes\";\n\nconst PLUGIN_NAME = \"claude-collective\";\n\ninterface 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\ninterface 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 // Detect what's installed\n const target = await detectInstallation(projectDir);\n\n // Determine what to uninstall based on flags\n const uninstallPlugin = !flags.local;\n const uninstallLocal = !flags.plugin;\n\n // Check if there's anything to uninstall\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 // Show what will be removed and get confirmation (unless --yes or --dry-run)\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 // In dry-run or --yes mode, just show what will be removed\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 // Dry run - show what would happen\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 // Uninstall plugin\n if (hasPluginToRemove) {\n this.log(\"Uninstalling plugin...\");\n\n try {\n // Try to use claude CLI to uninstall (handles settings.json)\n const cliAvailable = await isClaudeCLIAvailable();\n if (cliAvailable) {\n await claudePluginUninstall(PLUGIN_NAME, \"project\", projectDir);\n }\n\n // Remove plugin directory\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 // Remove local directories\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":[]}
|
package/dist/commands/update.js
CHANGED
|
@@ -4,38 +4,37 @@ import {
|
|
|
4
4
|
} from "../chunk-RTE64SJA.js";
|
|
5
5
|
import {
|
|
6
6
|
recompileAgents
|
|
7
|
-
} from "../chunk-
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
10
|
-
import "../chunk-I4TPKIYX.js";
|
|
7
|
+
} from "../chunk-N6JNE326.js";
|
|
8
|
+
import "../chunk-7SLV7CMF.js";
|
|
9
|
+
import "../chunk-VS4GVTZE.js";
|
|
11
10
|
import {
|
|
12
11
|
getCollectivePluginDir
|
|
13
|
-
} from "../chunk-
|
|
14
|
-
import "../chunk-
|
|
12
|
+
} from "../chunk-HPGFY5ZN.js";
|
|
13
|
+
import "../chunk-VFHWU7JU.js";
|
|
15
14
|
import {
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
compareSkills,
|
|
16
|
+
injectForkedFromMetadata
|
|
17
|
+
} from "../chunk-INJ2EFRW.js";
|
|
18
|
+
import "../chunk-IOBFMF6X.js";
|
|
18
19
|
import {
|
|
19
20
|
loadSkillsMatrixFromSource
|
|
20
|
-
} from "../chunk-
|
|
21
|
-
import "../chunk-
|
|
22
|
-
import "../chunk-
|
|
21
|
+
} from "../chunk-PLZOUVDD.js";
|
|
22
|
+
import "../chunk-CKPQHGXR.js";
|
|
23
|
+
import "../chunk-CA4LH4LI.js";
|
|
24
|
+
import "../chunk-BQX23RBV.js";
|
|
23
25
|
import {
|
|
24
26
|
BaseCommand,
|
|
25
27
|
EXIT_CODES
|
|
26
28
|
} from "../chunk-EHS3TWWP.js";
|
|
27
|
-
import "../chunk-
|
|
28
|
-
import "../chunk-
|
|
29
|
+
import "../chunk-374JNMR6.js";
|
|
30
|
+
import "../chunk-T25OEQFI.js";
|
|
29
31
|
import {
|
|
30
32
|
copy,
|
|
31
|
-
fileExists
|
|
32
|
-
|
|
33
|
-
readFile,
|
|
34
|
-
writeFile
|
|
35
|
-
} from "../chunk-TKFPKEV3.js";
|
|
33
|
+
fileExists
|
|
34
|
+
} from "../chunk-AL74GBW4.js";
|
|
36
35
|
import {
|
|
37
36
|
LOCAL_SKILLS_PATH
|
|
38
|
-
} from "../chunk-
|
|
37
|
+
} from "../chunk-FJFEKPXF.js";
|
|
39
38
|
import {
|
|
40
39
|
init_esm_shims
|
|
41
40
|
} from "../chunk-DHET7RCE.js";
|
|
@@ -46,109 +45,7 @@ import { render } from "ink";
|
|
|
46
45
|
import { Flags, Args } from "@oclif/core";
|
|
47
46
|
import { printTable } from "@oclif/table";
|
|
48
47
|
import path from "path";
|
|
49
|
-
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
50
48
|
import { jsx } from "react/jsx-runtime";
|
|
51
|
-
async function readForkedFromMetadata(skillDir) {
|
|
52
|
-
const metadataPath = path.join(skillDir, "metadata.yaml");
|
|
53
|
-
if (!await fileExists(metadataPath)) {
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
const content = await readFile(metadataPath);
|
|
57
|
-
const metadata = parseYaml(content);
|
|
58
|
-
return metadata.forked_from ?? null;
|
|
59
|
-
}
|
|
60
|
-
async function getLocalSkillsWithMetadata(projectDir) {
|
|
61
|
-
const localSkillsPath = path.join(projectDir, LOCAL_SKILLS_PATH);
|
|
62
|
-
const result = /* @__PURE__ */ new Map();
|
|
63
|
-
if (!await fileExists(localSkillsPath)) {
|
|
64
|
-
return result;
|
|
65
|
-
}
|
|
66
|
-
const skillDirs = await listDirectories(localSkillsPath);
|
|
67
|
-
for (const dirName of skillDirs) {
|
|
68
|
-
const skillDir = path.join(localSkillsPath, dirName);
|
|
69
|
-
const forkedFrom = await readForkedFromMetadata(skillDir);
|
|
70
|
-
const skillId = forkedFrom?.skill_id ?? dirName;
|
|
71
|
-
result.set(skillId, { dirName, forkedFrom });
|
|
72
|
-
}
|
|
73
|
-
return result;
|
|
74
|
-
}
|
|
75
|
-
async function computeSourceHash(sourcePath, skillPath) {
|
|
76
|
-
const skillMdPath = path.join(sourcePath, "src", skillPath, "SKILL.md");
|
|
77
|
-
if (!await fileExists(skillMdPath)) {
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
return hashFile(skillMdPath);
|
|
81
|
-
}
|
|
82
|
-
function getCurrentDate() {
|
|
83
|
-
return (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
84
|
-
}
|
|
85
|
-
async function compareSkills(projectDir, sourcePath, sourceSkills) {
|
|
86
|
-
const results = [];
|
|
87
|
-
const localSkills = await getLocalSkillsWithMetadata(projectDir);
|
|
88
|
-
for (const [skillId, { dirName, forkedFrom }] of localSkills) {
|
|
89
|
-
if (!forkedFrom) {
|
|
90
|
-
results.push({
|
|
91
|
-
id: skillId,
|
|
92
|
-
localHash: null,
|
|
93
|
-
sourceHash: null,
|
|
94
|
-
status: "local-only",
|
|
95
|
-
dirName
|
|
96
|
-
});
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
|
-
const localHash = forkedFrom.content_hash;
|
|
100
|
-
const sourceSkill = sourceSkills[forkedFrom.skill_id];
|
|
101
|
-
if (!sourceSkill) {
|
|
102
|
-
results.push({
|
|
103
|
-
id: forkedFrom.skill_id,
|
|
104
|
-
localHash,
|
|
105
|
-
sourceHash: null,
|
|
106
|
-
status: "local-only",
|
|
107
|
-
dirName
|
|
108
|
-
});
|
|
109
|
-
continue;
|
|
110
|
-
}
|
|
111
|
-
const sourceHash = await computeSourceHash(sourcePath, sourceSkill.path);
|
|
112
|
-
if (sourceHash === null) {
|
|
113
|
-
results.push({
|
|
114
|
-
id: forkedFrom.skill_id,
|
|
115
|
-
localHash,
|
|
116
|
-
sourceHash: null,
|
|
117
|
-
status: "local-only",
|
|
118
|
-
dirName
|
|
119
|
-
});
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
const status = localHash === sourceHash ? "current" : "outdated";
|
|
123
|
-
results.push({
|
|
124
|
-
id: forkedFrom.skill_id,
|
|
125
|
-
localHash,
|
|
126
|
-
sourceHash,
|
|
127
|
-
status,
|
|
128
|
-
dirName,
|
|
129
|
-
sourcePath: sourceSkill.path
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
results.sort((a, b) => a.id.localeCompare(b.id));
|
|
133
|
-
return results;
|
|
134
|
-
}
|
|
135
|
-
async function updateForkedFromMetadata(skillDir, skillId, contentHash) {
|
|
136
|
-
const metadataPath = path.join(skillDir, "metadata.yaml");
|
|
137
|
-
const rawContent = await readFile(metadataPath);
|
|
138
|
-
const lines = rawContent.split("\n");
|
|
139
|
-
let yamlContent = rawContent;
|
|
140
|
-
if (lines[0]?.startsWith("# yaml-language-server:")) {
|
|
141
|
-
yamlContent = lines.slice(1).join("\n");
|
|
142
|
-
}
|
|
143
|
-
const metadata = parseYaml(yamlContent);
|
|
144
|
-
metadata.forked_from = {
|
|
145
|
-
skill_id: skillId,
|
|
146
|
-
content_hash: contentHash,
|
|
147
|
-
date: getCurrentDate()
|
|
148
|
-
};
|
|
149
|
-
const newYamlContent = stringifyYaml(metadata, { lineWidth: 0 });
|
|
150
|
-
await writeFile(metadataPath, newYamlContent);
|
|
151
|
-
}
|
|
152
49
|
async function updateSkill(skill, projectDir, sourceResult) {
|
|
153
50
|
if (!skill.sourcePath || !skill.sourceHash) {
|
|
154
51
|
return { success: false, newHash: null, error: "No source path available" };
|
|
@@ -158,7 +55,7 @@ async function updateSkill(skill, projectDir, sourceResult) {
|
|
|
158
55
|
const srcPath = path.join(sourceResult.sourcePath, "src", skill.sourcePath);
|
|
159
56
|
try {
|
|
160
57
|
await copy(srcPath, destPath);
|
|
161
|
-
await
|
|
58
|
+
await injectForkedFromMetadata(destPath, skill.id, skill.sourceHash);
|
|
162
59
|
return { success: true, newHash: skill.sourceHash };
|
|
163
60
|
} catch (error) {
|
|
164
61
|
return {
|
|
@@ -176,9 +73,7 @@ function findSkillByPartialMatch(skillName, results) {
|
|
|
176
73
|
return nameWithoutAuthor === skillName.toLowerCase();
|
|
177
74
|
});
|
|
178
75
|
if (partial) return partial;
|
|
179
|
-
const byDir = results.find(
|
|
180
|
-
(r) => r.dirName.toLowerCase() === skillName.toLowerCase()
|
|
181
|
-
);
|
|
76
|
+
const byDir = results.find((r) => r.dirName.toLowerCase() === skillName.toLowerCase());
|
|
182
77
|
if (byDir) return byDir;
|
|
183
78
|
return null;
|
|
184
79
|
}
|
|
@@ -190,10 +85,7 @@ function findSimilarSkills(skillName, results) {
|
|
|
190
85
|
return name.includes(lowered) || dir.includes(lowered) || lowered.includes(name.split(" ")[0]);
|
|
191
86
|
}).map((r) => r.id).slice(0, 3);
|
|
192
87
|
}
|
|
193
|
-
var UpdateConfirm = ({
|
|
194
|
-
onConfirm,
|
|
195
|
-
onCancel
|
|
196
|
-
}) => {
|
|
88
|
+
var UpdateConfirm = ({ onConfirm, onCancel }) => {
|
|
197
89
|
return /* @__PURE__ */ jsx(
|
|
198
90
|
Confirm,
|
|
199
91
|
{
|
|
@@ -251,18 +143,12 @@ var Update = class _Update extends BaseCommand {
|
|
|
251
143
|
`Loaded from ${sourceResult.isLocal ? "local" : "remote"}: ${sourceResult.sourcePath}`
|
|
252
144
|
);
|
|
253
145
|
const sourceSkills = {};
|
|
254
|
-
for (const [skillId, skill] of Object.entries(
|
|
255
|
-
sourceResult.matrix.skills
|
|
256
|
-
)) {
|
|
146
|
+
for (const [skillId, skill] of Object.entries(sourceResult.matrix.skills)) {
|
|
257
147
|
if (!skill.local) {
|
|
258
148
|
sourceSkills[skillId] = { path: skill.path };
|
|
259
149
|
}
|
|
260
150
|
}
|
|
261
|
-
const allResults = await compareSkills(
|
|
262
|
-
projectDir,
|
|
263
|
-
sourceResult.sourcePath,
|
|
264
|
-
sourceSkills
|
|
265
|
-
);
|
|
151
|
+
const allResults = await compareSkills(projectDir, sourceResult.sourcePath, sourceSkills);
|
|
266
152
|
let outdatedSkills = allResults.filter((r) => r.status === "outdated");
|
|
267
153
|
if (args.skill) {
|
|
268
154
|
const foundSkill = findSkillByPartialMatch(args.skill, allResults);
|
|
@@ -278,9 +164,7 @@ var Update = class _Update extends BaseCommand {
|
|
|
278
164
|
}
|
|
279
165
|
this.log("");
|
|
280
166
|
}
|
|
281
|
-
this.log(
|
|
282
|
-
`Run \`cc search ${args.skill}\` to search available skills.`
|
|
283
|
-
);
|
|
167
|
+
this.log(`Run \`cc search ${args.skill}\` to search available skills.`);
|
|
284
168
|
this.log("");
|
|
285
169
|
this.error("Skill not found", { exit: EXIT_CODES.ERROR });
|
|
286
170
|
}
|
|
@@ -295,9 +179,7 @@ var Update = class _Update extends BaseCommand {
|
|
|
295
179
|
}
|
|
296
180
|
if (foundSkill.status === "local-only") {
|
|
297
181
|
this.log("");
|
|
298
|
-
this.log(
|
|
299
|
-
`Skill "${foundSkill.id}" is a local-only skill (not forked from source).`
|
|
300
|
-
);
|
|
182
|
+
this.log(`Skill "${foundSkill.id}" is a local-only skill (not forked from source).`);
|
|
301
183
|
this.log("Cannot update local-only skills.");
|
|
302
184
|
this.log("");
|
|
303
185
|
return;
|
|
@@ -404,9 +286,7 @@ var Update = class _Update extends BaseCommand {
|
|
|
404
286
|
this.log("");
|
|
405
287
|
if (failed.length === 0) {
|
|
406
288
|
const agentMsg = recompiledAgents.length > 0 ? `, ${recompiledAgents.length} agent(s) recompiled` : "";
|
|
407
|
-
this.logSuccess(
|
|
408
|
-
`Update complete! ${updated.length} skill(s) updated${agentMsg}.`
|
|
409
|
-
);
|
|
289
|
+
this.logSuccess(`Update complete! ${updated.length} skill(s) updated${agentMsg}.`);
|
|
410
290
|
} else {
|
|
411
291
|
this.warn(
|
|
412
292
|
`Update finished with errors: ${updated.length} updated, ${failed.length} failed.`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/commands/update.tsx"],"sourcesContent":["import React, { useState } from \"react\";\nimport { render } from \"ink\";\nimport { Flags, Args } from \"@oclif/core\";\nimport { printTable } from \"@oclif/table\";\nimport path from \"path\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { BaseCommand } from \"../base-command.js\";\nimport {\n loadSkillsMatrixFromSource,\n type SourceLoadResult,\n} from \"../lib/source-loader.js\";\nimport { hashFile } from \"../lib/versioning.js\";\nimport { recompileAgents } from \"../lib/agent-recompiler.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport {\n fileExists,\n readFile,\n writeFile,\n listDirectories,\n copy,\n} from \"../utils/fs.js\";\nimport { LOCAL_SKILLS_PATH } from \"../consts.js\";\nimport { getCollectivePluginDir } from \"../lib/plugin-finder.js\";\nimport { Confirm } from \"../components/common/confirm.js\";\n\n/**\n * ForkedFrom metadata stored in local skill's metadata.yaml\n */\ninterface ForkedFromMetadata {\n skill_id: string;\n content_hash: string;\n date: string;\n}\n\n/**\n * Local skill metadata structure\n */\ninterface LocalSkillMetadata {\n forked_from?: ForkedFromMetadata;\n [key: string]: unknown;\n}\n\n/**\n * Result of comparing a local skill to its source\n */\ninterface SkillComparisonResult {\n id: string;\n localHash: string | null;\n sourceHash: string | null;\n status: \"current\" | \"outdated\" | \"local-only\";\n dirName: string;\n sourcePath?: string;\n}\n\n/**\n * Read forked_from metadata from a local skill's metadata.yaml\n */\nasync function readForkedFromMetadata(\n skillDir: string,\n): Promise<ForkedFromMetadata | null> {\n const metadataPath = path.join(skillDir, \"metadata.yaml\");\n\n if (!(await fileExists(metadataPath))) {\n return null;\n }\n\n const content = await readFile(metadataPath);\n const metadata = parseYaml(content) as LocalSkillMetadata;\n\n return metadata.forked_from ?? null;\n}\n\n/**\n * Get local skills with their forked_from metadata\n */\nasync function getLocalSkillsWithMetadata(\n projectDir: string,\n): Promise<\n Map<string, { dirName: string; forkedFrom: ForkedFromMetadata | null }>\n> {\n const localSkillsPath = path.join(projectDir, LOCAL_SKILLS_PATH);\n const result = new Map<\n string,\n { dirName: string; forkedFrom: ForkedFromMetadata | null }\n >();\n\n if (!(await fileExists(localSkillsPath))) {\n return result;\n }\n\n const skillDirs = await listDirectories(localSkillsPath);\n\n for (const dirName of skillDirs) {\n const skillDir = path.join(localSkillsPath, dirName);\n const forkedFrom = await readForkedFromMetadata(skillDir);\n\n // Use the skill_id from forked_from if available, otherwise use directory name\n const skillId = forkedFrom?.skill_id ?? dirName;\n\n result.set(skillId, { dirName, forkedFrom });\n }\n\n return result;\n}\n\n/**\n * Compute source hash for a skill's SKILL.md file\n */\nasync function computeSourceHash(\n sourcePath: string,\n skillPath: string,\n): Promise<string | null> {\n const skillMdPath = path.join(sourcePath, \"src\", skillPath, \"SKILL.md\");\n\n if (!(await fileExists(skillMdPath))) {\n return null;\n }\n\n return hashFile(skillMdPath);\n}\n\n/**\n * Get the current date in ISO format (YYYY-MM-DD)\n */\nfunction getCurrentDate(): string {\n return new Date().toISOString().split(\"T\")[0];\n}\n\n/**\n * Compare local skills against source and determine status\n */\nasync function compareSkills(\n projectDir: string,\n sourcePath: string,\n sourceSkills: Record<string, { path: string }>,\n): Promise<SkillComparisonResult[]> {\n const results: SkillComparisonResult[] = [];\n const localSkills = await getLocalSkillsWithMetadata(projectDir);\n\n for (const [skillId, { dirName, forkedFrom }] of localSkills) {\n if (!forkedFrom) {\n // Local-only skill (no forked_from metadata)\n results.push({\n id: skillId,\n localHash: null,\n sourceHash: null,\n status: \"local-only\",\n dirName,\n });\n continue;\n }\n\n const localHash = forkedFrom.content_hash;\n const sourceSkill = sourceSkills[forkedFrom.skill_id];\n\n if (!sourceSkill) {\n // Skill was forked from a source that no longer exists\n results.push({\n id: forkedFrom.skill_id,\n localHash,\n sourceHash: null,\n status: \"local-only\",\n dirName,\n });\n continue;\n }\n\n const sourceHash = await computeSourceHash(sourcePath, sourceSkill.path);\n\n if (sourceHash === null) {\n results.push({\n id: forkedFrom.skill_id,\n localHash,\n sourceHash: null,\n status: \"local-only\",\n dirName,\n });\n continue;\n }\n\n const status = localHash === sourceHash ? \"current\" : \"outdated\";\n\n results.push({\n id: forkedFrom.skill_id,\n localHash,\n sourceHash,\n status,\n dirName,\n sourcePath: sourceSkill.path,\n });\n }\n\n // Sort results by skill ID\n results.sort((a, b) => a.id.localeCompare(b.id));\n\n return results;\n}\n\n/**\n * Update forked_from metadata in a skill's metadata.yaml\n */\nasync function updateForkedFromMetadata(\n skillDir: string,\n skillId: string,\n contentHash: string,\n): Promise<void> {\n const metadataPath = path.join(skillDir, \"metadata.yaml\");\n const rawContent = await readFile(metadataPath);\n\n const lines = rawContent.split(\"\\n\");\n let yamlContent = rawContent;\n\n if (lines[0]?.startsWith(\"# yaml-language-server:\")) {\n yamlContent = lines.slice(1).join(\"\\n\");\n }\n\n const metadata = parseYaml(yamlContent) as LocalSkillMetadata;\n\n metadata.forked_from = {\n skill_id: skillId,\n content_hash: contentHash,\n date: getCurrentDate(),\n };\n\n const newYamlContent = stringifyYaml(metadata, { lineWidth: 0 });\n await writeFile(metadataPath, newYamlContent);\n}\n\n/**\n * Update a single skill from source\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 // Copy skill files from source to local\n await copy(srcPath, destPath);\n\n // Update forked_from metadata\n await updateForkedFromMetadata(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\n/**\n * Find a skill by partial name match\n */\nfunction findSkillByPartialMatch(\n skillName: string,\n results: SkillComparisonResult[],\n): SkillComparisonResult | null {\n // Exact match first\n const exact = results.find((r) => r.id === skillName);\n if (exact) return exact;\n\n // Partial match (skill name without author)\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 // Directory name match\n const byDir = results.find(\n (r) => r.dirName.toLowerCase() === skillName.toLowerCase(),\n );\n if (byDir) return byDir;\n\n return null;\n}\n\n/**\n * Find similar skill names for suggestions\n */\nfunction findSimilarSkills(\n skillName: string,\n results: SkillComparisonResult[],\n): 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) ||\n dir.includes(lowered) ||\n lowered.includes(name.split(\" \")[0])\n );\n })\n .map((r) => r.id)\n .slice(0, 3);\n}\n\n/**\n * Confirmation component for update operation\n */\ninterface UpdateConfirmProps {\n onConfirm: () => void;\n onCancel: () => void;\n}\n\nconst UpdateConfirm: React.FC<UpdateConfirmProps> = ({\n onConfirm,\n onCancel,\n}) => {\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 // Check if local skills directory exists\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 // Build source skills map for lookup\n const sourceSkills: Record<string, { path: string }> = {};\n for (const [skillId, skill] of Object.entries(\n sourceResult.matrix.skills,\n )) {\n if (!skill.local) {\n sourceSkills[skillId] = { path: skill.path };\n }\n }\n\n // Compare local skills against source\n const allResults = await compareSkills(\n projectDir,\n sourceResult.sourcePath,\n sourceSkills,\n );\n\n // Filter to just outdated skills\n let outdatedSkills = allResults.filter((r) => r.status === \"outdated\");\n\n // Handle specific skill argument\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(\n `Run \\`cc search ${args.skill}\\` to search available skills.`,\n );\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(\n `Skill \"${foundSkill.id}\" is a local-only skill (not forked from source).`,\n );\n this.log(\"Cannot update local-only skills.\");\n this.log(\"\");\n return;\n }\n\n // Only update this specific skill\n outdatedSkills = [foundSkill];\n }\n\n // Check if there are any outdated skills\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 // Show what will be updated\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 // Confirm unless --yes flag\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 // Update each skill\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 // Recompile agents if needed\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 // Final summary\n this.log(\"\");\n if (failed.length === 0) {\n const agentMsg =\n recompiledAgents.length > 0\n ? `, ${recompiledAgents.length} agent(s) recompiled`\n : \"\";\n this.logSuccess(\n `Update complete! ${updated.length} skill(s) updated${agentMsg}.`,\n );\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\";\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/source-loader.js\";\nimport { recompileAgents } from \"../lib/agent-recompiler.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport {\n compareSkills,\n injectForkedFromMetadata,\n type SkillComparisonResult,\n} from \"../lib/skill-metadata.js\";\nimport { fileExists, copy } from \"../utils/fs.js\";\nimport { LOCAL_SKILLS_PATH } from \"../consts.js\";\nimport { getCollectivePluginDir } from \"../lib/plugin-finder.js\";\nimport { Confirm } from \"../components/common/confirm.js\";\n\n/**\n * Update a single skill from source\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 // Copy skill files from source to local\n await copy(srcPath, destPath);\n\n // Update forked_from metadata\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\n/**\n * Find a skill by partial name match\n */\nfunction findSkillByPartialMatch(\n skillName: string,\n results: SkillComparisonResult[],\n): SkillComparisonResult | null {\n // Exact match first\n const exact = results.find((r) => r.id === skillName);\n if (exact) return exact;\n\n // Partial match (skill name without author)\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 // Directory name match\n const byDir = results.find((r) => r.dirName.toLowerCase() === skillName.toLowerCase());\n if (byDir) return byDir;\n\n return null;\n}\n\n/**\n * Find similar skill names for suggestions\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\n/**\n * Confirmation component for update operation\n */\ninterface 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 // Check if local skills directory exists\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 // Build source skills map for lookup\n const sourceSkills: Record<string, { path: string }> = {};\n for (const [skillId, skill] of Object.entries(sourceResult.matrix.skills)) {\n if (!skill.local) {\n sourceSkills[skillId] = { path: skill.path };\n }\n }\n\n // Compare local skills against source\n const allResults = await compareSkills(projectDir, sourceResult.sourcePath, sourceSkills);\n\n // Filter to just outdated skills\n let outdatedSkills = allResults.filter((r) => r.status === \"outdated\");\n\n // Handle specific skill argument\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 // Only update this specific skill\n outdatedSkills = [foundSkill];\n }\n\n // Check if there are any outdated skills\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 // Show what will be updated\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 // Confirm unless --yes flag\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 // Update each skill\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 // Recompile agents if needed\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 // Final summary\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":[]}
|