@agents-inc/cli 0.60.1 → 0.64.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 +48 -0
- package/README.md +23 -172
- package/dist/{chunk-G6WHCALR.js → chunk-3YNT3NX3.js} +13 -11
- package/dist/chunk-3YNT3NX3.js.map +1 -0
- package/dist/{chunk-WF6RM73R.js → chunk-4C7CSZC5.js} +27 -149
- package/dist/chunk-4C7CSZC5.js.map +1 -0
- package/dist/{chunk-EMIUPGPL.js → chunk-4KVBH2X4.js} +33 -14
- package/dist/chunk-4KVBH2X4.js.map +1 -0
- package/dist/{chunk-KIWFEBKH.js → chunk-52THXN5G.js} +14 -5
- package/dist/chunk-52THXN5G.js.map +1 -0
- package/dist/{chunk-TZXYBG3R.js → chunk-53URJ5XK.js} +448 -153
- package/dist/chunk-53URJ5XK.js.map +1 -0
- package/dist/{chunk-MKCHLXMY.js → chunk-6DEK3TDF.js} +10 -10
- package/dist/chunk-6DEK3TDF.js.map +1 -0
- package/dist/{chunk-SDKCQXWE.js → chunk-6IK2TCK7.js} +13 -6
- package/dist/chunk-6IK2TCK7.js.map +1 -0
- package/dist/chunk-6VIOO74O.js +51 -0
- package/dist/chunk-6VIOO74O.js.map +1 -0
- package/dist/{chunk-52XO4ULK.js → chunk-7DI3HGKL.js} +32 -14
- package/dist/chunk-7DI3HGKL.js.map +1 -0
- package/dist/{chunk-MGNYPVOJ.js → chunk-AQYAVLZK.js} +2 -2
- package/dist/{chunk-BNQ5O6LE.js → chunk-AUNBGZS4.js} +2 -2
- package/dist/chunk-BGPGQF35.js +248 -0
- package/dist/chunk-BGPGQF35.js.map +1 -0
- package/dist/chunk-BKL3DF2Q.js +45 -0
- package/dist/chunk-BKL3DF2Q.js.map +1 -0
- package/dist/{chunk-AX3SZZWA.js → chunk-BKTPEATV.js} +13 -6
- package/dist/chunk-BKTPEATV.js.map +1 -0
- package/dist/{chunk-H7WJK7NJ.js → chunk-CKPJTMNC.js} +13 -6
- package/dist/chunk-CKPJTMNC.js.map +1 -0
- package/dist/{chunk-MR6OBL3B.js → chunk-CXRVM7BA.js} +2 -4
- package/dist/chunk-CXRVM7BA.js.map +1 -0
- package/dist/{chunk-VR3CDXDT.js → chunk-EE5EPS32.js} +2 -2
- package/dist/{chunk-6OWHQ7HM.js → chunk-EGMQ3SXN.js} +2 -11
- package/dist/{chunk-6OWHQ7HM.js.map → chunk-EGMQ3SXN.js.map} +1 -1
- package/dist/{chunk-BMJZBLP7.js → chunk-EZ35IPXZ.js} +10 -7
- package/dist/chunk-EZ35IPXZ.js.map +1 -0
- package/dist/{chunk-OCEFD7V6.js → chunk-F3REOP7N.js} +3 -3
- package/dist/{chunk-C577AJE7.js → chunk-FGLUQSVU.js} +3 -3
- package/dist/{chunk-SEJF7CGJ.js → chunk-J4POGAJF.js} +24 -24
- package/dist/chunk-J4POGAJF.js.map +1 -0
- package/dist/{chunk-O6BA7Q2B.js → chunk-KFDTVSIC.js} +18 -8
- package/dist/chunk-KFDTVSIC.js.map +1 -0
- package/dist/{chunk-LWXRUR6B.js → chunk-LMZXL5RQ.js} +2 -2
- package/dist/{chunk-LWXRUR6B.js.map → chunk-LMZXL5RQ.js.map} +1 -1
- package/dist/{chunk-7FMEMXJ4.js → chunk-MOMI77PL.js} +100 -59
- package/dist/chunk-MOMI77PL.js.map +1 -0
- package/dist/{chunk-BFD5NZQ4.js → chunk-MVYJVKVT.js} +19 -11
- package/dist/chunk-MVYJVKVT.js.map +1 -0
- package/dist/{chunk-X5EG4EFP.js → chunk-MWGDG4QN.js} +2 -2
- package/dist/{chunk-TGLRDEEL.js → chunk-O2HK3NTG.js} +10 -6
- package/dist/chunk-O2HK3NTG.js.map +1 -0
- package/dist/{chunk-6G3KZSO4.js → chunk-OORWBS6F.js} +45 -52
- package/dist/chunk-OORWBS6F.js.map +1 -0
- package/dist/{chunk-CIG7IKX3.js → chunk-OV5UJWS5.js} +4 -4
- package/dist/{chunk-RO6LX3UV.js → chunk-R46CB36B.js} +5 -5
- package/dist/{chunk-52M2XF3W.js → chunk-RG3KDXMR.js} +16 -8
- package/dist/chunk-RG3KDXMR.js.map +1 -0
- package/dist/{chunk-MMFQNJPE.js → chunk-SXGBPQY6.js} +3 -3
- package/dist/chunk-SXGBPQY6.js.map +1 -0
- package/dist/{chunk-XUDTFI4M.js → chunk-T5DJCIUP.js} +2 -2
- package/dist/{chunk-AJJJE7F7.js → chunk-TQLDQ3XZ.js} +2 -2
- package/dist/{chunk-SZRK3VOR.js → chunk-WSMQ5GAP.js} +33 -21
- package/dist/chunk-WSMQ5GAP.js.map +1 -0
- package/dist/{chunk-WYVDNGJB.js → chunk-XMLCXRTS.js} +3 -3
- package/dist/{chunk-K6OLORQL.js → chunk-YEGPTBX5.js} +4 -4
- package/dist/{chunk-YHCYKUA3.js → chunk-ZFY5EMDV.js} +5 -5
- package/dist/{chunk-BKJHAJQW.js → chunk-ZYUASJUN.js} +7 -4
- package/dist/chunk-ZYUASJUN.js.map +1 -0
- package/dist/commands/build/marketplace.js +4 -4
- package/dist/commands/build/plugins.js +7 -6
- package/dist/commands/build/plugins.js.map +1 -1
- package/dist/commands/build/stack.js +7 -6
- package/dist/commands/build/stack.js.map +1 -1
- package/dist/commands/compile.js +79 -138
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/config/index.js +7 -6
- package/dist/commands/config/index.js.map +1 -1
- package/dist/commands/config/path.js +6 -5
- package/dist/commands/config/path.js.map +1 -1
- package/dist/commands/config/show.js +7 -6
- package/dist/commands/diff.js +6 -5
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/doctor.js +11 -15
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +63 -69
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +13 -13
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/import/skill.js +7 -6
- package/dist/commands/import/skill.js.map +1 -1
- package/dist/commands/info.js +14 -16
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/init.js +32 -30
- package/dist/commands/list.js +6 -5
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/agent.js +7 -6
- package/dist/commands/new/agent.js.map +1 -1
- package/dist/commands/new/marketplace.js +28 -11
- package/dist/commands/new/marketplace.js.map +1 -1
- package/dist/commands/new/skill.js +7 -6
- package/dist/commands/outdated.js +6 -5
- package/dist/commands/outdated.js.map +1 -1
- package/dist/commands/search.js +13 -11
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/uninstall.js +9 -10
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +12 -8
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/validate.js +20 -42
- package/dist/commands/validate.js.map +1 -1
- package/dist/components/skill-search/skill-search.js +4 -3
- package/dist/components/wizard/category-grid.js +5 -3
- package/dist/components/wizard/category-grid.test.js +242 -194
- package/dist/components/wizard/category-grid.test.js.map +1 -1
- package/dist/components/wizard/checkbox-grid.js +5 -5
- package/dist/components/wizard/checkbox-grid.test.js +5 -5
- package/dist/components/wizard/domain-selection.js +12 -11
- package/dist/components/wizard/help-modal.js +3 -2
- package/dist/components/wizard/menu-item.js +1 -1
- package/dist/components/wizard/search-modal.js +3 -2
- package/dist/components/wizard/search-modal.test.js +3 -2
- package/dist/components/wizard/search-modal.test.js.map +1 -1
- package/dist/components/wizard/section-progress.js +2 -2
- package/dist/components/wizard/section-progress.test.js +3 -3
- package/dist/components/wizard/section-progress.test.js.map +1 -1
- package/dist/components/wizard/selection-card.js +2 -2
- package/dist/components/wizard/source-grid.js +6 -4
- package/dist/components/wizard/source-grid.test.js +65 -40
- package/dist/components/wizard/source-grid.test.js.map +1 -1
- package/dist/components/wizard/stack-selection.js +9 -8
- package/dist/components/wizard/step-agents.js +11 -10
- package/dist/components/wizard/step-agents.test.js +28 -25
- package/dist/components/wizard/step-agents.test.js.map +1 -1
- package/dist/components/wizard/step-build.js +12 -10
- package/dist/components/wizard/step-build.test.js +28 -34
- package/dist/components/wizard/step-build.test.js.map +1 -1
- package/dist/components/wizard/step-confirm.js +6 -4
- package/dist/components/wizard/step-confirm.test.js +11 -15
- package/dist/components/wizard/step-confirm.test.js.map +1 -1
- package/dist/components/wizard/step-refine.js +3 -2
- 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 +10 -8
- package/dist/components/wizard/step-settings.test.js +17 -13
- package/dist/components/wizard/step-settings.test.js.map +1 -1
- package/dist/components/wizard/step-sources.js +13 -11
- package/dist/components/wizard/step-sources.test.js +17 -14
- package/dist/components/wizard/step-sources.test.js.map +1 -1
- package/dist/components/wizard/step-stack.js +15 -14
- package/dist/components/wizard/step-stack.test.js +42 -38
- package/dist/components/wizard/step-stack.test.js.map +1 -1
- package/dist/components/wizard/view-title.js +2 -2
- package/dist/components/wizard/wizard-layout.js +10 -8
- package/dist/components/wizard/wizard-tabs.js +2 -2
- package/dist/components/wizard/wizard-tabs.test.js +2 -2
- package/dist/components/wizard/wizard.js +29 -27
- package/dist/hooks/init.js +32 -30
- package/dist/hooks/init.js.map +1 -1
- package/dist/{loader-2O32KKAQ.js → loader-4YOZCFIP.js} +4 -4
- package/dist/plugins/dummy-skill/.claude-plugin/.content-hash +1 -0
- package/dist/plugins/dummy-skill/.claude-plugin/plugin.json +13 -0
- package/dist/{source-loader-A6B3NDI4.js → source-loader-O5RMYUBW.js} +6 -5
- package/dist/{source-manager-Q7IQSGIX.js → source-manager-NKLL6HCL.js} +6 -5
- package/dist/stores/matrix-store.js +15 -0
- package/dist/stores/matrix-store.js.map +1 -0
- package/dist/stores/matrix-store.test.js +146 -0
- package/dist/stores/matrix-store.test.js.map +1 -0
- package/dist/stores/wizard-store.js +6 -5
- package/dist/stores/wizard-store.test.js +159 -107
- package/dist/stores/wizard-store.test.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-52M2XF3W.js.map +0 -1
- package/dist/chunk-52XO4ULK.js.map +0 -1
- package/dist/chunk-6G3KZSO4.js.map +0 -1
- package/dist/chunk-7FMEMXJ4.js.map +0 -1
- package/dist/chunk-AX3SZZWA.js.map +0 -1
- package/dist/chunk-BFD5NZQ4.js.map +0 -1
- package/dist/chunk-BKJHAJQW.js.map +0 -1
- package/dist/chunk-BMJZBLP7.js.map +0 -1
- package/dist/chunk-EMIUPGPL.js.map +0 -1
- package/dist/chunk-G6WHCALR.js.map +0 -1
- package/dist/chunk-H7WJK7NJ.js.map +0 -1
- package/dist/chunk-KIWFEBKH.js.map +0 -1
- package/dist/chunk-MKCHLXMY.js.map +0 -1
- package/dist/chunk-MMFQNJPE.js.map +0 -1
- package/dist/chunk-MR6OBL3B.js.map +0 -1
- package/dist/chunk-O6BA7Q2B.js.map +0 -1
- package/dist/chunk-SDKCQXWE.js.map +0 -1
- package/dist/chunk-SEJF7CGJ.js.map +0 -1
- package/dist/chunk-SZRK3VOR.js.map +0 -1
- package/dist/chunk-TC3NHO34.js +0 -151
- package/dist/chunk-TC3NHO34.js.map +0 -1
- package/dist/chunk-TGLRDEEL.js.map +0 -1
- package/dist/chunk-TZXYBG3R.js.map +0 -1
- package/dist/chunk-WF6RM73R.js.map +0 -1
- /package/dist/{chunk-MGNYPVOJ.js.map → chunk-AQYAVLZK.js.map} +0 -0
- /package/dist/{chunk-BNQ5O6LE.js.map → chunk-AUNBGZS4.js.map} +0 -0
- /package/dist/{chunk-VR3CDXDT.js.map → chunk-EE5EPS32.js.map} +0 -0
- /package/dist/{chunk-OCEFD7V6.js.map → chunk-F3REOP7N.js.map} +0 -0
- /package/dist/{chunk-C577AJE7.js.map → chunk-FGLUQSVU.js.map} +0 -0
- /package/dist/{chunk-X5EG4EFP.js.map → chunk-MWGDG4QN.js.map} +0 -0
- /package/dist/{chunk-CIG7IKX3.js.map → chunk-OV5UJWS5.js.map} +0 -0
- /package/dist/{chunk-RO6LX3UV.js.map → chunk-R46CB36B.js.map} +0 -0
- /package/dist/{chunk-XUDTFI4M.js.map → chunk-T5DJCIUP.js.map} +0 -0
- /package/dist/{chunk-AJJJE7F7.js.map → chunk-TQLDQ3XZ.js.map} +0 -0
- /package/dist/{chunk-WYVDNGJB.js.map → chunk-XMLCXRTS.js.map} +0 -0
- /package/dist/{chunk-K6OLORQL.js.map → chunk-YEGPTBX5.js.map} +0 -0
- /package/dist/{chunk-YHCYKUA3.js.map → chunk-ZFY5EMDV.js.map} +0 -0
- /package/dist/{loader-2O32KKAQ.js.map → loader-4YOZCFIP.js.map} +0 -0
- /package/dist/{source-loader-A6B3NDI4.js.map → source-loader-O5RMYUBW.js.map} +0 -0
- /package/dist/{source-manager-Q7IQSGIX.js.map → source-manager-NKLL6HCL.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/commands/search.tsx","../../src/cli/components/skill-search/index.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport { printTable } from \"@oclif/table\";\nimport { render } from \"ink\";\nimport path from \"path\";\nimport { sortBy } from \"remeda\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { SkillSearch, type SkillSearchResult } from \"../components/skill-search/index.js\";\nimport type { SourcedSkill } from \"../components/skill-search/skill-search.js\";\nimport { DEFAULT_SKILLS_SUBDIR, LOCAL_SKILLS_PATH, STANDARD_FILES } from \"../consts.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { resolveAllSources, type SourceEntry } from \"../lib/configuration/index.js\";\nimport {\n loadSkillsMatrixFromSource,\n fetchFromSource,\n parseFrontmatter,\n} from \"../lib/loading/index.js\";\nimport type { CategoryPath, ResolvedSkill, SkillSlug } from \"../types/index.js\";\nimport { listDirectories, fileExists, readFile, copy, ensureDir } from \"../utils/fs.js\";\nimport { SUCCESS_MESSAGES, STATUS_MESSAGES, INFO_MESSAGES } from \"../utils/messages.js\";\n\nconst MAX_DESCRIPTION_WIDTH = 50;\n\nfunction truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str;\n return `${str.slice(0, maxLength - 3)}...`;\n}\n\nfunction matchesQuery(skill: ResolvedSkill, query: string): boolean {\n const lowerQuery = query.toLowerCase();\n\n if (skill.id.toLowerCase().includes(lowerQuery)) return true;\n if (skill.displayName.toLowerCase().includes(lowerQuery)) return true;\n if (skill.slug?.toLowerCase().includes(lowerQuery)) return true;\n if (skill.description.toLowerCase().includes(lowerQuery)) return true;\n if (skill.category.toLowerCase().includes(lowerQuery)) return true;\n\n return skill.tags.some((tag) => tag.toLowerCase().includes(lowerQuery));\n}\n\nfunction matchesCategory(skill: ResolvedSkill, category: CategoryPath): boolean {\n const lowerCategory = category.toLowerCase();\n return skill.category.toLowerCase().includes(lowerCategory);\n}\n\nfunction toSourcedSkill(\n skill: ResolvedSkill,\n sourceName: string,\n sourceUrl?: string,\n): SourcedSkill {\n return {\n ...skill,\n sourceName,\n sourceUrl,\n };\n}\n\nasync function fetchSkillsFromSource(\n source: SourceEntry,\n forceRefresh: boolean,\n): Promise<SourcedSkill[]> {\n try {\n const result = await fetchFromSource(source.url, { forceRefresh });\n const skillsDir = path.join(result.path, DEFAULT_SKILLS_SUBDIR);\n\n if (!(await fileExists(skillsDir))) {\n return [];\n }\n\n const skillDirs = await listDirectories(skillsDir);\n const skills: SourcedSkill[] = [];\n\n for (const skillDir of skillDirs) {\n const skillMdPath = path.join(skillsDir, skillDir, STANDARD_FILES.SKILL_MD);\n if (!(await fileExists(skillMdPath))) continue;\n\n const content = await readFile(skillMdPath);\n const frontmatter = parseFrontmatter(content, skillMdPath);\n if (!frontmatter) continue;\n\n skills.push({\n id: frontmatter.name,\n description: frontmatter.description,\n // Boundary cast: directory name used as slug for third-party source skill\n slug: skillDir as SkillSlug,\n displayName: skillDir,\n // Boundary cast: external source skills have no category metadata\n category: \"imported\" as CategoryPath,\n tags: [],\n author: `@${source.name}`,\n conflictsWith: [],\n isRecommended: false,\n requires: [],\n alternatives: [],\n discourages: [],\n compatibleWith: [],\n requiresSetup: [],\n providesSetupFor: [],\n sourceName: source.name,\n sourceUrl: source.url,\n path: path.join(skillsDir, skillDir),\n });\n }\n\n return skills;\n } catch {\n // Source unavailable, return empty\n return [];\n }\n}\n\nexport default class Search extends BaseCommand {\n static summary = \"Search available skills\";\n static description =\n \"Search skills by ID, alias, description, category, or tags. \" +\n \"Run without arguments or with -i for interactive mode with multi-select.\";\n\n static examples = [\n {\n description: \"Search for React skills\",\n command: \"<%= config.bin %> search react\",\n },\n {\n description: \"Interactive search mode\",\n command: \"<%= config.bin %> search\",\n },\n {\n description: \"Interactive with pre-filled query\",\n command: \"<%= config.bin %> search -i react\",\n },\n {\n description: \"Search with category filter\",\n command: \"<%= config.bin %> search state -c frontend\",\n },\n ];\n\n static args = {\n query: Args.string({\n description: \"Search query (matches name, description, category, tags)\",\n required: false,\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n interactive: Flags.boolean({\n char: \"i\",\n description: \"Launch interactive search with multi-select\",\n default: false,\n }),\n category: Flags.string({\n char: \"c\",\n description: \"Filter by category\",\n required: false,\n }),\n refresh: Flags.boolean({\n description: \"Force refresh from remote sources\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Search);\n const projectDir = process.cwd();\n\n const isInteractive = flags.interactive || !args.query;\n\n if (isInteractive) {\n await this.runInteractive(args.query, flags.refresh, projectDir);\n } else {\n await this.runStatic(args.query!, flags);\n }\n }\n\n private async runInteractive(\n initialQuery: string | undefined,\n forceRefresh: boolean,\n projectDir: string,\n ): Promise<void> {\n this.log(\"Loading skills from all sources...\");\n\n try {\n const { matrix, sourcePath } = await loadSkillsMatrixFromSource({\n sourceFlag: undefined,\n projectDir,\n forceRefresh,\n });\n\n const primarySkills = Object.values(matrix.skills)\n .filter((skill): skill is ResolvedSkill => skill !== undefined)\n .map((skill) => toSourcedSkill(skill, \"marketplace\", sourcePath));\n\n const { extras } = await resolveAllSources(projectDir);\n\n const extraSkillArrays = await Promise.all(\n extras.map((source) => fetchSkillsFromSource(source, forceRefresh)),\n );\n\n const allSkills: SourcedSkill[] = [...primarySkills, ...extraSkillArrays.flat()];\n const sourceCount = 1 + extras.length;\n\n this.log(`Loaded ${allSkills.length} skills from ${sourceCount} source(s)`);\n this.log(\"\");\n\n const searchResultPromise = new Promise<SkillSearchResult>((resolve) => {\n const { waitUntilExit } = render(\n <SkillSearch\n skills={allSkills}\n sourceCount={sourceCount}\n initialQuery={initialQuery}\n onComplete={(result) => {\n resolve(result);\n }}\n onCancel={() => {\n resolve({ selectedSkills: [], cancelled: true });\n }}\n />,\n );\n\n waitUntilExit().then(() => {\n resolve({ selectedSkills: [], cancelled: true });\n });\n });\n\n const searchResult = await searchResultPromise;\n\n if (searchResult.cancelled) {\n this.log(\"Search cancelled\");\n this.exit(EXIT_CODES.CANCELLED);\n }\n\n if (searchResult.selectedSkills.length === 0) {\n this.log(\"No skills selected\");\n return;\n }\n\n this.log(\"\");\n this.log(`Importing ${searchResult.selectedSkills.length} skill(s)...`);\n\n const destDir = path.join(projectDir, LOCAL_SKILLS_PATH);\n\n for (const skill of searchResult.selectedSkills) {\n if (skill.path) {\n const destPath = path.join(destDir, skill.id);\n await ensureDir(path.dirname(destPath));\n await copy(skill.path, destPath);\n this.logSuccess(`Imported: ${skill.id}`);\n } else {\n this.warn(`Skipping ${skill.id}: No source path available`);\n }\n }\n\n this.log(\"\");\n this.logSuccess(SUCCESS_MESSAGES.IMPORT_COMPLETE);\n this.log(`Skills location: ${destDir}`);\n this.log(INFO_MESSAGES.RUN_COMPILE);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n private async runStatic(\n query: string,\n flags: { source?: string; category?: string },\n ): Promise<void> {\n try {\n this.log(STATUS_MESSAGES.LOADING_SKILLS);\n\n const { matrix, sourcePath, isLocal } = await loadSkillsMatrixFromSource({\n sourceFlag: flags.source,\n });\n\n this.log(`Loaded from ${isLocal ? \"local\" : \"remote\"}: ${sourcePath}`);\n\n const allSkills = Object.values(matrix.skills).filter(\n (skill): skill is ResolvedSkill => skill !== undefined,\n );\n\n let results = allSkills.filter((skill) => matchesQuery(skill, query));\n\n if (flags.category) {\n // CLI flag is an untyped string — cast at data boundary\n results = results.filter((skill) => matchesCategory(skill, flags.category as CategoryPath));\n }\n\n results = sortBy(results, (r) => (r.displayName || r.id).toLowerCase());\n\n this.log(\"\");\n if (results.length === 0) {\n this.warn(`No skills found matching \"${query}\"`);\n if (flags.category) {\n this.logInfo(`Category filter: ${flags.category}`);\n }\n } else {\n this.logInfo(\n `Found ${results.length} skill${results.length === 1 ? \"\" : \"s\"} matching \"${query}\"`,\n );\n if (flags.category) {\n this.logInfo(`Category filter: ${flags.category}`);\n }\n this.log(\"\");\n\n printTable({\n data: results.map((skill) => ({\n id: skill.displayName || skill.id,\n category: skill.category,\n description: truncate(skill.description, MAX_DESCRIPTION_WIDTH),\n })),\n columns: [\n { key: \"id\", name: \"ID\" },\n { key: \"category\", name: \"Category\" },\n { key: \"description\", name: \"Description\" },\n ],\n headerOptions: { bold: true },\n });\n }\n this.log(\"\");\n } catch (error) {\n this.handleError(error);\n }\n }\n}\n","export { SkillSearch, type SkillSearchResult } from \"./skill-search.js\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,SAAS,MAAM,aAAa;AAC5B,SAAS,kBAAkB;AAC3B,SAAS,cAAc;AACvB,OAAO,UAAU;AACjB,SAAS,cAAc;;;ACJvB;;;AD8MU;AAzLV,IAAM,wBAAwB;AAE9B,SAAS,SAAS,KAAa,WAA2B;AACxD,MAAI,IAAI,UAAU,UAAW,QAAO;AACpC,SAAO,GAAG,IAAI,MAAM,GAAG,YAAY,CAAC,CAAC;AACvC;AAEA,SAAS,aAAa,OAAsB,OAAwB;AAClE,QAAM,aAAa,MAAM,YAAY;AAErC,MAAI,MAAM,GAAG,YAAY,EAAE,SAAS,UAAU,EAAG,QAAO;AACxD,MAAI,MAAM,YAAY,YAAY,EAAE,SAAS,UAAU,EAAG,QAAO;AACjE,MAAI,MAAM,MAAM,YAAY,EAAE,SAAS,UAAU,EAAG,QAAO;AAC3D,MAAI,MAAM,YAAY,YAAY,EAAE,SAAS,UAAU,EAAG,QAAO;AACjE,MAAI,MAAM,SAAS,YAAY,EAAE,SAAS,UAAU,EAAG,QAAO;AAE9D,SAAO,MAAM,KAAK,KAAK,CAAC,QAAQ,IAAI,YAAY,EAAE,SAAS,UAAU,CAAC;AACxE;AAEA,SAAS,gBAAgB,OAAsB,UAAiC;AAC9E,QAAM,gBAAgB,SAAS,YAAY;AAC3C,SAAO,MAAM,SAAS,YAAY,EAAE,SAAS,aAAa;AAC5D;AAEA,SAAS,eACP,OACA,YACA,WACc;AACd,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,sBACb,QACA,cACyB;AACzB,MAAI;AACF,UAAM,SAAS,MAAM,gBAAgB,OAAO,KAAK,EAAE,aAAa,CAAC;AACjE,UAAM,YAAY,KAAK,KAAK,OAAO,MAAM,qBAAqB;AAE9D,QAAI,CAAE,MAAM,WAAW,SAAS,GAAI;AAClC,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,YAAY,MAAM,gBAAgB,SAAS;AACjD,UAAM,SAAyB,CAAC;AAEhC,eAAW,YAAY,WAAW;AAChC,YAAM,cAAc,KAAK,KAAK,WAAW,UAAU,eAAe,QAAQ;AAC1E,UAAI,CAAE,MAAM,WAAW,WAAW,EAAI;AAEtC,YAAM,UAAU,MAAM,SAAS,WAAW;AAC1C,YAAM,cAAc,iBAAiB,SAAS,WAAW;AACzD,UAAI,CAAC,YAAa;AAElB,aAAO,KAAK;AAAA,QACV,IAAI,YAAY;AAAA,QAChB,aAAa,YAAY;AAAA;AAAA,QAEzB,MAAM;AAAA,QACN,aAAa;AAAA;AAAA,QAEb,UAAU;AAAA,QACV,MAAM,CAAC;AAAA,QACP,QAAQ,IAAI,OAAO,IAAI;AAAA,QACvB,eAAe,CAAC;AAAA,QAChB,eAAe;AAAA,QACf,UAAU,CAAC;AAAA,QACX,cAAc,CAAC;AAAA,QACf,aAAa,CAAC;AAAA,QACd,gBAAgB,CAAC;AAAA,QACjB,eAAe,CAAC;AAAA,QAChB,kBAAkB,CAAC;AAAA,QACnB,YAAY,OAAO;AAAA,QACnB,WAAW,OAAO;AAAA,QAClB,MAAM,KAAK,KAAK,WAAW,QAAQ;AAAA,MACrC,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT,QAAQ;AAEN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,IAAqB,SAArB,MAAqB,gBAAe,YAAY;AAAA,EAC9C,OAAO,UAAU;AAAA,EACjB,OAAO,cACL;AAAA,EAGF,OAAO,WAAW;AAAA,IAChB;AAAA,MACE,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EAEA,OAAO,OAAO;AAAA,IACZ,OAAO,KAAK,OAAO;AAAA,MACjB,aAAa;AAAA,MACb,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AAAA,EAEA,OAAO,QAAQ;AAAA,IACb,GAAG,YAAY;AAAA,IACf,aAAa,MAAM,QAAQ;AAAA,MACzB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC;AAAA,IACD,UAAU,MAAM,OAAO;AAAA,MACrB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,UAAU;AAAA,IACZ,CAAC;AAAA,IACD,SAAS,MAAM,QAAQ;AAAA,MACrB,aAAa;AAAA,MACb,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,MAAqB;AACzB,UAAM,EAAE,MAAM,MAAM,IAAI,MAAM,KAAK,MAAM,OAAM;AAC/C,UAAM,aAAa,QAAQ,IAAI;AAE/B,UAAM,gBAAgB,MAAM,eAAe,CAAC,KAAK;AAEjD,QAAI,eAAe;AACjB,YAAM,KAAK,eAAe,KAAK,OAAO,MAAM,SAAS,UAAU;AAAA,IACjE,OAAO;AACL,YAAM,KAAK,UAAU,KAAK,OAAQ,KAAK;AAAA,IACzC;AAAA,EACF;AAAA,EAEA,MAAc,eACZ,cACA,cACA,YACe;AACf,SAAK,IAAI,oCAAoC;AAE7C,QAAI;AACF,YAAM,EAAE,QAAQ,WAAW,IAAI,MAAM,2BAA2B;AAAA,QAC9D,YAAY;AAAA,QACZ;AAAA,QACA;AAAA,MACF,CAAC;AAED,YAAM,gBAAgB,OAAO,OAAO,OAAO,MAAM,EAC9C,OAAO,CAAC,UAAkC,UAAU,MAAS,EAC7D,IAAI,CAAC,UAAU,eAAe,OAAO,eAAe,UAAU,CAAC;AAElE,YAAM,EAAE,OAAO,IAAI,MAAM,kBAAkB,UAAU;AAErD,YAAM,mBAAmB,MAAM,QAAQ;AAAA,QACrC,OAAO,IAAI,CAAC,WAAW,sBAAsB,QAAQ,YAAY,CAAC;AAAA,MACpE;AAEA,YAAM,YAA4B,CAAC,GAAG,eAAe,GAAG,iBAAiB,KAAK,CAAC;AAC/E,YAAM,cAAc,IAAI,OAAO;AAE/B,WAAK,IAAI,UAAU,UAAU,MAAM,gBAAgB,WAAW,YAAY;AAC1E,WAAK,IAAI,EAAE;AAEX,YAAM,sBAAsB,IAAI,QAA2B,CAAC,YAAY;AACtE,cAAM,EAAE,cAAc,IAAI;AAAA,UACxB;AAAA,YAAC;AAAA;AAAA,cACC,QAAQ;AAAA,cACR;AAAA,cACA;AAAA,cACA,YAAY,CAAC,WAAW;AACtB,wBAAQ,MAAM;AAAA,cAChB;AAAA,cACA,UAAU,MAAM;AACd,wBAAQ,EAAE,gBAAgB,CAAC,GAAG,WAAW,KAAK,CAAC;AAAA,cACjD;AAAA;AAAA,UACF;AAAA,QACF;AAEA,sBAAc,EAAE,KAAK,MAAM;AACzB,kBAAQ,EAAE,gBAAgB,CAAC,GAAG,WAAW,KAAK,CAAC;AAAA,QACjD,CAAC;AAAA,MACH,CAAC;AAED,YAAM,eAAe,MAAM;AAE3B,UAAI,aAAa,WAAW;AAC1B,aAAK,IAAI,kBAAkB;AAC3B,aAAK,KAAK,WAAW,SAAS;AAAA,MAChC;AAEA,UAAI,aAAa,eAAe,WAAW,GAAG;AAC5C,aAAK,IAAI,oBAAoB;AAC7B;AAAA,MACF;AAEA,WAAK,IAAI,EAAE;AACX,WAAK,IAAI,aAAa,aAAa,eAAe,MAAM,cAAc;AAEtE,YAAM,UAAU,KAAK,KAAK,YAAY,iBAAiB;AAEvD,iBAAW,SAAS,aAAa,gBAAgB;AAC/C,YAAI,MAAM,MAAM;AACd,gBAAM,WAAW,KAAK,KAAK,SAAS,MAAM,EAAE;AAC5C,gBAAM,UAAU,KAAK,QAAQ,QAAQ,CAAC;AACtC,gBAAM,KAAK,MAAM,MAAM,QAAQ;AAC/B,eAAK,WAAW,aAAa,MAAM,EAAE,EAAE;AAAA,QACzC,OAAO;AACL,eAAK,KAAK,YAAY,MAAM,EAAE,4BAA4B;AAAA,QAC5D;AAAA,MACF;AAEA,WAAK,IAAI,EAAE;AACX,WAAK,WAAW,iBAAiB,eAAe;AAChD,WAAK,IAAI,oBAAoB,OAAO,EAAE;AACtC,WAAK,IAAI,cAAc,WAAW;AAAA,IACpC,SAAS,OAAO;AACd,WAAK,YAAY,KAAK;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,MAAc,UACZ,OACA,OACe;AACf,QAAI;AACF,WAAK,IAAI,gBAAgB,cAAc;AAEvC,YAAM,EAAE,QAAQ,YAAY,QAAQ,IAAI,MAAM,2BAA2B;AAAA,QACvE,YAAY,MAAM;AAAA,MACpB,CAAC;AAED,WAAK,IAAI,eAAe,UAAU,UAAU,QAAQ,KAAK,UAAU,EAAE;AAErE,YAAM,YAAY,OAAO,OAAO,OAAO,MAAM,EAAE;AAAA,QAC7C,CAAC,UAAkC,UAAU;AAAA,MAC/C;AAEA,UAAI,UAAU,UAAU,OAAO,CAAC,UAAU,aAAa,OAAO,KAAK,CAAC;AAEpE,UAAI,MAAM,UAAU;AAElB,kBAAU,QAAQ,OAAO,CAAC,UAAU,gBAAgB,OAAO,MAAM,QAAwB,CAAC;AAAA,MAC5F;AAEA,gBAAU,OAAO,SAAS,CAAC,OAAO,EAAE,eAAe,EAAE,IAAI,YAAY,CAAC;AAEtE,WAAK,IAAI,EAAE;AACX,UAAI,QAAQ,WAAW,GAAG;AACxB,aAAK,KAAK,6BAA6B,KAAK,GAAG;AAC/C,YAAI,MAAM,UAAU;AAClB,eAAK,QAAQ,oBAAoB,MAAM,QAAQ,EAAE;AAAA,QACnD;AAAA,MACF,OAAO;AACL,aAAK;AAAA,UACH,SAAS,QAAQ,MAAM,SAAS,QAAQ,WAAW,IAAI,KAAK,GAAG,cAAc,KAAK;AAAA,QACpF;AACA,YAAI,MAAM,UAAU;AAClB,eAAK,QAAQ,oBAAoB,MAAM,QAAQ,EAAE;AAAA,QACnD;AACA,aAAK,IAAI,EAAE;AAEX,mBAAW;AAAA,UACT,MAAM,QAAQ,IAAI,CAAC,WAAW;AAAA,YAC5B,IAAI,MAAM,eAAe,MAAM;AAAA,YAC/B,UAAU,MAAM;AAAA,YAChB,aAAa,SAAS,MAAM,aAAa,qBAAqB;AAAA,UAChE,EAAE;AAAA,UACF,SAAS;AAAA,YACP,EAAE,KAAK,MAAM,MAAM,KAAK;AAAA,YACxB,EAAE,KAAK,YAAY,MAAM,WAAW;AAAA,YACpC,EAAE,KAAK,eAAe,MAAM,cAAc;AAAA,UAC5C;AAAA,UACA,eAAe,EAAE,MAAM,KAAK;AAAA,QAC9B,CAAC;AAAA,MACH;AACA,WAAK,IAAI,EAAE;AAAA,IACb,SAAS,OAAO;AACd,WAAK,YAAY,KAAK;AAAA,IACxB;AAAA,EACF;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/search.tsx","../../src/cli/components/skill-search/index.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport { printTable } from \"@oclif/table\";\nimport { render } from \"ink\";\nimport path from \"path\";\nimport { sortBy } from \"remeda\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { SkillSearch, type SkillSearchResult } from \"../components/skill-search/index.js\";\nimport type { SourcedSkill } from \"../components/skill-search/skill-search.js\";\nimport { DEFAULT_SKILLS_SUBDIR, LOCAL_SKILLS_PATH, STANDARD_FILES } from \"../consts.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { resolveAllSources, type SourceEntry } from \"../lib/configuration/index.js\";\nimport {\n loadSkillsMatrixFromSource,\n fetchFromSource,\n parseFrontmatter,\n} from \"../lib/loading/index.js\";\nimport type { CategoryPath, ResolvedSkill, SkillSlug } from \"../types/index.js\";\nimport { listDirectories, fileExists, readFile, copy, ensureDir } from \"../utils/fs.js\";\nimport { SUCCESS_MESSAGES, STATUS_MESSAGES, INFO_MESSAGES } from \"../utils/messages.js\";\n\nconst MAX_DESCRIPTION_WIDTH = 50;\n\nfunction truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str;\n return `${str.slice(0, maxLength - 3)}...`;\n}\n\nfunction matchesQuery(skill: ResolvedSkill, query: string): boolean {\n const lowerQuery = query.toLowerCase();\n\n if (skill.id.toLowerCase().includes(lowerQuery)) return true;\n if (skill.displayName.toLowerCase().includes(lowerQuery)) return true;\n if (skill.slug.toLowerCase().includes(lowerQuery)) return true;\n if (skill.description.toLowerCase().includes(lowerQuery)) return true;\n if (skill.category.toLowerCase().includes(lowerQuery)) return true;\n\n return skill.tags.some((tag) => tag.toLowerCase().includes(lowerQuery));\n}\n\nfunction matchesCategory(skill: ResolvedSkill, category: CategoryPath): boolean {\n const lowerCategory = category.toLowerCase();\n return skill.category.toLowerCase().includes(lowerCategory);\n}\n\nfunction toSourcedSkill(\n skill: ResolvedSkill,\n sourceName: string,\n sourceUrl?: string,\n): SourcedSkill {\n return {\n ...skill,\n sourceName,\n sourceUrl,\n };\n}\n\nasync function fetchSkillsFromSource(\n source: SourceEntry,\n forceRefresh: boolean,\n): Promise<SourcedSkill[]> {\n try {\n const result = await fetchFromSource(source.url, { forceRefresh });\n const skillsDir = path.join(result.path, DEFAULT_SKILLS_SUBDIR);\n\n if (!(await fileExists(skillsDir))) {\n return [];\n }\n\n const skillDirs = await listDirectories(skillsDir);\n const skills: SourcedSkill[] = [];\n\n for (const skillDir of skillDirs) {\n const skillMdPath = path.join(skillsDir, skillDir, STANDARD_FILES.SKILL_MD);\n if (!(await fileExists(skillMdPath))) continue;\n\n const content = await readFile(skillMdPath);\n const frontmatter = parseFrontmatter(content, skillMdPath);\n if (!frontmatter) continue;\n\n skills.push({\n id: frontmatter.name,\n description: frontmatter.description,\n // Boundary cast: directory name used as slug for third-party source skill\n slug: skillDir as SkillSlug,\n displayName: skillDir,\n // Boundary cast: external source skills have no category metadata\n category: \"imported\" as CategoryPath,\n tags: [],\n author: `@${source.name}`,\n conflictsWith: [],\n isRecommended: false,\n requires: [],\n alternatives: [],\n discourages: [],\n compatibleWith: [],\n requiresSetup: [],\n providesSetupFor: [],\n sourceName: source.name,\n sourceUrl: source.url,\n path: path.join(skillsDir, skillDir),\n });\n }\n\n return skills;\n } catch {\n // Source unavailable, return empty\n return [];\n }\n}\n\nexport default class Search extends BaseCommand {\n static summary = \"Search available skills\";\n static description =\n \"Search skills by ID, alias, description, category, or tags. \" +\n \"Run without arguments or with -i for interactive mode with multi-select.\";\n\n static examples = [\n {\n description: \"Search for React skills\",\n command: \"<%= config.bin %> search react\",\n },\n {\n description: \"Interactive search mode\",\n command: \"<%= config.bin %> search\",\n },\n {\n description: \"Interactive with pre-filled query\",\n command: \"<%= config.bin %> search -i react\",\n },\n {\n description: \"Search with category filter\",\n command: \"<%= config.bin %> search state -c frontend\",\n },\n ];\n\n static args = {\n query: Args.string({\n description: \"Search query (matches name, description, category, tags)\",\n required: false,\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n interactive: Flags.boolean({\n char: \"i\",\n description: \"Launch interactive search with multi-select\",\n default: false,\n }),\n category: Flags.string({\n char: \"c\",\n description: \"Filter by category\",\n required: false,\n }),\n refresh: Flags.boolean({\n description: \"Force refresh from remote sources\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Search);\n const projectDir = process.cwd();\n\n const isInteractive = flags.interactive || !args.query;\n\n if (isInteractive) {\n await this.runInteractive(args.query, flags.refresh, projectDir);\n } else {\n await this.runStatic(args.query!, flags);\n }\n }\n\n private async runInteractive(\n initialQuery: string | undefined,\n forceRefresh: boolean,\n projectDir: string,\n ): Promise<void> {\n this.log(\"Loading skills from all sources...\");\n\n try {\n const { matrix, sourcePath } = await loadSkillsMatrixFromSource({\n sourceFlag: undefined,\n projectDir,\n forceRefresh,\n });\n\n const primarySkills = Object.values(matrix.skills)\n .filter((skill): skill is ResolvedSkill => skill !== undefined)\n .map((skill) => toSourcedSkill(skill, \"marketplace\", sourcePath));\n\n const { extras } = await resolveAllSources(projectDir);\n\n const extraSkillArrays = await Promise.all(\n extras.map((source) => fetchSkillsFromSource(source, forceRefresh)),\n );\n\n const allSkills: SourcedSkill[] = [...primarySkills, ...extraSkillArrays.flat()];\n const sourceCount = 1 + extras.length;\n\n this.log(`Loaded ${allSkills.length} skills from ${sourceCount} source(s)`);\n this.log(\"\");\n\n const searchResultPromise = new Promise<SkillSearchResult>((resolve) => {\n const { waitUntilExit } = render(\n <SkillSearch\n skills={allSkills}\n sourceCount={sourceCount}\n initialQuery={initialQuery}\n onComplete={(result) => {\n resolve(result);\n }}\n onCancel={() => {\n resolve({ selectedSkills: [], cancelled: true });\n }}\n />,\n );\n\n waitUntilExit().then(() => {\n resolve({ selectedSkills: [], cancelled: true });\n });\n });\n\n const searchResult = await searchResultPromise;\n\n if (searchResult.cancelled) {\n this.log(\"Search cancelled\");\n this.exit(EXIT_CODES.CANCELLED);\n }\n\n if (searchResult.selectedSkills.length === 0) {\n this.log(\"No skills selected\");\n return;\n }\n\n this.log(\"\");\n this.log(`Importing ${searchResult.selectedSkills.length} skill(s)...`);\n\n const destDir = path.join(projectDir, LOCAL_SKILLS_PATH);\n\n for (const skill of searchResult.selectedSkills) {\n if (skill.path) {\n const destPath = path.join(destDir, skill.id);\n await ensureDir(path.dirname(destPath));\n await copy(skill.path, destPath);\n this.logSuccess(`Imported: ${skill.id}`);\n } else {\n this.warn(`Skipping ${skill.id}: No source path available`);\n }\n }\n\n this.log(\"\");\n this.logSuccess(SUCCESS_MESSAGES.IMPORT_COMPLETE);\n this.log(`Skills location: ${destDir}`);\n this.log(INFO_MESSAGES.RUN_COMPILE);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n private async runStatic(\n query: string,\n flags: { source?: string; category?: string },\n ): Promise<void> {\n try {\n this.log(STATUS_MESSAGES.LOADING_SKILLS);\n\n const { matrix, sourcePath, isLocal } = await loadSkillsMatrixFromSource({\n sourceFlag: flags.source,\n });\n\n this.log(`Loaded from ${isLocal ? \"local\" : \"remote\"}: ${sourcePath}`);\n\n const allSkills = Object.values(matrix.skills).filter(\n (skill): skill is ResolvedSkill => skill !== undefined,\n );\n\n let results = allSkills.filter((skill) => matchesQuery(skill, query));\n\n if (flags.category) {\n // CLI flag is an untyped string — cast at data boundary\n results = results.filter((skill) => matchesCategory(skill, flags.category as CategoryPath));\n }\n\n results = sortBy(results, (r) => r.displayName.toLowerCase());\n\n this.log(\"\");\n if (results.length === 0) {\n this.warn(`No skills found matching \"${query}\"`);\n if (flags.category) {\n this.logInfo(`Category filter: ${flags.category}`);\n }\n } else {\n this.logInfo(\n `Found ${results.length} skill${results.length === 1 ? \"\" : \"s\"} matching \"${query}\"`,\n );\n if (flags.category) {\n this.logInfo(`Category filter: ${flags.category}`);\n }\n this.log(\"\");\n\n printTable({\n data: results.map((skill) => ({\n id: skill.displayName,\n category: skill.category,\n description: truncate(skill.description, MAX_DESCRIPTION_WIDTH),\n })),\n columns: [\n { key: \"id\", name: \"ID\" },\n { key: \"category\", name: \"Category\" },\n { key: \"description\", name: \"Description\" },\n ],\n headerOptions: { bold: true },\n });\n }\n this.log(\"\");\n } catch (error) {\n this.handleError(error);\n }\n }\n}\n","export { SkillSearch, type SkillSearchResult } from \"./skill-search.js\";\n"],"mappings":"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","names":[]}
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
INFO_MESSAGES,
|
|
7
7
|
SUCCESS_MESSAGES
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-CXRVM7BA.js";
|
|
9
9
|
import {
|
|
10
10
|
claudePluginUninstall,
|
|
11
11
|
getProjectPluginsDir,
|
|
@@ -13,25 +13,26 @@ import {
|
|
|
13
13
|
listPluginNames,
|
|
14
14
|
loadProjectSourceConfig,
|
|
15
15
|
readForkedFromMetadata
|
|
16
|
-
} from "../chunk-
|
|
17
|
-
import "../chunk-
|
|
16
|
+
} from "../chunk-53URJ5XK.js";
|
|
17
|
+
import "../chunk-F3REOP7N.js";
|
|
18
18
|
import "../chunk-T4EXUIBY.js";
|
|
19
|
+
import "../chunk-BKL3DF2Q.js";
|
|
19
20
|
import {
|
|
20
21
|
BaseCommand,
|
|
21
22
|
EXIT_CODES
|
|
22
|
-
} from "../chunk-
|
|
23
|
+
} from "../chunk-EE5EPS32.js";
|
|
23
24
|
import {
|
|
24
25
|
directoryExists,
|
|
25
26
|
getErrorMessage,
|
|
26
27
|
listDirectories,
|
|
27
28
|
remove
|
|
28
|
-
} from "../chunk-
|
|
29
|
+
} from "../chunk-LMZXL5RQ.js";
|
|
29
30
|
import {
|
|
30
31
|
CLAUDE_DIR,
|
|
31
32
|
CLAUDE_SRC_DIR,
|
|
32
33
|
CLI_COLORS,
|
|
33
34
|
DEFAULT_BRANDING
|
|
34
|
-
} from "../chunk-
|
|
35
|
+
} from "../chunk-EGMQ3SXN.js";
|
|
35
36
|
import "../chunk-EC3UJRKZ.js";
|
|
36
37
|
import {
|
|
37
38
|
init_esm_shims
|
|
@@ -51,10 +52,8 @@ function collectConfiguredSources(config) {
|
|
|
51
52
|
];
|
|
52
53
|
}
|
|
53
54
|
function collectConfiguredAgents(config) {
|
|
54
|
-
if (!config) return [];
|
|
55
|
-
|
|
56
|
-
if (!Array.isArray(agents)) return [];
|
|
57
|
-
return agents.map((a) => a.name);
|
|
55
|
+
if (!config?.agents) return [];
|
|
56
|
+
return config.agents.map((a) => a.name);
|
|
58
57
|
}
|
|
59
58
|
async function detectUninstallTarget(projectDir) {
|
|
60
59
|
const pluginsDir = getProjectPluginsDir(projectDir);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/commands/uninstall.tsx"],"sourcesContent":["import React from \"react\";\n\nimport { Flags } from \"@oclif/core\";\nimport { render, Box, Text, useApp } from \"ink\";\nimport path from \"path\";\n\nimport { BaseCommand } from \"../base-command\";\nimport { Confirm } from \"../components/common/confirm\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport { directoryExists, listDirectories, remove } from \"../utils/fs\";\nimport { claudePluginUninstall, isClaudeCLIAvailable } from \"../utils/exec\";\nimport { listPluginNames, getProjectPluginsDir } from \"../lib/plugins\";\nimport { readForkedFromMetadata } from \"../lib/skills\";\nimport { loadProjectSourceConfig } from \"../lib/configuration/config\";\nimport type { ProjectSourceConfig } from \"../lib/configuration/config\";\nimport { CLAUDE_DIR, CLAUDE_SRC_DIR, CLI_COLORS, DEFAULT_BRANDING } from \"../consts\";\nimport { EXIT_CODES } from \"../lib/exit-codes\";\nimport { SUCCESS_MESSAGES, INFO_MESSAGES } from \"../utils/messages\";\n\ntype UninstallTarget = {\n hasPlugins: boolean;\n pluginNames: string[];\n hasLocalSkills: boolean;\n hasLocalAgents: boolean;\n hasClaudeDir: boolean;\n hasClaudeSrcDir: boolean;\n pluginsDir: string;\n skillsDir: string;\n agentsDir: string;\n claudeDir: string;\n claudeSrcDir: string;\n /** Resolved project source config from .claude-src/config.ts */\n config: ProjectSourceConfig | null;\n /** All configured source URLs (primary + extras) */\n configuredSources: string[];\n /** Agent names from the generated config (e.g., [\"web-developer\"]) */\n configuredAgents: string[];\n};\n\nfunction collectConfiguredSources(config: ProjectSourceConfig | null): string[] {\n if (!config) return [];\n return [\n ...(config.source ? [config.source] : []),\n ...(config.sources?.map((entry) => entry.url) ?? []),\n ];\n}\n\nfunction collectConfiguredAgents(config: ProjectSourceConfig | null): string[] {\n if (!config) return [];\n // Boundary cast: config loaded via .passthrough() schema, agents preserved as AgentScopeConfig[]\n const agents = (config as Record<string, unknown>).agents;\n if (!Array.isArray(agents)) return [];\n return agents.map((a: { name: string }) => a.name);\n}\n\nasync function detectUninstallTarget(projectDir: string): Promise<UninstallTarget> {\n const pluginsDir = getProjectPluginsDir(projectDir);\n const skillsDir = path.join(projectDir, CLAUDE_DIR, \"skills\");\n const agentsDir = path.join(projectDir, CLAUDE_DIR, \"agents\");\n const claudeDir = path.join(projectDir, CLAUDE_DIR);\n const claudeSrcDir = path.join(projectDir, CLAUDE_SRC_DIR);\n\n const [hasLocalSkills, hasLocalAgents, hasClaudeDir, hasClaudeSrcDir, config] = await Promise.all(\n [\n directoryExists(skillsDir),\n directoryExists(agentsDir),\n directoryExists(claudeDir),\n directoryExists(claudeSrcDir),\n loadProjectSourceConfig(projectDir),\n ],\n );\n\n let pluginNames: string[] = [];\n try {\n pluginNames = await listPluginNames(projectDir);\n } catch {\n // Best-effort: plugin detection may fail\n }\n\n const configuredSources = collectConfiguredSources(config);\n const configuredAgents = collectConfiguredAgents(config);\n\n return {\n hasPlugins: pluginNames.length > 0,\n pluginNames,\n hasLocalSkills,\n hasLocalAgents,\n hasClaudeDir,\n hasClaudeSrcDir,\n pluginsDir,\n skillsDir,\n agentsDir,\n claudeDir,\n claudeSrcDir,\n config,\n configuredSources,\n configuredAgents,\n };\n}\n\ntype UninstallConfirmProps = {\n target: UninstallTarget;\n removeAll: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n};\n\nconst UninstallConfirm: React.FC<UninstallConfirmProps> = ({\n target,\n removeAll,\n onConfirm,\n onCancel,\n}) => {\n const { exit } = useApp();\n\n return (\n <Box flexDirection=\"column\">\n <Text bold>The following will be removed:</Text>\n <Text> </Text>\n\n {target.hasPlugins && (\n <Box flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> Plugins:</Text>\n <Text dimColor> {target.pluginsDir}</Text>\n </Box>\n )}\n\n {(target.hasLocalSkills || target.hasLocalAgents) && (\n <Box flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> CLI-managed files:</Text>\n {target.hasLocalSkills && <Text dimColor> {target.skillsDir}/ (matching sources)</Text>}\n {target.hasLocalAgents && <Text dimColor> {target.agentsDir}/ (CLI-compiled)</Text>}\n </Box>\n )}\n\n {removeAll && target.hasClaudeSrcDir && (\n <Box flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> Config:</Text>\n <Text dimColor> {target.claudeSrcDir}/</Text>\n </Box>\n )}\n\n <Text> </Text>\n <Confirm\n message=\"Are you sure you want to uninstall?\"\n onConfirm={() => {\n onConfirm();\n exit();\n }}\n onCancel={() => {\n onCancel();\n exit();\n }}\n defaultValue={false}\n />\n </Box>\n );\n};\n\nasync function isDirectoryEmpty(dirPath: string): Promise<boolean> {\n const { readdir } = await import(\"fs/promises\");\n try {\n const allEntries = await readdir(dirPath);\n return allEntries.length === 0;\n } catch {\n return true;\n }\n}\n\nfunction skillMatchesConfiguredSource(\n forkedFromSource: string | undefined,\n configuredSources: string[],\n): boolean {\n if (!forkedFromSource || configuredSources.length === 0) return false;\n return configuredSources.includes(forkedFromSource);\n}\n\nfunction shouldRemoveSkill(\n forkedFrom: { source?: string } | null,\n configuredSources: string[],\n hasConfig: boolean,\n): boolean {\n return (\n forkedFrom !== null &&\n (skillMatchesConfiguredSource(forkedFrom.source, configuredSources) ||\n (!forkedFrom.source && hasConfig))\n );\n}\n\nexport default class Uninstall extends BaseCommand {\n static summary = `Remove ${DEFAULT_BRANDING.NAME} from this project`;\n\n static description = `Uninstall ${DEFAULT_BRANDING.NAME} from this project. Removes CLI-managed skills (matched by source), compiled agents, and plugins. User-created content is preserved.`;\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> --yes\",\n \"<%= config.bin %> <%= command.id %> --all\",\n ];\n\n static flags = {\n ...BaseCommand.baseFlags,\n yes: Flags.boolean({\n char: \"y\",\n description: \"Skip confirmation prompt\",\n default: false,\n }),\n all: Flags.boolean({\n description: \"Also remove .claude-src/ config directory\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Uninstall);\n const projectDir = process.cwd();\n\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} Uninstall`);\n this.log(\"\");\n\n const target = await detectUninstallTarget(projectDir);\n\n const hasAnythingToRemove =\n target.hasPlugins ||\n target.hasLocalSkills ||\n target.hasLocalAgents ||\n (flags.all && target.hasClaudeSrcDir);\n\n if (!hasAnythingToRemove) {\n this.warn(\"Nothing to uninstall.\");\n this.log(\"\");\n this.log(INFO_MESSAGES.NOT_INSTALLED);\n this.log(\"\");\n this.log(INFO_MESSAGES.NO_CHANGES_MADE);\n return;\n }\n\n if (!flags.yes) {\n const confirmed = await new Promise<boolean>((resolve) => {\n const { waitUntilExit } = render(\n <UninstallConfirm\n target={target}\n removeAll={flags.all}\n onConfirm={() => resolve(true)}\n onCancel={() => resolve(false)}\n />,\n );\n\n waitUntilExit().catch(() => resolve(false));\n });\n\n if (!confirmed) {\n this.log(\"\");\n this.log(\"Uninstall cancelled\");\n this.exit(EXIT_CODES.CANCELLED);\n }\n } else {\n this.log(\"The following will be removed:\");\n this.log(\"\");\n\n if (target.hasPlugins) {\n this.log(\" Plugins:\");\n this.log(` ${target.pluginsDir}`);\n }\n\n if (target.hasLocalSkills || target.hasLocalAgents) {\n this.log(\" CLI-managed files:\");\n if (target.hasLocalSkills) {\n this.log(` ${target.skillsDir}/ (matching sources)`);\n }\n if (target.hasLocalAgents) {\n this.log(` ${target.agentsDir}/ (CLI-compiled)`);\n }\n }\n\n if (flags.all && target.hasClaudeSrcDir) {\n this.log(\" Config:\");\n this.log(` ${target.claudeSrcDir}/`);\n }\n\n this.log(\"\");\n }\n\n if (target.hasPlugins) {\n this.log(\"Uninstalling plugins...\");\n\n try {\n const cliAvailable = await isClaudeCLIAvailable();\n\n for (const pluginName of target.pluginNames) {\n if (cliAvailable) {\n try {\n await claudePluginUninstall(pluginName, \"project\", projectDir);\n } catch {\n // Best-effort: plugin may not be registered with Claude CLI\n }\n }\n\n const pluginPath = path.join(target.pluginsDir, pluginName);\n await remove(pluginPath);\n this.log(` Uninstalled plugin '${pluginName}'`);\n }\n\n this.logSuccess(\n `Uninstalled ${target.pluginNames.length} ${target.pluginNames.length === 1 ? \"plugin\" : \"plugins\"}`,\n );\n } catch (error) {\n this.log(\"Plugin uninstall failed\");\n this.error(getErrorMessage(error), {\n exit: EXIT_CODES.ERROR,\n });\n }\n }\n\n try {\n await this.removeLocalFiles(target, flags.all);\n } catch (error) {\n this.log(\"Failed to remove local files\");\n this.error(getErrorMessage(error), {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} has been uninstalled.`);\n this.log(\"\");\n this.logSuccess(SUCCESS_MESSAGES.UNINSTALL_COMPLETE);\n this.log(\"\");\n }\n\n private async removeLocalFiles(target: UninstallTarget, removeAll: boolean): Promise<void> {\n await this.removeMatchingSkills(target);\n await this.removeMatchingAgents(target);\n\n if (removeAll && target.hasClaudeSrcDir) {\n await remove(target.claudeSrcDir);\n this.logSuccess(`Removed ${CLAUDE_SRC_DIR}/`);\n }\n\n await this.removeEmptyClaudeDir(target);\n }\n\n private async removeMatchingSkills(target: UninstallTarget): Promise<void> {\n if (!target.hasLocalSkills) return;\n\n const skillDirNames = await listDirectories(target.skillsDir);\n let removedCount = 0;\n let skippedCount = 0;\n\n for (const skillDirName of skillDirNames) {\n const skillDir = path.join(target.skillsDir, skillDirName);\n const forkedFrom = await readForkedFromMetadata(skillDir);\n\n if (shouldRemoveSkill(forkedFrom, target.configuredSources, target.config !== null)) {\n await remove(skillDir);\n removedCount++;\n this.log(` Uninstalled skill '${skillDirName}'`);\n } else {\n this.warn(`Skipping '${skillDirName}': not created by ${DEFAULT_BRANDING.NAME} CLI`);\n skippedCount++;\n }\n }\n\n if (removedCount > 0) {\n this.logSuccess(\n `Removed ${removedCount} CLI-installed ${removedCount === 1 ? \"skill\" : \"skills\"}`,\n );\n }\n\n if (skippedCount > 0) return;\n if (!(await directoryExists(target.skillsDir))) return;\n if (await isDirectoryEmpty(target.skillsDir)) {\n await remove(target.skillsDir);\n }\n }\n\n private async removeMatchingAgents(target: UninstallTarget): Promise<void> {\n if (!target.hasLocalAgents) return;\n if (target.configuredAgents.length === 0) return;\n\n const agentFiles = await this.listAgentFiles(target.agentsDir);\n let removedCount = 0;\n\n for (const agentFile of agentFiles) {\n const agentName = agentFile.replace(/\\.md$/, \"\");\n if (!target.configuredAgents.includes(agentName)) continue;\n\n await remove(path.join(target.agentsDir, agentFile));\n this.log(` Uninstalled agent '${agentName}'`);\n removedCount++;\n }\n\n if (removedCount > 0) {\n this.logSuccess(\n `Removed ${removedCount} compiled ${removedCount === 1 ? \"agent\" : \"agents\"}`,\n );\n }\n\n if (!(await directoryExists(target.agentsDir))) return;\n if (await isDirectoryEmpty(target.agentsDir)) {\n await remove(target.agentsDir);\n }\n }\n\n private async listAgentFiles(agentsDir: string): Promise<string[]> {\n try {\n const { readdir } = await import(\"fs/promises\");\n return (await readdir(agentsDir)).filter((f) => f.endsWith(\".md\"));\n } catch {\n return [];\n }\n }\n\n private async removeEmptyClaudeDir(target: UninstallTarget): Promise<void> {\n if (!target.hasClaudeDir) return;\n if (!(await directoryExists(target.claudeDir))) return;\n\n if (await isDirectoryEmpty(target.claudeDir)) {\n await remove(target.claudeDir);\n this.logSuccess(`Removed ${CLAUDE_DIR}/`);\n } else {\n this.log(`Kept ${CLAUDE_DIR}/ (contains user content)`);\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/uninstall.tsx"],"sourcesContent":["import React from \"react\";\n\nimport { Flags } from \"@oclif/core\";\nimport { render, Box, Text, useApp } from \"ink\";\nimport path from \"path\";\n\nimport { BaseCommand } from \"../base-command\";\nimport { Confirm } from \"../components/common/confirm\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport { directoryExists, listDirectories, remove } from \"../utils/fs\";\nimport { claudePluginUninstall, isClaudeCLIAvailable } from \"../utils/exec\";\nimport { listPluginNames, getProjectPluginsDir } from \"../lib/plugins\";\nimport { readForkedFromMetadata } from \"../lib/skills\";\nimport { loadProjectSourceConfig } from \"../lib/configuration/config\";\nimport type { ProjectConfig } from \"../types\";\nimport { CLAUDE_DIR, CLAUDE_SRC_DIR, CLI_COLORS, DEFAULT_BRANDING } from \"../consts\";\nimport { EXIT_CODES } from \"../lib/exit-codes\";\nimport { SUCCESS_MESSAGES, INFO_MESSAGES } from \"../utils/messages\";\n\ntype UninstallTarget = {\n hasPlugins: boolean;\n pluginNames: string[];\n hasLocalSkills: boolean;\n hasLocalAgents: boolean;\n hasClaudeDir: boolean;\n hasClaudeSrcDir: boolean;\n pluginsDir: string;\n skillsDir: string;\n agentsDir: string;\n claudeDir: string;\n claudeSrcDir: string;\n /** Resolved project source config from .claude-src/config.ts */\n config: Partial<ProjectConfig> | null;\n /** All configured source URLs (primary + extras) */\n configuredSources: string[];\n /** Agent names from the generated config (e.g., [\"web-developer\"]) */\n configuredAgents: string[];\n};\n\nfunction collectConfiguredSources(config: Partial<ProjectConfig> | null): string[] {\n if (!config) return [];\n return [\n ...(config.source ? [config.source] : []),\n ...(config.sources?.map((entry) => entry.url) ?? []),\n ];\n}\n\nfunction collectConfiguredAgents(config: Partial<ProjectConfig> | null): string[] {\n if (!config?.agents) return [];\n return config.agents.map((a) => a.name);\n}\n\nasync function detectUninstallTarget(projectDir: string): Promise<UninstallTarget> {\n const pluginsDir = getProjectPluginsDir(projectDir);\n const skillsDir = path.join(projectDir, CLAUDE_DIR, \"skills\");\n const agentsDir = path.join(projectDir, CLAUDE_DIR, \"agents\");\n const claudeDir = path.join(projectDir, CLAUDE_DIR);\n const claudeSrcDir = path.join(projectDir, CLAUDE_SRC_DIR);\n\n const [hasLocalSkills, hasLocalAgents, hasClaudeDir, hasClaudeSrcDir, config] = await Promise.all(\n [\n directoryExists(skillsDir),\n directoryExists(agentsDir),\n directoryExists(claudeDir),\n directoryExists(claudeSrcDir),\n loadProjectSourceConfig(projectDir),\n ],\n );\n\n let pluginNames: string[] = [];\n try {\n pluginNames = await listPluginNames(projectDir);\n } catch {\n // Best-effort: plugin detection may fail\n }\n\n const configuredSources = collectConfiguredSources(config);\n const configuredAgents = collectConfiguredAgents(config);\n\n return {\n hasPlugins: pluginNames.length > 0,\n pluginNames,\n hasLocalSkills,\n hasLocalAgents,\n hasClaudeDir,\n hasClaudeSrcDir,\n pluginsDir,\n skillsDir,\n agentsDir,\n claudeDir,\n claudeSrcDir,\n config,\n configuredSources,\n configuredAgents,\n };\n}\n\ntype UninstallConfirmProps = {\n target: UninstallTarget;\n removeAll: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n};\n\nconst UninstallConfirm: React.FC<UninstallConfirmProps> = ({\n target,\n removeAll,\n onConfirm,\n onCancel,\n}) => {\n const { exit } = useApp();\n\n return (\n <Box flexDirection=\"column\">\n <Text bold>The following will be removed:</Text>\n <Text> </Text>\n\n {target.hasPlugins && (\n <Box flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> Plugins:</Text>\n <Text dimColor> {target.pluginsDir}</Text>\n </Box>\n )}\n\n {(target.hasLocalSkills || target.hasLocalAgents) && (\n <Box flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> CLI-managed files:</Text>\n {target.hasLocalSkills && <Text dimColor> {target.skillsDir}/ (matching sources)</Text>}\n {target.hasLocalAgents && <Text dimColor> {target.agentsDir}/ (CLI-compiled)</Text>}\n </Box>\n )}\n\n {removeAll && target.hasClaudeSrcDir && (\n <Box flexDirection=\"column\">\n <Text color={CLI_COLORS.ERROR}> Config:</Text>\n <Text dimColor> {target.claudeSrcDir}/</Text>\n </Box>\n )}\n\n <Text> </Text>\n <Confirm\n message=\"Are you sure you want to uninstall?\"\n onConfirm={() => {\n onConfirm();\n exit();\n }}\n onCancel={() => {\n onCancel();\n exit();\n }}\n defaultValue={false}\n />\n </Box>\n );\n};\n\nasync function isDirectoryEmpty(dirPath: string): Promise<boolean> {\n const { readdir } = await import(\"fs/promises\");\n try {\n const allEntries = await readdir(dirPath);\n return allEntries.length === 0;\n } catch {\n return true;\n }\n}\n\nfunction skillMatchesConfiguredSource(\n forkedFromSource: string | undefined,\n configuredSources: string[],\n): boolean {\n if (!forkedFromSource || configuredSources.length === 0) return false;\n return configuredSources.includes(forkedFromSource);\n}\n\nfunction shouldRemoveSkill(\n forkedFrom: { source?: string } | null,\n configuredSources: string[],\n hasConfig: boolean,\n): boolean {\n return (\n forkedFrom !== null &&\n (skillMatchesConfiguredSource(forkedFrom.source, configuredSources) ||\n (!forkedFrom.source && hasConfig))\n );\n}\n\nexport default class Uninstall extends BaseCommand {\n static summary = `Remove ${DEFAULT_BRANDING.NAME} from this project`;\n\n static description = `Uninstall ${DEFAULT_BRANDING.NAME} from this project. Removes CLI-managed skills (matched by source), compiled agents, and plugins. User-created content is preserved.`;\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> --yes\",\n \"<%= config.bin %> <%= command.id %> --all\",\n ];\n\n static flags = {\n ...BaseCommand.baseFlags,\n yes: Flags.boolean({\n char: \"y\",\n description: \"Skip confirmation prompt\",\n default: false,\n }),\n all: Flags.boolean({\n description: \"Also remove .claude-src/ config directory\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Uninstall);\n const projectDir = process.cwd();\n\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} Uninstall`);\n this.log(\"\");\n\n const target = await detectUninstallTarget(projectDir);\n\n const hasAnythingToRemove =\n target.hasPlugins ||\n target.hasLocalSkills ||\n target.hasLocalAgents ||\n (flags.all && target.hasClaudeSrcDir);\n\n if (!hasAnythingToRemove) {\n this.warn(\"Nothing to uninstall.\");\n this.log(\"\");\n this.log(INFO_MESSAGES.NOT_INSTALLED);\n this.log(\"\");\n this.log(INFO_MESSAGES.NO_CHANGES_MADE);\n return;\n }\n\n if (!flags.yes) {\n const confirmed = await new Promise<boolean>((resolve) => {\n const { waitUntilExit } = render(\n <UninstallConfirm\n target={target}\n removeAll={flags.all}\n onConfirm={() => resolve(true)}\n onCancel={() => resolve(false)}\n />,\n );\n\n waitUntilExit().catch(() => resolve(false));\n });\n\n if (!confirmed) {\n this.log(\"\");\n this.log(\"Uninstall cancelled\");\n this.exit(EXIT_CODES.CANCELLED);\n }\n } else {\n this.log(\"The following will be removed:\");\n this.log(\"\");\n\n if (target.hasPlugins) {\n this.log(\" Plugins:\");\n this.log(` ${target.pluginsDir}`);\n }\n\n if (target.hasLocalSkills || target.hasLocalAgents) {\n this.log(\" CLI-managed files:\");\n if (target.hasLocalSkills) {\n this.log(` ${target.skillsDir}/ (matching sources)`);\n }\n if (target.hasLocalAgents) {\n this.log(` ${target.agentsDir}/ (CLI-compiled)`);\n }\n }\n\n if (flags.all && target.hasClaudeSrcDir) {\n this.log(\" Config:\");\n this.log(` ${target.claudeSrcDir}/`);\n }\n\n this.log(\"\");\n }\n\n if (target.hasPlugins) {\n this.log(\"Uninstalling plugins...\");\n\n try {\n const cliAvailable = await isClaudeCLIAvailable();\n\n for (const pluginName of target.pluginNames) {\n if (cliAvailable) {\n try {\n await claudePluginUninstall(pluginName, \"project\", projectDir);\n } catch {\n // Best-effort: plugin may not be registered with Claude CLI\n }\n }\n\n const pluginPath = path.join(target.pluginsDir, pluginName);\n await remove(pluginPath);\n this.log(` Uninstalled plugin '${pluginName}'`);\n }\n\n this.logSuccess(\n `Uninstalled ${target.pluginNames.length} ${target.pluginNames.length === 1 ? \"plugin\" : \"plugins\"}`,\n );\n } catch (error) {\n this.log(\"Plugin uninstall failed\");\n this.error(getErrorMessage(error), {\n exit: EXIT_CODES.ERROR,\n });\n }\n }\n\n try {\n await this.removeLocalFiles(target, flags.all);\n } catch (error) {\n this.log(\"Failed to remove local files\");\n this.error(getErrorMessage(error), {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} has been uninstalled.`);\n this.log(\"\");\n this.logSuccess(SUCCESS_MESSAGES.UNINSTALL_COMPLETE);\n this.log(\"\");\n }\n\n private async removeLocalFiles(target: UninstallTarget, removeAll: boolean): Promise<void> {\n await this.removeMatchingSkills(target);\n await this.removeMatchingAgents(target);\n\n if (removeAll && target.hasClaudeSrcDir) {\n await remove(target.claudeSrcDir);\n this.logSuccess(`Removed ${CLAUDE_SRC_DIR}/`);\n }\n\n await this.removeEmptyClaudeDir(target);\n }\n\n private async removeMatchingSkills(target: UninstallTarget): Promise<void> {\n if (!target.hasLocalSkills) return;\n\n const skillDirNames = await listDirectories(target.skillsDir);\n let removedCount = 0;\n let skippedCount = 0;\n\n for (const skillDirName of skillDirNames) {\n const skillDir = path.join(target.skillsDir, skillDirName);\n const forkedFrom = await readForkedFromMetadata(skillDir);\n\n if (shouldRemoveSkill(forkedFrom, target.configuredSources, target.config !== null)) {\n await remove(skillDir);\n removedCount++;\n this.log(` Uninstalled skill '${skillDirName}'`);\n } else {\n this.warn(`Skipping '${skillDirName}': not created by ${DEFAULT_BRANDING.NAME} CLI`);\n skippedCount++;\n }\n }\n\n if (removedCount > 0) {\n this.logSuccess(\n `Removed ${removedCount} CLI-installed ${removedCount === 1 ? \"skill\" : \"skills\"}`,\n );\n }\n\n if (skippedCount > 0) return;\n if (!(await directoryExists(target.skillsDir))) return;\n if (await isDirectoryEmpty(target.skillsDir)) {\n await remove(target.skillsDir);\n }\n }\n\n private async removeMatchingAgents(target: UninstallTarget): Promise<void> {\n if (!target.hasLocalAgents) return;\n if (target.configuredAgents.length === 0) return;\n\n const agentFiles = await this.listAgentFiles(target.agentsDir);\n let removedCount = 0;\n\n for (const agentFile of agentFiles) {\n const agentName = agentFile.replace(/\\.md$/, \"\");\n if (!target.configuredAgents.includes(agentName)) continue;\n\n await remove(path.join(target.agentsDir, agentFile));\n this.log(` Uninstalled agent '${agentName}'`);\n removedCount++;\n }\n\n if (removedCount > 0) {\n this.logSuccess(\n `Removed ${removedCount} compiled ${removedCount === 1 ? \"agent\" : \"agents\"}`,\n );\n }\n\n if (!(await directoryExists(target.agentsDir))) return;\n if (await isDirectoryEmpty(target.agentsDir)) {\n await remove(target.agentsDir);\n }\n }\n\n private async listAgentFiles(agentsDir: string): Promise<string[]> {\n try {\n const { readdir } = await import(\"fs/promises\");\n return (await readdir(agentsDir)).filter((f) => f.endsWith(\".md\"));\n } catch {\n return [];\n }\n }\n\n private async removeEmptyClaudeDir(target: UninstallTarget): Promise<void> {\n if (!target.hasClaudeDir) return;\n if (!(await directoryExists(target.claudeDir))) return;\n\n if (await isDirectoryEmpty(target.claudeDir)) {\n await remove(target.claudeDir);\n this.logSuccess(`Removed ${CLAUDE_DIR}/`);\n } else {\n this.log(`Kept ${CLAUDE_DIR}/ (contains user content)`);\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/commands/update.js
CHANGED
|
@@ -4,33 +4,36 @@ import {
|
|
|
4
4
|
} from "../chunk-N6S7ZRIL.js";
|
|
5
5
|
import {
|
|
6
6
|
recompileAgents
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-ZFY5EMDV.js";
|
|
8
8
|
import {
|
|
9
9
|
ERROR_MESSAGES,
|
|
10
10
|
INFO_MESSAGES,
|
|
11
11
|
STATUS_MESSAGES,
|
|
12
12
|
SUCCESS_MESSAGES
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-CXRVM7BA.js";
|
|
14
14
|
import {
|
|
15
15
|
compareLocalSkillsWithSource,
|
|
16
16
|
injectForkedFromMetadata,
|
|
17
17
|
loadSkillsMatrixFromSource
|
|
18
|
-
} from "../chunk-
|
|
19
|
-
import "../chunk-
|
|
18
|
+
} from "../chunk-53URJ5XK.js";
|
|
19
|
+
import "../chunk-F3REOP7N.js";
|
|
20
20
|
import "../chunk-T4EXUIBY.js";
|
|
21
|
+
import {
|
|
22
|
+
getMatrix
|
|
23
|
+
} from "../chunk-BKL3DF2Q.js";
|
|
21
24
|
import {
|
|
22
25
|
BaseCommand,
|
|
23
26
|
EXIT_CODES
|
|
24
|
-
} from "../chunk-
|
|
27
|
+
} from "../chunk-EE5EPS32.js";
|
|
25
28
|
import {
|
|
26
29
|
copy,
|
|
27
30
|
fileExists,
|
|
28
31
|
getErrorMessage
|
|
29
|
-
} from "../chunk-
|
|
32
|
+
} from "../chunk-LMZXL5RQ.js";
|
|
30
33
|
import {
|
|
31
34
|
CLI_BIN_NAME,
|
|
32
35
|
LOCAL_SKILLS_PATH
|
|
33
|
-
} from "../chunk-
|
|
36
|
+
} from "../chunk-EGMQ3SXN.js";
|
|
34
37
|
import "../chunk-EC3UJRKZ.js";
|
|
35
38
|
import {
|
|
36
39
|
init_esm_shims
|
|
@@ -140,7 +143,8 @@ var Update = class _Update extends BaseCommand {
|
|
|
140
143
|
`Loaded from ${sourceResult.isLocal ? "local" : "remote"}: ${sourceResult.sourcePath}`
|
|
141
144
|
);
|
|
142
145
|
const sourceSkills = {};
|
|
143
|
-
|
|
146
|
+
const matrix = getMatrix();
|
|
147
|
+
for (const [skillId, skill] of Object.entries(matrix.skills)) {
|
|
144
148
|
if (!skill) continue;
|
|
145
149
|
if (!skill.local) {
|
|
146
150
|
sourceSkills[skillId] = { path: skill.path };
|
|
@@ -1 +1 @@
|
|
|
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 { CLI_BIN_NAME, LOCAL_SKILLS_PATH } from \"../consts.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 \\`${CLI_BIN_NAME} 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 recompileResult = await recompileAgents({\n pluginDir: projectDir,\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
|
+
{"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 { getMatrix } from \"../stores/matrix-store\";\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 { CLI_BIN_NAME, LOCAL_SKILLS_PATH } from \"../consts.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 const matrix = getMatrix();\n for (const [skillId, skill] of Object.entries(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 \\`${CLI_BIN_NAME} 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 recompileResult = await recompileAgents({\n pluginDir: projectDir,\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,28 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ERROR_MESSAGES
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-CXRVM7BA.js";
|
|
5
5
|
import {
|
|
6
6
|
checkMatrixHealth,
|
|
7
|
-
extractAllSkills,
|
|
8
7
|
loadProjectSourceConfig,
|
|
9
|
-
|
|
10
|
-
loadSkillRules,
|
|
11
|
-
mergeMatrixWithSkills,
|
|
8
|
+
loadSkillsMatrixFromSource,
|
|
12
9
|
printPluginValidationResult,
|
|
13
10
|
printValidationResults,
|
|
14
11
|
validateAllPlugins,
|
|
15
12
|
validateAllSchemas,
|
|
16
13
|
validatePlugin
|
|
17
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-53URJ5XK.js";
|
|
18
15
|
import {
|
|
19
16
|
parseFrontmatter
|
|
20
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-F3REOP7N.js";
|
|
21
18
|
import "../chunk-T4EXUIBY.js";
|
|
19
|
+
import {
|
|
20
|
+
useMatrixStore
|
|
21
|
+
} from "../chunk-BKL3DF2Q.js";
|
|
22
22
|
import {
|
|
23
23
|
BaseCommand,
|
|
24
24
|
EXIT_CODES
|
|
25
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-EE5EPS32.js";
|
|
26
26
|
import {
|
|
27
27
|
SKILL_ID_PATTERN,
|
|
28
28
|
directoryExists,
|
|
@@ -30,15 +30,13 @@ import {
|
|
|
30
30
|
getErrorMessage,
|
|
31
31
|
glob,
|
|
32
32
|
metadataValidationSchema,
|
|
33
|
-
readFile
|
|
34
|
-
|
|
35
|
-
} from "../chunk-LWXRUR6B.js";
|
|
33
|
+
readFile
|
|
34
|
+
} from "../chunk-LMZXL5RQ.js";
|
|
36
35
|
import {
|
|
37
36
|
SKILLS_DIR_PATH,
|
|
38
37
|
SKILL_CATEGORIES_PATH,
|
|
39
|
-
SKILL_RULES_PATH,
|
|
40
38
|
STANDARD_FILES
|
|
41
|
-
} from "../chunk-
|
|
39
|
+
} from "../chunk-EGMQ3SXN.js";
|
|
42
40
|
import "../chunk-EC3UJRKZ.js";
|
|
43
41
|
import {
|
|
44
42
|
init_esm_shims
|
|
@@ -174,26 +172,10 @@ async function validateSource(sourcePath) {
|
|
|
174
172
|
}
|
|
175
173
|
}
|
|
176
174
|
try {
|
|
177
|
-
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
if (hasCats || hasRules) {
|
|
182
|
-
const cats = hasCats ? await loadSkillCategories(categoriesPath) : {};
|
|
183
|
-
const defaultRelationships = {
|
|
184
|
-
conflicts: [],
|
|
185
|
-
discourages: [],
|
|
186
|
-
recommends: [],
|
|
187
|
-
requires: [],
|
|
188
|
-
alternatives: []
|
|
189
|
-
};
|
|
190
|
-
const rules = hasRules ? await loadSkillRules(rulesPath) : {
|
|
191
|
-
version: "1.0.0",
|
|
192
|
-
relationships: defaultRelationships
|
|
193
|
-
};
|
|
194
|
-
const skills = await extractAllSkills(skillsDir);
|
|
195
|
-
const mergedMatrix = await mergeMatrixWithSkills(cats, rules.relationships, skills);
|
|
196
|
-
const healthIssues = checkMatrixHealth(mergedMatrix);
|
|
175
|
+
await loadSkillsMatrixFromSource({ sourceFlag: resolvedPath, skipExtraSources: true });
|
|
176
|
+
const matrix = useMatrixStore.getState().matrix;
|
|
177
|
+
if (matrix) {
|
|
178
|
+
const healthIssues = checkMatrixHealth(matrix);
|
|
197
179
|
for (const healthIssue of healthIssues) {
|
|
198
180
|
issues.push({
|
|
199
181
|
severity: healthIssue.severity,
|
|
@@ -201,10 +183,6 @@ async function validateSource(sourcePath) {
|
|
|
201
183
|
message: healthIssue.details
|
|
202
184
|
});
|
|
203
185
|
}
|
|
204
|
-
} else {
|
|
205
|
-
verbose(
|
|
206
|
-
`No categories/rules files at '${resolvedPath}' \u2014 skipping cross-reference validation`
|
|
207
|
-
);
|
|
208
186
|
}
|
|
209
187
|
} catch (error) {
|
|
210
188
|
issues.push({
|
|
@@ -302,15 +280,15 @@ var Validate = class _Validate extends BaseCommand {
|
|
|
302
280
|
this.error(`${ERROR_MESSAGES.VALIDATION_FAILED}: ${message}`, { exit: EXIT_CODES.ERROR });
|
|
303
281
|
}
|
|
304
282
|
}
|
|
305
|
-
async validatePlugins(pluginPath,
|
|
283
|
+
async validatePlugins(pluginPath, verbose, all) {
|
|
306
284
|
const targetPath = pluginPath ? path2.resolve(pluginPath) : process.cwd();
|
|
307
285
|
if (all) {
|
|
308
|
-
await this.validateAllPluginsInDirectory(targetPath,
|
|
286
|
+
await this.validateAllPluginsInDirectory(targetPath, verbose);
|
|
309
287
|
} else {
|
|
310
|
-
await this.validateSinglePlugin(targetPath,
|
|
288
|
+
await this.validateSinglePlugin(targetPath, verbose);
|
|
311
289
|
}
|
|
312
290
|
}
|
|
313
|
-
async validateAllPluginsInDirectory(targetPath,
|
|
291
|
+
async validateAllPluginsInDirectory(targetPath, verbose) {
|
|
314
292
|
this.log("");
|
|
315
293
|
this.log(`Validating all plugins in: ${targetPath}`);
|
|
316
294
|
this.log("");
|
|
@@ -326,7 +304,7 @@ var Validate = class _Validate extends BaseCommand {
|
|
|
326
304
|
this.log(` Invalid: ${result.summary.invalid}`);
|
|
327
305
|
this.log(` With warnings: ${result.summary.withWarnings}`);
|
|
328
306
|
for (const { name, result: pluginResult } of result.results) {
|
|
329
|
-
printPluginValidationResult(name, pluginResult,
|
|
307
|
+
printPluginValidationResult(name, pluginResult, verbose);
|
|
330
308
|
}
|
|
331
309
|
if (result.valid) {
|
|
332
310
|
this.log("");
|