@agents-inc/cli 0.41.2 → 0.42.1

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 (169) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/config/stacks.yaml +0 -321
  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/config/stacks.yaml +0 -321
  129. package/dist/hooks/init.js +3 -3
  130. package/dist/{source-manager-PPABS6BC.js → source-manager-ABK5COKX.js} +4 -4
  131. package/dist/source-manager-ABK5COKX.js.map +1 -0
  132. package/dist/stores/wizard-store.js +5 -5
  133. package/dist/stores/wizard-store.test.js +6 -6
  134. package/package.json +1 -1
  135. package/src/schemas/project-config.schema.json +7 -0
  136. package/dist/chunk-342YB6TQ.js.map +0 -1
  137. package/dist/chunk-4SYXPG7L.js.map +0 -1
  138. package/dist/chunk-4UTPJXUX.js.map +0 -1
  139. package/dist/chunk-5TMB53BV.js.map +0 -1
  140. package/dist/chunk-7FBM7V3E.js.map +0 -1
  141. package/dist/chunk-ACVJVYMC.js.map +0 -1
  142. package/dist/chunk-AH7XHAKN.js.map +0 -1
  143. package/dist/chunk-DV4ALU5I.js.map +0 -1
  144. package/dist/chunk-GEDWVX6Y.js.map +0 -1
  145. package/dist/chunk-KC2SIUIA.js.map +0 -1
  146. package/dist/chunk-KXM7KOPE.js +0 -31
  147. package/dist/chunk-KXM7KOPE.js.map +0 -1
  148. package/dist/chunk-R52N7DBG.js.map +0 -1
  149. package/dist/chunk-TTXV55NQ.js.map +0 -1
  150. package/dist/chunk-UKTYDNWJ.js.map +0 -1
  151. package/dist/chunk-WS6OQIEN.js +0 -32
  152. package/dist/chunk-WS6OQIEN.js.map +0 -1
  153. package/dist/chunk-XJXJZ2MJ.js.map +0 -1
  154. package/dist/chunk-YLJYAQSG.js.map +0 -1
  155. /package/dist/{chunk-ZLHGJSRK.js.map → chunk-2TWELY5M.js.map} +0 -0
  156. /package/dist/{chunk-NYP5SB2V.js.map → chunk-52SI5XJH.js.map} +0 -0
  157. /package/dist/{chunk-2D6LKRHW.js.map → chunk-ALWLM5MC.js.map} +0 -0
  158. /package/dist/{chunk-AVVYFEMF.js.map → chunk-AQANPOLS.js.map} +0 -0
  159. /package/dist/{chunk-BFISETQG.js.map → chunk-EFZN22TO.js.map} +0 -0
  160. /package/dist/{chunk-SILUTTV7.js.map → chunk-FDY6SGSA.js.map} +0 -0
  161. /package/dist/{chunk-FHBICUXB.js.map → chunk-GIZ6DENW.js.map} +0 -0
  162. /package/dist/{chunk-LJRP4SWY.js.map → chunk-HMGWGWFT.js.map} +0 -0
  163. /package/dist/{chunk-H6H3COI5.js.map → chunk-IUYU2TP6.js.map} +0 -0
  164. /package/dist/{chunk-TJAZ7QCF.js.map → chunk-KA253GGY.js.map} +0 -0
  165. /package/dist/{chunk-MNPPGIZQ.js.map → chunk-ORJPGZVD.js.map} +0 -0
  166. /package/dist/{chunk-4LT6RXMY.js.map → chunk-WMAALRQI.js.map} +0 -0
  167. /package/dist/{chunk-PURJZ72D.js.map → chunk-X34RGEFX.js.map} +0 -0
  168. /package/dist/{chunk-423MJ6DT.js.map → chunk-XRA4LHTJ.js.map} +0 -0
  169. /package/dist/{source-manager-PPABS6BC.js.map → components/wizard/selection-card.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/components/wizard/category-grid.tsx","../src/cli/components/hooks/use-category-grid-input.ts"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport { Box, type DOMElement, Text, measureElement } from \"ink\";\n\nimport { CLI_COLORS, SCROLL_VIEWPORT } from \"../../consts.js\";\nimport type { SkillId, Subcategory } from \"../../types/index.js\";\nimport { isSectionLocked, useCategoryGridInput } from \"../hooks/use-category-grid-input.js\";\nimport { useFocusedListItem } from \"../hooks/use-focused-list-item.js\";\n\nexport type OptionState = \"normal\" | \"recommended\" | \"discouraged\" | \"disabled\";\n\nexport type CategoryOption = {\n id: SkillId;\n label: string;\n state: OptionState;\n stateReason?: string;\n selected: boolean;\n local?: boolean;\n installed?: boolean;\n};\n\nexport type CategoryRow = {\n id: Subcategory;\n displayName: string;\n required: boolean;\n exclusive: boolean;\n options: CategoryOption[];\n};\n\nexport type CategoryGridProps = {\n categories: CategoryRow[];\n /** Available height in terminal lines for the scrollable viewport. 0 = no constraint. */\n availableHeight?: number;\n showLabels: boolean;\n expertMode: boolean;\n onToggle: (categoryId: Subcategory, technologyId: SkillId) => void;\n onToggleLabels: () => void;\n /** Optional initial focus row (default: 0). Use with React `key` to reset. */\n defaultFocusedRow?: number;\n /** Optional initial focus col (default: 0). Use with React `key` to reset. */\n defaultFocusedCol?: number;\n /** Optional callback fired whenever the focused position changes */\n onFocusChange?: (row: number, col: number) => void;\n};\n\nconst SYMBOL_REQUIRED = \"*\";\n\n/**\n * Priority order for skill states in the initial sort.\n * Lower numbers appear first. Selected skills are sorted above all states.\n */\nconst STATE_PRIORITY: Record<OptionState, number> = {\n recommended: 0,\n normal: 1,\n discouraged: 2,\n disabled: 3,\n};\n\n/**\n * Sort options by: selected first, then by state priority.\n * Within each group, original matrix order is preserved (stable sort).\n */\nconst stableSortByState = (options: CategoryOption[]): CategoryOption[] => {\n return [...options].sort((a, b) => {\n if (a.selected !== b.selected) return a.selected ? -1 : 1;\n return STATE_PRIORITY[a.state] - STATE_PRIORITY[b.state];\n });\n};\n\nconst findNextValidOption = (\n options: CategoryOption[],\n currentIndex: number,\n direction: 1 | -1,\n wrap = true,\n): number => {\n const length = options.length;\n if (length === 0) return currentIndex;\n\n let index = currentIndex + direction;\n\n if (wrap) {\n if (index < 0) index = length - 1;\n if (index >= length) index = 0;\n } else {\n if (index < 0) index = 0;\n if (index >= length) index = length - 1;\n }\n\n return index;\n};\n\ntype SkillTagProps = {\n option: CategoryOption;\n isFocused: boolean;\n isLocked: boolean;\n showLabels: boolean;\n};\n\nconst getCompatibilityLabel = (option: CategoryOption, isLocked: boolean): string | null => {\n if (option.selected) return \"(selected)\";\n if (isLocked || option.state === \"disabled\") return \"(disabled)\";\n if (option.state === \"recommended\") return \"(recommended)\";\n if (option.state === \"discouraged\") return \"(discouraged)\";\n return null;\n};\n\nconst SkillTag: React.FC<SkillTagProps> = ({ option, isFocused, isLocked, showLabels }) => {\n const getTextColor = (): string => {\n if (isLocked || option.state === \"disabled\") return CLI_COLORS.NEUTRAL;\n if (option.selected) return CLI_COLORS.PRIMARY;\n if (option.state === \"recommended\") return CLI_COLORS.UNFOCUSED;\n if (option.state === \"discouraged\") return CLI_COLORS.WARNING;\n\n return CLI_COLORS.NEUTRAL;\n };\n\n const getStateBorderColor = (): string => {\n if (isLocked || option.state === \"disabled\") return CLI_COLORS.NEUTRAL;\n if (option.selected) return CLI_COLORS.PRIMARY;\n if (option.state === \"recommended\") return CLI_COLORS.UNFOCUSED;\n if (option.state === \"discouraged\") return CLI_COLORS.WARNING;\n return CLI_COLORS.UNFOCUSED;\n };\n\n const textColor = getTextColor();\n const compatibilityLabel = showLabels ? getCompatibilityLabel(option, isLocked) : null;\n\n return (\n <Box\n marginRight={1}\n borderColor={isFocused ? getStateBorderColor() : CLI_COLORS.NEUTRAL}\n borderStyle=\"single\"\n flexShrink={0}\n >\n <>\n <Text color={textColor} bold>\n {\" \"}\n {option.label}{\" \"}\n </Text>\n {compatibilityLabel && <Text dimColor>{compatibilityLabel} </Text>}\n </>\n </Box>\n );\n};\n\ntype CategorySectionProps = {\n isFirst: boolean;\n category: CategoryRow;\n options: CategoryOption[];\n isLocked: boolean;\n isFocused: boolean;\n focusedOptionIndex: number;\n showLabels: boolean;\n};\n\nconst CategorySection: React.FC<CategorySectionProps> = ({\n isFirst,\n category,\n options,\n isLocked,\n isFocused,\n focusedOptionIndex,\n showLabels,\n}) => {\n return (\n <Box flexDirection=\"column\" marginTop={isFirst ? 0 : 1}>\n <Box flexDirection=\"row\">\n <Text dimColor={isLocked} color={isFocused ? \"#fff\" : \"gray\"}>\n {category.displayName}\n </Text>\n {category.required && (\n <Text color={isLocked ? CLI_COLORS.NEUTRAL : CLI_COLORS.ERROR} dimColor={isLocked}>\n {\" \"}\n {SYMBOL_REQUIRED}\n </Text>\n )}\n </Box>\n\n <Box flexDirection=\"row\" flexWrap=\"wrap\" marginTop={0}>\n {options.map((option, index) => (\n <SkillTag\n key={option.id}\n option={option}\n isFocused={isFocused && index === focusedOptionIndex && !isLocked}\n isLocked={isLocked}\n showLabels={showLabels}\n />\n ))}\n </Box>\n </Box>\n );\n};\n\ntype ProcessedCategory = CategoryRow & { sortedOptions: CategoryOption[] };\n\nexport const CategoryGrid: React.FC<CategoryGridProps> = ({\n categories,\n availableHeight = 0,\n showLabels,\n expertMode,\n onToggle,\n onToggleLabels,\n defaultFocusedRow = 0,\n defaultFocusedCol = 0,\n onFocusChange,\n}) => {\n // Cache the initial sort order per category so toggling selections does not reorder skills.\n // The ref resets when the component remounts (e.g., domain change via key={activeDomain}).\n const initialOrderRef = useRef<Map<string, SkillId[]>>(new Map());\n\n const processedCategories = useMemo(\n () =>\n categories.map((category) => {\n const cached = initialOrderRef.current.get(category.id);\n if (cached) {\n const orderMap = new Map(cached.map((id, idx) => [id, idx]));\n const sorted = [...category.options].sort((a, b) => {\n const aIdx = orderMap.get(a.id) ?? Infinity;\n const bIdx = orderMap.get(b.id) ?? Infinity;\n return aIdx - bIdx;\n });\n return { ...category, sortedOptions: sorted };\n }\n const sorted = stableSortByState(category.options);\n initialOrderRef.current.set(\n category.id,\n sorted.map((o) => o.id),\n );\n return { ...category, sortedOptions: sorted };\n }),\n [categories],\n );\n\n const getColCount = useCallback(\n (row: number): number => processedCategories[row]?.sortedOptions.length ?? 0,\n [processedCategories],\n );\n\n const isRowLocked = useCallback(\n (row: number): boolean => {\n const cat = processedCategories[row];\n return cat ? isSectionLocked(cat.id, categories) : false;\n },\n [processedCategories, categories],\n );\n\n const findValidCol = useCallback(\n (row: number, currentCol: number, direction: 1 | -1): number => {\n const options = processedCategories[row]?.sortedOptions || [];\n const catId = processedCategories[row]?.id;\n if (catId && isSectionLocked(catId, categories)) return currentCol;\n return findNextValidOption(options, currentCol, direction, true);\n },\n [processedCategories, categories],\n );\n\n const { focusedRow, focusedCol, setFocused, moveFocus } = useFocusedListItem(\n processedCategories.length,\n getColCount,\n {\n wrap: true,\n isRowLocked,\n findValidCol,\n onChange: onFocusChange,\n initialRow: defaultFocusedRow,\n initialCol: defaultFocusedCol,\n },\n );\n\n useCategoryGridInput({\n processedCategories,\n categories,\n focusedRow,\n focusedCol,\n setFocused,\n moveFocus,\n onToggle,\n onToggleLabels,\n });\n\n const sectionRefs = useRef<(DOMElement | null)[]>([]);\n const [sectionHeights, setSectionHeights] = useState<number[]>([]);\n const [scrollTopPx, setScrollTopPx] = useState(0);\n\n const setSectionRef = useCallback((index: number, el: DOMElement | null) => {\n sectionRefs.current[index] = el;\n }, []);\n\n useEffect(() => {\n const heights = sectionRefs.current.map((el) => {\n if (el) {\n const { height } = measureElement(el);\n return height;\n }\n return 0;\n });\n setSectionHeights((prev) => {\n if (prev.length === heights.length && prev.every((h, i) => h === heights[i])) {\n return prev;\n }\n return heights;\n });\n });\n\n const scrollEnabled = availableHeight > 0 && availableHeight >= SCROLL_VIEWPORT.MIN_VIEWPORT_ROWS;\n\n useEffect(() => {\n if (!scrollEnabled || sectionHeights.length === 0) return;\n\n let topOfFocused = 0;\n for (let i = 0; i < focusedRow; i++) {\n topOfFocused += sectionHeights[i] ?? 0;\n }\n const focusedHeight = sectionHeights[focusedRow] ?? 0;\n const bottomOfFocused = topOfFocused + focusedHeight;\n\n setScrollTopPx((prev) => {\n if (topOfFocused < prev) {\n return topOfFocused;\n }\n if (bottomOfFocused > prev + availableHeight) {\n return bottomOfFocused - availableHeight;\n }\n return prev;\n });\n }, [focusedRow, sectionHeights, scrollEnabled, availableHeight]);\n\n if (categories.length === 0) {\n return (\n <Box flexDirection=\"column\">\n <Text dimColor>No categories to display.</Text>\n </Box>\n );\n }\n\n const sectionElements = processedCategories.map((category, index) => {\n const isLocked = isSectionLocked(category.id, categories);\n\n return (\n <Box key={category.id} ref={(el) => setSectionRef(index, el)} flexShrink={0}>\n <CategorySection\n category={category}\n options={category.sortedOptions}\n isLocked={isLocked}\n isFocused={index === focusedRow}\n focusedOptionIndex={focusedCol}\n showLabels={showLabels}\n isFirst={index === 0}\n />\n </Box>\n );\n });\n\n // When no height constraint, render flat (tests, or before first measurement)\n if (!scrollEnabled) {\n return (\n <Box flexDirection=\"column\" flexGrow={1} overflow=\"hidden\">\n {sectionElements}\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" height={availableHeight} overflow=\"hidden\">\n <Box flexDirection=\"column\" marginTop={scrollTopPx > 0 ? -scrollTopPx : 0} flexShrink={0}>\n {sectionElements}\n </Box>\n </Box>\n );\n};\n","import { useCallback, useEffect, useRef } from \"react\";\nimport { useInput } from \"ink\";\n\nimport type { Subcategory, SkillId } from \"../../types/index.js\";\nimport type { CategoryOption, CategoryRow } from \"../wizard/category-grid.js\";\n\nconst FRAMEWORK_CATEGORY_ID = \"web-framework\";\n\n// Locked = non-framework section when no framework is selected\nexport const isSectionLocked = (categoryId: Subcategory, categories: CategoryRow[]): boolean => {\n if (categoryId === FRAMEWORK_CATEGORY_ID) {\n return false;\n }\n\n const frameworkCategory = categories.find((cat) => cat.id === FRAMEWORK_CATEGORY_ID);\n if (!frameworkCategory) return false;\n\n return !frameworkCategory.options.some((opt) => opt.selected);\n};\n\nexport const findValidStartColumn = (_options: CategoryOption[]): number => {\n return 0;\n};\n\n/** Find next unlocked section index (wrapping, direction: forward) */\nexport const findNextUnlockedIndex = (\n processed: { id: Subcategory; sortedOptions: CategoryOption[] }[],\n currentIndex: number,\n allCategories: CategoryRow[],\n): number => {\n const length = processed.length;\n if (length === 0) return currentIndex;\n\n let index = currentIndex;\n let attempts = 0;\n\n while (attempts < length) {\n index += 1;\n if (index >= length) index = 0;\n\n const category = processed[index];\n if (category && !isSectionLocked(category.id, allCategories)) {\n return index;\n }\n\n attempts++;\n }\n\n return currentIndex;\n};\n\ntype ProcessedCategory = CategoryRow & { sortedOptions: CategoryOption[] };\n\ntype UseCategoryGridInputOptions = {\n processedCategories: ProcessedCategory[];\n categories: CategoryRow[];\n focusedRow: number;\n focusedCol: number;\n setFocused: (row: number, col: number) => void;\n moveFocus: (direction: \"up\" | \"down\" | \"left\" | \"right\") => void;\n onToggle: (categoryId: Subcategory, technologyId: SkillId) => void;\n onToggleLabels: () => void;\n};\n\nexport function useCategoryGridInput({\n processedCategories,\n categories,\n focusedRow,\n focusedCol,\n setFocused,\n moveFocus,\n onToggle,\n onToggleLabels,\n}: UseCategoryGridInputOptions): void {\n const currentRow = processedCategories[focusedRow];\n const currentOptions = currentRow?.sortedOptions || [];\n const currentLocked = currentRow ? isSectionLocked(currentRow.id, categories) : false;\n\n // Adjust column when current row's options change externally (e.g. option becomes disabled)\n useEffect(() => {\n if (!currentRow) return;\n\n const maxCol = currentOptions.length - 1;\n if (focusedCol > maxCol) {\n const newCol = Math.max(0, maxCol);\n setFocused(focusedRow, newCol);\n }\n }, [focusedRow, currentOptions, focusedCol, setFocused, currentRow]);\n\n // Bounce off locked sections when a section becomes locked (e.g. framework deselected)\n useEffect(() => {\n if (currentRow && currentLocked) {\n const nextUnlocked = findNextUnlockedIndex(processedCategories, focusedRow, categories);\n if (nextUnlocked !== focusedRow) {\n const newRowOptions = processedCategories[nextUnlocked]?.sortedOptions || [];\n const newCol = findValidStartColumn(newRowOptions);\n setFocused(nextUnlocked, newCol);\n }\n }\n }, [currentRow, currentLocked, focusedRow, processedCategories, categories, setFocused]);\n\n // Store the latest handler in a ref so that the useInput effect never needs to\n // re-register on the event emitter. This avoids a stale-closure race condition\n // where, after a domain switch (CategoryGrid remount via key={activeDomain}),\n // the useInput effect may not yet have re-registered the updated handler when\n // the first keypress arrives — causing the first space press to be silently lost.\n type InputKey = {\n leftArrow: boolean;\n rightArrow: boolean;\n upArrow: boolean;\n downArrow: boolean;\n tab: boolean;\n shift: boolean;\n };\n\n const handlerRef = useRef<((input: string, key: InputKey) => void) | null>(null);\n handlerRef.current = (input: string, key: InputKey) => {\n if (key.tab && key.shift) {\n onToggleLabels();\n return;\n }\n\n if (key.tab && !key.shift) {\n const nextSection = findNextUnlockedIndex(processedCategories, focusedRow, categories);\n if (nextSection !== focusedRow) {\n const newRowOptions = processedCategories[nextSection]?.sortedOptions || [];\n const newCol = findValidStartColumn(newRowOptions);\n setFocused(nextSection, newCol);\n }\n return;\n }\n\n if (input === \"d\" || input === \"D\") {\n onToggleLabels();\n return;\n }\n\n if (input === \" \") {\n if (currentLocked) return;\n const currentOption = currentOptions[focusedCol];\n if (currentOption && currentOption.state !== \"disabled\") {\n onToggle(currentRow.id, currentOption.id);\n }\n return;\n }\n\n const isLeft = key.leftArrow || input === \"h\";\n const isRight = key.rightArrow || input === \"l\";\n const isUp = key.upArrow || input === \"k\";\n const isDown = key.downArrow || input === \"j\";\n\n if (isLeft) {\n if (currentLocked) return;\n moveFocus(\"left\");\n } else if (isRight) {\n if (currentLocked) return;\n moveFocus(\"right\");\n } else if (isUp) {\n moveFocus(\"up\");\n } else if (isDown) {\n moveFocus(\"down\");\n }\n };\n\n // Stable handler reference — never changes, so useInput's effect registers once\n const stableHandler = useCallback((input: string, key: InputKey) => {\n handlerRef.current?.(input, key);\n }, []);\n\n useInput(stableHandler);\n}\n"],"mappings":"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","names":["useCallback","useEffect","useRef","useRef","sorted","useCallback","useEffect"]}
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getErrorMessage
4
- } from "./chunk-XJXJZ2MJ.js";
4
+ } from "./chunk-UXNHU7Y7.js";
5
5
  import {
6
6
  init_esm_shims
7
7
  } from "./chunk-DHET7RCE.js";
@@ -53,4 +53,4 @@ export {
53
53
  EXIT_CODES,
54
54
  BaseCommand
55
55
  };
56
- //# sourceMappingURL=chunk-2D6LKRHW.js.map
56
+ //# sourceMappingURL=chunk-ALWLM5MC.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";
@@ -78,4 +78,4 @@ var cliTheme = extendTheme(defaultTheme, {
78
78
  export {
79
79
  cliTheme
80
80
  };
81
- //# sourceMappingURL=chunk-AVVYFEMF.js.map
81
+ //# sourceMappingURL=chunk-AQANPOLS.js.map
@@ -2,9 +2,12 @@
2
2
  import {
3
3
  getDomainDisplayName
4
4
  } from "./chunk-YRVTXSXP.js";
5
+ import {
6
+ ViewTitle
7
+ } from "./chunk-MMD26LKJ.js";
5
8
  import {
6
9
  CLI_COLORS
7
- } from "./chunk-BK7TANUV.js";
10
+ } from "./chunk-PP7NDFFE.js";
8
11
  import {
9
12
  init_esm_shims
10
13
  } from "./chunk-DHET7RCE.js";
@@ -35,7 +38,7 @@ var StepConfirm = ({
35
38
  const domainsText = selectedDomains?.map(getDomainDisplayName).join(" + ") || "";
36
39
  const title = stackName ? `Ready to install ${stackName}` : `Ready to install your custom stack${domainsText ? ` (${domainsText})` : ""}`;
37
40
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 2, children: [
38
- /* @__PURE__ */ jsx(Text, { bold: true, color: CLI_COLORS.SUCCESS, children: title }),
41
+ /* @__PURE__ */ jsx(ViewTitle, { children: title }),
39
42
  /* @__PURE__ */ jsx(Text, { children: " " }),
40
43
  domainSelections && selectedDomains && !stackName && /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginBottom: 1, children: selectedDomains.map((domain) => {
41
44
  const selections = domainSelections[domain] || {};
@@ -61,7 +64,7 @@ var StepConfirm = ({
61
64
  " ",
62
65
  /* @__PURE__ */ jsx(Text, { bold: true, children: skillCount }),
63
66
  " ",
64
- /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.SUCCESS, children: "(all verified)" })
67
+ /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.PRIMARY, children: "(all verified)" })
65
68
  ] }),
66
69
  agentCount !== void 0 && /* @__PURE__ */ jsxs(Text, { children: [
67
70
  /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Agents:" }),
@@ -81,4 +84,4 @@ var StepConfirm = ({
81
84
  export {
82
85
  StepConfirm
83
86
  };
84
- //# sourceMappingURL=chunk-5TMB53BV.js.map
87
+ //# sourceMappingURL=chunk-BKW34TKI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/components/wizard/step-confirm.tsx"],"sourcesContent":["import { Box, Text, useInput } from \"ink\";\nimport React from \"react\";\nimport { CLI_COLORS } from \"../../consts.js\";\nimport type { Domain, DomainSelections } from \"../../types/index.js\";\nimport { getDomainDisplayName } from \"./utils.js\";\nimport { ViewTitle } from \"./view-title.js\";\n\ntype StepConfirmProps = {\n onComplete: () => void;\n stackName?: string;\n selectedDomains?: Domain[];\n domainSelections?: DomainSelections;\n technologyCount?: number;\n skillCount?: number;\n agentCount?: number;\n installMode?: \"plugin\" | \"local\";\n onBack?: () => void;\n};\n\nexport const StepConfirm: React.FC<StepConfirmProps> = ({\n onComplete,\n stackName,\n selectedDomains,\n domainSelections,\n technologyCount,\n skillCount,\n agentCount,\n installMode,\n onBack,\n}) => {\n useInput((_input, key) => {\n if (key.return) {\n onComplete();\n }\n if (key.escape && onBack) {\n onBack();\n }\n });\n\n const domainsText = selectedDomains?.map(getDomainDisplayName).join(\" + \") || \"\";\n const title = stackName\n ? `Ready to install ${stackName}`\n : `Ready to install your custom stack${domainsText ? ` (${domainsText})` : \"\"}`;\n\n return (\n <Box flexDirection=\"column\" paddingX={2}>\n <ViewTitle>{title}</ViewTitle>\n <Text> </Text>\n\n {domainSelections && selectedDomains && !stackName && (\n <Box flexDirection=\"column\" marginBottom={1}>\n {selectedDomains.map((domain) => {\n const selections = domainSelections[domain] || {};\n const techs = Object.values(selections).flat();\n if (techs.length === 0) return null;\n return (\n <Text key={domain}>\n <Text bold>{getDomainDisplayName(domain)}:</Text> <Text>{techs.join(\", \")}</Text>\n </Text>\n );\n })}\n </Box>\n )}\n\n <Box flexDirection=\"column\" marginY={1}>\n {technologyCount !== undefined && (\n <Text>\n <Text dimColor>Technologies:</Text> <Text bold>{technologyCount}</Text>\n </Text>\n )}\n {skillCount !== undefined && (\n <Text>\n <Text dimColor>Skills:</Text> <Text bold>{skillCount}</Text>{\" \"}\n <Text color={CLI_COLORS.PRIMARY}>(all verified)</Text>\n </Text>\n )}\n {agentCount !== undefined && (\n <Text>\n <Text dimColor>Agents:</Text> <Text bold>{agentCount}</Text>\n </Text>\n )}\n {installMode && (\n <Text>\n <Text dimColor>Install mode:</Text>{\" \"}\n <Text bold>{installMode === \"plugin\" ? \"Plugin\" : \"Local\"}</Text>\n </Text>\n )}\n </Box>\n\n <Box marginTop={1}>\n <Text dimColor>ENTER install ESC go back</Text>\n </Box>\n </Box>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;AAAA;AAAA,SAAS,KAAK,MAAM,gBAAgB;AA8C9B,cAWU,YAXV;AA3BC,IAAM,cAA0C,CAAC;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,WAAS,CAAC,QAAQ,QAAQ;AACxB,QAAI,IAAI,QAAQ;AACd,iBAAW;AAAA,IACb;AACA,QAAI,IAAI,UAAU,QAAQ;AACxB,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,QAAM,cAAc,iBAAiB,IAAI,oBAAoB,EAAE,KAAK,KAAK,KAAK;AAC9E,QAAM,QAAQ,YACV,oBAAoB,SAAS,KAC7B,qCAAqC,cAAc,KAAK,WAAW,MAAM,EAAE;AAE/E,SACE,qBAAC,OAAI,eAAc,UAAS,UAAU,GACpC;AAAA,wBAAC,aAAW,iBAAM;AAAA,IAClB,oBAAC,QAAK,eAAC;AAAA,IAEN,oBAAoB,mBAAmB,CAAC,aACvC,oBAAC,OAAI,eAAc,UAAS,cAAc,GACvC,0BAAgB,IAAI,CAAC,WAAW;AAC/B,YAAM,aAAa,iBAAiB,MAAM,KAAK,CAAC;AAChD,YAAM,QAAQ,OAAO,OAAO,UAAU,EAAE,KAAK;AAC7C,UAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,aACE,qBAAC,QACC;AAAA,6BAAC,QAAK,MAAI,MAAE;AAAA,+BAAqB,MAAM;AAAA,UAAE;AAAA,WAAC;AAAA,QAAO;AAAA,QAAC,oBAAC,QAAM,gBAAM,KAAK,IAAI,GAAE;AAAA,WADjE,MAEX;AAAA,IAEJ,CAAC,GACH;AAAA,IAGF,qBAAC,OAAI,eAAc,UAAS,SAAS,GAClC;AAAA,0BAAoB,UACnB,qBAAC,QACC;AAAA,4BAAC,QAAK,UAAQ,MAAC,2BAAa;AAAA,QAAO;AAAA,QAAC,oBAAC,QAAK,MAAI,MAAE,2BAAgB;AAAA,SAClE;AAAA,MAED,eAAe,UACd,qBAAC,QACC;AAAA,4BAAC,QAAK,UAAQ,MAAC,qBAAO;AAAA,QAAO;AAAA,QAAC,oBAAC,QAAK,MAAI,MAAE,sBAAW;AAAA,QAAQ;AAAA,QAC7D,oBAAC,QAAK,OAAO,WAAW,SAAS,4BAAc;AAAA,SACjD;AAAA,MAED,eAAe,UACd,qBAAC,QACC;AAAA,4BAAC,QAAK,UAAQ,MAAC,qBAAO;AAAA,QAAO;AAAA,QAAC,oBAAC,QAAK,MAAI,MAAE,sBAAW;AAAA,SACvD;AAAA,MAED,eACC,qBAAC,QACC;AAAA,4BAAC,QAAK,UAAQ,MAAC,2BAAa;AAAA,QAAQ;AAAA,QACpC,oBAAC,QAAK,MAAI,MAAE,0BAAgB,WAAW,WAAW,SAAQ;AAAA,SAC5D;AAAA,OAEJ;AAAA,IAEA,oBAAC,OAAI,WAAW,GACd,8BAAC,QAAK,UAAQ,MAAC,uCAAyB,GAC1C;AAAA,KACF;AAEJ;","names":[]}
@@ -4,14 +4,14 @@ import {
4
4
  } from "./chunk-7SOPVGDV.js";
5
5
  import {
6
6
  SearchModal
7
- } from "./chunk-NYP5SB2V.js";
7
+ } from "./chunk-52SI5XJH.js";
8
8
  import {
9
9
  useFocusedListItem
10
10
  } from "./chunk-GG4BSB6S.js";
11
11
  import {
12
12
  CLI_COLORS,
13
13
  SCROLL_VIEWPORT
14
- } from "./chunk-BK7TANUV.js";
14
+ } from "./chunk-PP7NDFFE.js";
15
15
  import {
16
16
  init_esm_shims
17
17
  } from "./chunk-DHET7RCE.js";
@@ -280,4 +280,4 @@ var SourceGrid = ({
280
280
  export {
281
281
  SourceGrid
282
282
  };
283
- //# sourceMappingURL=chunk-BFISETQG.js.map
283
+ //# sourceMappingURL=chunk-EFZN22TO.js.map
@@ -2,30 +2,30 @@
2
2
  import {
3
3
  getDomainDisplayName
4
4
  } from "./chunk-YRVTXSXP.js";
5
- import {
6
- ViewTitle
7
- } from "./chunk-KXM7KOPE.js";
8
5
  import {
9
6
  useMeasuredHeight
10
7
  } from "./chunk-K77I4XGL.js";
8
+ import {
9
+ ViewTitle
10
+ } from "./chunk-MMD26LKJ.js";
11
11
  import {
12
12
  CategoryGrid
13
- } from "./chunk-GEDWVX6Y.js";
13
+ } from "./chunk-53K3URKF.js";
14
14
  import {
15
15
  buildCategoriesForDomain,
16
16
  validateBuildStep
17
- } from "./chunk-SILUTTV7.js";
17
+ } from "./chunk-FDY6SGSA.js";
18
18
  import {
19
19
  CLI_COLORS
20
- } from "./chunk-BK7TANUV.js";
20
+ } from "./chunk-PP7NDFFE.js";
21
21
  import {
22
22
  init_esm_shims
23
23
  } from "./chunk-DHET7RCE.js";
24
24
 
25
25
  // src/cli/components/wizard/step-build.tsx
26
26
  init_esm_shims();
27
- import { useState } from "react";
28
27
  import { Box, Text, useInput } from "ink";
28
+ import { useState } from "react";
29
29
 
30
30
  // src/cli/lib/wizard/index.ts
31
31
  init_esm_shims();
@@ -117,11 +117,11 @@ var StepBuild = ({
117
117
  borderStyle: "single",
118
118
  children: /* @__PURE__ */ jsx(Box, { columnGap: 2, flexDirection: "row", children: selectedDomains.map((domain) => {
119
119
  const isActive = domain === activeDomain;
120
- return /* @__PURE__ */ jsx(Text, { color: isActive ? CLI_COLORS.PRIMARY : void 0, bold: isActive, children: getDomainDisplayName(domain) }, domain);
120
+ return /* @__PURE__ */ jsx(Text, { color: isActive ? CLI_COLORS.WARNING : void 0, bold: isActive, children: getDomainDisplayName(domain) }, domain);
121
121
  }) })
122
122
  }
123
123
  ),
124
- /* @__PURE__ */ jsx(ViewTitle, { children: `[2] Customize your ${getDomainDisplayName(activeDomain)} stack` }),
124
+ /* @__PURE__ */ jsx(ViewTitle, { children: `Customize your ${getDomainDisplayName(activeDomain)} stack` }),
125
125
  /* @__PURE__ */ jsx(Box, { ref: gridRef, flexGrow: 1, flexBasis: 0, children: /* @__PURE__ */ jsx(
126
126
  CategoryGrid,
127
127
  {
@@ -141,4 +141,4 @@ var StepBuild = ({
141
141
  export {
142
142
  StepBuild
143
143
  };
144
- //# sourceMappingURL=chunk-7FBM7V3E.js.map
144
+ //# sourceMappingURL=chunk-EPJ2GJNJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/components/wizard/step-build.tsx","../src/cli/lib/wizard/index.ts","../src/cli/components/hooks/use-framework-filtering.ts"],"sourcesContent":["import { Box, Text, useInput } from \"ink\";\nimport React, { useState } from \"react\";\nimport { CLI_COLORS } from \"../../consts.js\";\nimport { validateBuildStep } from \"../../lib/wizard/index.js\";\nimport type {\n Domain,\n MergedSkillsMatrix,\n SkillId,\n Subcategory,\n SubcategorySelections,\n} from \"../../types/index.js\";\nimport { useFrameworkFiltering } from \"../hooks/use-framework-filtering.js\";\nimport { useMeasuredHeight } from \"../hooks/use-measured-height.js\";\nimport { CategoryGrid } from \"./category-grid.js\";\nimport { getDomainDisplayName } from \"./utils.js\";\nimport { ViewTitle } from \"./view-title.js\";\n\nexport type StepBuildProps = {\n matrix: MergedSkillsMatrix;\n domain: Domain;\n selectedDomains: Domain[];\n selections: SubcategorySelections;\n allSelections: SkillId[];\n showLabels: boolean;\n expertMode: boolean;\n /** Skill IDs already installed on disk, shown with a dimmed checkmark */\n installedSkillIds?: SkillId[];\n onToggle: (subcategoryId: Subcategory, technologyId: SkillId) => void;\n onToggleLabels: () => void;\n onContinue: () => void;\n onBack: () => void;\n};\n\ntype FooterProps = {\n validationError?: string;\n};\n\nconst Footer: React.FC<FooterProps> = ({ validationError }) => {\n return (\n <Box flexDirection=\"column\" marginTop={1}>\n {validationError && (\n <Box flexDirection=\"column\" marginBottom={1}>\n <Text color={CLI_COLORS.WARNING}>{validationError}</Text>\n <Text dimColor>Press ESC to go back, or select a skill and press ENTER to continue.</Text>\n </Box>\n )}\n </Box>\n );\n};\n\nexport const StepBuild: React.FC<StepBuildProps> = ({\n matrix,\n domain: activeDomain,\n selectedDomains,\n selections,\n allSelections,\n showLabels,\n expertMode,\n installedSkillIds,\n onToggle,\n onToggleLabels,\n onContinue,\n onBack,\n}) => {\n const [validationError, setValidationError] = useState<string | undefined>(undefined);\n const { ref: gridRef, measuredHeight: gridHeight } = useMeasuredHeight();\n\n const categories = useFrameworkFiltering({\n domain: activeDomain,\n allSelections,\n matrix,\n expertMode,\n selections,\n installedSkillIds,\n });\n\n useInput((_input, key) => {\n if (key.return) {\n const validation = validateBuildStep(categories, selections);\n if (validation.valid) {\n setValidationError(undefined);\n onContinue();\n } else {\n setValidationError(validation.message);\n }\n } else if (key.escape) {\n setValidationError(undefined);\n onBack();\n }\n });\n\n return (\n <Box flexDirection=\"column\" width=\"100%\" flexGrow={1} flexBasis={0}>\n <Box\n columnGap={2}\n flexDirection=\"row\"\n justifyContent=\"space-between\"\n marginBottom={1}\n paddingRight={1}\n marginTop={-1}\n borderTop={false}\n borderRight={false}\n borderLeft={false}\n borderColor={CLI_COLORS.NEUTRAL}\n borderStyle=\"single\"\n >\n <Box columnGap={2} flexDirection=\"row\">\n {selectedDomains.map((domain) => {\n const isActive = domain === activeDomain;\n return (\n <Text key={domain} color={isActive ? CLI_COLORS.WARNING : undefined} bold={isActive}>\n {getDomainDisplayName(domain)}\n </Text>\n );\n })}\n </Box>\n </Box>\n <ViewTitle>{`Customize your ${getDomainDisplayName(activeDomain)} stack`}</ViewTitle>\n\n <Box ref={gridRef} flexGrow={1} flexBasis={0}>\n <CategoryGrid\n key={activeDomain}\n categories={categories}\n availableHeight={gridHeight}\n expertMode={expertMode}\n showLabels={showLabels}\n onToggle={onToggle}\n onToggleLabels={onToggleLabels}\n />\n </Box>\n\n <Footer validationError={validationError} />\n </Box>\n );\n};\n","export {\n type BuildStepValidation,\n validateBuildStep,\n computeOptionState,\n getSkillDisplayLabel,\n buildCategoriesForDomain,\n} from \"./build-step-logic\";\n","import { useMemo } from \"react\";\nimport type {\n Domain,\n MergedSkillsMatrix,\n SkillId,\n SubcategorySelections,\n} from \"../../types/index.js\";\nimport { buildCategoriesForDomain } from \"../../lib/wizard/index.js\";\nimport type { CategoryRow } from \"../wizard/category-grid.js\";\n\ntype UseFrameworkFilteringOptions = {\n domain: Domain;\n allSelections: SkillId[];\n matrix: MergedSkillsMatrix;\n expertMode: boolean;\n selections: SubcategorySelections;\n installedSkillIds?: SkillId[];\n};\n\nexport function useFrameworkFiltering({\n domain,\n allSelections,\n matrix,\n expertMode,\n selections,\n installedSkillIds,\n}: UseFrameworkFilteringOptions): CategoryRow[] {\n return useMemo(\n () =>\n buildCategoriesForDomain(\n domain,\n allSelections,\n matrix,\n expertMode,\n selections,\n installedSkillIds,\n ),\n [domain, allSelections, matrix, expertMode, selections, installedSkillIds],\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,SAAS,KAAK,MAAM,gBAAgB;AACpC,SAAgB,gBAAgB;;;ACDhC;;;ACAA;AAAA,SAAS,eAAe;AAmBjB,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAgD;AAC9C,SAAO;AAAA,IACL,MACE;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACF,CAAC,QAAQ,eAAe,QAAQ,YAAY,YAAY,iBAAiB;AAAA,EAC3E;AACF;;;AFEQ,SACE,KADF;AAJR,IAAM,SAAgC,CAAC,EAAE,gBAAgB,MAAM;AAC7D,SACE,oBAAC,OAAI,eAAc,UAAS,WAAW,GACpC,6BACC,qBAAC,OAAI,eAAc,UAAS,cAAc,GACxC;AAAA,wBAAC,QAAK,OAAO,WAAW,SAAU,2BAAgB;AAAA,IAClD,oBAAC,QAAK,UAAQ,MAAC,kFAAoE;AAAA,KACrF,GAEJ;AAEJ;AAEO,IAAM,YAAsC,CAAC;AAAA,EAClD;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAA6B,MAAS;AACpF,QAAM,EAAE,KAAK,SAAS,gBAAgB,WAAW,IAAI,kBAAkB;AAEvE,QAAM,aAAa,sBAAsB;AAAA,IACvC,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,WAAS,CAAC,QAAQ,QAAQ;AACxB,QAAI,IAAI,QAAQ;AACd,YAAM,aAAa,kBAAkB,YAAY,UAAU;AAC3D,UAAI,WAAW,OAAO;AACpB,2BAAmB,MAAS;AAC5B,mBAAW;AAAA,MACb,OAAO;AACL,2BAAmB,WAAW,OAAO;AAAA,MACvC;AAAA,IACF,WAAW,IAAI,QAAQ;AACrB,yBAAmB,MAAS;AAC5B,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,SACE,qBAAC,OAAI,eAAc,UAAS,OAAM,QAAO,UAAU,GAAG,WAAW,GAC/D;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,QACX,eAAc;AAAA,QACd,gBAAe;AAAA,QACf,cAAc;AAAA,QACd,cAAc;AAAA,QACd,WAAW;AAAA,QACX,WAAW;AAAA,QACX,aAAa;AAAA,QACb,YAAY;AAAA,QACZ,aAAa,WAAW;AAAA,QACxB,aAAY;AAAA,QAEZ,8BAAC,OAAI,WAAW,GAAG,eAAc,OAC9B,0BAAgB,IAAI,CAAC,WAAW;AAC/B,gBAAM,WAAW,WAAW;AAC5B,iBACE,oBAAC,QAAkB,OAAO,WAAW,WAAW,UAAU,QAAW,MAAM,UACxE,+BAAqB,MAAM,KADnB,MAEX;AAAA,QAEJ,CAAC,GACH;AAAA;AAAA,IACF;AAAA,IACA,oBAAC,aAAW,4BAAkB,qBAAqB,YAAY,CAAC,UAAS;AAAA,IAEzE,oBAAC,OAAI,KAAK,SAAS,UAAU,GAAG,WAAW,GACzC;AAAA,MAAC;AAAA;AAAA,QAEC;AAAA,QACA,iBAAiB;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,MANK;AAAA,IAOP,GACF;AAAA,IAEA,oBAAC,UAAO,iBAAkC;AAAA,KAC5C;AAEJ;","names":[]}
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  getAvailableSkills,
4
4
  resolveAlias
5
- } from "./chunk-TTXV55NQ.js";
5
+ } from "./chunk-SYHRJG5G.js";
6
6
  import {
7
7
  init_esm_shims
8
8
  } from "./chunk-DHET7RCE.js";
@@ -110,4 +110,4 @@ export {
110
110
  getSkillDisplayLabel,
111
111
  buildCategoriesForDomain
112
112
  };
113
- //# sourceMappingURL=chunk-SILUTTV7.js.map
113
+ //# sourceMappingURL=chunk-FDY6SGSA.js.map
@@ -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