@agents-inc/cli 0.74.5 → 0.74.7

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.
Files changed (135) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/{chunk-AQBZJUAL.js → chunk-2GD57LQE.js} +6 -6
  3. package/dist/{chunk-JGSCFYCP.js → chunk-2ZQKORJI.js} +2 -2
  4. package/dist/{chunk-RINGLIE7.js → chunk-CJSCCLT5.js} +2 -2
  5. package/dist/{chunk-IK6GTV3N.js → chunk-COZ75NET.js} +2 -2
  6. package/dist/{chunk-KIY36DJU.js → chunk-FDIKV4ON.js} +5 -7
  7. package/dist/chunk-FDIKV4ON.js.map +1 -0
  8. package/dist/{chunk-PPFXT5LC.js → chunk-GFTBHBRQ.js} +15 -16
  9. package/dist/chunk-GFTBHBRQ.js.map +1 -0
  10. package/dist/{chunk-QK4CJOLO.js → chunk-HA35FGPO.js} +2 -2
  11. package/dist/{chunk-U3EDOGQG.js → chunk-HIVZDWJC.js} +2 -2
  12. package/dist/{chunk-KDEOCJMS.js → chunk-ICJV3JJF.js} +83 -3
  13. package/dist/chunk-ICJV3JJF.js.map +1 -0
  14. package/dist/{chunk-NIA3NQBT.js → chunk-IJNNVCS4.js} +2 -2
  15. package/dist/{chunk-4OLQ4QPH.js → chunk-JB2QTE7M.js} +2 -2
  16. package/dist/{chunk-DBPC4V25.js → chunk-JZPQI7YI.js} +2 -2
  17. package/dist/{chunk-TW64EOM7.js → chunk-LVNNP7T4.js} +16 -5
  18. package/dist/chunk-LVNNP7T4.js.map +1 -0
  19. package/dist/{chunk-JNMZVX5S.js → chunk-MOWZ2FLG.js} +3 -3
  20. package/dist/{chunk-4OBRPE6A.js → chunk-NG2GGK6P.js} +5 -1
  21. package/dist/{chunk-4OBRPE6A.js.map → chunk-NG2GGK6P.js.map} +1 -1
  22. package/dist/{chunk-JAPYUFAM.js → chunk-RHAZARG3.js} +4 -4
  23. package/dist/{chunk-FOPJDYUF.js → chunk-RO6BG4ZW.js} +3 -3
  24. package/dist/{chunk-HRJTZXRF.js → chunk-STC7IEVI.js} +6 -8
  25. package/dist/{chunk-HRJTZXRF.js.map → chunk-STC7IEVI.js.map} +1 -1
  26. package/dist/{chunk-XV6A6PAW.js → chunk-TJBOCGLR.js} +12 -12
  27. package/dist/{chunk-P2BH6X2C.js → chunk-UKYWXIDT.js} +7 -20
  28. package/dist/chunk-UKYWXIDT.js.map +1 -0
  29. package/dist/{chunk-WMSV5AJT.js → chunk-VMTZ5WC5.js} +4 -4
  30. package/dist/{chunk-CTKWL3GL.js → chunk-W3GHDONP.js} +4 -4
  31. package/dist/{chunk-FFNBQMMZ.js → chunk-ZU7AOE3X.js} +2 -2
  32. package/dist/commands/build/plugins.js +3 -4
  33. package/dist/commands/build/plugins.js.map +1 -1
  34. package/dist/commands/build/stack.js +3 -4
  35. package/dist/commands/build/stack.js.map +1 -1
  36. package/dist/commands/compile.js +3 -4
  37. package/dist/commands/compile.js.map +1 -1
  38. package/dist/commands/config/index.js +3 -4
  39. package/dist/commands/config/index.js.map +1 -1
  40. package/dist/commands/config/path.js +2 -3
  41. package/dist/commands/config/path.js.map +1 -1
  42. package/dist/commands/config/show.js +3 -4
  43. package/dist/commands/diff.js +2 -3
  44. package/dist/commands/diff.js.map +1 -1
  45. package/dist/commands/doctor.js +2 -3
  46. package/dist/commands/doctor.js.map +1 -1
  47. package/dist/commands/edit.js +26 -18
  48. package/dist/commands/edit.js.map +1 -1
  49. package/dist/commands/eject.js +2 -3
  50. package/dist/commands/eject.js.map +1 -1
  51. package/dist/commands/import/skill.js +2 -3
  52. package/dist/commands/import/skill.js.map +1 -1
  53. package/dist/commands/info.js +2 -3
  54. package/dist/commands/info.js.map +1 -1
  55. package/dist/commands/init.js +17 -18
  56. package/dist/commands/list.js +2 -3
  57. package/dist/commands/list.js.map +1 -1
  58. package/dist/commands/new/agent.js +3 -4
  59. package/dist/commands/new/agent.js.map +1 -1
  60. package/dist/commands/new/marketplace.js +3 -4
  61. package/dist/commands/new/marketplace.js.map +1 -1
  62. package/dist/commands/new/skill.js +3 -4
  63. package/dist/commands/outdated.js +2 -3
  64. package/dist/commands/outdated.js.map +1 -1
  65. package/dist/commands/search.js +2 -3
  66. package/dist/commands/search.js.map +1 -1
  67. package/dist/commands/uninstall.js +2 -3
  68. package/dist/commands/uninstall.js.map +1 -1
  69. package/dist/commands/update.js +3 -4
  70. package/dist/commands/update.js.map +1 -1
  71. package/dist/commands/validate.js +2 -3
  72. package/dist/commands/validate.js.map +1 -1
  73. package/dist/components/wizard/category-grid.js +2 -2
  74. package/dist/components/wizard/category-grid.test.js +7 -8
  75. package/dist/components/wizard/category-grid.test.js.map +1 -1
  76. package/dist/components/wizard/domain-selection.js +5 -6
  77. package/dist/components/wizard/source-grid.js +2 -2
  78. package/dist/components/wizard/source-grid.test.js +7 -8
  79. package/dist/components/wizard/source-grid.test.js.map +1 -1
  80. package/dist/components/wizard/stack-selection.js +4 -5
  81. package/dist/components/wizard/step-agents.js +5 -6
  82. package/dist/components/wizard/step-agents.test.js +8 -9
  83. package/dist/components/wizard/step-agents.test.js.map +1 -1
  84. package/dist/components/wizard/step-build.js +6 -7
  85. package/dist/components/wizard/step-build.test.js +8 -9
  86. package/dist/components/wizard/step-build.test.js.map +1 -1
  87. package/dist/components/wizard/step-confirm.js +3 -4
  88. package/dist/components/wizard/step-confirm.test.js +6 -7
  89. package/dist/components/wizard/step-confirm.test.js.map +1 -1
  90. package/dist/components/wizard/step-settings.js +3 -4
  91. package/dist/components/wizard/step-settings.test.js +6 -7
  92. package/dist/components/wizard/step-settings.test.js.map +1 -1
  93. package/dist/components/wizard/step-sources.js +5 -6
  94. package/dist/components/wizard/step-sources.test.js +8 -9
  95. package/dist/components/wizard/step-sources.test.js.map +1 -1
  96. package/dist/components/wizard/step-stack.js +7 -8
  97. package/dist/components/wizard/step-stack.test.js +8 -9
  98. package/dist/components/wizard/step-stack.test.js.map +1 -1
  99. package/dist/components/wizard/wizard-layout.js +4 -5
  100. package/dist/components/wizard/wizard.js +16 -17
  101. package/dist/hooks/init.js +19 -24
  102. package/dist/hooks/init.js.map +1 -1
  103. package/dist/plugins/dummy-skill/.claude-plugin/.content-hash +1 -0
  104. package/dist/plugins/dummy-skill/.claude-plugin/plugin.json +13 -0
  105. package/dist/{source-loader-IV6MOOPQ.js → source-loader-HQTTAMS7.js} +3 -4
  106. package/dist/{source-manager-FVOH3VXK.js → source-manager-A3QLBYCU.js} +3 -4
  107. package/dist/stores/wizard-store.js +3 -4
  108. package/dist/stores/wizard-store.test.js +6 -7
  109. package/dist/stores/wizard-store.test.js.map +1 -1
  110. package/package.json +1 -1
  111. package/dist/chunk-KDEOCJMS.js.map +0 -1
  112. package/dist/chunk-KIY36DJU.js.map +0 -1
  113. package/dist/chunk-P2BH6X2C.js.map +0 -1
  114. package/dist/chunk-PPFXT5LC.js.map +0 -1
  115. package/dist/chunk-TW64EOM7.js.map +0 -1
  116. package/dist/chunk-XXK6MFOA.js +0 -28
  117. package/dist/chunk-XXK6MFOA.js.map +0 -1
  118. /package/dist/{chunk-AQBZJUAL.js.map → chunk-2GD57LQE.js.map} +0 -0
  119. /package/dist/{chunk-JGSCFYCP.js.map → chunk-2ZQKORJI.js.map} +0 -0
  120. /package/dist/{chunk-RINGLIE7.js.map → chunk-CJSCCLT5.js.map} +0 -0
  121. /package/dist/{chunk-IK6GTV3N.js.map → chunk-COZ75NET.js.map} +0 -0
  122. /package/dist/{chunk-QK4CJOLO.js.map → chunk-HA35FGPO.js.map} +0 -0
  123. /package/dist/{chunk-U3EDOGQG.js.map → chunk-HIVZDWJC.js.map} +0 -0
  124. /package/dist/{chunk-NIA3NQBT.js.map → chunk-IJNNVCS4.js.map} +0 -0
  125. /package/dist/{chunk-4OLQ4QPH.js.map → chunk-JB2QTE7M.js.map} +0 -0
  126. /package/dist/{chunk-DBPC4V25.js.map → chunk-JZPQI7YI.js.map} +0 -0
  127. /package/dist/{chunk-JNMZVX5S.js.map → chunk-MOWZ2FLG.js.map} +0 -0
  128. /package/dist/{chunk-JAPYUFAM.js.map → chunk-RHAZARG3.js.map} +0 -0
  129. /package/dist/{chunk-FOPJDYUF.js.map → chunk-RO6BG4ZW.js.map} +0 -0
  130. /package/dist/{chunk-XV6A6PAW.js.map → chunk-TJBOCGLR.js.map} +0 -0
  131. /package/dist/{chunk-WMSV5AJT.js.map → chunk-VMTZ5WC5.js.map} +0 -0
  132. /package/dist/{chunk-CTKWL3GL.js.map → chunk-W3GHDONP.js.map} +0 -0
  133. /package/dist/{chunk-FFNBQMMZ.js.map → chunk-ZU7AOE3X.js.map} +0 -0
  134. /package/dist/{source-loader-IV6MOOPQ.js.map → source-loader-HQTTAMS7.js.map} +0 -0
  135. /package/dist/{source-manager-FVOH3VXK.js.map → source-manager-A3QLBYCU.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/doctor.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport { BaseCommand } from \"../base-command\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport { EXIT_CODES } from \"../lib/exit-codes\";\nimport { loadProjectConfig, validateProjectConfig } from \"../lib/configuration\";\nimport { loadSkillsMatrixFromSource } from \"../lib/loading\";\nimport { matrix } from \"../lib/matrix/matrix-provider\";\nimport { discoverLocalSkills } from \"../lib/skills\";\nimport { getStackSkillIds } from \"../lib/stacks\";\nimport type { AgentName, MergedSkillsMatrix, ProjectConfig, SkillId } from \"../types\";\nimport { fileExists, glob, directoryExists } from \"../utils/fs\";\nimport {\n CLAUDE_DIR,\n CLAUDE_SRC_DIR,\n CLI_BIN_NAME,\n DEFAULT_BRANDING,\n STANDARD_FILES,\n} from \"../consts\";\nimport { setVerbose } from \"../utils/logger\";\n\ntype CheckResult = {\n status: \"pass\" | \"fail\" | \"warn\" | \"skip\";\n message: string;\n details?: string[];\n};\n\nasync function checkConfigValid(projectDir: string): Promise<CheckResult> {\n const loaded = await loadProjectConfig(projectDir);\n\n if (!loaded) {\n return {\n status: \"fail\",\n message: `${CLAUDE_SRC_DIR}/${STANDARD_FILES.CONFIG_TS} not found`,\n details: [`Run '${CLI_BIN_NAME} init' to create a configuration`],\n };\n }\n\n const validation = validateProjectConfig(loaded.config);\n\n if (!validation.valid) {\n return {\n status: \"fail\",\n message: `${CLAUDE_SRC_DIR}/${STANDARD_FILES.CONFIG_TS} has errors`,\n details: validation.errors,\n };\n }\n\n if (validation.warnings.length > 0) {\n return {\n status: \"warn\",\n message: `${CLAUDE_SRC_DIR}/${STANDARD_FILES.CONFIG_TS} has warnings`,\n details: validation.warnings,\n };\n }\n\n return {\n status: \"pass\",\n message: `${CLAUDE_SRC_DIR}/${STANDARD_FILES.CONFIG_TS} is valid`,\n };\n}\n\nasync function checkSkillsResolved(\n config: ProjectConfig,\n matrix: MergedSkillsMatrix,\n projectDir: string,\n): Promise<CheckResult> {\n const uniqueSkills = config.stack ? getStackSkillIds(config.stack) : [];\n\n if (uniqueSkills.length === 0) {\n return {\n status: \"pass\",\n message: \"No skills configured\",\n };\n }\n\n const localResult = await discoverLocalSkills(projectDir);\n const localSkillIds = new Set(localResult?.skills.map((s) => s.id) ?? []);\n\n const missingSkills: string[] = [];\n for (const skillId of uniqueSkills) {\n const inMatrix = skillId in matrix.skills;\n const inLocal = localSkillIds.has(skillId);\n if (!inMatrix && !inLocal) {\n missingSkills.push(skillId);\n }\n }\n\n if (missingSkills.length > 0) {\n return {\n status: \"fail\",\n message: `${uniqueSkills.length - missingSkills.length}/${uniqueSkills.length} skills found`,\n details: missingSkills.map((s) => `- ${s} (not found)`),\n };\n }\n\n return {\n status: \"pass\",\n message: `${uniqueSkills.length}/${uniqueSkills.length} skills found`,\n };\n}\n\nasync function checkAgentsCompiled(\n config: ProjectConfig,\n projectDir: string,\n): Promise<CheckResult> {\n const agents = config.agents ?? [];\n\n if (agents.length === 0) {\n return {\n status: \"pass\",\n message: \"No agents configured\",\n };\n }\n\n const agentsDir = path.join(projectDir, CLAUDE_DIR, \"agents\");\n const missingAgents: string[] = [];\n\n for (const agent of agents) {\n const agentPath = path.join(agentsDir, `${agent.name}.md`);\n if (!(await fileExists(agentPath))) {\n missingAgents.push(agent.name);\n }\n }\n\n if (missingAgents.length > 0) {\n return {\n status: \"warn\",\n message: `${missingAgents.length} agent${missingAgents.length === 1 ? \"\" : \"s\"} need${missingAgents.length === 1 ? \"s\" : \"\"} recompilation`,\n details: missingAgents.map((a) => `- ${a} (missing)`),\n };\n }\n\n return {\n status: \"pass\",\n message: `${agents.length}/${agents.length} agents compiled`,\n };\n}\n\nasync function checkNoOrphans(config: ProjectConfig, projectDir: string): Promise<CheckResult> {\n const agentsDir = path.join(projectDir, CLAUDE_DIR, \"agents\");\n\n if (!(await directoryExists(agentsDir))) {\n return {\n status: \"pass\",\n message: \"No agents directory\",\n };\n }\n\n const mdFiles = await glob(\"*.md\", agentsDir);\n const configAgentNames: Set<string> = new Set((config.agents ?? []).map((a) => a.name));\n\n const orphanedFiles: string[] = [];\n for (const file of mdFiles) {\n const agentName = file.replace(/\\.md$/, \"\");\n if (!configAgentNames.has(agentName)) {\n orphanedFiles.push(agentName);\n }\n }\n\n if (orphanedFiles.length > 0) {\n return {\n status: \"warn\",\n message: `${orphanedFiles.length} orphaned agent file${orphanedFiles.length === 1 ? \"\" : \"s\"}`,\n details: orphanedFiles.map((f) => `- ${f}.md (not in config)`),\n };\n }\n\n return {\n status: \"pass\",\n message: \"No orphaned agent files\",\n };\n}\n\nasync function checkSourceReachable(\n sourceFlag: string | undefined,\n projectDir: string,\n): Promise<CheckResult> {\n try {\n const result = await loadSkillsMatrixFromSource({\n sourceFlag,\n projectDir,\n });\n\n const skillCount = Object.keys(matrix.skills).length;\n const sourceLabel = result.isLocal ? \"local\" : \"remote\";\n\n return {\n status: \"pass\",\n message: `Connected to ${sourceLabel}: ${result.sourcePath}`,\n details: [`${skillCount} skills available`],\n };\n } catch (error) {\n const message = getErrorMessage(error);\n return {\n status: \"fail\",\n message: \"Failed to load source\",\n details: [message],\n };\n }\n}\n\nconst CHECK_WIDTH = 20;\n\nfunction formatCheckName(name: string): string {\n return name.padEnd(CHECK_WIDTH);\n}\n\nfunction formatStatus(status: CheckResult[\"status\"]): string {\n switch (status) {\n case \"pass\":\n return \"\\u2713\"; // ✓\n case \"fail\":\n return \"\\u2717\"; // ✗\n case \"warn\":\n return \"!\";\n case \"skip\":\n return \"-\";\n default:\n return \"?\";\n }\n}\n\nfunction formatCheckLine(name: string, result: CheckResult, verbose: boolean): string[] {\n const statusIcon = formatStatus(result.status);\n const nameFormatted = formatCheckName(name);\n const lines: string[] = [];\n\n lines.push(` ${nameFormatted}${statusIcon} ${result.message}`);\n\n const shouldShowDetails =\n result.details &&\n result.details.length > 0 &&\n (verbose || result.status === \"fail\" || result.status === \"warn\");\n\n if (shouldShowDetails) {\n for (const detail of result.details!) {\n lines.push(` ${\" \".repeat(CHECK_WIDTH)} ${detail}`);\n }\n }\n\n return lines;\n}\n\nfunction formatSummary(results: CheckResult[]): string {\n let passed = 0;\n let warnings = 0;\n let errors = 0;\n\n for (const result of results) {\n switch (result.status) {\n case \"pass\":\n passed++;\n break;\n case \"warn\":\n warnings++;\n break;\n case \"fail\":\n errors++;\n break;\n // skip doesn't count\n default:\n break;\n }\n }\n\n const parts: string[] = [];\n parts.push(`${passed} passed`);\n\n if (warnings > 0) {\n parts.push(`${warnings} warning${warnings === 1 ? \"\" : \"s\"}`);\n } else {\n parts.push(`0 warnings`);\n }\n\n if (errors > 0) {\n parts.push(`${errors} error${errors === 1 ? \"\" : \"s\"}`);\n } else {\n parts.push(`0 errors`);\n }\n\n return ` Summary: ${parts.join(\", \")}`;\n}\n\nfunction formatTips(results: CheckResult[]): string[] {\n const hasAgentWarning = results.some(\n (r) => r.status === \"warn\" && r.message.includes(\"recompilation\"),\n );\n const hasConfigError = results.some((r) => r.status === \"fail\" && r.message.includes(\"config\"));\n const hasSkillError = results.some(\n (r) => r.status === \"fail\" && r.message.includes(\"skills found\"),\n );\n\n const tips: string[] = [];\n\n if (hasAgentWarning) {\n tips.push(` Tip: Run '${CLI_BIN_NAME} compile' to generate missing agent files`);\n }\n if (hasConfigError) {\n tips.push(` Tip: Run '${CLI_BIN_NAME} init' to create or fix configuration`);\n }\n if (hasSkillError) {\n tips.push(\" Tip: Check skill IDs in config match available skills\");\n }\n\n return tips;\n}\n\nexport default class Doctor extends BaseCommand {\n static summary = \"Diagnose common configuration issues\";\n\n static description = `Run diagnostic checks on your ${DEFAULT_BRANDING.NAME} configuration to identify issues with config validity, skill resolution, agent compilation, and source connectivity.`;\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> --verbose\",\n \"<%= config.bin %> <%= command.id %> --source /path/to/marketplace\",\n ];\n\n static flags = {\n source: Flags.string({\n char: \"s\",\n description: \"Skills source path or URL\",\n }),\n verbose: Flags.boolean({\n char: \"v\",\n description: \"Show detailed output\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Doctor);\n\n setVerbose(flags.verbose);\n\n const projectDir = process.cwd();\n\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} Doctor`);\n this.log(\"\");\n this.log(\" Checking configuration health...\");\n this.log(\"\");\n\n const results: CheckResult[] = [];\n\n const configResult = await checkConfigValid(projectDir);\n results.push(configResult);\n formatCheckLine(\"Config Valid\", configResult, flags.verbose).forEach((line) => this.log(line));\n\n let config: ProjectConfig | null = null;\n\n if (configResult.status !== \"fail\") {\n const loaded = await loadProjectConfig(projectDir);\n config = loaded?.config ?? null;\n }\n\n const sourceResult = await checkSourceReachable(flags.source, projectDir);\n\n // loadSkillsMatrixFromSource (called by checkSourceReachable) populates the matrix automatically\n if (config) {\n const skillsResult = await checkSkillsResolved(config, matrix, projectDir);\n results.push(skillsResult);\n formatCheckLine(\"Skills Resolved\", skillsResult, flags.verbose).forEach((line) =>\n this.log(line),\n );\n } else {\n const skipResult: CheckResult = {\n status: \"skip\",\n message: \"Skipped (config invalid)\",\n };\n results.push(skipResult);\n formatCheckLine(\"Skills Resolved\", skipResult, flags.verbose).forEach((line) =>\n this.log(line),\n );\n }\n\n if (config) {\n const agentsResult = await checkAgentsCompiled(config, projectDir);\n results.push(agentsResult);\n formatCheckLine(\"Agents Compiled\", agentsResult, flags.verbose).forEach((line) =>\n this.log(line),\n );\n } else {\n const skipResult: CheckResult = {\n status: \"skip\",\n message: \"Skipped (config invalid)\",\n };\n results.push(skipResult);\n formatCheckLine(\"Agents Compiled\", skipResult, flags.verbose).forEach((line) =>\n this.log(line),\n );\n }\n\n if (config) {\n const orphansResult = await checkNoOrphans(config, projectDir);\n results.push(orphansResult);\n formatCheckLine(\"No Orphans\", orphansResult, flags.verbose).forEach((line) => this.log(line));\n } else {\n const skipResult: CheckResult = {\n status: \"skip\",\n message: \"Skipped (config invalid)\",\n };\n results.push(skipResult);\n formatCheckLine(\"No Orphans\", skipResult, flags.verbose).forEach((line) => this.log(line));\n }\n\n results.push(sourceResult);\n formatCheckLine(\"Source Reachable\", sourceResult, flags.verbose).forEach((line) =>\n this.log(line),\n );\n\n this.log(\"\");\n this.log(formatSummary(results));\n\n const tips = formatTips(results);\n if (tips.length > 0) {\n this.log(\"\");\n tips.forEach((tip) => this.log(tip));\n }\n\n this.log(\"\");\n\n const hasErrors = results.some((r) => r.status === \"fail\");\n if (hasErrors) {\n this.exit(EXIT_CODES.ERROR);\n }\n }\n}\n"],"mappings":"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","names":["matrix"]}
1
+ {"version":3,"sources":["../../src/cli/commands/doctor.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport { BaseCommand } from \"../base-command\";\nimport { getErrorMessage } from \"../utils/errors\";\nimport { EXIT_CODES } from \"../lib/exit-codes\";\nimport { loadProjectConfig, validateProjectConfig } from \"../lib/configuration\";\nimport { loadSkillsMatrixFromSource } from \"../lib/loading\";\nimport { matrix } from \"../lib/matrix/matrix-provider\";\nimport { discoverLocalSkills } from \"../lib/skills\";\nimport { getStackSkillIds } from \"../lib/stacks\";\nimport type { AgentName, MergedSkillsMatrix, ProjectConfig, SkillId } from \"../types\";\nimport { fileExists, glob, directoryExists } from \"../utils/fs\";\nimport {\n CLAUDE_DIR,\n CLAUDE_SRC_DIR,\n CLI_BIN_NAME,\n DEFAULT_BRANDING,\n STANDARD_FILES,\n} from \"../consts\";\nimport { setVerbose } from \"../utils/logger\";\n\ntype CheckResult = {\n status: \"pass\" | \"fail\" | \"warn\" | \"skip\";\n message: string;\n details?: string[];\n};\n\nasync function checkConfigValid(projectDir: string): Promise<CheckResult> {\n const loaded = await loadProjectConfig(projectDir);\n\n if (!loaded) {\n return {\n status: \"fail\",\n message: `${CLAUDE_SRC_DIR}/${STANDARD_FILES.CONFIG_TS} not found`,\n details: [`Run '${CLI_BIN_NAME} init' to create a configuration`],\n };\n }\n\n const validation = validateProjectConfig(loaded.config);\n\n if (!validation.valid) {\n return {\n status: \"fail\",\n message: `${CLAUDE_SRC_DIR}/${STANDARD_FILES.CONFIG_TS} has errors`,\n details: validation.errors,\n };\n }\n\n if (validation.warnings.length > 0) {\n return {\n status: \"warn\",\n message: `${CLAUDE_SRC_DIR}/${STANDARD_FILES.CONFIG_TS} has warnings`,\n details: validation.warnings,\n };\n }\n\n return {\n status: \"pass\",\n message: `${CLAUDE_SRC_DIR}/${STANDARD_FILES.CONFIG_TS} is valid`,\n };\n}\n\nasync function checkSkillsResolved(\n config: ProjectConfig,\n matrix: MergedSkillsMatrix,\n projectDir: string,\n): Promise<CheckResult> {\n const uniqueSkills = config.stack ? getStackSkillIds(config.stack) : [];\n\n if (uniqueSkills.length === 0) {\n return {\n status: \"pass\",\n message: \"No skills configured\",\n };\n }\n\n const localResult = await discoverLocalSkills(projectDir);\n const localSkillIds = new Set(localResult?.skills.map((s) => s.id) ?? []);\n\n const missingSkills: string[] = [];\n for (const skillId of uniqueSkills) {\n const inMatrix = skillId in matrix.skills;\n const inLocal = localSkillIds.has(skillId);\n if (!inMatrix && !inLocal) {\n missingSkills.push(skillId);\n }\n }\n\n if (missingSkills.length > 0) {\n return {\n status: \"fail\",\n message: `${uniqueSkills.length - missingSkills.length}/${uniqueSkills.length} skills found`,\n details: missingSkills.map((s) => `- ${s} (not found)`),\n };\n }\n\n return {\n status: \"pass\",\n message: `${uniqueSkills.length}/${uniqueSkills.length} skills found`,\n };\n}\n\nasync function checkAgentsCompiled(\n config: ProjectConfig,\n projectDir: string,\n): Promise<CheckResult> {\n const agents = config.agents ?? [];\n\n if (agents.length === 0) {\n return {\n status: \"pass\",\n message: \"No agents configured\",\n };\n }\n\n const agentsDir = path.join(projectDir, CLAUDE_DIR, \"agents\");\n const missingAgents: string[] = [];\n\n for (const agent of agents) {\n const agentPath = path.join(agentsDir, `${agent.name}.md`);\n if (!(await fileExists(agentPath))) {\n missingAgents.push(agent.name);\n }\n }\n\n if (missingAgents.length > 0) {\n return {\n status: \"warn\",\n message: `${missingAgents.length} agent${missingAgents.length === 1 ? \"\" : \"s\"} need${missingAgents.length === 1 ? \"s\" : \"\"} recompilation`,\n details: missingAgents.map((a) => `- ${a} (missing)`),\n };\n }\n\n return {\n status: \"pass\",\n message: `${agents.length}/${agents.length} agents compiled`,\n };\n}\n\nasync function checkNoOrphans(config: ProjectConfig, projectDir: string): Promise<CheckResult> {\n const agentsDir = path.join(projectDir, CLAUDE_DIR, \"agents\");\n\n if (!(await directoryExists(agentsDir))) {\n return {\n status: \"pass\",\n message: \"No agents directory\",\n };\n }\n\n const mdFiles = await glob(\"*.md\", agentsDir);\n const configAgentNames: Set<string> = new Set((config.agents ?? []).map((a) => a.name));\n\n const orphanedFiles: string[] = [];\n for (const file of mdFiles) {\n const agentName = file.replace(/\\.md$/, \"\");\n if (!configAgentNames.has(agentName)) {\n orphanedFiles.push(agentName);\n }\n }\n\n if (orphanedFiles.length > 0) {\n return {\n status: \"warn\",\n message: `${orphanedFiles.length} orphaned agent file${orphanedFiles.length === 1 ? \"\" : \"s\"}`,\n details: orphanedFiles.map((f) => `- ${f}.md (not in config)`),\n };\n }\n\n return {\n status: \"pass\",\n message: \"No orphaned agent files\",\n };\n}\n\nasync function checkSourceReachable(\n sourceFlag: string | undefined,\n projectDir: string,\n): Promise<CheckResult> {\n try {\n const result = await loadSkillsMatrixFromSource({\n sourceFlag,\n projectDir,\n });\n\n const skillCount = Object.keys(matrix.skills).length;\n const sourceLabel = result.isLocal ? \"local\" : \"remote\";\n\n return {\n status: \"pass\",\n message: `Connected to ${sourceLabel}: ${result.sourcePath}`,\n details: [`${skillCount} skills available`],\n };\n } catch (error) {\n const message = getErrorMessage(error);\n return {\n status: \"fail\",\n message: \"Failed to load source\",\n details: [message],\n };\n }\n}\n\nconst CHECK_WIDTH = 20;\n\nfunction formatCheckName(name: string): string {\n return name.padEnd(CHECK_WIDTH);\n}\n\nfunction formatStatus(status: CheckResult[\"status\"]): string {\n switch (status) {\n case \"pass\":\n return \"\\u2713\"; // ✓\n case \"fail\":\n return \"\\u2717\"; // ✗\n case \"warn\":\n return \"!\";\n case \"skip\":\n return \"-\";\n default:\n return \"?\";\n }\n}\n\nfunction formatCheckLine(name: string, result: CheckResult, verbose: boolean): string[] {\n const statusIcon = formatStatus(result.status);\n const nameFormatted = formatCheckName(name);\n const lines: string[] = [];\n\n lines.push(` ${nameFormatted}${statusIcon} ${result.message}`);\n\n const shouldShowDetails =\n result.details &&\n result.details.length > 0 &&\n (verbose || result.status === \"fail\" || result.status === \"warn\");\n\n if (shouldShowDetails) {\n for (const detail of result.details!) {\n lines.push(` ${\" \".repeat(CHECK_WIDTH)} ${detail}`);\n }\n }\n\n return lines;\n}\n\nfunction formatSummary(results: CheckResult[]): string {\n let passed = 0;\n let warnings = 0;\n let errors = 0;\n\n for (const result of results) {\n switch (result.status) {\n case \"pass\":\n passed++;\n break;\n case \"warn\":\n warnings++;\n break;\n case \"fail\":\n errors++;\n break;\n // skip doesn't count\n default:\n break;\n }\n }\n\n const parts: string[] = [];\n parts.push(`${passed} passed`);\n\n if (warnings > 0) {\n parts.push(`${warnings} warning${warnings === 1 ? \"\" : \"s\"}`);\n } else {\n parts.push(`0 warnings`);\n }\n\n if (errors > 0) {\n parts.push(`${errors} error${errors === 1 ? \"\" : \"s\"}`);\n } else {\n parts.push(`0 errors`);\n }\n\n return ` Summary: ${parts.join(\", \")}`;\n}\n\nfunction formatTips(results: CheckResult[]): string[] {\n const hasAgentWarning = results.some(\n (r) => r.status === \"warn\" && r.message.includes(\"recompilation\"),\n );\n const hasConfigError = results.some((r) => r.status === \"fail\" && r.message.includes(\"config\"));\n const hasSkillError = results.some(\n (r) => r.status === \"fail\" && r.message.includes(\"skills found\"),\n );\n\n const tips: string[] = [];\n\n if (hasAgentWarning) {\n tips.push(` Tip: Run '${CLI_BIN_NAME} compile' to generate missing agent files`);\n }\n if (hasConfigError) {\n tips.push(` Tip: Run '${CLI_BIN_NAME} init' to create or fix configuration`);\n }\n if (hasSkillError) {\n tips.push(\" Tip: Check skill IDs in config match available skills\");\n }\n\n return tips;\n}\n\nexport default class Doctor extends BaseCommand {\n static summary = \"Diagnose common configuration issues\";\n\n static description = `Run diagnostic checks on your ${DEFAULT_BRANDING.NAME} configuration to identify issues with config validity, skill resolution, agent compilation, and source connectivity.`;\n\n static examples = [\n \"<%= config.bin %> <%= command.id %>\",\n \"<%= config.bin %> <%= command.id %> --verbose\",\n \"<%= config.bin %> <%= command.id %> --source /path/to/marketplace\",\n ];\n\n static flags = {\n source: Flags.string({\n char: \"s\",\n description: \"Skills source path or URL\",\n }),\n verbose: Flags.boolean({\n char: \"v\",\n description: \"Show detailed output\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Doctor);\n\n setVerbose(flags.verbose);\n\n const projectDir = process.cwd();\n\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} Doctor`);\n this.log(\"\");\n this.log(\" Checking configuration health...\");\n this.log(\"\");\n\n const results: CheckResult[] = [];\n\n const configResult = await checkConfigValid(projectDir);\n results.push(configResult);\n formatCheckLine(\"Config Valid\", configResult, flags.verbose).forEach((line) => this.log(line));\n\n let config: ProjectConfig | null = null;\n\n if (configResult.status !== \"fail\") {\n const loaded = await loadProjectConfig(projectDir);\n config = loaded?.config ?? null;\n }\n\n const sourceResult = await checkSourceReachable(flags.source, projectDir);\n\n // loadSkillsMatrixFromSource (called by checkSourceReachable) populates the matrix automatically\n if (config) {\n const skillsResult = await checkSkillsResolved(config, matrix, projectDir);\n results.push(skillsResult);\n formatCheckLine(\"Skills Resolved\", skillsResult, flags.verbose).forEach((line) =>\n this.log(line),\n );\n } else {\n const skipResult: CheckResult = {\n status: \"skip\",\n message: \"Skipped (config invalid)\",\n };\n results.push(skipResult);\n formatCheckLine(\"Skills Resolved\", skipResult, flags.verbose).forEach((line) =>\n this.log(line),\n );\n }\n\n if (config) {\n const agentsResult = await checkAgentsCompiled(config, projectDir);\n results.push(agentsResult);\n formatCheckLine(\"Agents Compiled\", agentsResult, flags.verbose).forEach((line) =>\n this.log(line),\n );\n } else {\n const skipResult: CheckResult = {\n status: \"skip\",\n message: \"Skipped (config invalid)\",\n };\n results.push(skipResult);\n formatCheckLine(\"Agents Compiled\", skipResult, flags.verbose).forEach((line) =>\n this.log(line),\n );\n }\n\n if (config) {\n const orphansResult = await checkNoOrphans(config, projectDir);\n results.push(orphansResult);\n formatCheckLine(\"No Orphans\", orphansResult, flags.verbose).forEach((line) => this.log(line));\n } else {\n const skipResult: CheckResult = {\n status: \"skip\",\n message: \"Skipped (config invalid)\",\n };\n results.push(skipResult);\n formatCheckLine(\"No Orphans\", skipResult, flags.verbose).forEach((line) => this.log(line));\n }\n\n results.push(sourceResult);\n formatCheckLine(\"Source Reachable\", sourceResult, flags.verbose).forEach((line) =>\n this.log(line),\n );\n\n this.log(\"\");\n this.log(formatSummary(results));\n\n const tips = formatTips(results);\n if (tips.length > 0) {\n this.log(\"\");\n tips.forEach((tip) => this.log(tip));\n }\n\n this.log(\"\");\n\n const hasErrors = results.some((r) => r.status === \"fail\");\n if (hasErrors) {\n this.exit(EXIT_CODES.ERROR);\n }\n }\n}\n"],"mappings":"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","names":["matrix"]}
@@ -1,26 +1,26 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  Wizard
4
- } from "../chunk-XV6A6PAW.js";
5
- import "../chunk-4OLQ4QPH.js";
4
+ } from "../chunk-TJBOCGLR.js";
5
+ import "../chunk-JB2QTE7M.js";
6
6
  import "../chunk-SXGBPQY6.js";
7
- import "../chunk-JGSCFYCP.js";
8
- import "../chunk-JAPYUFAM.js";
7
+ import "../chunk-2ZQKORJI.js";
8
+ import "../chunk-RHAZARG3.js";
9
9
  import "../chunk-HGTC76BX.js";
10
- import "../chunk-CTKWL3GL.js";
11
- import "../chunk-JNMZVX5S.js";
12
- import "../chunk-HRJTZXRF.js";
13
- import "../chunk-AQBZJUAL.js";
10
+ import "../chunk-W3GHDONP.js";
11
+ import "../chunk-MOWZ2FLG.js";
12
+ import "../chunk-STC7IEVI.js";
13
+ import "../chunk-2GD57LQE.js";
14
14
  import "../chunk-K77I4XGL.js";
15
- import "../chunk-RINGLIE7.js";
15
+ import "../chunk-CJSCCLT5.js";
16
16
  import "../chunk-MWGDG4QN.js";
17
- import "../chunk-IK6GTV3N.js";
17
+ import "../chunk-COZ75NET.js";
18
18
  import "../chunk-7SOPVGDV.js";
19
19
  import "../chunk-2MHSOPIU.js";
20
- import "../chunk-DBPC4V25.js";
20
+ import "../chunk-JZPQI7YI.js";
21
21
  import "../chunk-GG4BSB6S.js";
22
- import "../chunk-WMSV5AJT.js";
23
- import "../chunk-TW64EOM7.js";
22
+ import "../chunk-VMTZ5WC5.js";
23
+ import "../chunk-LVNNP7T4.js";
24
24
  import "../chunk-OV5UJWS5.js";
25
25
  import "../chunk-XMLCXRTS.js";
26
26
  import "../chunk-AQYAVLZK.js";
@@ -28,14 +28,14 @@ import "../chunk-AUNBGZS4.js";
28
28
  import "../chunk-KYULKBFC.js";
29
29
  import "../chunk-WF5PMBIR.js";
30
30
  import "../chunk-KUV24B5M.js";
31
- import "../chunk-PPFXT5LC.js";
31
+ import "../chunk-GFTBHBRQ.js";
32
32
  import "../chunk-T5DJCIUP.js";
33
33
  import "../chunk-U3IGFMCY.js";
34
34
  import "../chunk-6VIOO74O.js";
35
35
  import {
36
36
  getAgentDefinitions,
37
37
  recompileAgents
38
- } from "../chunk-FOPJDYUF.js";
38
+ } from "../chunk-RO6BG4ZW.js";
39
39
  import {
40
40
  ERROR_MESSAGES,
41
41
  INFO_MESSAGES,
@@ -44,6 +44,8 @@ import {
44
44
  import {
45
45
  buildAndMergeConfig,
46
46
  claudePluginInstall,
47
+ claudePluginMarketplaceAdd,
48
+ claudePluginMarketplaceExists,
47
49
  claudePluginUninstall,
48
50
  deleteLocalSkill,
49
51
  deriveInstallMode,
@@ -56,15 +58,14 @@ import {
56
58
  loadSkillsMatrixFromSource,
57
59
  migrateLocalSkillScope,
58
60
  writeScopedConfigs
59
- } from "../chunk-P2BH6X2C.js";
61
+ } from "../chunk-UKYWXIDT.js";
60
62
  import {
61
63
  loadAllAgents
62
64
  } from "../chunk-RRBWNEG3.js";
63
- import "../chunk-XXK6MFOA.js";
64
65
  import {
65
66
  getSkillById,
66
67
  matrix
67
- } from "../chunk-4OBRPE6A.js";
68
+ } from "../chunk-NG2GGK6P.js";
68
69
  import {
69
70
  BaseCommand,
70
71
  EXIT_CODES
@@ -333,6 +334,13 @@ var Edit = class _Edit extends BaseCommand {
333
334
  }
334
335
  }
335
336
  if (sourceResult.marketplace) {
337
+ const marketplaceExists = await claudePluginMarketplaceExists(sourceResult.marketplace);
338
+ if (!marketplaceExists) {
339
+ this.log(`Registering marketplace "${sourceResult.marketplace}"...`);
340
+ const marketplaceSource = sourceResult.sourceConfig.source.replace(/^github:/, "");
341
+ await claudePluginMarketplaceAdd(marketplaceSource);
342
+ this.log(`Registered marketplace: ${sourceResult.marketplace}`);
343
+ }
336
344
  for (const skillId of addedSkills) {
337
345
  const skillConfig = result.skills.find((s) => s.id === skillId);
338
346
  if (!skillConfig || skillConfig.source === "local") continue;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/edit.tsx"],"sourcesContent":["import os from \"os\";\n\nimport { Flags } from \"@oclif/core\";\nimport { render } from \"ink\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { Wizard, type WizardResultV2 } from \"../components/wizard/wizard.js\";\nimport {\n CLI_BIN_NAME,\n GLOBAL_INSTALL_ROOT,\n PROJECT_ROOT,\n SOURCE_DISPLAY_NAMES,\n} from \"../consts.js\";\nimport { getAgentDefinitions, recompileAgents } from \"../lib/agents/index.js\";\nimport { loadProjectConfig } from \"../lib/configuration/index.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport {\n detectInstallation,\n buildAndMergeConfig,\n writeScopedConfigs,\n detectMigrations,\n executeMigration,\n deriveInstallMode,\n} from \"../lib/installation/index.js\";\nimport {\n getMarketplaceLabel,\n loadAllAgents,\n loadSkillsMatrixFromSource,\n} from \"../lib/loading/index.js\";\nimport { matrix, getSkillById } from \"../lib/matrix/matrix-provider\";\nimport { discoverAllPluginSkills } from \"../lib/plugins/index.js\";\nimport { deleteLocalSkill, migrateLocalSkillScope } from \"../lib/skills/index.js\";\nimport type { AgentDefinition, AgentName, SkillId } from \"../types/index.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport { claudePluginInstall, claudePluginUninstall } from \"../utils/exec.js\";\nimport {\n enableBuffering,\n drainBuffer,\n disableBuffering,\n pushBufferMessage,\n type StartupMessage,\n} from \"../utils/logger.js\";\nimport { ERROR_MESSAGES, INFO_MESSAGES, STATUS_MESSAGES } from \"../utils/messages.js\";\n\nfunction formatSourceDisplayName(sourceName: string): string {\n return SOURCE_DISPLAY_NAMES[sourceName] ?? sourceName;\n}\n\nexport default class Edit extends BaseCommand {\n static summary = \"Edit skills in the plugin\";\n static description = \"Modify the currently installed skills via interactive wizard\";\n\n static examples = [\n {\n description: \"Open the edit wizard\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n {\n description: \"Edit with a custom source\",\n command: \"<%= config.bin %> <%= command.id %> --source github:org/marketplace\",\n },\n {\n description: \"Force refresh skills from remote\",\n command: \"<%= config.bin %> <%= command.id %> --refresh\",\n },\n ];\n\n static flags = {\n ...BaseCommand.baseFlags,\n refresh: Flags.boolean({\n description: \"Force refresh from remote sources\",\n default: false,\n }),\n \"agent-source\": Flags.string({\n description: \"Remote agent partials source (default: local CLI)\",\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Edit);\n\n const installation = await detectInstallation();\n\n if (!installation) {\n this.error(ERROR_MESSAGES.NO_INSTALLATION, {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n const projectDir = installation.projectDir;\n\n enableBuffering();\n\n if (installation.projectDir === os.homedir()) {\n pushBufferMessage(\n \"info\",\n \"No project installation found. Using global installation from ~/.claude-src/\",\n );\n }\n let sourceResult;\n let startupMessages: StartupMessage[] = [];\n try {\n sourceResult = await loadSkillsMatrixFromSource({\n sourceFlag: flags.source,\n projectDir,\n forceRefresh: flags.refresh,\n });\n\n const sourceInfo = sourceResult.isLocal ? \"local\" : sourceResult.sourceConfig.sourceOrigin;\n pushBufferMessage(\n \"info\",\n `Loaded ${Object.keys(matrix.skills).length} skills (${sourceInfo})`,\n );\n } catch (error) {\n disableBuffering();\n this.handleError(error);\n }\n\n const projectConfig = await loadProjectConfig(projectDir);\n\n let currentSkillIds: SkillId[];\n try {\n const discoveredSkills = await discoverAllPluginSkills(projectDir);\n // Boundary cast: discoverAllPluginSkills keys are skill IDs from frontmatter\n currentSkillIds = Object.keys(discoveredSkills) as SkillId[];\n\n // In local mode, plugin discovery returns empty — fall back to project config skills\n if (currentSkillIds.length === 0 && projectConfig?.config?.skills?.length) {\n currentSkillIds = projectConfig.config.skills.map((s) => s.id);\n pushBufferMessage(\"info\", `Found ${currentSkillIds.length} skills from project config`);\n } else {\n pushBufferMessage(\"info\", `Current plugin has ${currentSkillIds.length} skills`);\n }\n } catch (error) {\n disableBuffering();\n this.handleError(error);\n }\n\n startupMessages = drainBuffer();\n disableBuffering();\n\n let wizardResult: WizardResultV2 | null = null;\n const marketplaceLabel = getMarketplaceLabel(sourceResult);\n\n // D9: In project context, existing global items are read-only (locked).\n // When editing from ~/ (global context), nothing is locked.\n const isGlobalDir = projectDir === GLOBAL_INSTALL_ROOT;\n const lockedSkillIds = isGlobalDir\n ? undefined\n : projectConfig?.config?.skills?.filter((s) => s.scope === \"global\").map((s) => s.id);\n const lockedAgentNames = isGlobalDir\n ? undefined\n : projectConfig?.config?.agents?.filter((a) => a.scope === \"global\").map((a) => a.name);\n\n const { waitUntilExit } = render(\n <Wizard\n version={this.config.version}\n marketplaceLabel={marketplaceLabel}\n initialStep=\"build\"\n initialDomains={projectConfig?.config?.domains}\n initialAgents={projectConfig?.config?.selectedAgents}\n installedSkillIds={currentSkillIds}\n installedSkillConfigs={projectConfig?.config?.skills}\n lockedSkillIds={lockedSkillIds}\n installedAgentConfigs={projectConfig?.config?.agents}\n lockedAgentNames={lockedAgentNames}\n projectDir={projectDir}\n startupMessages={startupMessages}\n onComplete={(result) => {\n wizardResult = result;\n }}\n onCancel={() => {\n this.log(\"\\nEdit cancelled\");\n }}\n />,\n );\n\n await waitUntilExit();\n\n // TypeScript can't track that onComplete callback mutates wizardResult before waitUntilExit resolves\n const result = wizardResult as WizardResultV2 | null;\n\n if (!result || result.cancelled) {\n this.error(\"Cancelled\", { exit: EXIT_CODES.CANCELLED });\n }\n\n if (!result.validation.valid) {\n const errorMessages = result.validation.errors.map((e) => e.message).join(\"\\n \");\n this.error(`Selection has validation errors:\\n ${errorMessages}`, {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n const newSkillIds = result.skills.map((s) => s.id);\n const addedSkills = newSkillIds.filter((id) => !currentSkillIds.includes(id));\n const removedSkills = currentSkillIds.filter((id) => !newSkillIds.includes(id));\n\n const sourceChanges = new Map<SkillId, { from: string; to: string }>();\n const scopeChanges = new Map<\n SkillId,\n { from: \"project\" | \"global\"; to: \"project\" | \"global\" }\n >();\n if (projectConfig?.config?.skills) {\n for (const newSkill of result.skills) {\n const oldSkill = projectConfig.config.skills.find((s) => s.id === newSkill.id);\n if (oldSkill && oldSkill.source !== newSkill.source) {\n sourceChanges.set(newSkill.id, {\n from: oldSkill.source,\n to: newSkill.source,\n });\n }\n if (oldSkill && oldSkill.scope !== newSkill.scope) {\n scopeChanges.set(newSkill.id, {\n from: oldSkill.scope,\n to: newSkill.scope,\n });\n }\n }\n }\n\n const agentScopeChanges = new Map<\n AgentName,\n { from: \"project\" | \"global\"; to: \"project\" | \"global\" }\n >();\n if (projectConfig?.config?.agents) {\n for (const newAgent of result.agentConfigs) {\n const oldAgent = projectConfig.config.agents.find((a) => a.name === newAgent.name);\n if (oldAgent && oldAgent.scope !== newAgent.scope) {\n agentScopeChanges.set(newAgent.name, {\n from: oldAgent.scope,\n to: newAgent.scope,\n });\n }\n }\n }\n\n const hasSourceChanges = sourceChanges.size > 0;\n const hasScopeChanges = scopeChanges.size > 0;\n const hasAgentScopeChanges = agentScopeChanges.size > 0;\n const hasSkillChanges = addedSkills.length > 0 || removedSkills.length > 0;\n\n if (!hasSkillChanges && !hasSourceChanges && !hasScopeChanges && !hasAgentScopeChanges) {\n this.log(INFO_MESSAGES.NO_CHANGES_MADE);\n this.log(\"Plugin unchanged\\n\");\n return;\n }\n\n this.log(\"\\nChanges:\");\n for (const skillId of addedSkills) {\n this.log(` + ${getSkillById(skillId).displayName}`);\n }\n for (const skillId of removedSkills) {\n const skill = matrix.skills[skillId];\n this.log(` - ${skill?.displayName ?? skillId}`);\n }\n for (const [skillId, change] of sourceChanges) {\n const fromLabel = formatSourceDisplayName(change.from);\n const toLabel = formatSourceDisplayName(change.to);\n this.log(` ~ ${skillId} (${fromLabel} \\u2192 ${toLabel})`);\n }\n for (const [skillId, change] of scopeChanges) {\n const fromLabel = change.from === \"global\" ? \"[G]\" : \"[P]\";\n const toLabel = change.to === \"global\" ? \"[G]\" : \"[P]\";\n this.log(` ~ ${skillId} (${fromLabel} \\u2192 ${toLabel})`);\n }\n for (const [agentName, change] of agentScopeChanges) {\n const fromLabel = change.from === \"global\" ? \"[G]\" : \"[P]\";\n const toLabel = change.to === \"global\" ? \"[G]\" : \"[P]\";\n this.log(` ~ ${agentName} (${fromLabel} \\u2192 ${toLabel})`);\n }\n this.log(\"\");\n\n // Handle per-skill mode migrations (local <-> plugin)\n const oldSkills = projectConfig?.config?.skills ?? [];\n const migrationPlan = detectMigrations(oldSkills, result.skills);\n const hasMigrations = migrationPlan.toLocal.length > 0 || migrationPlan.toPlugin.length > 0;\n\n if (hasMigrations) {\n if (migrationPlan.toLocal.length > 0) {\n this.log(`Switching ${migrationPlan.toLocal.length} skill(s) to local:`);\n for (const migration of migrationPlan.toLocal) {\n this.log(` - ${migration.id}`);\n }\n }\n if (migrationPlan.toPlugin.length > 0) {\n this.log(`Switching ${migrationPlan.toPlugin.length} skill(s) to plugin:`);\n for (const migration of migrationPlan.toPlugin) {\n this.log(` - ${migration.id}`);\n }\n }\n\n const migrationResult = await executeMigration(migrationPlan, projectDir, sourceResult);\n\n for (const warning of migrationResult.warnings) {\n this.warn(warning);\n }\n }\n\n const migratedSkillIds = new Set([\n ...migrationPlan.toLocal.map((m) => m.id),\n ...migrationPlan.toPlugin.map((m) => m.id),\n ]);\n\n // Handle scope migrations (P→G or G→P) for local-mode skills\n for (const [skillId, change] of scopeChanges) {\n const skillConfig = result.skills.find((s) => s.id === skillId);\n if (skillConfig?.source === \"local\") {\n await migrateLocalSkillScope(skillId, change.from, projectDir);\n } else if (sourceResult.marketplace && skillConfig) {\n // Plugin-mode scope change: uninstall from old scope, install to new scope\n const oldPluginScope = change.from === \"global\" ? \"user\" : \"project\";\n const newPluginScope = change.to === \"global\" ? \"user\" : \"project\";\n try {\n await claudePluginUninstall(skillId, oldPluginScope, projectDir);\n const pluginRef = `${skillId}@${sourceResult.marketplace}`;\n await claudePluginInstall(pluginRef, newPluginScope, projectDir);\n } catch (error) {\n this.warn(`Failed to migrate plugin scope for ${skillId}: ${getErrorMessage(error)}`);\n }\n }\n }\n\n // Handle remaining non-migration source changes (e.g., marketplace A -> marketplace B)\n for (const [skillId, change] of sourceChanges) {\n // Skip skills already handled by mode migration\n if (migratedSkillIds.has(skillId)) {\n continue;\n }\n if (change.from === \"local\") {\n await deleteLocalSkill(projectDir, skillId);\n }\n }\n\n if (sourceResult.marketplace) {\n for (const skillId of addedSkills) {\n // Find the skill config to get its scope\n const skillConfig = result.skills.find((s) => s.id === skillId);\n if (!skillConfig || skillConfig.source === \"local\") continue;\n\n const pluginRef = `${skillId}@${sourceResult.marketplace}`;\n const pluginScope = skillConfig.scope === \"global\" ? \"user\" : \"project\";\n this.log(`Installing plugin: ${pluginRef}...`);\n try {\n await claudePluginInstall(pluginRef, pluginScope, projectDir);\n } catch (error) {\n this.warn(`Failed to install plugin ${pluginRef}: ${getErrorMessage(error)}`);\n }\n }\n for (const skillId of removedSkills) {\n // For removed skills, use old config to determine scope\n const oldSkill = projectConfig?.config?.skills?.find((s) => s.id === skillId);\n const pluginScope = oldSkill?.scope === \"global\" ? \"user\" : \"project\";\n this.log(`Uninstalling plugin: ${skillId}...`);\n try {\n await claudePluginUninstall(skillId, pluginScope, projectDir);\n } catch (error) {\n this.warn(`Failed to uninstall plugin ${skillId}: ${getErrorMessage(error)}`);\n }\n }\n }\n\n // Load agent definitions first — needed for both config-types.ts and recompilation\n let sourcePath: string;\n this.log(\n flags[\"agent-source\"]\n ? STATUS_MESSAGES.FETCHING_AGENT_PARTIALS\n : STATUS_MESSAGES.LOADING_AGENT_PARTIALS,\n );\n try {\n const agentDefs = await getAgentDefinitions(flags[\"agent-source\"], {\n forceRefresh: flags.refresh,\n });\n sourcePath = agentDefs.sourcePath;\n this.log(flags[\"agent-source\"] ? \"✓ Agent partials fetched\\n\" : \"✓ Agent partials loaded\\n\");\n } catch (error) {\n this.handleError(error);\n }\n\n // Persist wizard result to config.ts and config-types.ts (split by scope when in project context)\n try {\n const mergeResult = await buildAndMergeConfig(result, sourceResult, projectDir, flags.source);\n\n // Load full agent definitions for config-types.ts generation\n const cliAgents = await loadAllAgents(PROJECT_ROOT);\n const sourceAgents = await loadAllAgents(sourcePath);\n const agents: Record<AgentName, AgentDefinition> = { ...cliAgents, ...sourceAgents };\n\n await writeScopedConfigs(\n mergeResult.config,\n sourceResult.matrix,\n agents,\n projectDir,\n installation.configPath,\n );\n } catch (error) {\n this.warn(`Could not update config: ${getErrorMessage(error)}`);\n }\n\n this.log(STATUS_MESSAGES.RECOMPILING_AGENTS);\n try {\n const recompileSkills = await discoverAllPluginSkills(projectDir);\n\n // Build scope map so recompileAgents routes agents to the correct directory:\n // global agents -> ~/.claude/agents/, project agents -> installation.agentsDir\n const agentScopeMap = new Map(result.agentConfigs.map((a) => [a.name, a.scope] as const));\n\n const recompileResult = await recompileAgents({\n pluginDir: projectDir,\n sourcePath,\n skills: recompileSkills,\n projectDir,\n outputDir: installation.agentsDir,\n installMode: deriveInstallMode(result.skills),\n agentScopeMap,\n });\n\n if (recompileResult.failed.length > 0) {\n this.log(\n `✓ Recompiled ${recompileResult.compiled.length} agents (${recompileResult.failed.length} failed)\\n`,\n );\n for (const warning of recompileResult.warnings) {\n this.warn(warning);\n }\n } else if (recompileResult.compiled.length > 0) {\n this.log(`✓ Recompiled ${recompileResult.compiled.length} agents\\n`);\n } else {\n this.log(\"✓ No agents to recompile\\n\");\n }\n } catch (error) {\n this.warn(`Agent recompilation failed: ${getErrorMessage(error)}`);\n this.log(`You can manually recompile with '${CLI_BIN_NAME} compile'.\\n`);\n }\n\n const summaryParts = [`${addedSkills.length} added`, `${removedSkills.length} removed`];\n if (hasSourceChanges) {\n summaryParts.push(`${sourceChanges.size} source${sourceChanges.size > 1 ? \"s\" : \"\"} changed`);\n }\n if (hasScopeChanges || hasAgentScopeChanges) {\n const totalScopeChanges = scopeChanges.size + agentScopeChanges.size;\n summaryParts.push(`${totalScopeChanges} scope${totalScopeChanges > 1 ? \"s\" : \"\"} changed`);\n }\n this.log(`\\n\\u2713 Plugin updated! (${summaryParts.join(\", \")})\\n`);\n }\n}\n"],"mappings":"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","names":["result"]}
1
+ {"version":3,"sources":["../../src/cli/commands/edit.tsx"],"sourcesContent":["import os from \"os\";\n\nimport { Flags } from \"@oclif/core\";\nimport { render } from \"ink\";\n\nimport { BaseCommand } from \"../base-command.js\";\nimport { Wizard, type WizardResultV2 } from \"../components/wizard/wizard.js\";\nimport {\n CLI_BIN_NAME,\n GLOBAL_INSTALL_ROOT,\n PROJECT_ROOT,\n SOURCE_DISPLAY_NAMES,\n} from \"../consts.js\";\nimport { getAgentDefinitions, recompileAgents } from \"../lib/agents/index.js\";\nimport { loadProjectConfig } from \"../lib/configuration/index.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport {\n detectInstallation,\n buildAndMergeConfig,\n writeScopedConfigs,\n detectMigrations,\n executeMigration,\n deriveInstallMode,\n} from \"../lib/installation/index.js\";\nimport {\n getMarketplaceLabel,\n loadAllAgents,\n loadSkillsMatrixFromSource,\n} from \"../lib/loading/index.js\";\nimport { matrix, getSkillById } from \"../lib/matrix/matrix-provider\";\nimport { discoverAllPluginSkills } from \"../lib/plugins/index.js\";\nimport { deleteLocalSkill, migrateLocalSkillScope } from \"../lib/skills/index.js\";\nimport type { AgentDefinition, AgentName, SkillId } from \"../types/index.js\";\nimport { getErrorMessage } from \"../utils/errors.js\";\nimport {\n claudePluginInstall,\n claudePluginUninstall,\n claudePluginMarketplaceExists,\n claudePluginMarketplaceAdd,\n} from \"../utils/exec.js\";\nimport {\n enableBuffering,\n drainBuffer,\n disableBuffering,\n pushBufferMessage,\n type StartupMessage,\n} from \"../utils/logger.js\";\nimport { ERROR_MESSAGES, INFO_MESSAGES, STATUS_MESSAGES } from \"../utils/messages.js\";\n\nfunction formatSourceDisplayName(sourceName: string): string {\n return SOURCE_DISPLAY_NAMES[sourceName] ?? sourceName;\n}\n\nexport default class Edit extends BaseCommand {\n static summary = \"Edit skills in the plugin\";\n static description = \"Modify the currently installed skills via interactive wizard\";\n\n static examples = [\n {\n description: \"Open the edit wizard\",\n command: \"<%= config.bin %> <%= command.id %>\",\n },\n {\n description: \"Edit with a custom source\",\n command: \"<%= config.bin %> <%= command.id %> --source github:org/marketplace\",\n },\n {\n description: \"Force refresh skills from remote\",\n command: \"<%= config.bin %> <%= command.id %> --refresh\",\n },\n ];\n\n static flags = {\n ...BaseCommand.baseFlags,\n refresh: Flags.boolean({\n description: \"Force refresh from remote sources\",\n default: false,\n }),\n \"agent-source\": Flags.string({\n description: \"Remote agent partials source (default: local CLI)\",\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Edit);\n\n const installation = await detectInstallation();\n\n if (!installation) {\n this.error(ERROR_MESSAGES.NO_INSTALLATION, {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n const projectDir = installation.projectDir;\n\n enableBuffering();\n\n if (installation.projectDir === os.homedir()) {\n pushBufferMessage(\n \"info\",\n \"No project installation found. Using global installation from ~/.claude-src/\",\n );\n }\n let sourceResult;\n let startupMessages: StartupMessage[] = [];\n try {\n sourceResult = await loadSkillsMatrixFromSource({\n sourceFlag: flags.source,\n projectDir,\n forceRefresh: flags.refresh,\n });\n\n const sourceInfo = sourceResult.isLocal ? \"local\" : sourceResult.sourceConfig.sourceOrigin;\n pushBufferMessage(\n \"info\",\n `Loaded ${Object.keys(matrix.skills).length} skills (${sourceInfo})`,\n );\n } catch (error) {\n disableBuffering();\n this.handleError(error);\n }\n\n const projectConfig = await loadProjectConfig(projectDir);\n\n let currentSkillIds: SkillId[];\n try {\n const discoveredSkills = await discoverAllPluginSkills(projectDir);\n // Boundary cast: discoverAllPluginSkills keys are skill IDs from frontmatter\n currentSkillIds = Object.keys(discoveredSkills) as SkillId[];\n\n // In local mode, plugin discovery returns empty — fall back to project config skills\n if (currentSkillIds.length === 0 && projectConfig?.config?.skills?.length) {\n currentSkillIds = projectConfig.config.skills.map((s) => s.id);\n pushBufferMessage(\"info\", `Found ${currentSkillIds.length} skills from project config`);\n } else {\n pushBufferMessage(\"info\", `Current plugin has ${currentSkillIds.length} skills`);\n }\n } catch (error) {\n disableBuffering();\n this.handleError(error);\n }\n\n startupMessages = drainBuffer();\n disableBuffering();\n\n let wizardResult: WizardResultV2 | null = null;\n const marketplaceLabel = getMarketplaceLabel(sourceResult);\n\n // D9: In project context, existing global items are read-only (locked).\n // When editing from ~/ (global context), nothing is locked.\n const isGlobalDir = projectDir === GLOBAL_INSTALL_ROOT;\n const lockedSkillIds = isGlobalDir\n ? undefined\n : projectConfig?.config?.skills?.filter((s) => s.scope === \"global\").map((s) => s.id);\n const lockedAgentNames = isGlobalDir\n ? undefined\n : projectConfig?.config?.agents?.filter((a) => a.scope === \"global\").map((a) => a.name);\n\n const { waitUntilExit } = render(\n <Wizard\n version={this.config.version}\n marketplaceLabel={marketplaceLabel}\n initialStep=\"build\"\n initialDomains={projectConfig?.config?.domains}\n initialAgents={projectConfig?.config?.selectedAgents}\n installedSkillIds={currentSkillIds}\n installedSkillConfigs={projectConfig?.config?.skills}\n lockedSkillIds={lockedSkillIds}\n installedAgentConfigs={projectConfig?.config?.agents}\n lockedAgentNames={lockedAgentNames}\n projectDir={projectDir}\n startupMessages={startupMessages}\n onComplete={(result) => {\n wizardResult = result;\n }}\n onCancel={() => {\n this.log(\"\\nEdit cancelled\");\n }}\n />,\n );\n\n await waitUntilExit();\n\n // TypeScript can't track that onComplete callback mutates wizardResult before waitUntilExit resolves\n const result = wizardResult as WizardResultV2 | null;\n\n if (!result || result.cancelled) {\n this.error(\"Cancelled\", { exit: EXIT_CODES.CANCELLED });\n }\n\n if (!result.validation.valid) {\n const errorMessages = result.validation.errors.map((e) => e.message).join(\"\\n \");\n this.error(`Selection has validation errors:\\n ${errorMessages}`, {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n const newSkillIds = result.skills.map((s) => s.id);\n const addedSkills = newSkillIds.filter((id) => !currentSkillIds.includes(id));\n const removedSkills = currentSkillIds.filter((id) => !newSkillIds.includes(id));\n\n const sourceChanges = new Map<SkillId, { from: string; to: string }>();\n const scopeChanges = new Map<\n SkillId,\n { from: \"project\" | \"global\"; to: \"project\" | \"global\" }\n >();\n if (projectConfig?.config?.skills) {\n for (const newSkill of result.skills) {\n const oldSkill = projectConfig.config.skills.find((s) => s.id === newSkill.id);\n if (oldSkill && oldSkill.source !== newSkill.source) {\n sourceChanges.set(newSkill.id, {\n from: oldSkill.source,\n to: newSkill.source,\n });\n }\n if (oldSkill && oldSkill.scope !== newSkill.scope) {\n scopeChanges.set(newSkill.id, {\n from: oldSkill.scope,\n to: newSkill.scope,\n });\n }\n }\n }\n\n const agentScopeChanges = new Map<\n AgentName,\n { from: \"project\" | \"global\"; to: \"project\" | \"global\" }\n >();\n if (projectConfig?.config?.agents) {\n for (const newAgent of result.agentConfigs) {\n const oldAgent = projectConfig.config.agents.find((a) => a.name === newAgent.name);\n if (oldAgent && oldAgent.scope !== newAgent.scope) {\n agentScopeChanges.set(newAgent.name, {\n from: oldAgent.scope,\n to: newAgent.scope,\n });\n }\n }\n }\n\n const hasSourceChanges = sourceChanges.size > 0;\n const hasScopeChanges = scopeChanges.size > 0;\n const hasAgentScopeChanges = agentScopeChanges.size > 0;\n const hasSkillChanges = addedSkills.length > 0 || removedSkills.length > 0;\n\n if (!hasSkillChanges && !hasSourceChanges && !hasScopeChanges && !hasAgentScopeChanges) {\n this.log(INFO_MESSAGES.NO_CHANGES_MADE);\n this.log(\"Plugin unchanged\\n\");\n return;\n }\n\n this.log(\"\\nChanges:\");\n for (const skillId of addedSkills) {\n this.log(` + ${getSkillById(skillId).displayName}`);\n }\n for (const skillId of removedSkills) {\n const skill = matrix.skills[skillId];\n this.log(` - ${skill?.displayName ?? skillId}`);\n }\n for (const [skillId, change] of sourceChanges) {\n const fromLabel = formatSourceDisplayName(change.from);\n const toLabel = formatSourceDisplayName(change.to);\n this.log(` ~ ${skillId} (${fromLabel} \\u2192 ${toLabel})`);\n }\n for (const [skillId, change] of scopeChanges) {\n const fromLabel = change.from === \"global\" ? \"[G]\" : \"[P]\";\n const toLabel = change.to === \"global\" ? \"[G]\" : \"[P]\";\n this.log(` ~ ${skillId} (${fromLabel} \\u2192 ${toLabel})`);\n }\n for (const [agentName, change] of agentScopeChanges) {\n const fromLabel = change.from === \"global\" ? \"[G]\" : \"[P]\";\n const toLabel = change.to === \"global\" ? \"[G]\" : \"[P]\";\n this.log(` ~ ${agentName} (${fromLabel} \\u2192 ${toLabel})`);\n }\n this.log(\"\");\n\n // Handle per-skill mode migrations (local <-> plugin)\n const oldSkills = projectConfig?.config?.skills ?? [];\n const migrationPlan = detectMigrations(oldSkills, result.skills);\n const hasMigrations = migrationPlan.toLocal.length > 0 || migrationPlan.toPlugin.length > 0;\n\n if (hasMigrations) {\n if (migrationPlan.toLocal.length > 0) {\n this.log(`Switching ${migrationPlan.toLocal.length} skill(s) to local:`);\n for (const migration of migrationPlan.toLocal) {\n this.log(` - ${migration.id}`);\n }\n }\n if (migrationPlan.toPlugin.length > 0) {\n this.log(`Switching ${migrationPlan.toPlugin.length} skill(s) to plugin:`);\n for (const migration of migrationPlan.toPlugin) {\n this.log(` - ${migration.id}`);\n }\n }\n\n const migrationResult = await executeMigration(migrationPlan, projectDir, sourceResult);\n\n for (const warning of migrationResult.warnings) {\n this.warn(warning);\n }\n }\n\n const migratedSkillIds = new Set([\n ...migrationPlan.toLocal.map((m) => m.id),\n ...migrationPlan.toPlugin.map((m) => m.id),\n ]);\n\n // Handle scope migrations (P→G or G→P) for local-mode skills\n for (const [skillId, change] of scopeChanges) {\n const skillConfig = result.skills.find((s) => s.id === skillId);\n if (skillConfig?.source === \"local\") {\n await migrateLocalSkillScope(skillId, change.from, projectDir);\n } else if (sourceResult.marketplace && skillConfig) {\n // Plugin-mode scope change: uninstall from old scope, install to new scope\n const oldPluginScope = change.from === \"global\" ? \"user\" : \"project\";\n const newPluginScope = change.to === \"global\" ? \"user\" : \"project\";\n try {\n await claudePluginUninstall(skillId, oldPluginScope, projectDir);\n const pluginRef = `${skillId}@${sourceResult.marketplace}`;\n await claudePluginInstall(pluginRef, newPluginScope, projectDir);\n } catch (error) {\n this.warn(`Failed to migrate plugin scope for ${skillId}: ${getErrorMessage(error)}`);\n }\n }\n }\n\n // Handle remaining non-migration source changes (e.g., marketplace A -> marketplace B)\n for (const [skillId, change] of sourceChanges) {\n // Skip skills already handled by mode migration\n if (migratedSkillIds.has(skillId)) {\n continue;\n }\n if (change.from === \"local\") {\n await deleteLocalSkill(projectDir, skillId);\n }\n }\n\n if (sourceResult.marketplace) {\n const marketplaceExists = await claudePluginMarketplaceExists(sourceResult.marketplace);\n if (!marketplaceExists) {\n this.log(`Registering marketplace \"${sourceResult.marketplace}\"...`);\n const marketplaceSource = sourceResult.sourceConfig.source.replace(/^github:/, \"\");\n await claudePluginMarketplaceAdd(marketplaceSource);\n this.log(`Registered marketplace: ${sourceResult.marketplace}`);\n }\n\n for (const skillId of addedSkills) {\n // Find the skill config to get its scope\n const skillConfig = result.skills.find((s) => s.id === skillId);\n if (!skillConfig || skillConfig.source === \"local\") continue;\n\n const pluginRef = `${skillId}@${sourceResult.marketplace}`;\n const pluginScope = skillConfig.scope === \"global\" ? \"user\" : \"project\";\n this.log(`Installing plugin: ${pluginRef}...`);\n try {\n await claudePluginInstall(pluginRef, pluginScope, projectDir);\n } catch (error) {\n this.warn(`Failed to install plugin ${pluginRef}: ${getErrorMessage(error)}`);\n }\n }\n for (const skillId of removedSkills) {\n // For removed skills, use old config to determine scope\n const oldSkill = projectConfig?.config?.skills?.find((s) => s.id === skillId);\n const pluginScope = oldSkill?.scope === \"global\" ? \"user\" : \"project\";\n this.log(`Uninstalling plugin: ${skillId}...`);\n try {\n await claudePluginUninstall(skillId, pluginScope, projectDir);\n } catch (error) {\n this.warn(`Failed to uninstall plugin ${skillId}: ${getErrorMessage(error)}`);\n }\n }\n }\n\n // Load agent definitions first — needed for both config-types.ts and recompilation\n let sourcePath: string;\n this.log(\n flags[\"agent-source\"]\n ? STATUS_MESSAGES.FETCHING_AGENT_PARTIALS\n : STATUS_MESSAGES.LOADING_AGENT_PARTIALS,\n );\n try {\n const agentDefs = await getAgentDefinitions(flags[\"agent-source\"], {\n forceRefresh: flags.refresh,\n });\n sourcePath = agentDefs.sourcePath;\n this.log(flags[\"agent-source\"] ? \"✓ Agent partials fetched\\n\" : \"✓ Agent partials loaded\\n\");\n } catch (error) {\n this.handleError(error);\n }\n\n // Persist wizard result to config.ts and config-types.ts (split by scope when in project context)\n try {\n const mergeResult = await buildAndMergeConfig(result, sourceResult, projectDir, flags.source);\n\n // Load full agent definitions for config-types.ts generation\n const cliAgents = await loadAllAgents(PROJECT_ROOT);\n const sourceAgents = await loadAllAgents(sourcePath);\n const agents: Record<AgentName, AgentDefinition> = { ...cliAgents, ...sourceAgents };\n\n await writeScopedConfigs(\n mergeResult.config,\n sourceResult.matrix,\n agents,\n projectDir,\n installation.configPath,\n );\n } catch (error) {\n this.warn(`Could not update config: ${getErrorMessage(error)}`);\n }\n\n this.log(STATUS_MESSAGES.RECOMPILING_AGENTS);\n try {\n const recompileSkills = await discoverAllPluginSkills(projectDir);\n\n // Build scope map so recompileAgents routes agents to the correct directory:\n // global agents -> ~/.claude/agents/, project agents -> installation.agentsDir\n const agentScopeMap = new Map(result.agentConfigs.map((a) => [a.name, a.scope] as const));\n\n const recompileResult = await recompileAgents({\n pluginDir: projectDir,\n sourcePath,\n skills: recompileSkills,\n projectDir,\n outputDir: installation.agentsDir,\n installMode: deriveInstallMode(result.skills),\n agentScopeMap,\n });\n\n if (recompileResult.failed.length > 0) {\n this.log(\n `✓ Recompiled ${recompileResult.compiled.length} agents (${recompileResult.failed.length} failed)\\n`,\n );\n for (const warning of recompileResult.warnings) {\n this.warn(warning);\n }\n } else if (recompileResult.compiled.length > 0) {\n this.log(`✓ Recompiled ${recompileResult.compiled.length} agents\\n`);\n } else {\n this.log(\"✓ No agents to recompile\\n\");\n }\n } catch (error) {\n this.warn(`Agent recompilation failed: ${getErrorMessage(error)}`);\n this.log(`You can manually recompile with '${CLI_BIN_NAME} compile'.\\n`);\n }\n\n const summaryParts = [`${addedSkills.length} added`, `${removedSkills.length} removed`];\n if (hasSourceChanges) {\n summaryParts.push(`${sourceChanges.size} source${sourceChanges.size > 1 ? \"s\" : \"\"} changed`);\n }\n if (hasScopeChanges || hasAgentScopeChanges) {\n const totalScopeChanges = scopeChanges.size + agentScopeChanges.size;\n summaryParts.push(`${totalScopeChanges} scope${totalScopeChanges > 1 ? \"s\" : \"\"} changed`);\n }\n this.log(`\\n\\u2713 Plugin updated! (${summaryParts.join(\", \")})\\n`);\n }\n}\n"],"mappings":"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","names":["result"]}
@@ -5,13 +5,12 @@ import {
5
5
  loadSkillsMatrixFromSource,
6
6
  resolveSource,
7
7
  saveSourceToProjectConfig
8
- } from "../chunk-P2BH6X2C.js";
8
+ } from "../chunk-UKYWXIDT.js";
9
9
  import "../chunk-RRBWNEG3.js";
10
- import "../chunk-XXK6MFOA.js";
11
10
  import {
12
11
  matrix,
13
12
  typedKeys
14
- } from "../chunk-4OBRPE6A.js";
13
+ } from "../chunk-NG2GGK6P.js";
15
14
  import {
16
15
  BaseCommand,
17
16
  EXIT_CODES
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/commands/eject.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport os from \"os\";\nimport { BaseCommand } from \"../base-command.js\";\nimport {\n copy,\n ensureDir,\n directoryExists,\n fileExists,\n listDirectories,\n writeFile,\n} from \"../utils/fs.js\";\nimport {\n CLAUDE_SRC_DIR,\n DEFAULT_BRANDING,\n DIRS,\n LOCAL_SKILLS_PATH,\n PROJECT_ROOT,\n STANDARD_FILES,\n} from \"../consts.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { loadSkillsMatrixFromSource, type SourceLoadResult } from \"../lib/loading/index.js\";\nimport { matrix } from \"../lib/matrix/matrix-provider\";\nimport { copySkillsToLocalFlattened } from \"../lib/skills/index.js\";\nimport type { SkillId } from \"../types/index.js\";\nimport { typedKeys } from \"../utils/typed-object.js\";\nimport {\n loadProjectSourceConfig,\n resolveSource,\n saveSourceToProjectConfig,\n} from \"../lib/configuration/index.js\";\n\nconst EJECT_TYPES = [\"agent-partials\", \"templates\", \"skills\", \"all\"] as const;\ntype EjectType = (typeof EJECT_TYPES)[number];\n\nfunction isEjectType(value: string): value is EjectType {\n return (EJECT_TYPES as readonly string[]).includes(value);\n}\n\nexport default class Eject extends BaseCommand {\n static summary = \"Eject skills, agent partials, or templates for local customization\";\n static description =\n \"Copy agent partials, templates, or skills to your project for customization. \" +\n \"Agent partials and templates are always copied from the CLI. \" +\n \"Skills are copied from the configured source (public marketplace by default).\";\n\n static examples = [\n {\n description: \"Eject agent partials for customization\",\n command: \"<%= config.bin %> <%= command.id %> agent-partials\",\n },\n {\n description: \"Eject only agent templates\",\n command: \"<%= config.bin %> <%= command.id %> templates\",\n },\n {\n description: \"Eject skills to local directory\",\n command: \"<%= config.bin %> <%= command.id %> skills\",\n },\n {\n description: \"Eject everything with force overwrite\",\n command: \"<%= config.bin %> <%= command.id %> all --force\",\n },\n {\n description: \"Eject to a custom output directory\",\n command: \"<%= config.bin %> <%= command.id %> skills -o ./custom-dir\",\n },\n ];\n\n static args = {\n type: Args.string({\n description: \"What to eject: agent-partials, templates, skills, all\",\n required: false,\n options: [...EJECT_TYPES],\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n force: Flags.boolean({\n char: \"f\",\n description: \"Overwrite existing files\",\n default: false,\n }),\n output: Flags.string({\n char: \"o\",\n description: \"Output directory (default: .claude/ in current directory)\",\n }),\n refresh: Flags.boolean({\n description: \"Force refresh from remote source\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Eject);\n const projectDir = process.cwd();\n\n if (!args.type) {\n this.error(\"Please specify what to eject: agent-partials, templates, skills, or all\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (!isEjectType(args.type)) {\n this.error(`Unknown eject type: ${args.type}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n let outputBase: string;\n if (flags.output) {\n const expandedPath = flags.output.startsWith(\"~\")\n ? path.join(os.homedir(), flags.output.slice(1))\n : flags.output;\n outputBase = path.resolve(projectDir, expandedPath);\n\n if (await fileExists(outputBase)) {\n this.error(`Output path exists as a file: ${outputBase}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n } else {\n outputBase = path.join(projectDir, CLAUDE_SRC_DIR);\n }\n\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} Eject`);\n this.log(\"\");\n\n if (flags.output) {\n this.log(`Output directory: ${outputBase}`);\n }\n\n const ejectType = args.type;\n const directOutput = !!flags.output;\n\n let sourceResult: SourceLoadResult | undefined;\n if (ejectType === \"skills\" || ejectType === \"all\") {\n sourceResult = await loadSkillsMatrixFromSource({\n sourceFlag: flags.source,\n projectDir,\n forceRefresh: flags.refresh,\n });\n }\n\n switch (ejectType) {\n case \"agent-partials\":\n await this.ejectAgentPartials(outputBase, flags.force, directOutput, false);\n break;\n case \"templates\":\n await this.ejectAgentPartials(outputBase, flags.force, directOutput, true);\n break;\n case \"skills\":\n await this.ejectSkills(\n projectDir,\n flags.force,\n sourceResult!,\n directOutput,\n directOutput ? outputBase : undefined,\n );\n break;\n case \"all\":\n await this.ejectAgentPartials(outputBase, flags.force, directOutput, false);\n await this.ejectAgentPartials(outputBase, true, directOutput, true);\n await this.ejectSkills(\n projectDir,\n flags.force,\n sourceResult!,\n directOutput,\n directOutput ? outputBase : undefined,\n );\n break;\n default:\n break;\n }\n\n if (flags.source) {\n await saveSourceToProjectConfig(projectDir, flags.source, path.basename(projectDir));\n this.log(`Source saved to .claude-src/config.ts`);\n }\n\n await this.ensureMinimalConfig(projectDir, flags.source, sourceResult);\n\n this.log(\"\");\n this.logSuccess(\"Eject complete!\");\n this.log(\"\");\n }\n\n // Ensures a minimal config exists so `agentsinc compile` works after eject\n private async ensureMinimalConfig(\n projectDir: string,\n sourceFlag?: string,\n sourceResult?: SourceLoadResult,\n ): Promise<void> {\n const tsConfigPath = path.join(projectDir, CLAUDE_SRC_DIR, STANDARD_FILES.CONFIG_TS);\n\n if (await fileExists(tsConfigPath)) {\n return;\n }\n\n const projectName = path.basename(projectDir);\n\n const config: Record<string, unknown> = {\n name: projectName,\n };\n\n const resolvedConfig =\n sourceResult?.sourceConfig ?? (await resolveSource(sourceFlag, projectDir));\n\n if (sourceFlag) {\n config.source = sourceFlag;\n } else if (resolvedConfig.source) {\n config.source = resolvedConfig.source;\n }\n\n if (resolvedConfig.marketplace) {\n config.marketplace = resolvedConfig.marketplace;\n }\n\n const existingProjectConfig = await loadProjectSourceConfig(projectDir);\n if (existingProjectConfig?.author) {\n config.author = existingProjectConfig.author;\n }\n if (existingProjectConfig?.agentsSource) {\n config.agentsSource = existingProjectConfig.agentsSource;\n }\n\n await ensureDir(path.join(projectDir, CLAUDE_SRC_DIR));\n\n // JSON.parse(JSON.stringify(x)) removes undefined values\n const cleaned = JSON.parse(JSON.stringify(config));\n const body = JSON.stringify(cleaned, null, 2);\n const content = `export default ${body};\\n`;\n\n await writeFile(tsConfigPath, content);\n\n this.logSuccess(`Created ${CLAUDE_SRC_DIR}/config.ts`);\n }\n\n private async ejectAgentPartials(\n outputBase: string,\n force: boolean,\n directOutput = false,\n templatesFlag = false,\n ): Promise<void> {\n const sourceDir = templatesFlag\n ? path.join(PROJECT_ROOT, DIRS.templates)\n : path.join(PROJECT_ROOT, DIRS.agents);\n\n if (!(await directoryExists(sourceDir))) {\n this.warn(\n templatesFlag ? \"No agent templates found in CLI.\" : \"No agent partials found in CLI.\",\n );\n return;\n }\n\n const destDir = directOutput\n ? outputBase\n : templatesFlag\n ? path.join(outputBase, path.basename(DIRS.agents), path.basename(DIRS.templates))\n : path.join(outputBase, path.basename(DIRS.agents));\n\n const templatesBasename = path.basename(DIRS.templates);\n\n if ((await directoryExists(destDir)) && !force) {\n if (templatesFlag) {\n this.warn(`Agent templates already exist at ${destDir}. Use --force to overwrite.`);\n return;\n }\n\n const hasTemplates = await directoryExists(path.join(destDir, templatesBasename));\n if ((await this.hasAgentPartialDirs(destDir)) && !hasTemplates) {\n this.warn(`Agent partials already exist at ${destDir}. Use --force to overwrite.`);\n return;\n }\n }\n\n await ensureDir(destDir);\n\n const skipTemplates =\n !templatesFlag && !force && (await directoryExists(path.join(destDir, templatesBasename)));\n\n if (skipTemplates) {\n const sourceEntries = await listDirectories(sourceDir);\n const nonTemplateEntries = sourceEntries.filter((entry) => entry !== templatesBasename);\n for (const entry of nonTemplateEntries) {\n await copy(path.join(sourceDir, entry), path.join(destDir, entry));\n }\n this.warn(\n \"Agent templates already exist — skipping templates, only ejecting agent partials.\",\n );\n } else {\n await copy(sourceDir, destDir);\n }\n\n this.logSuccess(\n `${templatesFlag ? \"Agent templates\" : \"Agent partials\"} ejected to ${destDir}`,\n );\n this.log(\n templatesFlag\n ? \"You can now customize agent templates locally.\"\n : \"You can now customize templates, agent intro, workflow, and examples locally.\",\n );\n }\n\n /** Checks whether the agents directory contains any agent subdirectories (not just _templates). */\n private async hasAgentPartialDirs(agentsDir: string): Promise<boolean> {\n const subdirs = await listDirectories(agentsDir);\n const templatesBasename = path.basename(DIRS.templates);\n return subdirs.some((dir) => dir !== templatesBasename);\n }\n\n private async ejectSkills(\n projectDir: string,\n force: boolean,\n sourceResult: SourceLoadResult,\n directOutput = false,\n customOutputBase?: string,\n ): Promise<void> {\n const destDir =\n directOutput && customOutputBase\n ? customOutputBase\n : path.join(projectDir, LOCAL_SKILLS_PATH);\n\n if ((await directoryExists(destDir)) && !force) {\n this.warn(`Skills already exist at ${destDir}. Use --force to overwrite.`);\n return;\n }\n\n const skillIds = typedKeys<SkillId>(matrix.skills).filter(\n (skillId) => !matrix.skills[skillId]?.local,\n );\n\n if (skillIds.length === 0) {\n this.warn(\"No skills found in source to eject.\");\n return;\n }\n\n await ensureDir(destDir);\n\n const copiedSkills = await copySkillsToLocalFlattened(skillIds, destDir, matrix, sourceResult);\n\n const sourceLabel = sourceResult.isLocal\n ? sourceResult.sourcePath\n : sourceResult.marketplace || sourceResult.sourceConfig.source;\n\n this.logSuccess(`${copiedSkills.length} skills ejected to ${destDir} from ${sourceLabel}`);\n this.log(\"You can now customize skill content locally.\");\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/cli/commands/eject.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport os from \"os\";\nimport { BaseCommand } from \"../base-command.js\";\nimport {\n copy,\n ensureDir,\n directoryExists,\n fileExists,\n listDirectories,\n writeFile,\n} from \"../utils/fs.js\";\nimport {\n CLAUDE_SRC_DIR,\n DEFAULT_BRANDING,\n DIRS,\n LOCAL_SKILLS_PATH,\n PROJECT_ROOT,\n STANDARD_FILES,\n} from \"../consts.js\";\nimport { EXIT_CODES } from \"../lib/exit-codes.js\";\nimport { loadSkillsMatrixFromSource, type SourceLoadResult } from \"../lib/loading/index.js\";\nimport { matrix } from \"../lib/matrix/matrix-provider\";\nimport { copySkillsToLocalFlattened } from \"../lib/skills/index.js\";\nimport type { SkillId } from \"../types/index.js\";\nimport { typedKeys } from \"../utils/typed-object.js\";\nimport {\n loadProjectSourceConfig,\n resolveSource,\n saveSourceToProjectConfig,\n} from \"../lib/configuration/index.js\";\n\nconst EJECT_TYPES = [\"agent-partials\", \"templates\", \"skills\", \"all\"] as const;\ntype EjectType = (typeof EJECT_TYPES)[number];\n\nfunction isEjectType(value: string): value is EjectType {\n return (EJECT_TYPES as readonly string[]).includes(value);\n}\n\nexport default class Eject extends BaseCommand {\n static summary = \"Eject skills, agent partials, or templates for local customization\";\n static description =\n \"Copy agent partials, templates, or skills to your project for customization. \" +\n \"Agent partials and templates are always copied from the CLI. \" +\n \"Skills are copied from the configured source (public marketplace by default).\";\n\n static examples = [\n {\n description: \"Eject agent partials for customization\",\n command: \"<%= config.bin %> <%= command.id %> agent-partials\",\n },\n {\n description: \"Eject only agent templates\",\n command: \"<%= config.bin %> <%= command.id %> templates\",\n },\n {\n description: \"Eject skills to local directory\",\n command: \"<%= config.bin %> <%= command.id %> skills\",\n },\n {\n description: \"Eject everything with force overwrite\",\n command: \"<%= config.bin %> <%= command.id %> all --force\",\n },\n {\n description: \"Eject to a custom output directory\",\n command: \"<%= config.bin %> <%= command.id %> skills -o ./custom-dir\",\n },\n ];\n\n static args = {\n type: Args.string({\n description: \"What to eject: agent-partials, templates, skills, all\",\n required: false,\n options: [...EJECT_TYPES],\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n force: Flags.boolean({\n char: \"f\",\n description: \"Overwrite existing files\",\n default: false,\n }),\n output: Flags.string({\n char: \"o\",\n description: \"Output directory (default: .claude/ in current directory)\",\n }),\n refresh: Flags.boolean({\n description: \"Force refresh from remote source\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(Eject);\n const projectDir = process.cwd();\n\n if (!args.type) {\n this.error(\"Please specify what to eject: agent-partials, templates, skills, or all\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (!isEjectType(args.type)) {\n this.error(`Unknown eject type: ${args.type}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n let outputBase: string;\n if (flags.output) {\n const expandedPath = flags.output.startsWith(\"~\")\n ? path.join(os.homedir(), flags.output.slice(1))\n : flags.output;\n outputBase = path.resolve(projectDir, expandedPath);\n\n if (await fileExists(outputBase)) {\n this.error(`Output path exists as a file: ${outputBase}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n } else {\n outputBase = path.join(projectDir, CLAUDE_SRC_DIR);\n }\n\n this.log(\"\");\n this.log(`${DEFAULT_BRANDING.NAME} Eject`);\n this.log(\"\");\n\n if (flags.output) {\n this.log(`Output directory: ${outputBase}`);\n }\n\n const ejectType = args.type;\n const directOutput = !!flags.output;\n\n let sourceResult: SourceLoadResult | undefined;\n if (ejectType === \"skills\" || ejectType === \"all\") {\n sourceResult = await loadSkillsMatrixFromSource({\n sourceFlag: flags.source,\n projectDir,\n forceRefresh: flags.refresh,\n });\n }\n\n switch (ejectType) {\n case \"agent-partials\":\n await this.ejectAgentPartials(outputBase, flags.force, directOutput, false);\n break;\n case \"templates\":\n await this.ejectAgentPartials(outputBase, flags.force, directOutput, true);\n break;\n case \"skills\":\n await this.ejectSkills(\n projectDir,\n flags.force,\n sourceResult!,\n directOutput,\n directOutput ? outputBase : undefined,\n );\n break;\n case \"all\":\n await this.ejectAgentPartials(outputBase, flags.force, directOutput, false);\n await this.ejectAgentPartials(outputBase, true, directOutput, true);\n await this.ejectSkills(\n projectDir,\n flags.force,\n sourceResult!,\n directOutput,\n directOutput ? outputBase : undefined,\n );\n break;\n default:\n break;\n }\n\n if (flags.source) {\n await saveSourceToProjectConfig(projectDir, flags.source, path.basename(projectDir));\n this.log(`Source saved to .claude-src/config.ts`);\n }\n\n await this.ensureMinimalConfig(projectDir, flags.source, sourceResult);\n\n this.log(\"\");\n this.logSuccess(\"Eject complete!\");\n this.log(\"\");\n }\n\n // Ensures a minimal config exists so `agentsinc compile` works after eject\n private async ensureMinimalConfig(\n projectDir: string,\n sourceFlag?: string,\n sourceResult?: SourceLoadResult,\n ): Promise<void> {\n const tsConfigPath = path.join(projectDir, CLAUDE_SRC_DIR, STANDARD_FILES.CONFIG_TS);\n\n if (await fileExists(tsConfigPath)) {\n return;\n }\n\n const projectName = path.basename(projectDir);\n\n const config: Record<string, unknown> = {\n name: projectName,\n };\n\n const resolvedConfig =\n sourceResult?.sourceConfig ?? (await resolveSource(sourceFlag, projectDir));\n\n if (sourceFlag) {\n config.source = sourceFlag;\n } else if (resolvedConfig.source) {\n config.source = resolvedConfig.source;\n }\n\n if (resolvedConfig.marketplace) {\n config.marketplace = resolvedConfig.marketplace;\n }\n\n const existingProjectConfig = await loadProjectSourceConfig(projectDir);\n if (existingProjectConfig?.author) {\n config.author = existingProjectConfig.author;\n }\n if (existingProjectConfig?.agentsSource) {\n config.agentsSource = existingProjectConfig.agentsSource;\n }\n\n await ensureDir(path.join(projectDir, CLAUDE_SRC_DIR));\n\n // JSON.parse(JSON.stringify(x)) removes undefined values\n const cleaned = JSON.parse(JSON.stringify(config));\n const body = JSON.stringify(cleaned, null, 2);\n const content = `export default ${body};\\n`;\n\n await writeFile(tsConfigPath, content);\n\n this.logSuccess(`Created ${CLAUDE_SRC_DIR}/config.ts`);\n }\n\n private async ejectAgentPartials(\n outputBase: string,\n force: boolean,\n directOutput = false,\n templatesFlag = false,\n ): Promise<void> {\n const sourceDir = templatesFlag\n ? path.join(PROJECT_ROOT, DIRS.templates)\n : path.join(PROJECT_ROOT, DIRS.agents);\n\n if (!(await directoryExists(sourceDir))) {\n this.warn(\n templatesFlag ? \"No agent templates found in CLI.\" : \"No agent partials found in CLI.\",\n );\n return;\n }\n\n const destDir = directOutput\n ? outputBase\n : templatesFlag\n ? path.join(outputBase, path.basename(DIRS.agents), path.basename(DIRS.templates))\n : path.join(outputBase, path.basename(DIRS.agents));\n\n const templatesBasename = path.basename(DIRS.templates);\n\n if ((await directoryExists(destDir)) && !force) {\n if (templatesFlag) {\n this.warn(`Agent templates already exist at ${destDir}. Use --force to overwrite.`);\n return;\n }\n\n const hasTemplates = await directoryExists(path.join(destDir, templatesBasename));\n if ((await this.hasAgentPartialDirs(destDir)) && !hasTemplates) {\n this.warn(`Agent partials already exist at ${destDir}. Use --force to overwrite.`);\n return;\n }\n }\n\n await ensureDir(destDir);\n\n const skipTemplates =\n !templatesFlag && !force && (await directoryExists(path.join(destDir, templatesBasename)));\n\n if (skipTemplates) {\n const sourceEntries = await listDirectories(sourceDir);\n const nonTemplateEntries = sourceEntries.filter((entry) => entry !== templatesBasename);\n for (const entry of nonTemplateEntries) {\n await copy(path.join(sourceDir, entry), path.join(destDir, entry));\n }\n this.warn(\n \"Agent templates already exist — skipping templates, only ejecting agent partials.\",\n );\n } else {\n await copy(sourceDir, destDir);\n }\n\n this.logSuccess(\n `${templatesFlag ? \"Agent templates\" : \"Agent partials\"} ejected to ${destDir}`,\n );\n this.log(\n templatesFlag\n ? \"You can now customize agent templates locally.\"\n : \"You can now customize templates, agent intro, workflow, and examples locally.\",\n );\n }\n\n /** Checks whether the agents directory contains any agent subdirectories (not just _templates). */\n private async hasAgentPartialDirs(agentsDir: string): Promise<boolean> {\n const subdirs = await listDirectories(agentsDir);\n const templatesBasename = path.basename(DIRS.templates);\n return subdirs.some((dir) => dir !== templatesBasename);\n }\n\n private async ejectSkills(\n projectDir: string,\n force: boolean,\n sourceResult: SourceLoadResult,\n directOutput = false,\n customOutputBase?: string,\n ): Promise<void> {\n const destDir =\n directOutput && customOutputBase\n ? customOutputBase\n : path.join(projectDir, LOCAL_SKILLS_PATH);\n\n if ((await directoryExists(destDir)) && !force) {\n this.warn(`Skills already exist at ${destDir}. Use --force to overwrite.`);\n return;\n }\n\n const skillIds = typedKeys<SkillId>(matrix.skills).filter(\n (skillId) => !matrix.skills[skillId]?.local,\n );\n\n if (skillIds.length === 0) {\n this.warn(\"No skills found in source to eject.\");\n return;\n }\n\n await ensureDir(destDir);\n\n const copiedSkills = await copySkillsToLocalFlattened(skillIds, destDir, matrix, sourceResult);\n\n const sourceLabel = sourceResult.isLocal\n ? sourceResult.sourcePath\n : sourceResult.marketplace || sourceResult.sourceConfig.source;\n\n this.logSuccess(`${copiedSkills.length} skills ejected to ${destDir} from ${sourceLabel}`);\n this.log(\"You can now customize skill content locally.\");\n }\n}\n"],"mappings":"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","names":[]}
@@ -8,10 +8,9 @@ import {
8
8
  computeFileHash,
9
9
  fetchFromSource,
10
10
  getCurrentDate
11
- } from "../../chunk-P2BH6X2C.js";
11
+ } from "../../chunk-UKYWXIDT.js";
12
12
  import "../../chunk-RRBWNEG3.js";
13
- import "../../chunk-XXK6MFOA.js";
14
- import "../../chunk-4OBRPE6A.js";
13
+ import "../../chunk-NG2GGK6P.js";
15
14
  import {
16
15
  BaseCommand,
17
16
  EXIT_CODES
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/cli/commands/import/skill.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { BaseCommand } from \"../../base-command.js\";\nimport { getErrorMessage } from \"../../utils/errors.js\";\nimport { EXIT_CODES } from \"../../lib/exit-codes.js\";\nimport { fetchFromSource } from \"../../lib/loading/index.js\";\nimport { importedSkillMetadataSchema } from \"../../lib/schemas.js\";\nimport { getCurrentDate, computeFileHash } from \"../../lib/versioning.js\";\nimport {\n copy,\n directoryExists,\n fileExists,\n listDirectories,\n readFile,\n writeFile,\n ensureDir,\n} from \"../../utils/fs.js\";\nimport {\n DEFAULT_SKILLS_SUBDIR,\n GITHUB_SOURCE,\n LOCAL_SKILLS_PATH,\n STANDARD_FILES,\n YAML_FORMATTING,\n} from \"../../consts.js\";\nimport { IMPORT_DEFAULTS } from \"../../lib/metadata-keys.js\";\nimport { STATUS_MESSAGES, INFO_MESSAGES } from \"../../utils/messages.js\";\n\n/**\n * Metadata for tracking third-party imports. Different from ForkedFromMetadata\n * in skill-metadata.ts which tracks internal fork lineage (uses skillId\n * instead of source/skillName).\n */\ntype ImportedForkedFromMetadata = {\n source: string;\n skillName: string;\n contentHash: string;\n date: string;\n};\n\ntype SkillMetadata = {\n forkedFrom?: ImportedForkedFromMetadata;\n [key: string]: unknown;\n};\n\nconst SKILL_MD_FILE = STANDARD_FILES.SKILL_MD;\nconst METADATA_YAML_FILE = STANDARD_FILES.METADATA_YAML;\nconst METADATA_JSON_FILE = STANDARD_FILES.METADATA_JSON;\n\nfunction parseGitHubSource(source: string): {\n gigetSource: string;\n displaySource: string;\n} {\n if (source.startsWith(GITHUB_SOURCE.HTTPS_PREFIX)) {\n const path = source.replace(GITHUB_SOURCE.HTTPS_PREFIX, \"\");\n return {\n gigetSource: `${GITHUB_SOURCE.GITHUB_PREFIX}${path}`,\n displaySource: source,\n };\n }\n\n if (\n source.startsWith(GITHUB_SOURCE.GITHUB_PREFIX) ||\n source.startsWith(GITHUB_SOURCE.GH_PREFIX)\n ) {\n const normalized = source.startsWith(GITHUB_SOURCE.GH_PREFIX)\n ? GITHUB_SOURCE.GITHUB_PREFIX + source.slice(GITHUB_SOURCE.GH_PREFIX.length)\n : source;\n return {\n gigetSource: normalized,\n displaySource: `${GITHUB_SOURCE.HTTPS_PREFIX}${normalized.replace(GITHUB_SOURCE.GITHUB_PREFIX, \"\")}`,\n };\n }\n\n if (source.includes(\"/\") && !source.includes(\":\")) {\n return {\n gigetSource: `${GITHUB_SOURCE.GITHUB_PREFIX}${source}`,\n displaySource: `${GITHUB_SOURCE.HTTPS_PREFIX}${source}`,\n };\n }\n\n return {\n gigetSource: source,\n displaySource: source,\n };\n}\n\nasync function discoverValidSkills(skillsDir: string, skillDirs: string[]): Promise<string[]> {\n const validSkills: string[] = [];\n\n for (const skillDir of skillDirs) {\n const skillMdPath = path.join(skillsDir, skillDir, SKILL_MD_FILE);\n if (await fileExists(skillMdPath)) {\n validSkills.push(skillDir);\n }\n }\n\n return validSkills.sort();\n}\n\nexport default class ImportSkill extends BaseCommand {\n static summary = \"Import a skill from a third-party GitHub repository\";\n static description =\n \"Download and import skills from external GitHub repositories into your local \" +\n \".claude/skills/ directory. Supports importing specific skills or listing available skills.\";\n\n static examples = [\n {\n description: \"List available skills from a repository\",\n command: \"<%= config.bin %> import skill github:vercel-labs/agent-skills --list\",\n },\n {\n description: \"Import a specific skill\",\n command:\n \"<%= config.bin %> import skill github:vercel-labs/agent-skills --skill react-best-practices\",\n },\n {\n description: \"Import all skills from a repository\",\n command: \"<%= config.bin %> import skill github:vercel-labs/agent-skills --all\",\n },\n {\n description: \"Import with custom skills directory\",\n command:\n \"<%= config.bin %> import skill github:owner/repo --skill my-skill --subdir custom-skills\",\n },\n ];\n\n static args = {\n source: Args.string({\n description:\n \"GitHub repository source (github:owner/repo, https://github.com/owner/repo, or owner/repo)\",\n required: true,\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n skill: Flags.string({\n char: \"n\",\n description: \"Name of the specific skill to import\",\n required: false,\n }),\n all: Flags.boolean({\n char: \"a\",\n description: \"Import all skills from the repository\",\n default: false,\n }),\n list: Flags.boolean({\n char: \"l\",\n description: \"List available skills without importing\",\n default: false,\n }),\n subdir: Flags.string({\n description: \"Subdirectory containing skills (default: skills)\",\n default: DEFAULT_SKILLS_SUBDIR,\n }),\n force: Flags.boolean({\n char: \"f\",\n description: \"Overwrite existing skills\",\n default: false,\n }),\n refresh: Flags.boolean({\n description: \"Force refresh from remote (ignore cache)\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(ImportSkill);\n const projectDir = process.cwd();\n\n this.log(\"\");\n this.log(\"Import Third-Party Skill\");\n this.log(\"\");\n\n if (!flags.list && !flags.skill && !flags.all) {\n this.error(\"Please specify --skill <name>, --all, or --list to list available skills\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (flags.skill && flags.all) {\n this.error(\"Cannot use --skill and --all together\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n const { gigetSource, displaySource } = parseGitHubSource(args.source);\n this.log(`Source: ${displaySource}`);\n\n this.log(STATUS_MESSAGES.FETCHING_REPOSITORY);\n\n let repoPath: string;\n try {\n const result = await fetchFromSource(gigetSource, {\n forceRefresh: flags.refresh,\n });\n repoPath = result.path;\n this.log(result.fromCache ? \"Using cached source\" : \"Downloaded fresh copy\");\n } catch (error) {\n this.error(error instanceof Error ? error.message : `Failed to fetch: ${args.source}`, {\n exit: EXIT_CODES.NETWORK_ERROR,\n });\n }\n\n // Validate --subdir to prevent path traversal outside repository boundary\n const subdir = flags.subdir;\n if (/\\0/.test(subdir)) {\n this.error(\"--subdir contains null bytes\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n if (path.isAbsolute(subdir)) {\n this.error(`--subdir must be a relative path, got: ${subdir}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n const skillsDir = path.resolve(path.join(repoPath, subdir));\n const resolvedRepoPath = path.resolve(repoPath);\n if (!skillsDir.startsWith(resolvedRepoPath + path.sep) && skillsDir !== resolvedRepoPath) {\n this.error(`--subdir path escapes repository boundary: ${subdir}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (!(await directoryExists(skillsDir))) {\n this.error(\n `Skills directory not found: ${flags.subdir}\\n` +\n `The repository doesn't have a '${flags.subdir}' directory.\\n` +\n `Use --subdir to specify a different location.`,\n { exit: EXIT_CODES.INVALID_ARGS },\n );\n }\n\n const skillDirs = await listDirectories(skillsDir);\n const availableSkills = await discoverValidSkills(skillsDir, skillDirs);\n\n if (availableSkills.length === 0) {\n this.error(`No valid skills found in ${flags.subdir}/\\nSkills must have a SKILL.md file.`, {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n if (flags.list) {\n this.log(\"\");\n this.log(`Available skills (${availableSkills.length}):`);\n this.log(\"\");\n for (const skill of availableSkills) {\n this.log(` - ${skill}`);\n }\n this.log(\"\");\n this.log(\"Use --skill <name> to import a specific skill, or --all to import all.\");\n return;\n }\n\n let skillsToImport: string[] = [];\n\n if (flags.all) {\n skillsToImport = availableSkills;\n } else if (flags.skill) {\n if (!availableSkills.includes(flags.skill)) {\n this.error(\n `Skill '${flags.skill}' not found in repository.\\n` +\n `Available skills: ${availableSkills.join(\", \")}\\n` +\n `Use --list to see all available skills.`,\n { exit: EXIT_CODES.INVALID_ARGS },\n );\n }\n skillsToImport = [flags.skill];\n }\n\n const destDir = path.join(projectDir, LOCAL_SKILLS_PATH);\n\n this.log(\"\");\n this.log(`Importing ${skillsToImport.length} skill(s)...`);\n\n let imported = 0;\n let skipped = 0;\n\n for (const skillName of skillsToImport) {\n const sourcePath = path.join(skillsDir, skillName);\n const destPath = path.join(destDir, skillName);\n\n if (await directoryExists(destPath)) {\n if (!flags.force) {\n this.warn(`Skipping '${skillName}': already exists. Use --force to overwrite.`);\n skipped++;\n continue;\n }\n }\n\n try {\n await this.importSkill(sourcePath, destPath, skillName, displaySource);\n this.logSuccess(`Imported: ${skillName}`);\n imported++;\n } catch (error) {\n this.warn(`Failed to import '${skillName}': ${getErrorMessage(error)}`);\n skipped++;\n }\n }\n\n this.log(\"\");\n this.logSuccess(`Import complete: ${imported} imported, ${skipped} skipped`);\n this.log(`Skills location: ${destDir}`);\n this.log(\"\");\n this.log(INFO_MESSAGES.RUN_COMPILE);\n this.log(\"\");\n }\n\n private async importSkill(\n sourcePath: string,\n destPath: string,\n skillName: string,\n source: string,\n ): Promise<void> {\n const skillMdPath = path.join(sourcePath, SKILL_MD_FILE);\n if (!(await fileExists(skillMdPath))) {\n throw new Error(\n `Missing required SKILL.md file at ${skillMdPath}\\n` +\n `Every skill must have a SKILL.md file containing the skill's prompt content.\\n` +\n `Create one with:\\n` +\n ` echo \"# ${skillName}\" > ${path.join(sourcePath, SKILL_MD_FILE)}`,\n );\n }\n\n const contentHash = await computeFileHash(skillMdPath);\n\n await ensureDir(path.dirname(destPath));\n await copy(sourcePath, destPath);\n\n await this.injectForkedFromMetadata(destPath, skillName, source, contentHash);\n }\n\n private async injectForkedFromMetadata(\n destPath: string,\n skillName: string,\n source: string,\n contentHash: string,\n ): Promise<void> {\n const metadataYamlPath = path.join(destPath, METADATA_YAML_FILE);\n const metadataJsonPath = path.join(destPath, METADATA_JSON_FILE);\n\n const forkedFrom: ImportedForkedFromMetadata = {\n source,\n skillName: skillName,\n contentHash: contentHash,\n date: getCurrentDate(),\n };\n\n if (await fileExists(metadataYamlPath)) {\n const rawContent = await readFile(metadataYamlPath);\n const lines = rawContent.split(\"\\n\");\n let yamlContent = rawContent;\n let schemaComment = \"\";\n\n if (lines[0]?.startsWith(\"# yaml-language-server:\")) {\n schemaComment = `${lines[0]}\\n`;\n yamlContent = lines.slice(1).join(\"\\n\");\n }\n\n const raw = parseYaml(yamlContent);\n const parseResult = importedSkillMetadataSchema.safeParse(raw);\n if (!parseResult.success) {\n this.warn(\n `Malformed metadata.yaml at ${metadataYamlPath} — existing fields may be lost\\n` +\n ` Validation errors: ${parseResult.error.issues.map((i) => i.message).join(\", \")}\\n` +\n ` Expected fields: displayName (string), cliDescription (string), category (string)\\n` +\n ` Validate your YAML syntax at https://yamllint.com`,\n );\n }\n const metadata = parseResult.success\n ? (parseResult.data as SkillMetadata)\n : { forkedFrom: undefined };\n metadata.forkedFrom = forkedFrom;\n\n const newYamlContent = stringifyYaml(metadata, {\n lineWidth: YAML_FORMATTING.LINE_WIDTH_NONE,\n });\n await writeFile(metadataYamlPath, schemaComment + newYamlContent);\n return;\n }\n\n if (await fileExists(metadataJsonPath)) {\n const rawContent = await readFile(metadataJsonPath);\n let jsonParsed: unknown;\n try {\n jsonParsed = JSON.parse(rawContent);\n } catch {\n this.warn(\n `Malformed JSON in ${metadataJsonPath} — skipping metadata injection\\n` +\n ` Common issues: trailing commas, unquoted keys, single quotes instead of double quotes\\n` +\n ` Validate your JSON at https://jsonlint.com`,\n );\n return;\n }\n const jsonResult = importedSkillMetadataSchema.safeParse(jsonParsed);\n const metadata = jsonResult.success\n ? (jsonResult.data as SkillMetadata)\n : { forkedFrom: undefined };\n metadata.forkedFrom = forkedFrom;\n\n const yamlContent = stringifyYaml(metadata, { lineWidth: YAML_FORMATTING.LINE_WIDTH_NONE });\n await writeFile(metadataYamlPath, yamlContent);\n return;\n }\n\n const minimalMetadata: SkillMetadata = {\n displayName: skillName\n .split(\"-\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \"),\n cliDescription: \"Imported from third-party repository\",\n category: IMPORT_DEFAULTS.CATEGORY,\n author: IMPORT_DEFAULTS.AUTHOR,\n forkedFrom: forkedFrom,\n };\n\n const yamlContent = stringifyYaml(minimalMetadata, {\n lineWidth: YAML_FORMATTING.LINE_WIDTH_NONE,\n });\n await writeFile(metadataYamlPath, yamlContent);\n }\n}\n"],"mappings":"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","names":["path","yamlContent"]}
1
+ {"version":3,"sources":["../../../src/cli/commands/import/skill.ts"],"sourcesContent":["import { Args, Flags } from \"@oclif/core\";\nimport path from \"path\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { BaseCommand } from \"../../base-command.js\";\nimport { getErrorMessage } from \"../../utils/errors.js\";\nimport { EXIT_CODES } from \"../../lib/exit-codes.js\";\nimport { fetchFromSource } from \"../../lib/loading/index.js\";\nimport { importedSkillMetadataSchema } from \"../../lib/schemas.js\";\nimport { getCurrentDate, computeFileHash } from \"../../lib/versioning.js\";\nimport {\n copy,\n directoryExists,\n fileExists,\n listDirectories,\n readFile,\n writeFile,\n ensureDir,\n} from \"../../utils/fs.js\";\nimport {\n DEFAULT_SKILLS_SUBDIR,\n GITHUB_SOURCE,\n LOCAL_SKILLS_PATH,\n STANDARD_FILES,\n YAML_FORMATTING,\n} from \"../../consts.js\";\nimport { IMPORT_DEFAULTS } from \"../../lib/metadata-keys.js\";\nimport { STATUS_MESSAGES, INFO_MESSAGES } from \"../../utils/messages.js\";\n\n/**\n * Metadata for tracking third-party imports. Different from ForkedFromMetadata\n * in skill-metadata.ts which tracks internal fork lineage (uses skillId\n * instead of source/skillName).\n */\ntype ImportedForkedFromMetadata = {\n source: string;\n skillName: string;\n contentHash: string;\n date: string;\n};\n\ntype SkillMetadata = {\n forkedFrom?: ImportedForkedFromMetadata;\n [key: string]: unknown;\n};\n\nconst SKILL_MD_FILE = STANDARD_FILES.SKILL_MD;\nconst METADATA_YAML_FILE = STANDARD_FILES.METADATA_YAML;\nconst METADATA_JSON_FILE = STANDARD_FILES.METADATA_JSON;\n\nfunction parseGitHubSource(source: string): {\n gigetSource: string;\n displaySource: string;\n} {\n if (source.startsWith(GITHUB_SOURCE.HTTPS_PREFIX)) {\n const path = source.replace(GITHUB_SOURCE.HTTPS_PREFIX, \"\");\n return {\n gigetSource: `${GITHUB_SOURCE.GITHUB_PREFIX}${path}`,\n displaySource: source,\n };\n }\n\n if (\n source.startsWith(GITHUB_SOURCE.GITHUB_PREFIX) ||\n source.startsWith(GITHUB_SOURCE.GH_PREFIX)\n ) {\n const normalized = source.startsWith(GITHUB_SOURCE.GH_PREFIX)\n ? GITHUB_SOURCE.GITHUB_PREFIX + source.slice(GITHUB_SOURCE.GH_PREFIX.length)\n : source;\n return {\n gigetSource: normalized,\n displaySource: `${GITHUB_SOURCE.HTTPS_PREFIX}${normalized.replace(GITHUB_SOURCE.GITHUB_PREFIX, \"\")}`,\n };\n }\n\n if (source.includes(\"/\") && !source.includes(\":\")) {\n return {\n gigetSource: `${GITHUB_SOURCE.GITHUB_PREFIX}${source}`,\n displaySource: `${GITHUB_SOURCE.HTTPS_PREFIX}${source}`,\n };\n }\n\n return {\n gigetSource: source,\n displaySource: source,\n };\n}\n\nasync function discoverValidSkills(skillsDir: string, skillDirs: string[]): Promise<string[]> {\n const validSkills: string[] = [];\n\n for (const skillDir of skillDirs) {\n const skillMdPath = path.join(skillsDir, skillDir, SKILL_MD_FILE);\n if (await fileExists(skillMdPath)) {\n validSkills.push(skillDir);\n }\n }\n\n return validSkills.sort();\n}\n\nexport default class ImportSkill extends BaseCommand {\n static summary = \"Import a skill from a third-party GitHub repository\";\n static description =\n \"Download and import skills from external GitHub repositories into your local \" +\n \".claude/skills/ directory. Supports importing specific skills or listing available skills.\";\n\n static examples = [\n {\n description: \"List available skills from a repository\",\n command: \"<%= config.bin %> import skill github:vercel-labs/agent-skills --list\",\n },\n {\n description: \"Import a specific skill\",\n command:\n \"<%= config.bin %> import skill github:vercel-labs/agent-skills --skill react-best-practices\",\n },\n {\n description: \"Import all skills from a repository\",\n command: \"<%= config.bin %> import skill github:vercel-labs/agent-skills --all\",\n },\n {\n description: \"Import with custom skills directory\",\n command:\n \"<%= config.bin %> import skill github:owner/repo --skill my-skill --subdir custom-skills\",\n },\n ];\n\n static args = {\n source: Args.string({\n description:\n \"GitHub repository source (github:owner/repo, https://github.com/owner/repo, or owner/repo)\",\n required: true,\n }),\n };\n\n static flags = {\n ...BaseCommand.baseFlags,\n skill: Flags.string({\n char: \"n\",\n description: \"Name of the specific skill to import\",\n required: false,\n }),\n all: Flags.boolean({\n char: \"a\",\n description: \"Import all skills from the repository\",\n default: false,\n }),\n list: Flags.boolean({\n char: \"l\",\n description: \"List available skills without importing\",\n default: false,\n }),\n subdir: Flags.string({\n description: \"Subdirectory containing skills (default: skills)\",\n default: DEFAULT_SKILLS_SUBDIR,\n }),\n force: Flags.boolean({\n char: \"f\",\n description: \"Overwrite existing skills\",\n default: false,\n }),\n refresh: Flags.boolean({\n description: \"Force refresh from remote (ignore cache)\",\n default: false,\n }),\n };\n\n async run(): Promise<void> {\n const { args, flags } = await this.parse(ImportSkill);\n const projectDir = process.cwd();\n\n this.log(\"\");\n this.log(\"Import Third-Party Skill\");\n this.log(\"\");\n\n if (!flags.list && !flags.skill && !flags.all) {\n this.error(\"Please specify --skill <name>, --all, or --list to list available skills\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (flags.skill && flags.all) {\n this.error(\"Cannot use --skill and --all together\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n const { gigetSource, displaySource } = parseGitHubSource(args.source);\n this.log(`Source: ${displaySource}`);\n\n this.log(STATUS_MESSAGES.FETCHING_REPOSITORY);\n\n let repoPath: string;\n try {\n const result = await fetchFromSource(gigetSource, {\n forceRefresh: flags.refresh,\n });\n repoPath = result.path;\n this.log(result.fromCache ? \"Using cached source\" : \"Downloaded fresh copy\");\n } catch (error) {\n this.error(error instanceof Error ? error.message : `Failed to fetch: ${args.source}`, {\n exit: EXIT_CODES.NETWORK_ERROR,\n });\n }\n\n // Validate --subdir to prevent path traversal outside repository boundary\n const subdir = flags.subdir;\n if (/\\0/.test(subdir)) {\n this.error(\"--subdir contains null bytes\", {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n if (path.isAbsolute(subdir)) {\n this.error(`--subdir must be a relative path, got: ${subdir}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n const skillsDir = path.resolve(path.join(repoPath, subdir));\n const resolvedRepoPath = path.resolve(repoPath);\n if (!skillsDir.startsWith(resolvedRepoPath + path.sep) && skillsDir !== resolvedRepoPath) {\n this.error(`--subdir path escapes repository boundary: ${subdir}`, {\n exit: EXIT_CODES.INVALID_ARGS,\n });\n }\n\n if (!(await directoryExists(skillsDir))) {\n this.error(\n `Skills directory not found: ${flags.subdir}\\n` +\n `The repository doesn't have a '${flags.subdir}' directory.\\n` +\n `Use --subdir to specify a different location.`,\n { exit: EXIT_CODES.INVALID_ARGS },\n );\n }\n\n const skillDirs = await listDirectories(skillsDir);\n const availableSkills = await discoverValidSkills(skillsDir, skillDirs);\n\n if (availableSkills.length === 0) {\n this.error(`No valid skills found in ${flags.subdir}/\\nSkills must have a SKILL.md file.`, {\n exit: EXIT_CODES.ERROR,\n });\n }\n\n if (flags.list) {\n this.log(\"\");\n this.log(`Available skills (${availableSkills.length}):`);\n this.log(\"\");\n for (const skill of availableSkills) {\n this.log(` - ${skill}`);\n }\n this.log(\"\");\n this.log(\"Use --skill <name> to import a specific skill, or --all to import all.\");\n return;\n }\n\n let skillsToImport: string[] = [];\n\n if (flags.all) {\n skillsToImport = availableSkills;\n } else if (flags.skill) {\n if (!availableSkills.includes(flags.skill)) {\n this.error(\n `Skill '${flags.skill}' not found in repository.\\n` +\n `Available skills: ${availableSkills.join(\", \")}\\n` +\n `Use --list to see all available skills.`,\n { exit: EXIT_CODES.INVALID_ARGS },\n );\n }\n skillsToImport = [flags.skill];\n }\n\n const destDir = path.join(projectDir, LOCAL_SKILLS_PATH);\n\n this.log(\"\");\n this.log(`Importing ${skillsToImport.length} skill(s)...`);\n\n let imported = 0;\n let skipped = 0;\n\n for (const skillName of skillsToImport) {\n const sourcePath = path.join(skillsDir, skillName);\n const destPath = path.join(destDir, skillName);\n\n if (await directoryExists(destPath)) {\n if (!flags.force) {\n this.warn(`Skipping '${skillName}': already exists. Use --force to overwrite.`);\n skipped++;\n continue;\n }\n }\n\n try {\n await this.importSkill(sourcePath, destPath, skillName, displaySource);\n this.logSuccess(`Imported: ${skillName}`);\n imported++;\n } catch (error) {\n this.warn(`Failed to import '${skillName}': ${getErrorMessage(error)}`);\n skipped++;\n }\n }\n\n this.log(\"\");\n this.logSuccess(`Import complete: ${imported} imported, ${skipped} skipped`);\n this.log(`Skills location: ${destDir}`);\n this.log(\"\");\n this.log(INFO_MESSAGES.RUN_COMPILE);\n this.log(\"\");\n }\n\n private async importSkill(\n sourcePath: string,\n destPath: string,\n skillName: string,\n source: string,\n ): Promise<void> {\n const skillMdPath = path.join(sourcePath, SKILL_MD_FILE);\n if (!(await fileExists(skillMdPath))) {\n throw new Error(\n `Missing required SKILL.md file at ${skillMdPath}\\n` +\n `Every skill must have a SKILL.md file containing the skill's prompt content.\\n` +\n `Create one with:\\n` +\n ` echo \"# ${skillName}\" > ${path.join(sourcePath, SKILL_MD_FILE)}`,\n );\n }\n\n const contentHash = await computeFileHash(skillMdPath);\n\n await ensureDir(path.dirname(destPath));\n await copy(sourcePath, destPath);\n\n await this.injectForkedFromMetadata(destPath, skillName, source, contentHash);\n }\n\n private async injectForkedFromMetadata(\n destPath: string,\n skillName: string,\n source: string,\n contentHash: string,\n ): Promise<void> {\n const metadataYamlPath = path.join(destPath, METADATA_YAML_FILE);\n const metadataJsonPath = path.join(destPath, METADATA_JSON_FILE);\n\n const forkedFrom: ImportedForkedFromMetadata = {\n source,\n skillName: skillName,\n contentHash: contentHash,\n date: getCurrentDate(),\n };\n\n if (await fileExists(metadataYamlPath)) {\n const rawContent = await readFile(metadataYamlPath);\n const lines = rawContent.split(\"\\n\");\n let yamlContent = rawContent;\n let schemaComment = \"\";\n\n if (lines[0]?.startsWith(\"# yaml-language-server:\")) {\n schemaComment = `${lines[0]}\\n`;\n yamlContent = lines.slice(1).join(\"\\n\");\n }\n\n const raw = parseYaml(yamlContent);\n const parseResult = importedSkillMetadataSchema.safeParse(raw);\n if (!parseResult.success) {\n this.warn(\n `Malformed metadata.yaml at ${metadataYamlPath} — existing fields may be lost\\n` +\n ` Validation errors: ${parseResult.error.issues.map((i) => i.message).join(\", \")}\\n` +\n ` Expected fields: displayName (string), cliDescription (string), category (string)\\n` +\n ` Validate your YAML syntax at https://yamllint.com`,\n );\n }\n const metadata = parseResult.success\n ? (parseResult.data as SkillMetadata)\n : { forkedFrom: undefined };\n metadata.forkedFrom = forkedFrom;\n\n const newYamlContent = stringifyYaml(metadata, {\n lineWidth: YAML_FORMATTING.LINE_WIDTH_NONE,\n });\n await writeFile(metadataYamlPath, schemaComment + newYamlContent);\n return;\n }\n\n if (await fileExists(metadataJsonPath)) {\n const rawContent = await readFile(metadataJsonPath);\n let jsonParsed: unknown;\n try {\n jsonParsed = JSON.parse(rawContent);\n } catch {\n this.warn(\n `Malformed JSON in ${metadataJsonPath} — skipping metadata injection\\n` +\n ` Common issues: trailing commas, unquoted keys, single quotes instead of double quotes\\n` +\n ` Validate your JSON at https://jsonlint.com`,\n );\n return;\n }\n const jsonResult = importedSkillMetadataSchema.safeParse(jsonParsed);\n const metadata = jsonResult.success\n ? (jsonResult.data as SkillMetadata)\n : { forkedFrom: undefined };\n metadata.forkedFrom = forkedFrom;\n\n const yamlContent = stringifyYaml(metadata, { lineWidth: YAML_FORMATTING.LINE_WIDTH_NONE });\n await writeFile(metadataYamlPath, yamlContent);\n return;\n }\n\n const minimalMetadata: SkillMetadata = {\n displayName: skillName\n .split(\"-\")\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \"),\n cliDescription: \"Imported from third-party repository\",\n category: IMPORT_DEFAULTS.CATEGORY,\n author: IMPORT_DEFAULTS.AUTHOR,\n forkedFrom: forkedFrom,\n };\n\n const yamlContent = stringifyYaml(minimalMetadata, {\n lineWidth: YAML_FORMATTING.LINE_WIDTH_NONE,\n });\n await writeFile(metadataYamlPath, yamlContent);\n }\n}\n"],"mappings":"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","names":["path","yamlContent"]}
@@ -5,12 +5,11 @@ import {
5
5
  import {
6
6
  discoverLocalSkills,
7
7
  loadSkillsMatrixFromSource
8
- } from "../chunk-P2BH6X2C.js";
8
+ } from "../chunk-UKYWXIDT.js";
9
9
  import "../chunk-RRBWNEG3.js";
10
- import "../chunk-XXK6MFOA.js";
11
10
  import {
12
11
  matrix
13
- } from "../chunk-4OBRPE6A.js";
12
+ } from "../chunk-NG2GGK6P.js";
14
13
  import {
15
14
  BaseCommand,
16
15
  EXIT_CODES