@claude-collective/cli 0.2.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/CHANGELOG.md +178 -0
  2. package/README.md +1 -1
  3. package/dist/chunk-3HBTELJN.js +114 -0
  4. package/dist/chunk-3HBTELJN.js.map +1 -0
  5. package/dist/chunk-3ZCB5K33.js +54 -0
  6. package/dist/chunk-3ZCB5K33.js.map +1 -0
  7. package/dist/chunk-66UDJBF6.js +96 -0
  8. package/dist/chunk-66UDJBF6.js.map +1 -0
  9. package/dist/chunk-6LS7XO3H.js +31 -0
  10. package/dist/chunk-6LS7XO3H.js.map +1 -0
  11. package/dist/chunk-A3J6IAXK.js +57 -0
  12. package/dist/chunk-A3J6IAXK.js.map +1 -0
  13. package/dist/chunk-A65SBAAJ.js +69 -0
  14. package/dist/chunk-A65SBAAJ.js.map +1 -0
  15. package/dist/chunk-ALEPJ6YN.js +80 -0
  16. package/dist/chunk-ALEPJ6YN.js.map +1 -0
  17. package/dist/chunk-C4ZTIYFR.js +84 -0
  18. package/dist/chunk-C4ZTIYFR.js.map +1 -0
  19. package/dist/chunk-CIY5UBRB.js +453 -0
  20. package/dist/chunk-CIY5UBRB.js.map +1 -0
  21. package/dist/chunk-DHET7RCE.js +50 -0
  22. package/dist/chunk-DHET7RCE.js.map +1 -0
  23. package/dist/chunk-DHFFRMF6.js +31 -0
  24. package/dist/chunk-DHFFRMF6.js.map +1 -0
  25. package/dist/chunk-DKGL77IY.js +307 -0
  26. package/dist/chunk-DKGL77IY.js.map +1 -0
  27. package/dist/chunk-ED73HCW2.js +315 -0
  28. package/dist/chunk-ED73HCW2.js.map +1 -0
  29. package/dist/chunk-FNOYEXUE.js +308 -0
  30. package/dist/chunk-FNOYEXUE.js.map +1 -0
  31. package/dist/chunk-G2FBJOZG.js +141 -0
  32. package/dist/chunk-G2FBJOZG.js.map +1 -0
  33. package/dist/chunk-HNDT5QRB.js +120 -0
  34. package/dist/chunk-HNDT5QRB.js.map +1 -0
  35. package/dist/chunk-K7PTOVX4.js +158 -0
  36. package/dist/chunk-K7PTOVX4.js.map +1 -0
  37. package/dist/chunk-LQTST4WY.js +91 -0
  38. package/dist/chunk-LQTST4WY.js.map +1 -0
  39. package/dist/chunk-LVKRVFYR.js +54 -0
  40. package/dist/chunk-LVKRVFYR.js.map +1 -0
  41. package/dist/chunk-M7YCPFIX.js +108 -0
  42. package/dist/chunk-M7YCPFIX.js.map +1 -0
  43. package/dist/chunk-MJSFR562.js +57 -0
  44. package/dist/chunk-MJSFR562.js.map +1 -0
  45. package/dist/chunk-MMDXNZPF.js +69 -0
  46. package/dist/chunk-MMDXNZPF.js.map +1 -0
  47. package/dist/chunk-MYAVQ23U.js +356 -0
  48. package/dist/chunk-MYAVQ23U.js.map +1 -0
  49. package/dist/chunk-NGBFJJ7Q.js +124 -0
  50. package/dist/chunk-NGBFJJ7Q.js.map +1 -0
  51. package/dist/chunk-OLBOTK3O.js +64 -0
  52. package/dist/chunk-OLBOTK3O.js.map +1 -0
  53. package/dist/chunk-PPNTD5LO.js +330 -0
  54. package/dist/chunk-PPNTD5LO.js.map +1 -0
  55. package/dist/chunk-Q2LH2DAB.js +392 -0
  56. package/dist/chunk-Q2LH2DAB.js.map +1 -0
  57. package/dist/chunk-Q6DR5QUH.js +547 -0
  58. package/dist/chunk-Q6DR5QUH.js.map +1 -0
  59. package/dist/chunk-QESUUPOE.js +241 -0
  60. package/dist/chunk-QESUUPOE.js.map +1 -0
  61. package/dist/chunk-QGGSLMO3.js +607 -0
  62. package/dist/chunk-QGGSLMO3.js.map +1 -0
  63. package/dist/chunk-SEBPPFUW.js +478 -0
  64. package/dist/chunk-SEBPPFUW.js.map +1 -0
  65. package/dist/chunk-SYQ7R2JO.js +95 -0
  66. package/dist/chunk-SYQ7R2JO.js.map +1 -0
  67. package/dist/chunk-TOPAIL5W.js +22 -0
  68. package/dist/chunk-TOPAIL5W.js.map +1 -0
  69. package/dist/chunk-U4VYHKPM.js +110 -0
  70. package/dist/chunk-U4VYHKPM.js.map +1 -0
  71. package/dist/chunk-UOWHJ6BE.js +83 -0
  72. package/dist/chunk-UOWHJ6BE.js.map +1 -0
  73. package/dist/chunk-XKEG3SCV.js +86 -0
  74. package/dist/chunk-XKEG3SCV.js.map +1 -0
  75. package/dist/chunk-XY3XDVMI.js +15599 -0
  76. package/dist/chunk-XY3XDVMI.js.map +1 -0
  77. package/dist/chunk-Y3V43XCU.js +76 -0
  78. package/dist/chunk-Y3V43XCU.js.map +1 -0
  79. package/dist/chunk-YKXBGCFD.js +129 -0
  80. package/dist/chunk-YKXBGCFD.js.map +1 -0
  81. package/dist/cli-v2/defaults/agent-mappings.yaml +185 -0
  82. package/dist/commands/build/marketplace.js +254 -0
  83. package/dist/commands/build/marketplace.js.map +1 -0
  84. package/dist/commands/build/plugins.js +324 -0
  85. package/dist/commands/build/plugins.js.map +1 -0
  86. package/dist/commands/build/stack.js +169 -0
  87. package/dist/commands/build/stack.js.map +1 -0
  88. package/dist/commands/compile.js +461 -0
  89. package/dist/commands/compile.js.map +1 -0
  90. package/dist/commands/config/get.js +60 -0
  91. package/dist/commands/config/get.js.map +1 -0
  92. package/dist/commands/config/index.js +22 -0
  93. package/dist/commands/config/index.js.map +1 -0
  94. package/dist/commands/config/path.js +35 -0
  95. package/dist/commands/config/path.js.map +1 -0
  96. package/dist/commands/config/set-project.js +61 -0
  97. package/dist/commands/config/set-project.js.map +1 -0
  98. package/dist/commands/config/set.js +60 -0
  99. package/dist/commands/config/set.js.map +1 -0
  100. package/dist/commands/config/show.js +13 -0
  101. package/dist/commands/config/show.js.map +1 -0
  102. package/dist/commands/config/unset-project.js +57 -0
  103. package/dist/commands/config/unset-project.js.map +1 -0
  104. package/dist/commands/config/unset.js +56 -0
  105. package/dist/commands/config/unset.js.map +1 -0
  106. package/dist/commands/diff.js +755 -0
  107. package/dist/commands/diff.js.map +1 -0
  108. package/dist/commands/doctor.js +413 -0
  109. package/dist/commands/doctor.js.map +1 -0
  110. package/dist/commands/edit.js +254 -0
  111. package/dist/commands/edit.js.map +1 -0
  112. package/dist/commands/eject.js +208 -0
  113. package/dist/commands/eject.js.map +1 -0
  114. package/dist/commands/info.js +205 -0
  115. package/dist/commands/info.js.map +1 -0
  116. package/dist/commands/init.js +915 -0
  117. package/dist/commands/init.js.map +1 -0
  118. package/dist/commands/list.js +44 -0
  119. package/dist/commands/list.js.map +1 -0
  120. package/dist/commands/new/agent.js +230 -0
  121. package/dist/commands/new/agent.js.map +1 -0
  122. package/dist/commands/new/skill.js +204 -0
  123. package/dist/commands/new/skill.js.map +1 -0
  124. package/dist/commands/outdated.js +242 -0
  125. package/dist/commands/outdated.js.map +1 -0
  126. package/dist/commands/search.js +115 -0
  127. package/dist/commands/search.js.map +1 -0
  128. package/dist/commands/test-imports.js +92 -0
  129. package/dist/commands/test-imports.js.map +1 -0
  130. package/dist/commands/uninstall.js +309 -0
  131. package/dist/commands/uninstall.js.map +1 -0
  132. package/dist/commands/update.js +428 -0
  133. package/dist/commands/update.js.map +1 -0
  134. package/dist/commands/validate.js +375 -0
  135. package/dist/commands/validate.js.map +1 -0
  136. package/dist/commands/version/bump.js +95 -0
  137. package/dist/commands/version/bump.js.map +1 -0
  138. package/dist/commands/version/index.js +70 -0
  139. package/dist/commands/version/index.js.map +1 -0
  140. package/dist/commands/version/set.js +101 -0
  141. package/dist/commands/version/set.js.map +1 -0
  142. package/dist/commands/version/show.js +70 -0
  143. package/dist/commands/version/show.js.map +1 -0
  144. package/dist/components/common/confirm.js +9 -0
  145. package/dist/components/common/confirm.js.map +1 -0
  146. package/dist/components/common/message.js +24 -0
  147. package/dist/components/common/message.js.map +1 -0
  148. package/dist/components/common/spinner.js +14 -0
  149. package/dist/components/common/spinner.js.map +1 -0
  150. package/dist/components/wizard/category-grid.js +9 -0
  151. package/dist/components/wizard/category-grid.js.map +1 -0
  152. package/dist/components/wizard/category-grid.test.js +728 -0
  153. package/dist/components/wizard/category-grid.test.js.map +1 -0
  154. package/dist/components/wizard/section-progress.js +9 -0
  155. package/dist/components/wizard/section-progress.js.map +1 -0
  156. package/dist/components/wizard/section-progress.test.js +281 -0
  157. package/dist/components/wizard/section-progress.test.js.map +1 -0
  158. package/dist/components/wizard/step-approach.js +11 -0
  159. package/dist/components/wizard/step-approach.js.map +1 -0
  160. package/dist/components/wizard/step-build.js +15 -0
  161. package/dist/components/wizard/step-build.js.map +1 -0
  162. package/dist/components/wizard/step-build.test.js +729 -0
  163. package/dist/components/wizard/step-build.test.js.map +1 -0
  164. package/dist/components/wizard/step-confirm.js +9 -0
  165. package/dist/components/wizard/step-confirm.js.map +1 -0
  166. package/dist/components/wizard/step-refine.js +9 -0
  167. package/dist/components/wizard/step-refine.js.map +1 -0
  168. package/dist/components/wizard/step-refine.test.js +235 -0
  169. package/dist/components/wizard/step-refine.test.js.map +1 -0
  170. package/dist/components/wizard/step-stack-options.js +11 -0
  171. package/dist/components/wizard/step-stack-options.js.map +1 -0
  172. package/dist/components/wizard/step-stack.js +11 -0
  173. package/dist/components/wizard/step-stack.js.map +1 -0
  174. package/dist/components/wizard/wizard-tabs.js +11 -0
  175. package/dist/components/wizard/wizard-tabs.js.map +1 -0
  176. package/dist/components/wizard/wizard.js +20 -0
  177. package/dist/components/wizard/wizard.js.map +1 -0
  178. package/dist/hooks/init.js +41 -0
  179. package/dist/hooks/init.js.map +1 -0
  180. package/dist/index.js +10 -0
  181. package/dist/index.js.map +1 -0
  182. package/dist/magic-string.es-RGXYGAW3.js +1316 -0
  183. package/dist/magic-string.es-RGXYGAW3.js.map +1 -0
  184. package/dist/stores/wizard-store.js +10 -0
  185. package/dist/stores/wizard-store.js.map +1 -0
  186. package/dist/stores/wizard-store.test.js +405 -0
  187. package/dist/stores/wizard-store.test.js.map +1 -0
  188. package/package.json +44 -25
  189. package/dist/cli/index.js +0 -6314
  190. package/dist/cli/index.js.map +0 -1
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ init_esm_shims
4
+ } from "./chunk-DHET7RCE.js";
5
+
6
+ // src/cli-v2/components/wizard/step-refine.tsx
7
+ init_esm_shims();
8
+ import { Box, Text, useInput } from "ink";
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ var StepRefine = ({
11
+ technologyCount,
12
+ refineAction,
13
+ onSelectAction,
14
+ onContinue,
15
+ onBack
16
+ }) => {
17
+ useInput((input, key) => {
18
+ if (key.return) {
19
+ onContinue();
20
+ }
21
+ if (key.escape) {
22
+ onBack();
23
+ }
24
+ if (key.upArrow || key.downArrow) {
25
+ onSelectAction("all-recommended");
26
+ }
27
+ });
28
+ const isRecommendedSelected = refineAction === "all-recommended" || refineAction === null;
29
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 2, children: [
30
+ /* @__PURE__ */ jsxs(Text, { children: [
31
+ "Your stack includes",
32
+ " ",
33
+ /* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: technologyCount }),
34
+ " ",
35
+ "technologies."
36
+ ] }),
37
+ /* @__PURE__ */ jsx(Text, { children: " " }),
38
+ /* @__PURE__ */ jsx(
39
+ Box,
40
+ {
41
+ borderStyle: "round",
42
+ borderColor: isRecommendedSelected ? "green" : "gray",
43
+ paddingX: 2,
44
+ paddingY: 1,
45
+ marginBottom: 1,
46
+ children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
47
+ /* @__PURE__ */ jsxs(Text, { color: "green", bold: true, children: [
48
+ ">",
49
+ " Use all recommended skills (verified)"
50
+ ] }),
51
+ /* @__PURE__ */ jsx(Text, { children: " " }),
52
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "This is the fastest option. All skills are verified and" }),
53
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "maintained by Claude Collective." })
54
+ ] })
55
+ }
56
+ ),
57
+ /* @__PURE__ */ jsx(Box, { paddingLeft: 2, children: /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
58
+ "\u25CB",
59
+ " Customize skill sources ",
60
+ /* @__PURE__ */ jsx(Text, { color: "gray", children: "(coming soon)" })
61
+ ] }) }),
62
+ /* @__PURE__ */ jsx(Box, { paddingLeft: 4, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Choose alternative skills for each technology" }) }),
63
+ /* @__PURE__ */ jsx(Text, { children: " " }),
64
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
65
+ "\u2191",
66
+ "/",
67
+ "\u2193",
68
+ " navigate ENTER continue ESC back"
69
+ ] })
70
+ ] });
71
+ };
72
+
73
+ export {
74
+ StepRefine
75
+ };
76
+ //# sourceMappingURL=chunk-Y3V43XCU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli-v2/components/wizard/step-refine.tsx"],"sourcesContent":["/**\n * StepRefine component - Refine step for skill source selection.\n *\n * For Phase 7, this implements only the \"Use all recommended\" path.\n * The \"Customize\" option (skills.sh integration) is deferred to Phase 8.\n *\n * Visual design:\n * - Prominent \"Use all recommended\" option with border (default/selected)\n * - Grayed out \"Customize\" option with \"(coming soon)\" label\n * - Keyboard navigation: Enter to continue, Escape to go back\n */\nimport React from \"react\";\nimport { Box, Text, useInput } from \"ink\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type RefineAction = \"all-recommended\" | \"customize\" | null;\n\nexport interface StepRefineProps {\n /** Count of selected technologies */\n technologyCount: number;\n /** Current selection: use all recommended or customize */\n refineAction: RefineAction;\n /** Callback when action is selected */\n onSelectAction: (action: RefineAction) => void;\n /** Continue to confirm step */\n onContinue: () => void;\n /** Go back to build step */\n onBack: () => void;\n}\n\n// =============================================================================\n// Main Component\n// =============================================================================\n\nexport const StepRefine: React.FC<StepRefineProps> = ({\n technologyCount,\n refineAction,\n onSelectAction,\n onContinue,\n onBack,\n}) => {\n useInput((input, key) => {\n if (key.return) {\n onContinue();\n }\n if (key.escape) {\n onBack();\n }\n // Arrow keys to move between options (for future)\n // For now, only \"all-recommended\" is selectable\n if (key.upArrow || key.downArrow) {\n onSelectAction(\"all-recommended\");\n }\n });\n\n // Determine if \"all-recommended\" is the current selection\n // Default to \"all-recommended\" if nothing selected\n const isRecommendedSelected =\n refineAction === \"all-recommended\" || refineAction === null;\n\n return (\n <Box flexDirection=\"column\" paddingX={2}>\n {/* Technology count header */}\n <Text>\n Your stack includes{\" \"}\n <Text color=\"cyan\" bold>\n {technologyCount}\n </Text>{\" \"}\n technologies.\n </Text>\n <Text> </Text>\n\n {/* Recommended option - highlighted with border */}\n <Box\n borderStyle=\"round\"\n borderColor={isRecommendedSelected ? \"green\" : \"gray\"}\n paddingX={2}\n paddingY={1}\n marginBottom={1}\n >\n <Box flexDirection=\"column\">\n <Text color=\"green\" bold>\n {\">\"} Use all recommended skills (verified)\n </Text>\n <Text> </Text>\n <Text dimColor>\n This is the fastest option. All skills are verified and\n </Text>\n <Text dimColor>maintained by Claude Collective.</Text>\n </Box>\n </Box>\n\n {/* Customize option - disabled/grayed */}\n <Box paddingLeft={2}>\n <Text dimColor>\n {\"○\"} Customize skill sources <Text color=\"gray\">(coming soon)</Text>\n </Text>\n </Box>\n <Box paddingLeft={4}>\n <Text dimColor>Choose alternative skills for each technology</Text>\n </Box>\n\n {/* Footer with keyboard shortcuts */}\n <Text> </Text>\n <Text dimColor>\n {\"\\u2191\"}/{\"\\u2193\"} navigate ENTER continue ESC back\n </Text>\n </Box>\n );\n};\n"],"mappings":";;;;;;AAAA;AAYA,SAAS,KAAK,MAAM,gBAAgB;AAsD9B,SAEE,KAFF;AA7BC,IAAM,aAAwC,CAAC;AAAA,EACpD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,WAAS,CAAC,OAAO,QAAQ;AACvB,QAAI,IAAI,QAAQ;AACd,iBAAW;AAAA,IACb;AACA,QAAI,IAAI,QAAQ;AACd,aAAO;AAAA,IACT;AAGA,QAAI,IAAI,WAAW,IAAI,WAAW;AAChC,qBAAe,iBAAiB;AAAA,IAClC;AAAA,EACF,CAAC;AAID,QAAM,wBACJ,iBAAiB,qBAAqB,iBAAiB;AAEzD,SACE,qBAAC,OAAI,eAAc,UAAS,UAAU,GAEpC;AAAA,yBAAC,QAAK;AAAA;AAAA,MACgB;AAAA,MACpB,oBAAC,QAAK,OAAM,QAAO,MAAI,MACpB,2BACH;AAAA,MAAQ;AAAA,MAAI;AAAA,OAEd;AAAA,IACA,oBAAC,QAAK,eAAC;AAAA,IAGP;AAAA,MAAC;AAAA;AAAA,QACC,aAAY;AAAA,QACZ,aAAa,wBAAwB,UAAU;AAAA,QAC/C,UAAU;AAAA,QACV,UAAU;AAAA,QACV,cAAc;AAAA,QAEd,+BAAC,OAAI,eAAc,UACjB;AAAA,+BAAC,QAAK,OAAM,SAAQ,MAAI,MACrB;AAAA;AAAA,YAAI;AAAA,aACP;AAAA,UACA,oBAAC,QAAK,eAAC;AAAA,UACP,oBAAC,QAAK,UAAQ,MAAC,qEAEf;AAAA,UACA,oBAAC,QAAK,UAAQ,MAAC,8CAAgC;AAAA,WACjD;AAAA;AAAA,IACF;AAAA,IAGA,oBAAC,OAAI,aAAa,GAChB,+BAAC,QAAK,UAAQ,MACX;AAAA;AAAA,MAAI;AAAA,MAAyB,oBAAC,QAAK,OAAM,QAAO,2BAAa;AAAA,OAChE,GACF;AAAA,IACA,oBAAC,OAAI,aAAa,GAChB,8BAAC,QAAK,UAAQ,MAAC,2DAA6C,GAC9D;AAAA,IAGA,oBAAC,QAAK,eAAC;AAAA,IACP,qBAAC,QAAK,UAAQ,MACX;AAAA;AAAA,MAAS;AAAA,MAAE;AAAA,MAAS;AAAA,OACvB;AAAA,KACF;AAEJ;","names":[]}
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ detectInstallation
4
+ } from "./chunk-3ZCB5K33.js";
5
+ import {
6
+ loadProjectConfig
7
+ } from "./chunk-MYAVQ23U.js";
8
+ import {
9
+ getCollectivePluginDir,
10
+ getPluginAgentsDir,
11
+ getPluginSkillsDir,
12
+ readPluginManifest
13
+ } from "./chunk-3HBTELJN.js";
14
+ import {
15
+ DEFAULT_DISPLAY_VERSION
16
+ } from "./chunk-A3J6IAXK.js";
17
+ import {
18
+ directoryExists
19
+ } from "./chunk-MMDXNZPF.js";
20
+ import {
21
+ init_esm_shims
22
+ } from "./chunk-DHET7RCE.js";
23
+
24
+ // src/cli-v2/lib/plugin-info.ts
25
+ init_esm_shims();
26
+ import { readdir } from "fs/promises";
27
+ var DEFAULT_NAME = "claude-collective";
28
+ async function getPluginInfo() {
29
+ const pluginDir = getCollectivePluginDir();
30
+ if (!await directoryExists(pluginDir)) {
31
+ return null;
32
+ }
33
+ const manifest = await readPluginManifest(pluginDir);
34
+ if (!manifest) {
35
+ return null;
36
+ }
37
+ const skillsDir = getPluginSkillsDir(pluginDir);
38
+ const agentsDir = getPluginAgentsDir(pluginDir);
39
+ let skillCount = 0;
40
+ let agentCount = 0;
41
+ if (await directoryExists(skillsDir)) {
42
+ const skills = await readdir(skillsDir, { withFileTypes: true });
43
+ skillCount = skills.filter((s) => s.isDirectory()).length;
44
+ }
45
+ if (await directoryExists(agentsDir)) {
46
+ const agents = await readdir(agentsDir, { withFileTypes: true });
47
+ agentCount = agents.filter(
48
+ (a) => a.isFile() && a.name.endsWith(".md")
49
+ ).length;
50
+ }
51
+ return {
52
+ name: manifest.name || DEFAULT_NAME,
53
+ version: manifest.version || DEFAULT_DISPLAY_VERSION,
54
+ skillCount,
55
+ agentCount,
56
+ path: pluginDir
57
+ };
58
+ }
59
+ async function getInstallationInfo() {
60
+ const installation = await detectInstallation();
61
+ if (!installation) {
62
+ return null;
63
+ }
64
+ let skillCount = 0;
65
+ let agentCount = 0;
66
+ let name = DEFAULT_NAME;
67
+ let version = DEFAULT_DISPLAY_VERSION;
68
+ if (await directoryExists(installation.skillsDir)) {
69
+ try {
70
+ const skills = await readdir(installation.skillsDir, {
71
+ withFileTypes: true
72
+ });
73
+ skillCount = skills.filter((s) => s.isDirectory()).length;
74
+ } catch {
75
+ }
76
+ }
77
+ if (await directoryExists(installation.agentsDir)) {
78
+ try {
79
+ const agents = await readdir(installation.agentsDir, {
80
+ withFileTypes: true
81
+ });
82
+ agentCount = agents.filter(
83
+ (a) => a.isFile() && a.name.endsWith(".md")
84
+ ).length;
85
+ } catch {
86
+ }
87
+ }
88
+ if (installation.mode === "local") {
89
+ const loaded = await loadProjectConfig(installation.projectDir);
90
+ if (loaded?.config) {
91
+ name = loaded.config.name || DEFAULT_NAME;
92
+ version = "local";
93
+ }
94
+ } else {
95
+ const pluginDir = getCollectivePluginDir(installation.projectDir);
96
+ const manifest = await readPluginManifest(pluginDir);
97
+ if (manifest) {
98
+ name = manifest.name || DEFAULT_NAME;
99
+ version = manifest.version || DEFAULT_DISPLAY_VERSION;
100
+ }
101
+ }
102
+ return {
103
+ mode: installation.mode,
104
+ name,
105
+ version,
106
+ skillCount,
107
+ agentCount,
108
+ configPath: installation.configPath,
109
+ agentsDir: installation.agentsDir,
110
+ skillsDir: installation.skillsDir
111
+ };
112
+ }
113
+ function formatInstallationDisplay(info) {
114
+ const modeLabel = info.mode === "local" ? "Local" : "Plugin";
115
+ const versionDisplay = info.mode === "local" ? "(local mode)" : `v${info.version}`;
116
+ return `Installation: ${info.name} ${versionDisplay}
117
+ Mode: ${modeLabel}
118
+ Skills: ${info.skillCount}
119
+ Agents: ${info.agentCount}
120
+ Config: ${info.configPath}
121
+ Agents: ${info.agentsDir}`;
122
+ }
123
+
124
+ export {
125
+ getPluginInfo,
126
+ getInstallationInfo,
127
+ formatInstallationDisplay
128
+ };
129
+ //# sourceMappingURL=chunk-YKXBGCFD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli-v2/lib/plugin-info.ts"],"sourcesContent":["import { readdir } from \"fs/promises\";\nimport {\n getCollectivePluginDir,\n getPluginSkillsDir,\n getPluginAgentsDir,\n readPluginManifest,\n} from \"./plugin-finder\";\nimport { directoryExists } from \"../utils/fs\";\nimport { DEFAULT_DISPLAY_VERSION } from \"../consts\";\nimport { detectInstallation, type InstallMode } from \"./installation\";\nimport { loadProjectConfig } from \"./project-config\";\n\nconst DEFAULT_NAME = \"claude-collective\";\n\nexport interface PluginInfo {\n name: string;\n version: string;\n skillCount: number;\n agentCount: number;\n path: string;\n}\n\nexport interface InstallationInfo {\n mode: InstallMode;\n name: string;\n version: string;\n skillCount: number;\n agentCount: number;\n configPath: string;\n agentsDir: string;\n skillsDir: string;\n}\n\nexport async function getPluginInfo(): Promise<PluginInfo | null> {\n const pluginDir = getCollectivePluginDir();\n\n if (!(await directoryExists(pluginDir))) {\n return null;\n }\n\n const manifest = await readPluginManifest(pluginDir);\n if (!manifest) {\n return null;\n }\n\n const skillsDir = getPluginSkillsDir(pluginDir);\n const agentsDir = getPluginAgentsDir(pluginDir);\n\n let skillCount = 0;\n let agentCount = 0;\n\n if (await directoryExists(skillsDir)) {\n const skills = await readdir(skillsDir, { withFileTypes: true });\n skillCount = skills.filter((s) => s.isDirectory()).length;\n }\n\n if (await directoryExists(agentsDir)) {\n const agents = await readdir(agentsDir, { withFileTypes: true });\n agentCount = agents.filter(\n (a) => a.isFile() && a.name.endsWith(\".md\"),\n ).length;\n }\n\n return {\n name: manifest.name || DEFAULT_NAME,\n version: manifest.version || DEFAULT_DISPLAY_VERSION,\n skillCount,\n agentCount,\n path: pluginDir,\n };\n}\n\nexport function formatPluginDisplay(info: PluginInfo): string {\n return `Plugin: ${info.name} v${info.version}\n Skills: ${info.skillCount}\n Agents: ${info.agentCount}\n Path: ${info.path}`;\n}\n\n/**\n * Get installation info for either local or plugin mode.\n * Auto-detects the installation mode and returns unified info.\n */\nexport async function getInstallationInfo(): Promise<InstallationInfo | null> {\n const installation = await detectInstallation();\n\n if (!installation) {\n return null;\n }\n\n let skillCount = 0;\n let agentCount = 0;\n let name = DEFAULT_NAME;\n let version = DEFAULT_DISPLAY_VERSION;\n\n // Count skills\n if (await directoryExists(installation.skillsDir)) {\n try {\n const skills = await readdir(installation.skillsDir, {\n withFileTypes: true,\n });\n skillCount = skills.filter((s) => s.isDirectory()).length;\n } catch {\n // Ignore errors\n }\n }\n\n // Count agents\n if (await directoryExists(installation.agentsDir)) {\n try {\n const agents = await readdir(installation.agentsDir, {\n withFileTypes: true,\n });\n agentCount = agents.filter(\n (a) => a.isFile() && a.name.endsWith(\".md\"),\n ).length;\n } catch {\n // Ignore errors\n }\n }\n\n // Get name/version from config or manifest depending on mode\n if (installation.mode === \"local\") {\n const loaded = await loadProjectConfig(installation.projectDir);\n if (loaded?.config) {\n name = loaded.config.name || DEFAULT_NAME;\n // Local mode doesn't have version in the same way\n version = \"local\";\n }\n } else {\n // Plugin mode - read from manifest\n const pluginDir = getCollectivePluginDir(installation.projectDir);\n const manifest = await readPluginManifest(pluginDir);\n if (manifest) {\n name = manifest.name || DEFAULT_NAME;\n version = manifest.version || DEFAULT_DISPLAY_VERSION;\n }\n }\n\n return {\n mode: installation.mode,\n name,\n version,\n skillCount,\n agentCount,\n configPath: installation.configPath,\n agentsDir: installation.agentsDir,\n skillsDir: installation.skillsDir,\n };\n}\n\nexport function formatInstallationDisplay(info: InstallationInfo): string {\n const modeLabel = info.mode === \"local\" ? \"Local\" : \"Plugin\";\n const versionDisplay =\n info.mode === \"local\" ? \"(local mode)\" : `v${info.version}`;\n\n return `Installation: ${info.name} ${versionDisplay}\n Mode: ${modeLabel}\n Skills: ${info.skillCount}\n Agents: ${info.agentCount}\n Config: ${info.configPath}\n Agents: ${info.agentsDir}`;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,185 @@
1
+ # Default agent-skill mappings for Claude Collective CLI
2
+ # Users can override these in .claude/config.yaml via agent_skills
3
+ #
4
+ # This file is bundled with the CLI and provides sensible defaults
5
+ # for which agents should receive which skills based on skill category.
6
+
7
+ # Mapping from skill path patterns to agent lists
8
+ # Pattern "frontend/*" matches skills like frontend/framework/react, frontend/styling/tailwind, etc.
9
+ skill_to_agents:
10
+ "frontend/*":
11
+ - web-developer
12
+ - web-reviewer
13
+ - web-researcher
14
+ - web-pm
15
+ - web-pattern-scout
16
+ - web-pattern-critique
17
+ - agent-summoner
18
+ - skill-summoner
19
+ - documentor
20
+
21
+ "backend/*":
22
+ - api-developer
23
+ - api-reviewer
24
+ - api-researcher
25
+ - web-architecture
26
+ - web-pm
27
+ - web-pattern-scout
28
+ - web-pattern-critique
29
+ - agent-summoner
30
+ - skill-summoner
31
+ - documentor
32
+
33
+ "mobile/*":
34
+ - web-developer
35
+ - web-reviewer
36
+ - web-researcher
37
+ - web-pm
38
+ - agent-summoner
39
+ - skill-summoner
40
+ - documentor
41
+
42
+ "setup/*":
43
+ - web-architecture
44
+ - web-developer
45
+ - api-developer
46
+ - agent-summoner
47
+ - skill-summoner
48
+ - documentor
49
+
50
+ "security/*":
51
+ - web-developer
52
+ - api-developer
53
+ - web-reviewer
54
+ - api-reviewer
55
+ - web-architecture
56
+ - web-pm
57
+ - agent-summoner
58
+ - skill-summoner
59
+ - documentor
60
+
61
+ "reviewing/*":
62
+ - web-reviewer
63
+ - api-reviewer
64
+ - cli-reviewer
65
+ - web-pattern-critique
66
+ - agent-summoner
67
+ - skill-summoner
68
+ - documentor
69
+
70
+ "cli/*":
71
+ - cli-developer
72
+ - cli-reviewer
73
+ - api-developer
74
+ - api-reviewer
75
+ - api-researcher
76
+ - web-architecture
77
+ - web-pm
78
+ - agent-summoner
79
+ - skill-summoner
80
+ - documentor
81
+
82
+ "research/*":
83
+ - web-researcher
84
+ - api-researcher
85
+ - web-pm
86
+ - web-pattern-scout
87
+ - web-pattern-critique
88
+ - documentor
89
+ - agent-summoner
90
+ - skill-summoner
91
+
92
+ "methodology/*":
93
+ - web-developer
94
+ - api-developer
95
+ - web-reviewer
96
+ - api-reviewer
97
+ - web-researcher
98
+ - api-researcher
99
+ - web-tester
100
+ - web-pm
101
+ - web-architecture
102
+ - web-pattern-scout
103
+ - web-pattern-critique
104
+ - agent-summoner
105
+ - skill-summoner
106
+ - documentor
107
+
108
+ # Specific patterns (more specific than wildcards)
109
+ "frontend/testing":
110
+ - web-tester
111
+ - web-developer
112
+ - web-reviewer
113
+
114
+ "backend/testing":
115
+ - web-tester
116
+ - api-developer
117
+ - api-reviewer
118
+
119
+ "frontend/mocks":
120
+ - web-tester
121
+ - web-developer
122
+ - web-reviewer
123
+
124
+ # Skills that should be preloaded (embedded) for each agent
125
+ # Maps agent name to categories/patterns that trigger preloading
126
+ preloaded_skills:
127
+ web-developer:
128
+ - framework
129
+ - styling
130
+ api-developer:
131
+ - api
132
+ - database
133
+ - cli
134
+ cli-developer:
135
+ - cli
136
+ web-reviewer:
137
+ - framework
138
+ - styling
139
+ - reviewing
140
+ api-reviewer:
141
+ - api
142
+ - database
143
+ - reviewing
144
+ cli-reviewer:
145
+ - cli
146
+ - reviewing
147
+ - cli-reviewing
148
+ web-researcher:
149
+ - framework
150
+ - research-methodology
151
+ api-researcher:
152
+ - api
153
+ - research-methodology
154
+ web-tester:
155
+ - testing
156
+ - mocks
157
+ web-architecture:
158
+ - monorepo
159
+ - turborepo
160
+ - cli
161
+ web-pm:
162
+ - research-methodology
163
+ web-pattern-scout:
164
+ - research-methodology
165
+ web-pattern-critique:
166
+ - research-methodology
167
+ - reviewing
168
+ documentor:
169
+ - research-methodology
170
+ agent-summoner: []
171
+ skill-summoner: []
172
+
173
+ # Aliases for subcategory resolution
174
+ # Maps short names to full paths for convenience
175
+ subcategory_aliases:
176
+ framework: frontend/framework
177
+ styling: frontend/styling
178
+ api: backend/api
179
+ database: backend/database
180
+ mocks: frontend/mocks
181
+ testing: testing
182
+ reviewing: reviewing
183
+ research-methodology: research/research-methodology
184
+ monorepo: setup/monorepo
185
+ cli: cli
@@ -0,0 +1,254 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ DEFAULT_VERSION
4
+ } from "../../chunk-A3J6IAXK.js";
5
+ import {
6
+ BaseCommand,
7
+ EXIT_CODES
8
+ } from "../../chunk-SYQ7R2JO.js";
9
+ import {
10
+ setVerbose,
11
+ verbose
12
+ } from "../../chunk-TOPAIL5W.js";
13
+ import {
14
+ ensureDir,
15
+ glob,
16
+ readFile,
17
+ writeFile
18
+ } from "../../chunk-MMDXNZPF.js";
19
+ import {
20
+ init_esm_shims
21
+ } from "../../chunk-DHET7RCE.js";
22
+
23
+ // src/cli-v2/commands/build/marketplace.ts
24
+ init_esm_shims();
25
+ import { Flags } from "@oclif/core";
26
+ import path2 from "path";
27
+
28
+ // src/cli-v2/lib/marketplace-generator.ts
29
+ init_esm_shims();
30
+ import path from "path";
31
+ var PLUGIN_MANIFEST_PATH = ".claude-plugin/plugin.json";
32
+ var MARKETPLACE_SCHEMA_URL = "https://anthropic.com/claude-code/marketplace.schema.json";
33
+ var CATEGORY_PATTERNS = [
34
+ // Primary patterns based on normalized ID category prefix
35
+ { pattern: /^skill-web-/, category: "frontend" },
36
+ { pattern: /^skill-api-/, category: "backend" },
37
+ { pattern: /^skill-cli-/, category: "cli" },
38
+ { pattern: /^skill-meta-/, category: "methodology" },
39
+ { pattern: /^skill-infra-/, category: "infrastructure" },
40
+ { pattern: /^skill-mobile-/, category: "mobile" },
41
+ { pattern: /^skill-security-/, category: "security" },
42
+ // Fallback patterns for non-prefixed skills
43
+ { pattern: /^skill-setup-/, category: "setup" },
44
+ { pattern: /^skill-backend-/, category: "backend" },
45
+ { pattern: /^skill-frontend-/, category: "frontend" }
46
+ ];
47
+ function inferCategory(pluginName) {
48
+ for (const { pattern, category } of CATEGORY_PATTERNS) {
49
+ if (pattern.test(pluginName)) {
50
+ return category;
51
+ }
52
+ }
53
+ return void 0;
54
+ }
55
+ async function readPluginManifest(pluginDir) {
56
+ const manifestPath = path.join(pluginDir, PLUGIN_MANIFEST_PATH);
57
+ try {
58
+ const content = await readFile(manifestPath);
59
+ return JSON.parse(content);
60
+ } catch {
61
+ return null;
62
+ }
63
+ }
64
+ function toMarketplacePlugin(manifest, pluginRoot, pluginDirName) {
65
+ const category = inferCategory(manifest.name);
66
+ const plugin = {
67
+ name: manifest.name,
68
+ source: `./${pluginRoot}/${pluginDirName}`,
69
+ description: manifest.description,
70
+ version: manifest.version,
71
+ author: manifest.author,
72
+ keywords: manifest.keywords
73
+ };
74
+ if (category) {
75
+ plugin.category = category;
76
+ }
77
+ return plugin;
78
+ }
79
+ async function generateMarketplace(pluginsDir, options) {
80
+ verbose(`Scanning plugins directory: ${pluginsDir}`);
81
+ const manifestFiles = await glob(`**/${PLUGIN_MANIFEST_PATH}`, pluginsDir);
82
+ verbose(`Found ${manifestFiles.length} plugin manifests`);
83
+ const plugins = [];
84
+ for (const manifestFile of manifestFiles) {
85
+ const pluginDirName = manifestFile.split("/")[0];
86
+ const pluginDir = path.join(pluginsDir, pluginDirName);
87
+ const manifest = await readPluginManifest(pluginDir);
88
+ if (!manifest) {
89
+ verbose(` [WARN] Could not read manifest: ${manifestFile}`);
90
+ continue;
91
+ }
92
+ const plugin = toMarketplacePlugin(
93
+ manifest,
94
+ options.pluginRoot.replace(/^\.\//, ""),
95
+ pluginDirName
96
+ );
97
+ plugins.push(plugin);
98
+ verbose(` [OK] ${plugin.name}`);
99
+ }
100
+ plugins.sort((a, b) => a.name.localeCompare(b.name));
101
+ const marketplace = {
102
+ $schema: MARKETPLACE_SCHEMA_URL,
103
+ name: options.name,
104
+ version: options.version ?? "1.0.0",
105
+ owner: {
106
+ name: options.ownerName
107
+ },
108
+ metadata: {
109
+ pluginRoot: options.pluginRoot
110
+ },
111
+ plugins
112
+ };
113
+ if (options.description) {
114
+ marketplace.description = options.description;
115
+ }
116
+ if (options.ownerEmail) {
117
+ marketplace.owner.email = options.ownerEmail;
118
+ }
119
+ return marketplace;
120
+ }
121
+ async function writeMarketplace(outputPath, marketplace) {
122
+ await ensureDir(path.dirname(outputPath));
123
+ const content = JSON.stringify(marketplace, null, 2) + "\n";
124
+ await writeFile(outputPath, content);
125
+ }
126
+ function getMarketplaceStats(marketplace) {
127
+ const byCategory = {};
128
+ for (const plugin of marketplace.plugins) {
129
+ const category = plugin.category ?? "uncategorized";
130
+ byCategory[category] = (byCategory[category] ?? 0) + 1;
131
+ }
132
+ return {
133
+ total: marketplace.plugins.length,
134
+ byCategory
135
+ };
136
+ }
137
+
138
+ // src/cli-v2/commands/build/marketplace.ts
139
+ var DEFAULT_PLUGINS_DIR = "dist/plugins";
140
+ var DEFAULT_OUTPUT_FILE = ".claude-plugin/marketplace.json";
141
+ var DEFAULT_NAME = "claude-collective";
142
+ var DEFAULT_DESCRIPTION = "Community skills and stacks for Claude Code";
143
+ var DEFAULT_OWNER_NAME = "Claude Collective";
144
+ var DEFAULT_OWNER_EMAIL = "hello@claude-collective.com";
145
+ var BuildMarketplace = class _BuildMarketplace extends BaseCommand {
146
+ static summary = "Generate marketplace.json from built plugins (requires skills repo)";
147
+ static description = "Generate marketplace.json from built plugins. This command scans the plugins directory and generates a marketplace manifest file.";
148
+ static examples = [
149
+ "<%= config.bin %> <%= command.id %>",
150
+ "<%= config.bin %> <%= command.id %> --plugins-dir dist/stacks",
151
+ "<%= config.bin %> <%= command.id %> --output .claude-plugin/market.json",
152
+ "<%= config.bin %> <%= command.id %> --name my-marketplace --version 2.0.0"
153
+ ];
154
+ static flags = {
155
+ ...BaseCommand.baseFlags,
156
+ "plugins-dir": Flags.string({
157
+ char: "p",
158
+ description: "Plugins directory",
159
+ default: DEFAULT_PLUGINS_DIR
160
+ }),
161
+ output: Flags.string({
162
+ char: "o",
163
+ description: "Output file",
164
+ default: DEFAULT_OUTPUT_FILE
165
+ }),
166
+ name: Flags.string({
167
+ description: "Marketplace name",
168
+ default: DEFAULT_NAME
169
+ }),
170
+ version: Flags.string({
171
+ description: "Marketplace version",
172
+ default: DEFAULT_VERSION
173
+ }),
174
+ description: Flags.string({
175
+ description: "Marketplace description",
176
+ default: DEFAULT_DESCRIPTION
177
+ }),
178
+ "owner-name": Flags.string({
179
+ description: "Owner name",
180
+ default: DEFAULT_OWNER_NAME
181
+ }),
182
+ "owner-email": Flags.string({
183
+ description: "Owner email",
184
+ default: DEFAULT_OWNER_EMAIL
185
+ }),
186
+ verbose: Flags.boolean({
187
+ char: "v",
188
+ description: "Enable verbose logging",
189
+ default: false
190
+ })
191
+ };
192
+ async run() {
193
+ const { flags } = await this.parse(_BuildMarketplace);
194
+ setVerbose(flags.verbose);
195
+ const projectRoot = process.cwd();
196
+ const pluginsDir = path2.resolve(projectRoot, flags["plugins-dir"]);
197
+ const outputPath = path2.resolve(projectRoot, flags.output);
198
+ this.log("");
199
+ this.log("Generating marketplace.json");
200
+ this.log(` Plugins directory: ${pluginsDir}`);
201
+ this.log(` Output file: ${outputPath}`);
202
+ this.log("");
203
+ try {
204
+ this.log("Scanning plugins...");
205
+ const marketplace = await generateMarketplace(pluginsDir, {
206
+ name: flags.name,
207
+ version: flags.version,
208
+ description: flags.description,
209
+ ownerName: flags["owner-name"],
210
+ ownerEmail: flags["owner-email"],
211
+ pluginRoot: `./${flags["plugins-dir"]}`
212
+ });
213
+ const stats = getMarketplaceStats(marketplace);
214
+ this.log(`Found ${stats.total} plugins`);
215
+ this.log("");
216
+ this.log("Category breakdown:");
217
+ const sortedCategories = Object.entries(stats.byCategory).sort(
218
+ ([, a], [, b]) => b - a
219
+ );
220
+ for (const [category, count] of sortedCategories) {
221
+ this.log(` ${category}: ${count}`);
222
+ }
223
+ this.log("Writing marketplace.json...");
224
+ await writeMarketplace(outputPath, marketplace);
225
+ this.log(`Wrote ${outputPath}`);
226
+ this.log("");
227
+ this.log("Sample plugins:");
228
+ const sampleSize = 5;
229
+ for (const plugin of marketplace.plugins.slice(0, sampleSize)) {
230
+ const version = plugin.version ? `v${plugin.version}` : "";
231
+ const category = plugin.category ? `[${plugin.category}]` : "";
232
+ this.log(` ${plugin.name} ${version} ${category}`);
233
+ if (plugin.description) {
234
+ this.log(` ${plugin.description}`);
235
+ }
236
+ }
237
+ if (marketplace.plugins.length > sampleSize) {
238
+ this.log(` ... and ${marketplace.plugins.length - sampleSize} more`);
239
+ }
240
+ this.log("");
241
+ this.logSuccess(`Marketplace generated with ${stats.total} plugins!`);
242
+ this.log("");
243
+ } catch (error) {
244
+ this.log("Generation failed");
245
+ this.error(error instanceof Error ? error.message : String(error), {
246
+ exit: EXIT_CODES.ERROR
247
+ });
248
+ }
249
+ }
250
+ };
251
+ export {
252
+ BuildMarketplace as default
253
+ };
254
+ //# sourceMappingURL=marketplace.js.map