@agents-inc/cli 0.41.1 → 0.42.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 (168) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +1 -1
  3. package/dist/{chunk-ZLHGJSRK.js → chunk-2TWELY5M.js} +3 -3
  4. package/dist/{chunk-4UTPJXUX.js → chunk-33D24DAF.js} +22 -54
  5. package/dist/chunk-33D24DAF.js.map +1 -0
  6. package/dist/{chunk-UKTYDNWJ.js → chunk-44QCEK7E.js} +5 -5
  7. package/dist/chunk-44QCEK7E.js.map +1 -0
  8. package/dist/{chunk-NYP5SB2V.js → chunk-52SI5XJH.js} +2 -2
  9. package/dist/{chunk-GEDWVX6Y.js → chunk-53K3URKF.js} +8 -8
  10. package/dist/chunk-53K3URKF.js.map +1 -0
  11. package/dist/{chunk-2D6LKRHW.js → chunk-ALWLM5MC.js} +2 -2
  12. package/dist/{chunk-AVVYFEMF.js → chunk-AQANPOLS.js} +2 -2
  13. package/dist/{chunk-5TMB53BV.js → chunk-BKW34TKI.js} +7 -4
  14. package/dist/chunk-BKW34TKI.js.map +1 -0
  15. package/dist/{chunk-BFISETQG.js → chunk-EFZN22TO.js} +3 -3
  16. package/dist/{chunk-7FBM7V3E.js → chunk-EPJ2GJNJ.js} +10 -10
  17. package/dist/chunk-EPJ2GJNJ.js.map +1 -0
  18. package/dist/{chunk-SILUTTV7.js → chunk-FDY6SGSA.js} +2 -2
  19. package/dist/{chunk-342YB6TQ.js → chunk-FF4Z7MHY.js} +20 -13
  20. package/dist/chunk-FF4Z7MHY.js.map +1 -0
  21. package/dist/{chunk-ACVJVYMC.js → chunk-GCN7GGWE.js} +15 -27
  22. package/dist/chunk-GCN7GGWE.js.map +1 -0
  23. package/dist/{chunk-FHBICUXB.js → chunk-GIZ6DENW.js} +4 -4
  24. package/dist/{chunk-KC2SIUIA.js → chunk-GVRZY5KI.js} +4 -5
  25. package/dist/chunk-GVRZY5KI.js.map +1 -0
  26. package/dist/{chunk-LJRP4SWY.js → chunk-HMGWGWFT.js} +2 -2
  27. package/dist/{chunk-H6H3COI5.js → chunk-IUYU2TP6.js} +5 -5
  28. package/dist/{chunk-AH7XHAKN.js → chunk-J73KIP6Z.js} +2 -2
  29. package/dist/chunk-J73KIP6Z.js.map +1 -0
  30. package/dist/{chunk-TJAZ7QCF.js → chunk-KA253GGY.js} +4 -4
  31. package/dist/{chunk-4SYXPG7L.js → chunk-MHET2RG2.js} +8 -3
  32. package/dist/chunk-MHET2RG2.js.map +1 -0
  33. package/dist/{chunk-DV4ALU5I.js → chunk-MI4NWOWD.js} +17 -24
  34. package/dist/chunk-MI4NWOWD.js.map +1 -0
  35. package/dist/chunk-MMD26LKJ.js +20 -0
  36. package/dist/chunk-MMD26LKJ.js.map +1 -0
  37. package/dist/{chunk-MNPPGIZQ.js → chunk-ORJPGZVD.js} +5 -5
  38. package/dist/{chunk-R52N7DBG.js → chunk-PEAPABFI.js} +4 -4
  39. package/dist/chunk-PEAPABFI.js.map +1 -0
  40. package/dist/{chunk-BK7TANUV.js → chunk-PP7NDFFE.js} +4 -3
  41. package/dist/{chunk-BK7TANUV.js.map → chunk-PP7NDFFE.js.map} +1 -1
  42. package/dist/{chunk-TTXV55NQ.js → chunk-SYHRJG5G.js} +6 -3
  43. package/dist/chunk-SYHRJG5G.js.map +1 -0
  44. package/dist/{chunk-NZYKDVRL.js → chunk-UVVNWF43.js} +2 -2
  45. package/dist/{chunk-NZYKDVRL.js.map → chunk-UVVNWF43.js.map} +1 -1
  46. package/dist/{chunk-XJXJZ2MJ.js → chunk-UXNHU7Y7.js} +5 -1
  47. package/dist/chunk-UXNHU7Y7.js.map +1 -0
  48. package/dist/{chunk-YLJYAQSG.js → chunk-VHGIQN5O.js} +7 -5
  49. package/dist/chunk-VHGIQN5O.js.map +1 -0
  50. package/dist/{chunk-4LT6RXMY.js → chunk-WMAALRQI.js} +4 -4
  51. package/dist/{chunk-PURJZ72D.js → chunk-X34RGEFX.js} +2 -2
  52. package/dist/{chunk-423MJ6DT.js → chunk-XRA4LHTJ.js} +5 -5
  53. package/dist/chunk-ZHJEZ7AU.js +40 -0
  54. package/dist/chunk-ZHJEZ7AU.js.map +1 -0
  55. package/dist/commands/build/marketplace.js +3 -3
  56. package/dist/commands/build/plugins.js +5 -5
  57. package/dist/commands/build/stack.js +5 -5
  58. package/dist/commands/compile.js +6 -6
  59. package/dist/commands/config/get.js +4 -4
  60. package/dist/commands/config/index.js +5 -5
  61. package/dist/commands/config/path.js +4 -4
  62. package/dist/commands/config/set-project.js +4 -4
  63. package/dist/commands/config/show.js +5 -5
  64. package/dist/commands/config/unset-project.js +4 -4
  65. package/dist/commands/diff.js +4 -4
  66. package/dist/commands/doctor.js +4 -4
  67. package/dist/commands/edit.js +37 -30
  68. package/dist/commands/edit.js.map +1 -1
  69. package/dist/commands/eject.js +33 -13
  70. package/dist/commands/eject.js.map +1 -1
  71. package/dist/commands/import/skill.js +5 -5
  72. package/dist/commands/info.js +5 -5
  73. package/dist/commands/init.js +27 -27
  74. package/dist/commands/list.js +4 -4
  75. package/dist/commands/new/agent.js +5 -5
  76. package/dist/commands/new/skill.js +4 -4
  77. package/dist/commands/outdated.js +4 -4
  78. package/dist/commands/search.js +7 -7
  79. package/dist/commands/uninstall.js +6 -6
  80. package/dist/commands/update.js +6 -6
  81. package/dist/commands/validate.js +5 -5
  82. package/dist/commands/version/bump.js +4 -4
  83. package/dist/commands/version/index.js +4 -4
  84. package/dist/commands/version/set.js +4 -4
  85. package/dist/commands/version/show.js +4 -4
  86. package/dist/components/skill-search/skill-search.js +3 -3
  87. package/dist/components/wizard/category-grid.js +2 -2
  88. package/dist/components/wizard/category-grid.test.js +2 -2
  89. package/dist/components/wizard/checkbox-grid.js +3 -2
  90. package/dist/components/wizard/checkbox-grid.test.js +16 -22
  91. package/dist/components/wizard/checkbox-grid.test.js.map +1 -1
  92. package/dist/components/wizard/domain-selection.js +8 -7
  93. package/dist/components/wizard/help-modal.js +2 -2
  94. package/dist/components/wizard/menu-item.js +25 -4
  95. package/dist/components/wizard/menu-item.js.map +1 -1
  96. package/dist/components/wizard/search-modal.js +2 -2
  97. package/dist/components/wizard/search-modal.test.js +2 -2
  98. package/dist/components/wizard/section-progress.js +2 -2
  99. package/dist/components/wizard/section-progress.test.js +2 -2
  100. package/dist/components/wizard/selection-card.js +10 -0
  101. package/dist/components/wizard/source-grid.js +3 -3
  102. package/dist/components/wizard/source-grid.test.js +3 -3
  103. package/dist/components/wizard/stack-selection.js +8 -8
  104. package/dist/components/wizard/step-agents.js +7 -6
  105. package/dist/components/wizard/step-agents.test.js +8 -8
  106. package/dist/components/wizard/step-agents.test.js.map +1 -1
  107. package/dist/components/wizard/step-build.js +7 -7
  108. package/dist/components/wizard/step-build.test.js +18 -18
  109. package/dist/components/wizard/step-build.test.js.map +1 -1
  110. package/dist/components/wizard/step-confirm.js +3 -2
  111. package/dist/components/wizard/step-confirm.test.js +7 -6
  112. package/dist/components/wizard/step-confirm.test.js.map +1 -1
  113. package/dist/components/wizard/step-refine.js +2 -2
  114. package/dist/components/wizard/step-refine.test.js +2 -2
  115. package/dist/components/wizard/step-settings.js +5 -5
  116. package/dist/components/wizard/step-settings.test.js +8 -8
  117. package/dist/components/wizard/step-sources.js +10 -9
  118. package/dist/components/wizard/step-sources.test.js +14 -12
  119. package/dist/components/wizard/step-sources.test.js.map +1 -1
  120. package/dist/components/wizard/step-stack.js +11 -11
  121. package/dist/components/wizard/step-stack.test.js +15 -16
  122. package/dist/components/wizard/step-stack.test.js.map +1 -1
  123. package/dist/components/wizard/view-title.js +2 -2
  124. package/dist/components/wizard/wizard-layout.js +8 -8
  125. package/dist/components/wizard/wizard-tabs.js +2 -2
  126. package/dist/components/wizard/wizard-tabs.test.js +2 -2
  127. package/dist/components/wizard/wizard.js +24 -24
  128. package/dist/hooks/init.js +3 -3
  129. package/dist/{source-manager-PPABS6BC.js → source-manager-ABK5COKX.js} +4 -4
  130. package/dist/source-manager-ABK5COKX.js.map +1 -0
  131. package/dist/stores/wizard-store.js +5 -5
  132. package/dist/stores/wizard-store.test.js +6 -6
  133. package/package.json +1 -1
  134. package/src/schemas/project-config.schema.json +7 -0
  135. package/dist/chunk-342YB6TQ.js.map +0 -1
  136. package/dist/chunk-4SYXPG7L.js.map +0 -1
  137. package/dist/chunk-4UTPJXUX.js.map +0 -1
  138. package/dist/chunk-5TMB53BV.js.map +0 -1
  139. package/dist/chunk-7FBM7V3E.js.map +0 -1
  140. package/dist/chunk-ACVJVYMC.js.map +0 -1
  141. package/dist/chunk-AH7XHAKN.js.map +0 -1
  142. package/dist/chunk-DV4ALU5I.js.map +0 -1
  143. package/dist/chunk-GEDWVX6Y.js.map +0 -1
  144. package/dist/chunk-KC2SIUIA.js.map +0 -1
  145. package/dist/chunk-KXM7KOPE.js +0 -31
  146. package/dist/chunk-KXM7KOPE.js.map +0 -1
  147. package/dist/chunk-R52N7DBG.js.map +0 -1
  148. package/dist/chunk-TTXV55NQ.js.map +0 -1
  149. package/dist/chunk-UKTYDNWJ.js.map +0 -1
  150. package/dist/chunk-WS6OQIEN.js +0 -32
  151. package/dist/chunk-WS6OQIEN.js.map +0 -1
  152. package/dist/chunk-XJXJZ2MJ.js.map +0 -1
  153. package/dist/chunk-YLJYAQSG.js.map +0 -1
  154. /package/dist/{chunk-ZLHGJSRK.js.map → chunk-2TWELY5M.js.map} +0 -0
  155. /package/dist/{chunk-NYP5SB2V.js.map → chunk-52SI5XJH.js.map} +0 -0
  156. /package/dist/{chunk-2D6LKRHW.js.map → chunk-ALWLM5MC.js.map} +0 -0
  157. /package/dist/{chunk-AVVYFEMF.js.map → chunk-AQANPOLS.js.map} +0 -0
  158. /package/dist/{chunk-BFISETQG.js.map → chunk-EFZN22TO.js.map} +0 -0
  159. /package/dist/{chunk-SILUTTV7.js.map → chunk-FDY6SGSA.js.map} +0 -0
  160. /package/dist/{chunk-FHBICUXB.js.map → chunk-GIZ6DENW.js.map} +0 -0
  161. /package/dist/{chunk-LJRP4SWY.js.map → chunk-HMGWGWFT.js.map} +0 -0
  162. /package/dist/{chunk-H6H3COI5.js.map → chunk-IUYU2TP6.js.map} +0 -0
  163. /package/dist/{chunk-TJAZ7QCF.js.map → chunk-KA253GGY.js.map} +0 -0
  164. /package/dist/{chunk-MNPPGIZQ.js.map → chunk-ORJPGZVD.js.map} +0 -0
  165. /package/dist/{chunk-4LT6RXMY.js.map → chunk-WMAALRQI.js.map} +0 -0
  166. /package/dist/{chunk-PURJZ72D.js.map → chunk-X34RGEFX.js.map} +0 -0
  167. /package/dist/{chunk-423MJ6DT.js.map → chunk-XRA4LHTJ.js.map} +0 -0
  168. /package/dist/{source-manager-PPABS6BC.js.map → components/wizard/selection-card.js.map} +0 -0
@@ -1,44 +1,44 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  StepStack
4
- } from "./chunk-4LT6RXMY.js";
4
+ } from "./chunk-WMAALRQI.js";
5
5
  import {
6
6
  WizardLayout
7
- } from "./chunk-MNPPGIZQ.js";
7
+ } from "./chunk-ORJPGZVD.js";
8
8
  import {
9
9
  StepConfirm
10
- } from "./chunk-5TMB53BV.js";
10
+ } from "./chunk-BKW34TKI.js";
11
11
  import {
12
12
  StepSettings
13
- } from "./chunk-H6H3COI5.js";
13
+ } from "./chunk-IUYU2TP6.js";
14
14
  import {
15
15
  StepSources
16
- } from "./chunk-4UTPJXUX.js";
16
+ } from "./chunk-33D24DAF.js";
17
17
  import {
18
18
  StepAgents
19
- } from "./chunk-YLJYAQSG.js";
19
+ } from "./chunk-VHGIQN5O.js";
20
20
  import {
21
21
  StepBuild
22
- } from "./chunk-7FBM7V3E.js";
22
+ } from "./chunk-EPJ2GJNJ.js";
23
23
  import {
24
24
  getStackName
25
25
  } from "./chunk-YRVTXSXP.js";
26
26
  import {
27
27
  cliTheme
28
- } from "./chunk-AVVYFEMF.js";
28
+ } from "./chunk-AQANPOLS.js";
29
29
  import {
30
30
  useWizardStore
31
- } from "./chunk-423MJ6DT.js";
31
+ } from "./chunk-XRA4LHTJ.js";
32
32
  import {
33
33
  resolveAlias,
34
34
  validateSelection
35
- } from "./chunk-TTXV55NQ.js";
35
+ } from "./chunk-SYHRJG5G.js";
36
36
  import {
37
37
  warn
38
- } from "./chunk-XJXJZ2MJ.js";
38
+ } from "./chunk-UXNHU7Y7.js";
39
39
  import {
40
40
  CLI_COLORS
41
- } from "./chunk-BK7TANUV.js";
41
+ } from "./chunk-PP7NDFFE.js";
42
42
  import {
43
43
  init_esm_shims
44
44
  } from "./chunk-DHET7RCE.js";
@@ -57,6 +57,7 @@ function useWizardInitialization({
57
57
  initialStep,
58
58
  initialInstallMode,
59
59
  initialExpertMode,
60
+ initialDomains,
60
61
  installedSkillIds
61
62
  }) {
62
63
  const initialized = useRef(false);
@@ -74,6 +75,9 @@ function useWizardInitialization({
74
75
  if (initialExpertMode) {
75
76
  useWizardStore.setState({ expertMode: initialExpertMode });
76
77
  }
78
+ if (initialDomains?.length) {
79
+ useWizardStore.setState({ selectedDomains: initialDomains });
80
+ }
77
81
  }
78
82
  }
79
83
 
@@ -138,6 +142,7 @@ var Wizard = ({
138
142
  initialStep,
139
143
  initialInstallMode,
140
144
  initialExpertMode,
145
+ initialDomains,
141
146
  installedSkillIds,
142
147
  projectDir
143
148
  }) => {
@@ -153,6 +158,7 @@ var Wizard = ({
153
158
  initialStep,
154
159
  initialInstallMode,
155
160
  initialExpertMode,
161
+ initialDomains,
156
162
  installedSkillIds
157
163
  });
158
164
  const buildStepProps = useBuildStepProps({ store, matrix, installedSkillIds });
@@ -228,6 +234,7 @@ var Wizard = ({
228
234
  selectedAgents: store.selectedAgents,
229
235
  selectedStackId: store.selectedStackId,
230
236
  domainSelections: store.domainSelections,
237
+ selectedDomains: store.selectedDomains,
231
238
  sourceSelections: store.sourceSelections,
232
239
  expertMode: store.expertMode,
233
240
  installMode: store.installMode,
@@ -308,4 +315,4 @@ var Wizard = ({
308
315
  export {
309
316
  Wizard
310
317
  };
311
- //# sourceMappingURL=chunk-342YB6TQ.js.map
318
+ //# sourceMappingURL=chunk-FF4Z7MHY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/components/wizard/wizard.tsx","../src/cli/components/hooks/use-wizard-initialization.ts","../src/cli/components/hooks/use-build-step-props.ts"],"sourcesContent":["import React, { useCallback } from \"react\";\nimport { Box, Text, useApp, useInput, useStdout } from \"ink\";\nimport { ThemeProvider } from \"@inkjs/ui\";\nimport { useWizardStore, type WizardStep } from \"../../stores/wizard-store.js\";\nimport { CLI_COLORS } from \"../../consts.js\";\nimport { cliTheme } from \"../themes/default.js\";\nimport { WizardLayout } from \"./wizard-layout.js\";\nimport { StepStack } from \"./step-stack.js\";\nimport { StepBuild } from \"./step-build.js\";\nimport { StepConfirm } from \"./step-confirm.js\";\nimport { StepSources } from \"./step-sources.js\";\nimport { StepSettings } from \"./step-settings.js\";\nimport { StepAgents } from \"./step-agents.js\";\nimport { resolveAlias, validateSelection } from \"../../lib/matrix/index.js\";\nimport type {\n AgentName,\n Domain,\n DomainSelections,\n MergedSkillsMatrix,\n SkillId,\n} from \"../../types/index.js\";\nimport { getStackName } from \"./utils.js\";\nimport { warn } from \"../../utils/logger.js\";\nimport { useWizardInitialization } from \"../hooks/use-wizard-initialization.js\";\nimport { useBuildStepProps } from \"../hooks/use-build-step-props.js\";\n\nexport type WizardResultV2 = {\n selectedSkills: SkillId[];\n selectedAgents: AgentName[];\n selectedStackId: string | null;\n domainSelections: DomainSelections;\n selectedDomains: Domain[];\n sourceSelections: Partial<Record<SkillId, string>>;\n expertMode: boolean;\n installMode: \"plugin\" | \"local\";\n cancelled: boolean;\n validation: {\n valid: boolean;\n errors: Array<{ message: string }>;\n warnings: Array<{ message: string }>;\n };\n};\n\ntype WizardProps = {\n matrix: MergedSkillsMatrix;\n onComplete: (result: WizardResultV2) => void;\n onCancel: () => void;\n version?: string;\n marketplaceLabel?: string;\n logo?: string;\n initialStep?: WizardStep;\n initialInstallMode?: \"plugin\" | \"local\";\n initialExpertMode?: boolean;\n initialDomains?: Domain[];\n installedSkillIds?: SkillId[];\n projectDir?: string;\n};\n\nconst MIN_TERMINAL_WIDTH = 80;\nconst MIN_TERMINAL_HEIGHT = 15;\n\nexport const Wizard: React.FC<WizardProps> = ({\n matrix,\n onComplete,\n onCancel,\n version,\n marketplaceLabel,\n logo,\n initialStep,\n initialInstallMode,\n initialExpertMode,\n initialDomains,\n installedSkillIds,\n projectDir,\n}) => {\n const store = useWizardStore();\n const { exit } = useApp();\n const { stdout } = useStdout();\n\n const terminalWidth = stdout.columns || MIN_TERMINAL_WIDTH;\n const terminalHeight = stdout.rows || MIN_TERMINAL_HEIGHT;\n const isNarrowTerminal = terminalWidth < MIN_TERMINAL_WIDTH;\n const isShortTerminal = terminalHeight < MIN_TERMINAL_HEIGHT;\n\n useWizardInitialization({\n matrix,\n initialStep,\n initialInstallMode,\n initialExpertMode,\n initialDomains,\n installedSkillIds,\n });\n\n const buildStepProps = useBuildStepProps({ store, matrix, installedSkillIds });\n\n useInput((input, key) => {\n // ESC is handled by step-settings.tsx's own useKeyboardNavigation hook\n if (store.showSettings) {\n if (input === \"g\" || input === \"G\") {\n store.toggleSettings();\n }\n return;\n }\n\n if (store.showHelp) {\n if (key.escape || input === \"?\") {\n store.toggleHelp();\n }\n return;\n }\n\n if (input === \"?\") {\n store.toggleHelp();\n return;\n }\n\n if (key.escape) {\n // At the initial stack/scratch selection (approach not yet set), ESC cancels the wizard.\n // StackSelection handles its own ESC via the onCancel prop.\n // Other steps that don't have their own escape handler use goBack.\n if (\n store.step !== \"build\" &&\n store.step !== \"confirm\" &&\n store.step !== \"sources\" &&\n store.step !== \"agents\" &&\n store.step !== \"stack\"\n ) {\n store.goBack();\n }\n return;\n }\n\n if ((input === \"a\" || input === \"A\") && store.step === \"build\" && store.selectedStackId) {\n store.setStackAction(\"defaults\");\n store.setStep(\"confirm\");\n return;\n }\n\n if ((input === \"g\" || input === \"G\") && store.step === \"sources\") {\n store.toggleSettings();\n return;\n }\n\n if (input === \"e\" || input === \"E\") {\n store.toggleExpertMode();\n return;\n }\n if (input === \"p\" || input === \"P\") {\n store.toggleInstallMode();\n }\n });\n\n const handleComplete = useCallback(() => {\n let allSkills: SkillId[];\n\n if (store.selectedStackId && store.stackAction === \"defaults\") {\n const stack = matrix.suggestedStacks.find((s) => s.id === store.selectedStackId);\n if (!stack) {\n warn(`Stack not found in matrix: '${store.selectedStackId}'`);\n }\n allSkills = [...(stack?.allSkillIds || [])];\n } else {\n const techNames = store.getAllSelectedTechnologies();\n allSkills = techNames.map((tech) => {\n const resolved = resolveAlias(tech, matrix);\n if (!matrix.skills[resolved]) {\n warn(\n `Technology '${tech}' could not be resolved to a skill ID - it may be missing from skill_aliases`,\n );\n }\n return resolved;\n });\n }\n\n const methodologySkills = store.getDefaultMethodologySkills();\n for (const skill of methodologySkills) {\n if (!allSkills.includes(skill)) {\n allSkills.push(skill);\n }\n }\n\n const validation = validateSelection(allSkills, matrix);\n\n const result: WizardResultV2 = {\n selectedSkills: allSkills,\n selectedAgents: store.selectedAgents,\n selectedStackId: store.selectedStackId,\n domainSelections: store.domainSelections,\n selectedDomains: store.selectedDomains,\n sourceSelections: store.sourceSelections,\n expertMode: store.expertMode,\n installMode: store.installMode,\n cancelled: false,\n validation,\n };\n\n onComplete(result);\n exit();\n }, [store, matrix, onComplete, exit]);\n\n const handleCancel = useCallback(() => {\n onCancel();\n exit();\n }, [onCancel, exit]);\n\n const renderStep = () => {\n switch (store.step) {\n case \"stack\":\n return <StepStack matrix={matrix} onCancel={handleCancel} />;\n\n case \"build\":\n return <StepBuild {...buildStepProps} />;\n\n case \"sources\": {\n if (store.showSettings) {\n return (\n <StepSettings\n projectDir={projectDir || process.cwd()}\n onClose={() => store.toggleSettings()}\n />\n );\n }\n return (\n <StepSources\n matrix={matrix}\n projectDir={projectDir}\n onContinue={() => {\n store.preselectAgentsFromDomains();\n store.setStep(\"agents\");\n }}\n onBack={store.goBack}\n />\n );\n }\n\n case \"agents\":\n return <StepAgents />;\n\n case \"confirm\": {\n const stackName = getStackName(store.selectedStackId, matrix);\n const technologyCount = store.getTechnologyCount();\n return (\n <StepConfirm\n onComplete={handleComplete}\n stackName={stackName}\n selectedDomains={store.selectedDomains}\n domainSelections={store.domainSelections}\n technologyCount={technologyCount}\n skillCount={technologyCount}\n agentCount={store.selectedAgents.length}\n installMode={store.installMode}\n onBack={store.goBack}\n />\n );\n }\n\n default:\n return null;\n }\n };\n\n if (isNarrowTerminal || isShortTerminal) {\n const issue = isNarrowTerminal\n ? `too narrow (${terminalWidth} columns, need ${MIN_TERMINAL_WIDTH})`\n : `too short (${terminalHeight} rows, need ${MIN_TERMINAL_HEIGHT})`;\n\n return (\n <ThemeProvider theme={cliTheme}>\n <Box flexDirection=\"column\" padding={1}>\n <Text color={CLI_COLORS.WARNING}>Terminal {issue}. Please resize your terminal.</Text>\n </Box>\n </ThemeProvider>\n );\n }\n\n return (\n <ThemeProvider theme={cliTheme}>\n <WizardLayout version={version} marketplaceLabel={marketplaceLabel} logo={logo}>\n {renderStep()}\n </WizardLayout>\n </ThemeProvider>\n );\n};\n","import { useRef } from \"react\";\nimport { useWizardStore, type WizardStep } from \"../../stores/wizard-store.js\";\nimport type { Domain, MergedSkillsMatrix, SkillId } from \"../../types/index.js\";\n\ntype UseWizardInitializationOptions = {\n matrix: MergedSkillsMatrix;\n initialStep?: WizardStep;\n initialInstallMode?: \"plugin\" | \"local\";\n initialExpertMode?: boolean;\n initialDomains?: Domain[];\n installedSkillIds?: SkillId[];\n};\n\n/**\n * Runs one-time wizard store initialization before the first render.\n * Populates step, approach, install mode, and skill selections from props.\n */\nexport function useWizardInitialization({\n matrix,\n initialStep,\n initialInstallMode,\n initialExpertMode,\n initialDomains,\n installedSkillIds,\n}: UseWizardInitializationOptions): void {\n const initialized = useRef(false);\n\n if (!initialized.current) {\n initialized.current = true;\n\n if (initialStep) {\n if (installedSkillIds?.length) {\n useWizardStore\n .getState()\n .populateFromSkillIds(installedSkillIds, matrix.skills, matrix.categories);\n }\n useWizardStore.setState({ step: initialStep, approach: \"scratch\" });\n }\n if (initialInstallMode) {\n useWizardStore.setState({ installMode: initialInstallMode });\n }\n if (initialExpertMode) {\n useWizardStore.setState({ expertMode: initialExpertMode });\n }\n // Restore saved domains from config, overriding the ALL_DOMAINS default\n // set by populateFromSkillIds\n if (initialDomains?.length) {\n useWizardStore.setState({ selectedDomains: initialDomains });\n }\n }\n}\n","import { useCallback } from \"react\";\nimport type { Domain, MergedSkillsMatrix, SkillId } from \"../../types/index.js\";\nimport type { WizardState } from \"../../stores/wizard-store.js\";\nimport type { StepBuildProps } from \"../wizard/step-build.js\";\n\ntype UseBuildStepPropsOptions = {\n store: WizardState;\n matrix: MergedSkillsMatrix;\n installedSkillIds?: SkillId[];\n};\n\nexport function useBuildStepProps({\n store,\n matrix,\n installedSkillIds,\n}: UseBuildStepPropsOptions): StepBuildProps {\n const currentDomain = store.getCurrentDomain();\n const defaultDomains: Domain[] = [\"web\"];\n const effectiveDomains =\n store.selectedDomains.length > 0 ? store.selectedDomains : defaultDomains;\n\n const allSelections = store.getAllSelectedTechnologies();\n\n const activeDomain: Domain = currentDomain || effectiveDomains[0] || \"web\";\n\n const onToggle = useCallback(\n (subcategoryId: Parameters<StepBuildProps[\"onToggle\"]>[0], techId: SkillId) => {\n const domain: Domain = store.getCurrentDomain() || \"web\";\n const cat = matrix.categories[subcategoryId];\n store.toggleTechnology(domain, subcategoryId, techId, cat?.exclusive ?? true);\n },\n [store, matrix],\n );\n\n const onContinue = useCallback(() => {\n if (!store.nextDomain()) {\n store.setStep(\"sources\");\n }\n }, [store]);\n\n const onBack = useCallback(() => {\n if (!store.prevDomain()) {\n store.goBack();\n }\n }, [store]);\n\n return {\n matrix,\n domain: activeDomain,\n selectedDomains: effectiveDomains,\n selections: store.domainSelections[activeDomain] || {},\n allSelections,\n showLabels: store.showLabels,\n expertMode: store.expertMode,\n installedSkillIds,\n onToggle,\n onToggleLabels: store.toggleShowLabels,\n onContinue,\n onBack,\n };\n}\n"],"mappings":"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","names":["useCallback","useCallback"]}
@@ -1,16 +1,19 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ ViewTitle
4
+ } from "./chunk-MMD26LKJ.js";
2
5
  import {
3
6
  CLI_COLORS,
4
7
  UI_SYMBOLS
5
- } from "./chunk-BK7TANUV.js";
8
+ } from "./chunk-PP7NDFFE.js";
6
9
  import {
7
10
  init_esm_shims
8
11
  } from "./chunk-DHET7RCE.js";
9
12
 
10
13
  // src/cli/components/wizard/checkbox-grid.tsx
11
14
  init_esm_shims();
12
- import { useState } from "react";
13
15
  import { Box, Text, useInput } from "ink";
16
+ import { useState } from "react";
14
17
  import { jsx, jsxs } from "react/jsx-runtime";
15
18
  var CheckboxGrid = ({
16
19
  title,
@@ -51,14 +54,13 @@ var CheckboxGrid = ({
51
54
  });
52
55
  const continueIndex = items.length;
53
56
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
54
- /* @__PURE__ */ jsx(Text, { bold: true, children: title }),
55
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: subtitle }),
56
- /* @__PURE__ */ jsx(Text, { children: " " }),
57
+ /* @__PURE__ */ jsx(ViewTitle, { children: title }),
58
+ subtitle && /* @__PURE__ */ jsx(Text, { dimColor: true, children: subtitle }),
57
59
  items.map((item, index) => {
58
60
  const isFocused = index === focusedIndex;
59
61
  const isSelected = selectedIds.includes(item.id);
60
62
  const checkbox = isSelected ? "[\u2713]" : "[ ]";
61
- const pointer = isFocused ? UI_SYMBOLS.CURRENT : " ";
63
+ const pointer = isFocused ? UI_SYMBOLS.CHEVRON : UI_SYMBOLS.CHEVRON_SPACER;
62
64
  return /* @__PURE__ */ jsxs(Text, { children: [
63
65
  /* @__PURE__ */ jsx(Text, { color: isFocused ? CLI_COLORS.PRIMARY : void 0, children: pointer }),
64
66
  /* @__PURE__ */ jsxs(Text, { color: isSelected || isFocused ? CLI_COLORS.PRIMARY : void 0, bold: isFocused, children: [
@@ -67,45 +69,31 @@ var CheckboxGrid = ({
67
69
  " ",
68
70
  item.label
69
71
  ] }),
70
- /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
71
- " - ",
72
+ isFocused && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
73
+ " ",
72
74
  item.description
73
75
  ] })
74
76
  ] }, item.id);
75
77
  }),
76
- /* @__PURE__ */ jsxs(
78
+ /* @__PURE__ */ jsx(
77
79
  Text,
78
80
  {
79
81
  color: focusedIndex === continueIndex ? CLI_COLORS.PRIMARY : void 0,
80
- bold: focusedIndex === continueIndex,
81
- children: [
82
- focusedIndex === continueIndex ? UI_SYMBOLS.CURRENT : " ",
83
- " ",
84
- "\u2192",
85
- " ",
86
- continueLabel(selectedIds.length)
87
- ]
82
+ bold: focusedIndex === continueIndex
88
83
  }
89
84
  ),
90
85
  selectedIds.length > 0 ? /* @__PURE__ */ jsxs(Text, { children: [
91
86
  "\n",
92
87
  "Selected: ",
93
- /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.PRIMARY, children: selectedIds.join(", ") })
88
+ /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.WARNING, children: selectedIds.join(", ") })
94
89
  ] }) : emptyMessage ? /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
95
90
  "\n",
96
91
  emptyMessage
97
- ] }) : null,
98
- /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
99
- "\n",
100
- "\u2191",
101
- "/",
102
- "\u2193",
103
- " navigate SPACE toggle ENTER continue ESC back"
104
- ] })
92
+ ] }) : null
105
93
  ] });
106
94
  };
107
95
 
108
96
  export {
109
97
  CheckboxGrid
110
98
  };
111
- //# sourceMappingURL=chunk-ACVJVYMC.js.map
99
+ //# sourceMappingURL=chunk-GCN7GGWE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/components/wizard/checkbox-grid.tsx"],"sourcesContent":["import { Box, Text, useInput } from \"ink\";\nimport React, { useState } from \"react\";\nimport { CLI_COLORS, UI_SYMBOLS } from \"../../consts.js\";\nimport { ViewTitle } from \"./view-title.js\";\n\nexport type CheckboxItem<T extends string = string> = {\n id: T;\n label: string;\n description: string;\n};\n\nexport type CheckboxGridProps<T extends string = string> = {\n title: string;\n subtitle?: string;\n items: CheckboxItem<T>[];\n selectedIds: T[];\n onToggle: (id: T) => void;\n onContinue: () => void;\n onBack: () => void;\n /** Label for the continue button, e.g. \"Continue with 3 domain(s)\" */\n continueLabel?: (count: number) => string;\n /** Message shown when nothing is selected */\n emptyMessage?: string;\n};\n\nexport const CheckboxGrid = <T extends string = string>({\n title,\n subtitle,\n items,\n selectedIds,\n onToggle,\n onContinue,\n onBack,\n continueLabel = (count) => `Continue with ${count} item(s)`,\n emptyMessage = \"Please select at least one item\",\n}: CheckboxGridProps<T>): React.ReactElement => {\n // Items + continue option at the end\n const totalItems = items.length + 1;\n const [focusedIndex, setFocusedIndex] = useState(0);\n\n useInput((input, key) => {\n if (key.escape) {\n onBack();\n return;\n }\n\n if (key.upArrow || input === \"k\") {\n setFocusedIndex((prev) => (prev <= 0 ? totalItems - 1 : prev - 1));\n return;\n }\n\n if (key.downArrow || input === \"j\") {\n setFocusedIndex((prev) => (prev >= totalItems - 1 ? 0 : prev + 1));\n return;\n }\n\n if (key.return) {\n onContinue();\n return;\n }\n\n if (input === \" \") {\n const item = items[focusedIndex];\n if (item) {\n onToggle(item.id);\n }\n }\n });\n\n const continueIndex = items.length;\n\n return (\n <Box flexDirection=\"column\">\n <ViewTitle>{title}</ViewTitle>\n {subtitle && <Text dimColor>{subtitle}</Text>}\n {items.map((item, index) => {\n const isFocused = index === focusedIndex;\n const isSelected = selectedIds.includes(item.id);\n const checkbox = isSelected ? \"[\\u2713]\" : \"[ ]\";\n const pointer = isFocused ? UI_SYMBOLS.CHEVRON : UI_SYMBOLS.CHEVRON_SPACER;\n\n return (\n <Text key={item.id}>\n <Text color={isFocused ? CLI_COLORS.PRIMARY : undefined}>{pointer}</Text>\n <Text color={isSelected || isFocused ? CLI_COLORS.PRIMARY : undefined} bold={isFocused}>\n {\" \"}\n {checkbox} {item.label}\n </Text>\n {isFocused && (\n <Text dimColor>\n {\" \"}\n {item.description}\n </Text>\n )}\n </Text>\n );\n })}\n <Text\n color={focusedIndex === continueIndex ? CLI_COLORS.PRIMARY : undefined}\n bold={focusedIndex === continueIndex}\n >\n {/* {focusedIndex === continueIndex ? UI_SYMBOLS.CURRENT : \" \"} {\"\\u2192\"}{\" \"} */}\n {/* {continueLabel(selectedIds.length)} */}\n </Text>\n {selectedIds.length > 0 ? (\n <Text>\n {\"\\n\"}Selected: <Text color={CLI_COLORS.WARNING}>{selectedIds.join(\", \")}</Text>\n </Text>\n ) : emptyMessage ? (\n <Text dimColor>\n {\"\\n\"}\n {emptyMessage}\n </Text>\n ) : null}\n </Box>\n );\n};\n"],"mappings":";;;;;;;;;;;;;AAAA;AAAA,SAAS,KAAK,MAAM,gBAAgB;AACpC,SAAgB,gBAAgB;AAwE1B,cAWM,YAXN;AAhDC,IAAM,eAAe,CAA4B;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB,CAAC,UAAU,iBAAiB,KAAK;AAAA,EACjD,eAAe;AACjB,MAAgD;AAE9C,QAAM,aAAa,MAAM,SAAS;AAClC,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,CAAC;AAElD,WAAS,CAAC,OAAO,QAAQ;AACvB,QAAI,IAAI,QAAQ;AACd,aAAO;AACP;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,UAAU,KAAK;AAChC,sBAAgB,CAAC,SAAU,QAAQ,IAAI,aAAa,IAAI,OAAO,CAAE;AACjE;AAAA,IACF;AAEA,QAAI,IAAI,aAAa,UAAU,KAAK;AAClC,sBAAgB,CAAC,SAAU,QAAQ,aAAa,IAAI,IAAI,OAAO,CAAE;AACjE;AAAA,IACF;AAEA,QAAI,IAAI,QAAQ;AACd,iBAAW;AACX;AAAA,IACF;AAEA,QAAI,UAAU,KAAK;AACjB,YAAM,OAAO,MAAM,YAAY;AAC/B,UAAI,MAAM;AACR,iBAAS,KAAK,EAAE;AAAA,MAClB;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,gBAAgB,MAAM;AAE5B,SACE,qBAAC,OAAI,eAAc,UACjB;AAAA,wBAAC,aAAW,iBAAM;AAAA,IACjB,YAAY,oBAAC,QAAK,UAAQ,MAAE,oBAAS;AAAA,IACrC,MAAM,IAAI,CAAC,MAAM,UAAU;AAC1B,YAAM,YAAY,UAAU;AAC5B,YAAM,aAAa,YAAY,SAAS,KAAK,EAAE;AAC/C,YAAM,WAAW,aAAa,aAAa;AAC3C,YAAM,UAAU,YAAY,WAAW,UAAU,WAAW;AAE5D,aACE,qBAAC,QACC;AAAA,4BAAC,QAAK,OAAO,YAAY,WAAW,UAAU,QAAY,mBAAQ;AAAA,QAClE,qBAAC,QAAK,OAAO,cAAc,YAAY,WAAW,UAAU,QAAW,MAAM,WAC1E;AAAA;AAAA,UACA;AAAA,UAAS;AAAA,UAAE,KAAK;AAAA,WACnB;AAAA,QACC,aACC,qBAAC,QAAK,UAAQ,MACX;AAAA;AAAA,UACA,KAAK;AAAA,WACR;AAAA,WAVO,KAAK,EAYhB;AAAA,IAEJ,CAAC;AAAA,IACD;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,iBAAiB,gBAAgB,WAAW,UAAU;AAAA,QAC7D,MAAM,iBAAiB;AAAA;AAAA,IAIzB;AAAA,IACC,YAAY,SAAS,IACpB,qBAAC,QACE;AAAA;AAAA,MAAK;AAAA,MAAU,oBAAC,QAAK,OAAO,WAAW,SAAU,sBAAY,KAAK,IAAI,GAAE;AAAA,OAC3E,IACE,eACF,qBAAC,QAAK,UAAQ,MACX;AAAA;AAAA,MACA;AAAA,OACH,IACE;AAAA,KACN;AAEJ;","names":[]}
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  BaseCommand
4
- } from "./chunk-2D6LKRHW.js";
4
+ } from "./chunk-ALWLM5MC.js";
5
5
  import {
6
6
  DEFAULT_SOURCE,
7
7
  SOURCE_ENV_VAR,
@@ -10,10 +10,10 @@ import {
10
10
  loadProjectSourceConfig,
11
11
  resolveAgentsSource,
12
12
  resolveSource
13
- } from "./chunk-TTXV55NQ.js";
13
+ } from "./chunk-SYHRJG5G.js";
14
14
  import {
15
15
  DEFAULT_BRANDING
16
- } from "./chunk-BK7TANUV.js";
16
+ } from "./chunk-PP7NDFFE.js";
17
17
  import {
18
18
  init_esm_shims
19
19
  } from "./chunk-DHET7RCE.js";
@@ -90,4 +90,4 @@ ${DEFAULT_BRANDING.NAME} Configuration
90
90
  export {
91
91
  ConfigShow
92
92
  };
93
- //# sourceMappingURL=chunk-FHBICUXB.js.map
93
+ //# sourceMappingURL=chunk-GIZ6DENW.js.map
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CheckboxGrid
4
- } from "./chunk-ACVJVYMC.js";
4
+ } from "./chunk-GCN7GGWE.js";
5
5
  import {
6
6
  useWizardStore
7
- } from "./chunk-423MJ6DT.js";
7
+ } from "./chunk-XRA4LHTJ.js";
8
8
  import {
9
9
  init_esm_shims
10
10
  } from "./chunk-DHET7RCE.js";
@@ -27,8 +27,7 @@ var DomainSelection = () => {
27
27
  return /* @__PURE__ */ jsx(
28
28
  CheckboxGrid,
29
29
  {
30
- title: "Select domains to configure:",
31
- subtitle: "Select one or more domains, then continue",
30
+ title: "Select domains to configure",
32
31
  items: AVAILABLE_DOMAINS,
33
32
  selectedIds: selectedDomains,
34
33
  onToggle: toggleDomain,
@@ -43,4 +42,4 @@ var DomainSelection = () => {
43
42
  export {
44
43
  DomainSelection
45
44
  };
46
- //# sourceMappingURL=chunk-KC2SIUIA.js.map
45
+ //# sourceMappingURL=chunk-GVRZY5KI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/components/wizard/domain-selection.tsx"],"sourcesContent":["import React from \"react\";\nimport { useWizardStore } from \"../../stores/wizard-store.js\";\nimport type { Domain } from \"../../types/index.js\";\nimport { CheckboxGrid, type CheckboxItem } from \"./checkbox-grid.js\";\n\nconst AVAILABLE_DOMAINS: CheckboxItem<Domain>[] = [\n { id: \"web\", label: \"Web\", description: \"Frontend web applications\" },\n { id: \"api\", label: \"API\", description: \"Backend APIs and services\" },\n { id: \"cli\", label: \"CLI\", description: \"Command-line tools\" },\n { id: \"mobile\", label: \"Mobile\", description: \"Mobile applications\" },\n];\n\nexport const DomainSelection: React.FC = () => {\n const { selectedDomains, toggleDomain, setStep, setApproach, selectStack } = useWizardStore();\n\n const handleBack = () => {\n setApproach(null);\n selectStack(null);\n };\n\n return (\n <CheckboxGrid\n title=\"Select domains to configure\"\n // subtitle=\"Select one or more domains, then continue\"\n items={AVAILABLE_DOMAINS}\n selectedIds={selectedDomains}\n onToggle={toggleDomain}\n onContinue={() => setStep(\"build\")}\n onBack={handleBack}\n continueLabel={(count) => `Continue with ${count} domain(s)`}\n emptyMessage=\"Please select at least one domain\"\n />\n );\n};\n"],"mappings":";;;;;;;;;;;;AAAA;AAqBI;AAhBJ,IAAM,oBAA4C;AAAA,EAChD,EAAE,IAAI,OAAO,OAAO,OAAO,aAAa,4BAA4B;AAAA,EACpE,EAAE,IAAI,OAAO,OAAO,OAAO,aAAa,4BAA4B;AAAA,EACpE,EAAE,IAAI,OAAO,OAAO,OAAO,aAAa,qBAAqB;AAAA,EAC7D,EAAE,IAAI,UAAU,OAAO,UAAU,aAAa,sBAAsB;AACtE;AAEO,IAAM,kBAA4B,MAAM;AAC7C,QAAM,EAAE,iBAAiB,cAAc,SAAS,aAAa,YAAY,IAAI,eAAe;AAE5F,QAAM,aAAa,MAAM;AACvB,gBAAY,IAAI;AAChB,gBAAY,IAAI;AAAA,EAClB;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MAEN,OAAO;AAAA,MACP,aAAa;AAAA,MACb,UAAU;AAAA,MACV,YAAY,MAAM,QAAQ,OAAO;AAAA,MACjC,QAAQ;AAAA,MACR,eAAe,CAAC,UAAU,iBAAiB,KAAK;AAAA,MAChD,cAAa;AAAA;AAAA,EACf;AAEJ;","names":[]}
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  CLI_BIN_NAME,
4
4
  DEFAULT_BRANDING
5
- } from "./chunk-BK7TANUV.js";
5
+ } from "./chunk-PP7NDFFE.js";
6
6
  import {
7
7
  init_esm_shims
8
8
  } from "./chunk-DHET7RCE.js";
@@ -67,4 +67,4 @@ export {
67
67
  INFO_MESSAGES,
68
68
  DRY_RUN_MESSAGES
69
69
  };
70
- //# sourceMappingURL=chunk-LJRP4SWY.js.map
70
+ //# sourceMappingURL=chunk-HMGWGWFT.js.map
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-7SOPVGDV.js";
5
5
  import {
6
6
  ViewTitle
7
- } from "./chunk-KXM7KOPE.js";
7
+ } from "./chunk-MMD26LKJ.js";
8
8
  import {
9
9
  useKeyboardNavigation
10
10
  } from "./chunk-KUV24B5M.js";
@@ -16,14 +16,14 @@ import {
16
16
  addSource,
17
17
  getSourceSummary,
18
18
  removeSource
19
- } from "./chunk-TTXV55NQ.js";
19
+ } from "./chunk-SYHRJG5G.js";
20
20
  import {
21
21
  getErrorMessage,
22
22
  verbose
23
- } from "./chunk-XJXJZ2MJ.js";
23
+ } from "./chunk-UXNHU7Y7.js";
24
24
  import {
25
25
  CLI_COLORS
26
- } from "./chunk-BK7TANUV.js";
26
+ } from "./chunk-PP7NDFFE.js";
27
27
  import {
28
28
  init_esm_shims
29
29
  } from "./chunk-DHET7RCE.js";
@@ -232,4 +232,4 @@ var StepSettings = ({ projectDir, onClose }) => {
232
232
  export {
233
233
  StepSettings
234
234
  };
235
- //# sourceMappingURL=chunk-H6H3COI5.js.map
235
+ //# sourceMappingURL=chunk-IUYU2TP6.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  DEFAULT_BRANDING
4
- } from "./chunk-BK7TANUV.js";
4
+ } from "./chunk-PP7NDFFE.js";
5
5
  import {
6
6
  init_esm_shims
7
7
  } from "./chunk-DHET7RCE.js";
@@ -183,4 +183,4 @@ export {
183
183
  createMockCategory,
184
184
  createMockResolvedStack
185
185
  };
186
- //# sourceMappingURL=chunk-AH7XHAKN.js.map
186
+ //# sourceMappingURL=chunk-J73KIP6Z.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/lib/__tests__/test-fixtures.ts","../src/cli/lib/__tests__/helpers.ts"],"sourcesContent":["import type { CategoryPath, ResolvedSkill, SkillDisplayName, SkillId } from \"../../types\";\nimport { createMockSkill } from \"./helpers\";\n\ninterface SkillFixtureConfig {\n id: SkillId;\n category: CategoryPath;\n displayName?: SkillDisplayName;\n description: string;\n tags: string[];\n}\n\nconst SKILL_FIXTURES: Record<string, SkillFixtureConfig> = {\n react: {\n id: \"web-framework-react\",\n category: \"web-framework\",\n displayName: \"react\",\n description: \"React framework for building user interfaces\",\n tags: [\"react\", \"web\", \"ui\", \"component\"],\n },\n zustand: {\n id: \"web-state-zustand\",\n category: \"web-client-state\",\n displayName: \"zustand\",\n description: \"Bear necessities state management\",\n tags: [\"state\", \"react\", \"zustand\"],\n },\n hono: {\n id: \"api-framework-hono\",\n category: \"api-api\",\n displayName: \"hono\",\n description: \"Lightweight web framework for the edge\",\n tags: [\"api\", \"api\", \"edge\", \"serverless\"],\n },\n vitest: {\n id: \"web-testing-vitest\",\n category: \"web-testing\",\n displayName: \"vitest\",\n description: \"Next generation testing framework\",\n tags: [\"testing\", \"vitest\", \"unit\"],\n },\n vue: {\n id: \"web-framework-vue\",\n category: \"web-framework\",\n displayName: \"vue\",\n description: \"Progressive JavaScript framework\",\n tags: [\"vue\", \"web\", \"reactive\"],\n },\n \"auth-patterns\": {\n id: \"api-security-auth-patterns\",\n category: \"api-security\",\n description: \"Authentication and authorization patterns\",\n tags: [\"auth\", \"security\", \"jwt\", \"oauth\"],\n },\n drizzle: {\n id: \"api-database-drizzle\",\n category: \"api-database\",\n displayName: \"drizzle\",\n description: \"TypeScript ORM for SQL databases\",\n tags: [\"database\", \"orm\", \"sql\"],\n },\n methodology: {\n id: \"meta-methodology-anti-over-engineering\",\n category: \"shared-methodology\",\n description: \"Surgical implementation, not architectural innovation\",\n tags: [\"methodology\", \"foundational\"],\n },\n \"scss-modules\": {\n id: \"web-styling-scss-modules\",\n category: \"web-styling\",\n displayName: \"scss-modules\",\n description: \"CSS Modules with SCSS\",\n tags: [\"css\", \"scss\", \"modules\"],\n },\n} as const;\n\nexport type TestSkillName = keyof typeof SKILL_FIXTURES;\n\nexport function getTestSkill(\n name: TestSkillName,\n overrides?: Partial<ResolvedSkill>,\n): ResolvedSkill {\n const config = SKILL_FIXTURES[name];\n const { id, category, ...defaults } = config;\n return createMockSkill(id, category, { ...defaults, ...overrides });\n}\n","import path from \"path\";\nimport os from \"os\";\nimport { fileURLToPath } from \"url\";\nimport { mkdtemp, rm, mkdir, writeFile, readFile, stat } from \"fs/promises\";\nimport { parse as parseYaml, stringify as stringifyYaml } from \"yaml\";\nimport { run, Errors } from \"@oclif/core\";\nimport ansis from \"ansis\";\nimport { DEFAULT_BRANDING, DEFAULT_PLUGIN_NAME, STANDARD_FILES } from \"../../consts\";\nimport { typedEntries } from \"../../utils/typed-object\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport const CLI_ROOT = path.resolve(__dirname, \"../../../..\");\n\nexport const OUTPUT_STRINGS = {\n CONFIG_HEADER: `${DEFAULT_BRANDING.NAME} Configuration`,\n CONFIG_PATHS_HEADER: \"Configuration File Paths\",\n CONFIG_LAYERS_HEADER: \"Configuration Layers:\",\n CONFIG_PRECEDENCE: \"Precedence: flag > env > project > global > default\",\n SOURCE_LABEL: \"Source:\",\n MARKETPLACE_LABEL: \"Marketplace:\",\n AGENTS_SOURCE_LABEL: \"Agents Source:\",\n GLOBAL_LABEL: \"Global:\",\n PROJECT_LABEL: \"Project:\",\n\n // Setup/Init outputs\n INIT_HEADER: `${DEFAULT_BRANDING.NAME} Setup`,\n INIT_SUCCESS: `${DEFAULT_BRANDING.NAME} initialized successfully!`,\n LOADING_MATRIX: \"Loading skills matrix...\",\n LOADING_SKILLS: \"Loading skills...\",\n LOADING_AGENTS: \"Loading agent partials...\",\n\n // Plugin/installation outputs\n NO_PLUGIN_FOUND: \"No plugin found\",\n NO_INSTALLATION_FOUND: \"No installation found\",\n NO_PLUGIN_INSTALLATION: \"No plugin installation found\",\n NOT_INSTALLED: `${DEFAULT_BRANDING.NAME} is not installed`,\n UNINSTALL_HEADER: `${DEFAULT_BRANDING.NAME} Uninstall`,\n UNINSTALL_COMPLETE: `${DEFAULT_BRANDING.NAME} has been uninstalled`,\n EJECT_HEADER: `${DEFAULT_BRANDING.NAME} Eject`,\n\n // Doctor command outputs\n DOCTOR_HEADER: `${DEFAULT_BRANDING.NAME} Doctor`,\n\n // Error message patterns (lowercase for case-insensitive matching)\n ERROR_MISSING_ARG: \"missing required arg\",\n ERROR_UNEXPECTED_ARG: \"unexpected argument\",\n ERROR_UNKNOWN_FLAG: \"unknown flag\",\n ERROR_PARSE: \"parse\",\n} as const;\n\n/**\n * Run a CLI command and capture its output.\n *\n * Bun's `console.log` does not go through `process.stdout.write`, so\n * `@oclif/test`'s `runCommand` (which only intercepts `process.stdout.write`)\n * returns empty stdout/stderr in bun. This helper intercepts both layers\n * to work correctly in both Node.js and bun environments.\n */\nexport async function runCliCommand(args: string[]) {\n const origStdoutWrite = process.stdout.write;\n const origStderrWrite = process.stderr.write;\n const origLog = console.log;\n const origWarn = console.warn;\n const origError = console.error;\n\n const stdoutBuf: string[] = [];\n const stderrBuf: string[] = [];\n\n // Intercept process.stdout/stderr.write (Node.js path)\n process.stdout.write = function (str: unknown, encoding?: unknown, cb?: unknown): boolean {\n stdoutBuf.push(String(str));\n if (typeof encoding === \"function\") {\n (encoding as () => void)();\n } else if (typeof cb === \"function\") {\n (cb as () => void)();\n }\n return true;\n } as typeof process.stdout.write;\n\n process.stderr.write = function (str: unknown, encoding?: unknown, cb?: unknown): boolean {\n stderrBuf.push(String(str));\n if (typeof encoding === \"function\") {\n (encoding as () => void)();\n } else if (typeof cb === \"function\") {\n (cb as () => void)();\n }\n return true;\n } as typeof process.stderr.write;\n\n // Intercept console methods (bun path — console.log bypasses process.stdout.write)\n console.log = (...logArgs: unknown[]) => {\n stdoutBuf.push(logArgs.map(String).join(\" \") + \"\\n\");\n };\n console.warn = (...warnArgs: unknown[]) => {\n stderrBuf.push(warnArgs.map(String).join(\" \") + \"\\n\");\n };\n console.error = (...errArgs: unknown[]) => {\n stderrBuf.push(errArgs.map(String).join(\" \") + \"\\n\");\n };\n\n let error: (Error & Partial<Errors.CLIError>) | undefined;\n try {\n await run(args, { root: CLI_ROOT });\n } catch (e) {\n if (e instanceof Error) {\n error = Object.assign(e, { message: ansis.strip(e.message) }) as Error &\n Partial<Errors.CLIError>;\n }\n } finally {\n process.stdout.write = origStdoutWrite;\n process.stderr.write = origStderrWrite;\n console.log = origLog;\n console.warn = origWarn;\n console.error = origError;\n }\n\n return {\n stdout: stdoutBuf.map((s) => ansis.strip(s)).join(\"\"),\n stderr: stderrBuf.map((s) => ansis.strip(s)).join(\"\"),\n error,\n };\n}\nimport type {\n AgentConfig,\n AgentDefinition,\n CategoryDefinition,\n CategoryPath,\n CompileContext,\n Domain,\n DomainSelections,\n ExtractedSkillMetadata,\n MergedSkillsMatrix,\n ResolvedSkill,\n ResolvedStack,\n Skill,\n SkillDefinition,\n SkillDisplayName,\n SkillId,\n Stack,\n StackAgentConfig,\n Subcategory,\n} from \"../../types\";\nimport type { WizardResultV2 } from \"../../components/wizard/wizard\";\nimport type { SourceLoadResult } from \"../loading/source-loader\";\nimport type { ResolvedConfig } from \"../configuration/config\";\nimport { useWizardStore } from \"../../stores/wizard-store\";\nimport { resolveAlias, validateSelection } from \"../matrix\";\nimport type { TestProjectConfig } from \"./fixtures/create-test-source\";\nimport { getTestSkill } from \"./test-fixtures\";\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n const s = await stat(filePath);\n return s.isFile();\n } catch {\n return false;\n }\n}\n\nexport async function directoryExists(dirPath: string): Promise<boolean> {\n try {\n const s = await stat(dirPath);\n return s.isDirectory();\n } catch {\n return false;\n }\n}\n\nexport async function readTestYaml<T>(filePath: string): Promise<T> {\n const content = await readFile(filePath, \"utf-8\");\n // Boundary cast: YAML parse returns `unknown`, caller provides expected type\n return parseYaml(content) as T;\n}\n\nexport function buildWizardResult(\n selectedSkills: SkillId[],\n overrides?: Partial<WizardResultV2>,\n): WizardResultV2 {\n return {\n selectedSkills,\n selectedAgents: [],\n selectedStackId: null,\n domainSelections: {} as DomainSelections,\n selectedDomains: [],\n sourceSelections: {},\n expertMode: false,\n installMode: \"local\",\n cancelled: false,\n validation: { valid: true, errors: [], warnings: [] },\n ...overrides,\n };\n}\n\nexport function buildSourceResult(\n matrix: MergedSkillsMatrix,\n sourcePath: string,\n overrides?: Partial<SourceLoadResult>,\n): SourceLoadResult {\n const sourceConfig: ResolvedConfig = {\n source: sourcePath,\n sourceOrigin: \"flag\",\n };\n return {\n matrix,\n sourceConfig,\n sourcePath,\n isLocal: true,\n ...overrides,\n };\n}\n\n/**\n * Lightweight frontmatter parser for test assertions.\n * Returns raw key-value pairs (unlike the production parseFrontmatter which\n * returns typed SkillFrontmatter with Zod validation).\n */\nexport function parseTestFrontmatter(content: string): Record<string, unknown> | null {\n if (!content.startsWith(\"---\")) {\n return null;\n }\n\n const endIndex = content.indexOf(\"---\", 3);\n if (endIndex === -1) {\n return null;\n }\n\n const yamlContent = content.slice(3, endIndex).trim();\n try {\n // Boundary cast: YAML parse returns `unknown`\n return parseYaml(yamlContent) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nexport async function createTempDir(prefix = \"cc-test-\"): Promise<string> {\n return mkdtemp(path.join(os.tmpdir(), prefix));\n}\n\nconst CLEANUP_MAX_RETRIES = 3;\nconst CLEANUP_RETRY_DELAY_MS = 100;\n\nexport async function cleanupTempDir(dirPath: string): Promise<void> {\n for (let attempt = 0; attempt < CLEANUP_MAX_RETRIES; attempt++) {\n try {\n await rm(dirPath, { recursive: true, force: true });\n return;\n } catch (error: unknown) {\n const isRetryable =\n error instanceof Error &&\n \"code\" in error &&\n (error as NodeJS.ErrnoException).code === \"ENOTEMPTY\";\n if (!isRetryable || attempt === CLEANUP_MAX_RETRIES - 1) {\n throw error;\n }\n // Transient ENOTEMPTY on macOS: kernel hasn't released directory entries yet\n await new Promise((resolve) => setTimeout(resolve, CLEANUP_RETRY_DELAY_MS));\n }\n }\n}\n\nexport interface TestDirs {\n tempDir: string;\n projectDir: string;\n pluginDir: string;\n skillsDir: string;\n agentsDir: string;\n}\n\nexport async function createTestDirs(prefix = \"cc-test-\"): Promise<TestDirs> {\n const tempDir = await createTempDir(prefix);\n const projectDir = path.join(tempDir, \"project\");\n const pluginDir = path.join(projectDir, \".claude\", \"plugins\", DEFAULT_PLUGIN_NAME);\n const skillsDir = path.join(pluginDir, \"skills\");\n const agentsDir = path.join(pluginDir, \"agents\");\n\n await mkdir(skillsDir, { recursive: true });\n await mkdir(agentsDir, { recursive: true });\n\n return { tempDir, projectDir, pluginDir, skillsDir, agentsDir };\n}\n\nexport async function cleanupTestDirs(dirs: TestDirs): Promise<void> {\n await cleanupTempDir(dirs.tempDir);\n}\n\nexport function createMockSkill(\n id: SkillId,\n category: CategoryPath,\n overrides?: Partial<ResolvedSkill>,\n): ResolvedSkill {\n return {\n id,\n description: `${id} skill`,\n category,\n categoryExclusive: false,\n tags: [],\n author: \"@test\",\n conflictsWith: [],\n recommends: [],\n requires: [],\n alternatives: [],\n discourages: [],\n compatibleWith: [],\n requiresSetup: [],\n providesSetupFor: [],\n path: `skills/${category}/${id}/`,\n ...overrides,\n };\n}\n\n/**\n * Creates a mock ExtractedSkillMetadata for testing.\n * Used when mocking extractAllSkills() return values.\n */\nexport function createMockExtractedSkill(\n id: SkillId,\n overrides?: Partial<ExtractedSkillMetadata>,\n): ExtractedSkillMetadata {\n // Derive directory path and category from the skill ID convention: \"domain-subcategory-name\"\n const segments = id.split(\"-\");\n const domain = segments[0] ?? \"web\";\n const subcategory = segments[1] ?? \"framework\";\n const name = segments.slice(2).join(\"-\") || \"skill\";\n const directoryPath = `${domain}/${subcategory}/${name}`;\n\n return {\n id,\n directoryPath,\n description: `${id} skill`,\n category: `${domain}-${subcategory}` as CategoryPath,\n categoryExclusive: true,\n author: \"@test\",\n tags: [],\n compatibleWith: [],\n conflictsWith: [],\n requires: [],\n requiresSetup: [],\n providesSetupFor: [],\n path: `skills/${directoryPath}/`,\n ...overrides,\n };\n}\n\nexport function createMockMatrix(\n skills: Record<string, ResolvedSkill>,\n overrides?: Partial<MergedSkillsMatrix>,\n): MergedSkillsMatrix {\n return {\n version: \"1.0.0\",\n categories: {} as Record<Subcategory, import(\"../../types\").CategoryDefinition>,\n skills,\n suggestedStacks: [],\n displayNameToId: {} as Record<SkillDisplayName, SkillId>,\n displayNames: {} as Record<SkillId, SkillDisplayName>,\n generatedAt: new Date().toISOString(),\n ...overrides,\n };\n}\n\nexport function createMockAgent(\n name: string,\n overrides?: Partial<AgentDefinition>,\n): AgentDefinition {\n return {\n title: name,\n description: `${name} agent`,\n tools: [\"Read\", \"Write\", \"Edit\", \"Grep\", \"Glob\", \"Bash\"],\n model: \"opus\",\n permissionMode: \"default\",\n ...overrides,\n };\n}\n\nexport function createMockAgentConfig(\n name: string,\n skills: Skill[] = [],\n overrides?: Partial<AgentConfig>,\n): AgentConfig {\n return {\n name,\n title: `${name} agent`,\n description: `Test ${name}`,\n tools: [\"Read\", \"Write\"],\n skills,\n path: name,\n ...overrides,\n };\n}\n\nexport function createMockSkillEntry(\n id: SkillId,\n preloaded = false,\n overrides?: Partial<Skill>,\n): Skill {\n return {\n id,\n path: `skills/${id}/`,\n description: `${id} skill`,\n usage: `when working with ${id}`,\n preloaded,\n ...overrides,\n };\n}\n\nexport function createCompileContext(overrides?: Partial<CompileContext>): CompileContext {\n return {\n stackId: \"test-stack\",\n verbose: false,\n projectRoot: \"/project\",\n outputDir: `/project/.claude/plugins/${DEFAULT_PLUGIN_NAME}`,\n ...overrides,\n };\n}\n\nexport function createSkillContent(name: string, description = \"A test skill\"): string {\n return `---\nname: ${name}\ndescription: ${description}\ncategory: test\n---\n\n# ${name}\n\nThis is a test skill.\n`;\n}\n\nfunction createMetadataContent(author = \"@test\"): string {\n return `version: 1\nauthor: ${author}\n`;\n}\n\nexport function createAgentYamlContent(name: string, description = `Test ${name} agent`): string {\n return `id: ${name}\ntitle: ${name} Agent\ndescription: ${description}\ntools:\n - Read\n - Write`;\n}\n\nexport async function writeTestSkill(\n skillsDir: string,\n skillName: string,\n options?: {\n author?: string;\n description?: string;\n /** Extra fields to merge into metadata.yaml (e.g., forkedFrom, cliName) */\n extraMetadata?: Record<string, unknown>;\n /** Skip metadata.yaml creation entirely */\n skipMetadata?: boolean;\n /** Custom SKILL.md content (overrides default generated content) */\n skillContent?: string;\n },\n): Promise<string> {\n const skillDir = path.join(skillsDir, skillName);\n await mkdir(skillDir, { recursive: true });\n\n await writeFile(\n path.join(skillDir, STANDARD_FILES.SKILL_MD),\n options?.skillContent ?? createSkillContent(skillName, options?.description),\n );\n\n if (!options?.skipMetadata) {\n if (options?.extraMetadata) {\n const metadata = {\n version: 1,\n author: options?.author ?? \"@test\",\n ...options.extraMetadata,\n };\n await writeFile(path.join(skillDir, STANDARD_FILES.METADATA_YAML), stringifyYaml(metadata));\n } else {\n await writeFile(\n path.join(skillDir, STANDARD_FILES.METADATA_YAML),\n createMetadataContent(options?.author),\n );\n }\n }\n\n return skillDir;\n}\n\n/**\n * Creates a source-level skill directory with SKILL.md and rich metadata.yaml.\n * Use this when testing `extractAllSkills()` and `mergeMatrixWithSkills()`.\n *\n * Unlike `writeTestSkill()` which creates installed skills, this writes skills\n * in the source directory layout (under `src/skills/<domain>/<subcategory>/<name>/`).\n */\nexport async function writeSourceSkill(\n skillsDir: string,\n directoryPath: string,\n config: {\n id: string;\n description: string;\n category: string;\n author?: string;\n tags?: string[];\n categoryExclusive?: boolean;\n content?: string;\n },\n): Promise<string> {\n const skillDir = path.join(skillsDir, directoryPath);\n await mkdir(skillDir, { recursive: true });\n\n await writeFile(\n path.join(skillDir, STANDARD_FILES.SKILL_MD),\n createSkillContent(config.id, config.description),\n );\n\n const metadata: Record<string, unknown> = {\n cliName: config.id,\n category: config.category,\n author: config.author ?? \"@test\",\n version: \"1\",\n };\n if (config.tags) {\n metadata.tags = config.tags;\n }\n if (config.categoryExclusive !== undefined) {\n metadata.categoryExclusive = config.categoryExclusive;\n }\n\n await writeFile(path.join(skillDir, STANDARD_FILES.METADATA_YAML), stringifyYaml(metadata));\n\n return skillDir;\n}\n\nexport async function writeTestAgent(\n agentsDir: string,\n agentName: string,\n options?: { description?: string },\n): Promise<string> {\n const agentDir = path.join(agentsDir, agentName);\n await mkdir(agentDir, { recursive: true });\n\n await writeFile(\n path.join(agentDir, STANDARD_FILES.AGENT_YAML),\n createAgentYamlContent(agentName, options?.description),\n );\n\n return agentDir;\n}\n\nexport function createMockCategory(\n id: Subcategory,\n displayName: string,\n overrides?: Partial<CategoryDefinition>,\n): CategoryDefinition {\n return {\n id,\n displayName,\n description: `${displayName} category`,\n exclusive: true,\n required: false,\n order: 0,\n ...overrides,\n };\n}\n\nexport function createMockResolvedStack(\n id: string,\n name: string,\n overrides?: Partial<ResolvedStack>,\n): ResolvedStack {\n return {\n id,\n name,\n description: `${name} stack`,\n audience: [],\n skills: {},\n allSkillIds: [],\n philosophy: \"\",\n ...overrides,\n };\n}\n\n/**\n * Builds a comprehensive test matrix with 13 skills across 7 categories,\n * 2 suggested stacks, display name mappings, and relationship data\n * (conflicts, recommends). Includes all 6 DEFAULT_PRESELECTED_SKILLS\n * (methodology) so wizard handleComplete can resolve them.\n * @returns A fully populated MergedSkillsMatrix with realistic test data\n */\nexport function createComprehensiveMatrix(\n overrides?: Partial<MergedSkillsMatrix>,\n): MergedSkillsMatrix {\n // Skill categories use domain-prefixed Subcategory IDs (matching production\n // metadata.yaml and the categories map keys, e.g., \"web-framework\", \"api-api\").\n const skills = {\n \"web-framework-react\": getTestSkill(\"react\", { category: \"web-framework\" }),\n \"web-framework-vue\": getTestSkill(\"vue\", {\n category: \"web-framework\",\n conflictsWith: [{ skillId: \"web-framework-react\", reason: \"Choose one framework\" }],\n }),\n \"web-state-zustand\": getTestSkill(\"zustand\", {\n category: \"web-client-state\",\n recommends: [{ skillId: \"web-framework-react\", reason: \"Works great with React\" }],\n }),\n \"web-styling-scss-modules\": getTestSkill(\"scss-modules\", { category: \"web-styling\" }),\n \"api-framework-hono\": getTestSkill(\"hono\", { category: \"api-api\" }),\n \"api-database-drizzle\": getTestSkill(\"drizzle\", { category: \"api-database\" }),\n \"web-testing-vitest\": getTestSkill(\"vitest\", { category: \"web-testing\" }),\n // Methodology skills (DEFAULT_PRESELECTED_SKILLS) — auto-injected by wizard\n \"meta-methodology-investigation-requirements\": createMockSkill(\n \"meta-methodology-investigation-requirements\",\n \"shared-methodology\",\n { description: \"Never speculate - read actual code first\", categoryExclusive: false },\n ),\n \"meta-methodology-anti-over-engineering\": createMockSkill(\n \"meta-methodology-anti-over-engineering\",\n \"shared-methodology\",\n {\n description: \"Surgical implementation, not architectural innovation\",\n categoryExclusive: false,\n },\n ),\n \"meta-methodology-success-criteria\": createMockSkill(\n \"meta-methodology-success-criteria\",\n \"shared-methodology\",\n { description: \"Explicit, measurable criteria defining done\", categoryExclusive: false },\n ),\n \"meta-methodology-write-verification\": createMockSkill(\n \"meta-methodology-write-verification\",\n \"shared-methodology\",\n { description: \"Verify work was actually saved\", categoryExclusive: false },\n ),\n \"meta-methodology-improvement-protocol\": createMockSkill(\n \"meta-methodology-improvement-protocol\",\n \"shared-methodology\",\n { description: \"Evidence-based self-improvement\", categoryExclusive: false },\n ),\n \"meta-methodology-context-management\": createMockSkill(\n \"meta-methodology-context-management\",\n \"shared-methodology\",\n { description: \"Maintain project continuity across sessions\", categoryExclusive: false },\n ),\n };\n\n const categories = {\n \"web-framework\": createMockCategory(\"web-framework\" as Subcategory, \"Framework\", {\n domain: \"web\" as Domain,\n exclusive: true,\n required: true,\n }),\n \"web-client-state\": createMockCategory(\"web-client-state\" as Subcategory, \"State\", {\n domain: \"web\" as Domain,\n order: 1,\n }),\n \"web-styling\": createMockCategory(\"web-styling\" as Subcategory, \"Styling\", {\n domain: \"web\" as Domain,\n order: 2,\n }),\n \"api-api\": createMockCategory(\"api-api\" as Subcategory, \"Backend Framework\", {\n domain: \"api\" as Domain,\n exclusive: true,\n required: true,\n }),\n \"api-database\": createMockCategory(\"api-database\" as Subcategory, \"Database\", {\n domain: \"api\" as Domain,\n order: 1,\n }),\n \"web-testing\": createMockCategory(\"web-testing\" as Subcategory, \"Testing\", {\n domain: \"shared\" as Domain,\n exclusive: false,\n order: 10,\n }),\n \"shared-methodology\": createMockCategory(\"shared-methodology\" as Subcategory, \"Methodology\", {\n domain: \"shared\" as Domain,\n exclusive: false,\n required: false,\n order: 11,\n }),\n } as Record<Subcategory, CategoryDefinition>;\n\n const suggestedStacks: ResolvedStack[] = [\n createMockResolvedStack(\"nextjs-fullstack\", \"Next.js Fullstack\", {\n description: \"Complete Next.js stack with React and Hono\",\n audience: [\"startups\", \"enterprise\"],\n skills: {\n \"web-developer\": {\n \"web-framework\": \"web-framework-react\",\n \"web-client-state\": \"web-state-zustand\",\n \"web-styling\": \"web-styling-scss-modules\",\n },\n \"api-developer\": {\n \"api-api\": \"api-framework-hono\",\n \"api-database\": \"api-database-drizzle\",\n },\n } as ResolvedStack[\"skills\"],\n allSkillIds: [\n \"web-framework-react\",\n \"web-state-zustand\",\n \"web-styling-scss-modules\",\n \"api-framework-hono\",\n \"api-database-drizzle\",\n ],\n philosophy: \"Modern, type-safe fullstack development\",\n }),\n createMockResolvedStack(\"vue-stack\", \"Vue Stack\", {\n description: \"Vue.js frontend stack\",\n audience: [\"startups\"],\n skills: {\n \"web-developer\": {\n \"web-framework\": \"web-framework-vue\",\n },\n } as ResolvedStack[\"skills\"],\n allSkillIds: [\"web-framework-vue\"],\n philosophy: \"Progressive framework approach\",\n }),\n ];\n\n const displayNameToId = {\n react: \"web-framework-react\",\n vue: \"web-framework-vue\",\n zustand: \"web-state-zustand\",\n \"scss-modules\": \"web-styling-scss-modules\",\n hono: \"api-framework-hono\",\n drizzle: \"api-database-drizzle\",\n vitest: \"web-testing-vitest\",\n \"investigation-requirements\": \"meta-methodology-investigation-requirements\",\n \"anti-over-engineering\": \"meta-methodology-anti-over-engineering\",\n \"success-criteria\": \"meta-methodology-success-criteria\",\n \"write-verification\": \"meta-methodology-write-verification\",\n \"improvement-protocol\": \"meta-methodology-improvement-protocol\",\n \"context-management\": \"meta-methodology-context-management\",\n // Double cast needed: object literal's string keys are not assignable to branded\n // SkillDisplayName/SkillId types without going through `unknown` first (boundary cast)\n } as unknown as Record<SkillDisplayName, SkillId>;\n\n const displayNames = {} as Record<SkillId, SkillDisplayName>;\n for (const [displayName, fullId] of typedEntries(displayNameToId)) {\n (displayNames as Record<string, string>)[fullId] = displayName;\n }\n\n return createMockMatrix(skills, {\n categories,\n suggestedStacks,\n displayNameToId,\n displayNames,\n ...overrides,\n });\n}\n\n/**\n * Builds a lightweight test matrix with 4 skills, 4 categories, and 2 stacks.\n * Use instead of createComprehensiveMatrix when relationship data is not needed.\n * @returns A minimal MergedSkillsMatrix for basic integration tests\n */\nexport function createBasicMatrix(overrides?: Partial<MergedSkillsMatrix>): MergedSkillsMatrix {\n // Domain-prefixed Subcategory IDs — see createComprehensiveMatrix comment\n const skills = {\n \"web-framework-react\": getTestSkill(\"react\", { category: \"web-framework\" }),\n \"web-state-zustand\": getTestSkill(\"zustand\", { category: \"web-client-state\" }),\n \"api-framework-hono\": getTestSkill(\"hono\", { category: \"api-api\" }),\n \"web-testing-vitest\": getTestSkill(\"vitest\", { category: \"web-testing\" }),\n };\n\n const suggestedStacks: ResolvedStack[] = [\n createMockResolvedStack(\"react-fullstack\", \"React Fullstack\", {\n allSkillIds: [\"web-framework-react\", \"web-state-zustand\", \"api-framework-hono\"],\n }),\n createMockResolvedStack(\"testing-stack\", \"Testing Stack\", {\n allSkillIds: [\"web-testing-vitest\"],\n }),\n ];\n\n return createMockMatrix(skills, {\n suggestedStacks,\n categories: {\n \"web-framework\": createMockCategory(\"web-framework\" as Subcategory, \"Framework\", {\n domain: \"web\" as Domain,\n exclusive: true,\n required: true,\n }),\n \"web-client-state\": createMockCategory(\"web-client-state\" as Subcategory, \"State\", {\n domain: \"web\" as Domain,\n order: 1,\n }),\n \"api-api\": createMockCategory(\"api-api\" as Subcategory, \"Backend Framework\", {\n domain: \"api\" as Domain,\n exclusive: true,\n required: true,\n }),\n \"web-testing\": createMockCategory(\"web-testing\" as Subcategory, \"Testing Framework\", {\n domain: \"shared\" as Domain,\n exclusive: false,\n }),\n } as Record<Subcategory, CategoryDefinition>,\n ...overrides,\n });\n}\n\n/**\n * Replicates `handleComplete` from wizard.tsx for the \"customize\" path.\n *\n * Given the wizard store state (after simulated user selections), this\n * builds the same WizardResultV2 that the real wizard produces:\n * 1. Collects all selected technologies from domainSelections\n * 2. Resolves aliases to canonical skill IDs\n * 3. Adds methodology skills (DEFAULT_PRESELECTED_SKILLS)\n * 4. Runs validation\n */\nexport function buildWizardResultFromStore(\n matrix: MergedSkillsMatrix,\n overrides?: Partial<WizardResultV2>,\n): WizardResultV2 {\n const store = useWizardStore.getState();\n\n let allSkills: SkillId[];\n\n if (store.selectedStackId && store.stackAction === \"defaults\") {\n const stack = matrix.suggestedStacks.find((s) => s.id === store.selectedStackId);\n allSkills = [...(stack?.allSkillIds || [])];\n } else {\n const techNames = store.getAllSelectedTechnologies();\n allSkills = techNames.map((tech) => resolveAlias(tech, matrix));\n }\n\n const methodologySkills = store.getDefaultMethodologySkills();\n for (const skill of methodologySkills) {\n if (!allSkills.includes(skill)) {\n allSkills.push(skill);\n }\n }\n\n const validation = validateSelection(allSkills, matrix);\n\n return {\n selectedSkills: allSkills,\n selectedAgents: store.selectedAgents,\n selectedStackId: store.selectedStackId,\n domainSelections: store.domainSelections,\n selectedDomains: store.selectedDomains,\n sourceSelections: store.sourceSelections,\n expertMode: store.expertMode,\n installMode: store.installMode,\n cancelled: false,\n validation,\n ...overrides,\n };\n}\n\n/**\n * Simulates a user selecting specific skills via the wizard store.\n *\n * Sets up domainSelections as if the user toggled each skill in the build step,\n * using the matrix to look up the correct domain and subcategory per skill.\n */\nexport function simulateSkillSelections(\n skillIds: SkillId[],\n matrix: MergedSkillsMatrix,\n selectedDomains: string[],\n): void {\n const domainSelections: DomainSelections = {};\n\n for (const skillId of skillIds) {\n const skill = matrix.skills[skillId];\n if (!skill) continue;\n\n // Boundary cast: skill.category is a Subcategory at runtime\n const subcategory = skill.category as Subcategory;\n const categoryDef = matrix.categories[subcategory];\n const domain = categoryDef?.domain;\n if (!domain) continue;\n\n if (!domainSelections[domain]) {\n domainSelections[domain] = {};\n }\n if (!domainSelections[domain][subcategory]) {\n domainSelections[domain][subcategory] = [];\n }\n if (!domainSelections[domain][subcategory].includes(skillId)) {\n domainSelections[domain][subcategory].push(skillId);\n }\n }\n\n useWizardStore.setState({\n domainSelections,\n selectedDomains: selectedDomains as Domain[],\n approach: \"scratch\",\n step: \"confirm\",\n });\n}\n\n/**\n * Extracts skill IDs from a stack assignment value, which may be:\n * - A bare string (e.g., \"web-framework-react\")\n * - An object with .id (e.g., { id: \"web-framework-react\", preloaded: true })\n * - An array of strings or objects\n */\nexport function extractSkillIdsFromAssignment(assignment: unknown): string[] {\n if (typeof assignment === \"string\") {\n return [assignment];\n }\n if (Array.isArray(assignment)) {\n return assignment.flatMap((item) => extractSkillIdsFromAssignment(item));\n }\n if (typeof assignment === \"object\" && assignment !== null && \"id\" in assignment) {\n return [String((assignment as { id: string }).id)];\n }\n return [];\n}\n\nexport function buildTestProjectConfig(\n agents: string[],\n skills: Array<string | { id: string }>,\n overrides?: Partial<TestProjectConfig>,\n): TestProjectConfig {\n return {\n name: \"test-project\",\n description: \"Test project\",\n agents,\n skills,\n ...overrides,\n };\n}\n\nexport function createMockSkillDefinition(\n id: SkillId,\n overrides?: Partial<SkillDefinition>,\n): SkillDefinition {\n return {\n id,\n path: `skills/${id}/`,\n description: `${id} skill`,\n ...overrides,\n };\n}\n\nexport function createMockStack(\n id: string,\n config: {\n name: string;\n description?: string;\n agents: Record<string, StackAgentConfig>;\n philosophy?: string;\n },\n): Stack {\n return {\n id,\n name: config.name,\n description: config.description ?? \"\",\n // Boundary cast: test callers may pass arbitrary agent names (e.g., \"nonexistent-agent\")\n agents: config.agents as Stack[\"agents\"],\n philosophy: config.philosophy,\n };\n}\n\nexport { getTestSkill } from \"./test-fixtures\";\nexport type { TestSkillName } from \"./test-fixtures\";\n"],"mappings":"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","names":[]}
@@ -18,7 +18,7 @@ import {
18
18
  resolveAgents,
19
19
  writeContentHash,
20
20
  writePluginManifest
21
- } from "./chunk-TTXV55NQ.js";
21
+ } from "./chunk-SYHRJG5G.js";
22
22
  import {
23
23
  typedEntries,
24
24
  typedKeys
@@ -36,12 +36,12 @@ import {
36
36
  verbose,
37
37
  warn,
38
38
  writeFile
39
- } from "./chunk-XJXJZ2MJ.js";
39
+ } from "./chunk-UXNHU7Y7.js";
40
40
  import {
41
41
  CLAUDE_DIR,
42
42
  DIRS,
43
43
  PROJECT_ROOT
44
- } from "./chunk-BK7TANUV.js";
44
+ } from "./chunk-PP7NDFFE.js";
45
45
  import {
46
46
  init_esm_shims
47
47
  } from "./chunk-DHET7RCE.js";
@@ -315,4 +315,4 @@ export {
315
315
  compileAllAgentPlugins,
316
316
  printAgentCompilationSummary
317
317
  };
318
- //# sourceMappingURL=chunk-TJAZ7QCF.js.map
318
+ //# sourceMappingURL=chunk-KA253GGY.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CLI_COLORS
4
- } from "./chunk-BK7TANUV.js";
4
+ } from "./chunk-PP7NDFFE.js";
5
5
  import {
6
6
  init_esm_shims
7
7
  } from "./chunk-DHET7RCE.js";
@@ -33,7 +33,11 @@ var Tab = ({ step, state }) => {
33
33
  const label = `[${step.number}] ${step.label}`;
34
34
  switch (state) {
35
35
  case "current":
36
- return /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.PRIMARY, children: label });
36
+ return /* @__PURE__ */ jsxs(Text, { color: CLI_COLORS.UNFOCUSED, backgroundColor: CLI_COLORS.WARNING, bold: true, children: [
37
+ " ",
38
+ label,
39
+ " "
40
+ ] });
37
41
  case "completed":
38
42
  return /* @__PURE__ */ jsx(Text, { children: label });
39
43
  case "skipped":
@@ -60,6 +64,7 @@ var WizardTabs = ({
60
64
  borderColor: "blackBright",
61
65
  borderStyle: "single",
62
66
  paddingRight: 1,
67
+ alignItems: "center",
63
68
  children: [
64
69
  steps.map((step) => {
65
70
  const state = getStepState(step.id, currentStep, completedSteps, skippedSteps);
@@ -76,4 +81,4 @@ export {
76
81
  formatStepLabel,
77
82
  WizardTabs
78
83
  };
79
- //# sourceMappingURL=chunk-4SYXPG7L.js.map
84
+ //# sourceMappingURL=chunk-MHET2RG2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/components/wizard/wizard-tabs.tsx"],"sourcesContent":["import { Box, Text } from \"ink\";\nimport React from \"react\";\nimport { CLI_COLORS } from \"../../consts.js\";\nimport type { WizardStep } from \"../../stores/wizard-store.js\";\n\ntype WizardTabStep = {\n id: WizardStep;\n label: string;\n number: number;\n};\n\nexport type WizardTabsProps = {\n steps: WizardTabStep[];\n currentStep: WizardStep;\n completedSteps: WizardStep[];\n skippedSteps?: WizardStep[];\n version?: string;\n};\n\nexport const WIZARD_STEPS: WizardTabStep[] = [\n { id: \"stack\", label: \"Stack\", number: 1 },\n { id: \"build\", label: \"Build\", number: 2 },\n { id: \"sources\", label: \"Sources\", number: 3 },\n { id: \"agents\", label: \"Agents\", number: 4 },\n { id: \"confirm\", label: \"Confirm\", number: 5 },\n];\n\ntype FormattedStepLabel = {\n /** The step number indicator, e.g. \"[1]\" */\n prefix: string;\n /** The step label text, e.g. \"Stack\" */\n label: string;\n /** The complete formatted string, e.g. \"[1] Stack\" */\n full: string;\n};\n\n/** Format a wizard step as its tab label parts and full string, e.g. \"[1] Stack\" */\nexport function formatStepLabel(stepId: WizardStep): FormattedStepLabel {\n const step = WIZARD_STEPS.find((s) => s.id === stepId);\n if (!step) return { prefix: \"\", label: stepId, full: stepId };\n const prefix = `[${step.number}]`;\n return { prefix, label: step.label, full: `${prefix} ${step.label}` };\n}\n\ntype StepState = \"completed\" | \"current\" | \"pending\" | \"skipped\";\n\nconst getStepState = (\n stepId: WizardStep,\n currentStep: WizardStep,\n completedSteps: WizardStep[],\n skippedSteps: WizardStep[],\n): StepState => {\n if (completedSteps.includes(stepId)) return \"completed\";\n if (stepId === currentStep) return \"current\";\n if (skippedSteps.includes(stepId)) return \"skipped\";\n return \"pending\";\n};\n\ntype TabProps = {\n step: WizardTabStep;\n state: StepState;\n};\n\nconst Tab: React.FC<TabProps> = ({ step, state }) => {\n const label = `[${step.number}] ${step.label}`;\n\n switch (state) {\n case \"current\":\n return (\n <Text color={CLI_COLORS.UNFOCUSED} backgroundColor={CLI_COLORS.WARNING} bold>\n {\" \"}\n {label}{\" \"}\n </Text>\n );\n case \"completed\":\n return <Text>{label}</Text>;\n case \"skipped\":\n return <Text dimColor>{label}</Text>;\n case \"pending\":\n default:\n return <Text color={CLI_COLORS.UNFOCUSED}>{label}</Text>;\n }\n};\n\nexport const WizardTabs: React.FC<WizardTabsProps> = ({\n steps,\n currentStep,\n completedSteps,\n skippedSteps = [],\n version,\n}) => {\n return (\n <Box\n flexDirection=\"row\"\n columnGap={2}\n borderRight={false}\n borderLeft={false}\n borderColor=\"blackBright\"\n borderStyle=\"single\"\n paddingRight={1}\n alignItems=\"center\"\n >\n {steps.map((step) => {\n const state = getStepState(step.id, currentStep, completedSteps, skippedSteps);\n\n return <Tab key={step.id} step={step} state={state} />;\n })}\n <Box flexGrow={1} justifyContent=\"flex-end\">\n <Text dimColor>{`v${version}`}</Text>\n </Box>\n </Box>\n );\n};\n"],"mappings":";;;;;;;;;AAAA;AAAA,SAAS,KAAK,YAAY;AAqElB,SAMK,KANL;AAlDD,IAAM,eAAgC;AAAA,EAC3C,EAAE,IAAI,SAAS,OAAO,SAAS,QAAQ,EAAE;AAAA,EACzC,EAAE,IAAI,SAAS,OAAO,SAAS,QAAQ,EAAE;AAAA,EACzC,EAAE,IAAI,WAAW,OAAO,WAAW,QAAQ,EAAE;AAAA,EAC7C,EAAE,IAAI,UAAU,OAAO,UAAU,QAAQ,EAAE;AAAA,EAC3C,EAAE,IAAI,WAAW,OAAO,WAAW,QAAQ,EAAE;AAC/C;AAYO,SAAS,gBAAgB,QAAwC;AACtE,QAAM,OAAO,aAAa,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM;AACrD,MAAI,CAAC,KAAM,QAAO,EAAE,QAAQ,IAAI,OAAO,QAAQ,MAAM,OAAO;AAC5D,QAAM,SAAS,IAAI,KAAK,MAAM;AAC9B,SAAO,EAAE,QAAQ,OAAO,KAAK,OAAO,MAAM,GAAG,MAAM,IAAI,KAAK,KAAK,GAAG;AACtE;AAIA,IAAM,eAAe,CACnB,QACA,aACA,gBACA,iBACc;AACd,MAAI,eAAe,SAAS,MAAM,EAAG,QAAO;AAC5C,MAAI,WAAW,YAAa,QAAO;AACnC,MAAI,aAAa,SAAS,MAAM,EAAG,QAAO;AAC1C,SAAO;AACT;AAOA,IAAM,MAA0B,CAAC,EAAE,MAAM,MAAM,MAAM;AACnD,QAAM,QAAQ,IAAI,KAAK,MAAM,KAAK,KAAK,KAAK;AAE5C,UAAQ,OAAO;AAAA,IACb,KAAK;AACH,aACE,qBAAC,QAAK,OAAO,WAAW,WAAW,iBAAiB,WAAW,SAAS,MAAI,MACzE;AAAA;AAAA,QACA;AAAA,QAAO;AAAA,SACV;AAAA,IAEJ,KAAK;AACH,aAAO,oBAAC,QAAM,iBAAM;AAAA,IACtB,KAAK;AACH,aAAO,oBAAC,QAAK,UAAQ,MAAE,iBAAM;AAAA,IAC/B,KAAK;AAAA,IACL;AACE,aAAO,oBAAC,QAAK,OAAO,WAAW,WAAY,iBAAM;AAAA,EACrD;AACF;AAEO,IAAM,aAAwC,CAAC;AAAA,EACpD;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe,CAAC;AAAA,EAChB;AACF,MAAM;AACJ,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAc;AAAA,MACd,WAAW;AAAA,MACX,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,aAAY;AAAA,MACZ,aAAY;AAAA,MACZ,cAAc;AAAA,MACd,YAAW;AAAA,MAEV;AAAA,cAAM,IAAI,CAAC,SAAS;AACnB,gBAAM,QAAQ,aAAa,KAAK,IAAI,aAAa,gBAAgB,YAAY;AAE7E,iBAAO,oBAAC,OAAkB,MAAY,SAArB,KAAK,EAA8B;AAAA,QACtD,CAAC;AAAA,QACD,oBAAC,OAAI,UAAU,GAAG,gBAAe,YAC/B,8BAAC,QAAK,UAAQ,MAAE,cAAI,OAAO,IAAG,GAChC;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -1,33 +1,32 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ SelectionCard
4
+ } from "./chunk-ZHJEZ7AU.js";
2
5
  import {
3
6
  getDomainsFromStack
4
7
  } from "./chunk-YRVTXSXP.js";
5
8
  import {
6
9
  ViewTitle
7
- } from "./chunk-KXM7KOPE.js";
8
- import {
9
- MenuItem
10
- } from "./chunk-WS6OQIEN.js";
10
+ } from "./chunk-MMD26LKJ.js";
11
11
  import {
12
12
  useWizardStore
13
- } from "./chunk-423MJ6DT.js";
13
+ } from "./chunk-XRA4LHTJ.js";
14
14
  import {
15
15
  DEFAULT_SCRATCH_DOMAINS
16
- } from "./chunk-BK7TANUV.js";
16
+ } from "./chunk-PP7NDFFE.js";
17
17
  import {
18
18
  init_esm_shims
19
19
  } from "./chunk-DHET7RCE.js";
20
20
 
21
21
  // src/cli/components/wizard/stack-selection.tsx
22
22
  init_esm_shims();
23
+ import { Box, useInput } from "ink";
23
24
  import { useState } from "react";
24
- import { Box, Text, useInput } from "ink";
25
25
  import { jsx, jsxs } from "react/jsx-runtime";
26
26
  var INITIAL_FOCUSED_INDEX = 0;
27
27
  var SCRATCH_LABEL = "Start from scratch";
28
28
  var SCRATCH_DESCRIPTION = "Select domains and skills manually";
29
29
  var EXTRA_ITEMS_COUNT = 1;
30
- var DIVIDER_WIDTH = 30;
31
30
  var StackSelection = ({ matrix, onCancel }) => {
32
31
  const { selectStack, setApproach, setStackAction, populateFromSkillIds, toggleDomain } = useWizardStore();
33
32
  const [focusedIndex, setFocusedIndex] = useState(INITIAL_FOCUSED_INDEX);
@@ -73,37 +72,31 @@ var StackSelection = ({ matrix, onCancel }) => {
73
72
  }
74
73
  });
75
74
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
76
- /* @__PURE__ */ jsx(ViewTitle, { children: "[1] Choose a stack" }),
77
- /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
75
+ /* @__PURE__ */ jsx(ViewTitle, { children: "Choose a stack" }),
76
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
78
77
  stacks.map((stack, index) => /* @__PURE__ */ jsx(
79
- MenuItem,
78
+ SelectionCard,
80
79
  {
81
80
  label: stack.name,
82
81
  description: stack.description,
83
- isFocused: index === focusedIndex
82
+ isFocused: index === focusedIndex,
83
+ marginBottom: 1
84
84
  },
85
85
  stack.id
86
86
  )),
87
- stackCount > 0 && /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2500".repeat(DIVIDER_WIDTH) }) }),
88
- /* @__PURE__ */ jsx(Box, { marginTop: stackCount > 0 ? 0 : void 0, children: /* @__PURE__ */ jsx(
89
- MenuItem,
87
+ /* @__PURE__ */ jsx(
88
+ SelectionCard,
90
89
  {
91
90
  label: SCRATCH_LABEL,
92
91
  description: SCRATCH_DESCRIPTION,
93
92
  isFocused: focusedIndex === scratchIndex
94
93
  }
95
- ) })
96
- ] }),
97
- /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
98
- "\u2191",
99
- "/",
100
- "\u2193",
101
- " navigate ENTER select ESC quit"
102
- ] }) })
94
+ )
95
+ ] })
103
96
  ] });
104
97
  };
105
98
 
106
99
  export {
107
100
  StackSelection
108
101
  };
109
- //# sourceMappingURL=chunk-DV4ALU5I.js.map
102
+ //# sourceMappingURL=chunk-MI4NWOWD.js.map