agents-inc 0.167.0 → 0.170.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 (200) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +18 -15
  3. package/dist/{chunk-ZR4YPKXQ.js → chunk-3G7X2WKI.js} +4 -4
  4. package/dist/{chunk-JOEA52NR.js → chunk-44TE3RKH.js} +46 -2
  5. package/dist/chunk-44TE3RKH.js.map +1 -0
  6. package/dist/{chunk-V5WXIM2F.js → chunk-52HDHJ7I.js} +11 -19
  7. package/dist/chunk-52HDHJ7I.js.map +1 -0
  8. package/dist/{chunk-V3I7VQ7N.js → chunk-6HNXYYVF.js} +39 -22
  9. package/dist/chunk-6HNXYYVF.js.map +1 -0
  10. package/dist/{chunk-MAWNVT2C.js → chunk-6ZRH5RHC.js} +10 -11
  11. package/dist/chunk-6ZRH5RHC.js.map +1 -0
  12. package/dist/{chunk-G6UREQ4V.js → chunk-7RDMTR64.js} +14 -34
  13. package/dist/chunk-7RDMTR64.js.map +1 -0
  14. package/dist/{chunk-GE3WKJ6Q.js → chunk-BMRUNMPV.js} +4 -4
  15. package/dist/{chunk-VAPTVR3J.js → chunk-CLPUWOSA.js} +4 -4
  16. package/dist/{chunk-VAPTVR3J.js.map → chunk-CLPUWOSA.js.map} +1 -1
  17. package/dist/{chunk-HWEKHVLE.js → chunk-F2BHT5C4.js} +9 -7
  18. package/dist/chunk-F2BHT5C4.js.map +1 -0
  19. package/dist/{chunk-ZXKBERQU.js → chunk-F5EBEATU.js} +2 -2
  20. package/dist/{chunk-PMJWD27C.js → chunk-HED2DAXZ.js} +3 -3
  21. package/dist/{chunk-SAYZWCH6.js → chunk-KOLDW6SF.js} +3 -3
  22. package/dist/{chunk-SAYZWCH6.js.map → chunk-KOLDW6SF.js.map} +1 -1
  23. package/dist/{chunk-A4KDXNOT.js → chunk-MQ6CGZNJ.js} +171 -522
  24. package/dist/chunk-MQ6CGZNJ.js.map +1 -0
  25. package/dist/{chunk-G4JK7WVO.js → chunk-NCWDK6L7.js} +115 -196
  26. package/dist/chunk-NCWDK6L7.js.map +1 -0
  27. package/dist/{chunk-VRXX4D6K.js → chunk-NEZ4OAOL.js} +1 -1
  28. package/dist/chunk-NEZ4OAOL.js.map +1 -0
  29. package/dist/chunk-NIHUOWE4.js +106 -0
  30. package/dist/chunk-NIHUOWE4.js.map +1 -0
  31. package/dist/{chunk-OI2H6M5I.js → chunk-NQW25DCF.js} +2 -2
  32. package/dist/chunk-NQW25DCF.js.map +1 -0
  33. package/dist/{chunk-25MPBIK3.js → chunk-OYJQUA3D.js} +3 -3
  34. package/dist/{chunk-25MPBIK3.js.map → chunk-OYJQUA3D.js.map} +1 -1
  35. package/dist/{chunk-ENGYJCTF.js → chunk-PJWGTNOX.js} +220 -254
  36. package/dist/chunk-PJWGTNOX.js.map +1 -0
  37. package/dist/{chunk-NBXXFIIW.js → chunk-RIPSGNLU.js} +3 -3
  38. package/dist/chunk-RIPSGNLU.js.map +1 -0
  39. package/dist/{chunk-Y47EV74W.js → chunk-SZYQISA2.js} +10 -13
  40. package/dist/chunk-SZYQISA2.js.map +1 -0
  41. package/dist/{chunk-TODCQFRB.js → chunk-USVBYQSQ.js} +2 -2
  42. package/dist/{chunk-Y3VIRVVE.js → chunk-V3KTSP3Q.js} +50 -42
  43. package/dist/chunk-V3KTSP3Q.js.map +1 -0
  44. package/dist/{chunk-PXWG7KFO.js → chunk-WTWMGH2C.js} +2 -2
  45. package/dist/commands/build/marketplace.js +23 -22
  46. package/dist/commands/build/marketplace.js.map +1 -1
  47. package/dist/commands/build/plugins.js +8 -9
  48. package/dist/commands/build/plugins.js.map +1 -1
  49. package/dist/commands/compile.js +19 -20
  50. package/dist/commands/compile.js.map +1 -1
  51. package/dist/commands/doctor.js +17 -18
  52. package/dist/commands/doctor.js.map +1 -1
  53. package/dist/commands/edit.js +138 -488
  54. package/dist/commands/edit.js.map +1 -1
  55. package/dist/commands/eject.js +21 -33
  56. package/dist/commands/eject.js.map +1 -1
  57. package/dist/commands/init.js +17 -45
  58. package/dist/commands/list.js +19 -17
  59. package/dist/commands/list.js.map +1 -1
  60. package/dist/commands/new/marketplace.js +11 -11
  61. package/dist/commands/new/marketplace.js.map +1 -1
  62. package/dist/commands/search.js +12 -13
  63. package/dist/commands/search.js.map +1 -1
  64. package/dist/commands/share.js +11 -12
  65. package/dist/commands/share.js.map +1 -1
  66. package/dist/commands/uninstall.js +18 -20
  67. package/dist/commands/uninstall.js.map +1 -1
  68. package/dist/commands/update.js +8 -9
  69. package/dist/commands/update.js.map +1 -1
  70. package/dist/components/common/removal-plan-confirm.js +2 -2
  71. package/dist/components/common/scroll-affordance.js +9 -0
  72. package/dist/components/common/select-list.js +2 -3
  73. package/dist/components/common/skill-agent-summary.js +11 -0
  74. package/dist/components/common/spinner.js +1 -1
  75. package/dist/{chunk-2VUYFTUB.js → components/common/summary-panel.js} +57 -31
  76. package/dist/components/common/summary-panel.js.map +1 -0
  77. package/dist/config-exports.js +1 -1
  78. package/dist/hooks/init.js +18 -46
  79. package/dist/hooks/init.js.map +1 -1
  80. package/dist/load-agent-defs-YMDWBFDP.js +14 -0
  81. package/dist/recompile-project-agents-SZ76WNTW.js +18 -0
  82. package/dist/{source-loader-7KZ3MD5O.js → source-loader-C5SQXZXI.js} +5 -5
  83. package/dist/src/agents/meta/codex-keeper/playbook.md +2 -3
  84. package/package.json +6 -4
  85. package/src/agents/meta/codex-keeper/playbook.md +2 -3
  86. package/src/schemas/project-config.schema.json +1 -1
  87. package/assets/demo.tape +0 -266
  88. package/dist/chunk-2VUYFTUB.js.map +0 -1
  89. package/dist/chunk-4NDBUJHK.js +0 -237
  90. package/dist/chunk-4NDBUJHK.js.map +0 -1
  91. package/dist/chunk-6L75SQZU.js +0 -168
  92. package/dist/chunk-6L75SQZU.js.map +0 -1
  93. package/dist/chunk-6LF4CQBY.js +0 -51
  94. package/dist/chunk-6LF4CQBY.js.map +0 -1
  95. package/dist/chunk-7JNJ52CD.js +0 -1179
  96. package/dist/chunk-7JNJ52CD.js.map +0 -1
  97. package/dist/chunk-A4KDXNOT.js.map +0 -1
  98. package/dist/chunk-DAIEQJIF.js +0 -48
  99. package/dist/chunk-DAIEQJIF.js.map +0 -1
  100. package/dist/chunk-ENGYJCTF.js.map +0 -1
  101. package/dist/chunk-G4JK7WVO.js.map +0 -1
  102. package/dist/chunk-G6UREQ4V.js.map +0 -1
  103. package/dist/chunk-HHIYT3PI.js +0 -53
  104. package/dist/chunk-HHIYT3PI.js.map +0 -1
  105. package/dist/chunk-HWEKHVLE.js.map +0 -1
  106. package/dist/chunk-JOEA52NR.js.map +0 -1
  107. package/dist/chunk-JQRJQ4SS.js +0 -118
  108. package/dist/chunk-JQRJQ4SS.js.map +0 -1
  109. package/dist/chunk-LFWLEDUG.js +0 -59
  110. package/dist/chunk-LFWLEDUG.js.map +0 -1
  111. package/dist/chunk-MAWNVT2C.js.map +0 -1
  112. package/dist/chunk-MPTNC32T.js +0 -92
  113. package/dist/chunk-MPTNC32T.js.map +0 -1
  114. package/dist/chunk-NBXXFIIW.js.map +0 -1
  115. package/dist/chunk-OI2H6M5I.js.map +0 -1
  116. package/dist/chunk-PNB3524H.js +0 -197
  117. package/dist/chunk-PNB3524H.js.map +0 -1
  118. package/dist/chunk-QHDPLLK6.js +0 -35
  119. package/dist/chunk-QHDPLLK6.js.map +0 -1
  120. package/dist/chunk-RAHSOJQ2.js +0 -25
  121. package/dist/chunk-RAHSOJQ2.js.map +0 -1
  122. package/dist/chunk-RZDXDMT6.js +0 -23
  123. package/dist/chunk-RZDXDMT6.js.map +0 -1
  124. package/dist/chunk-SCOQ34YM.js +0 -17
  125. package/dist/chunk-SCOQ34YM.js.map +0 -1
  126. package/dist/chunk-SXVHSOTH.js +0 -268
  127. package/dist/chunk-SXVHSOTH.js.map +0 -1
  128. package/dist/chunk-T6UWJAB3.js +0 -28
  129. package/dist/chunk-T6UWJAB3.js.map +0 -1
  130. package/dist/chunk-TSIU7DME.js +0 -43
  131. package/dist/chunk-TSIU7DME.js.map +0 -1
  132. package/dist/chunk-TTY6DPJN.js +0 -27
  133. package/dist/chunk-TTY6DPJN.js.map +0 -1
  134. package/dist/chunk-TZ2YJJKK.js +0 -292
  135. package/dist/chunk-TZ2YJJKK.js.map +0 -1
  136. package/dist/chunk-V3I7VQ7N.js.map +0 -1
  137. package/dist/chunk-V5WXIM2F.js.map +0 -1
  138. package/dist/chunk-VRXX4D6K.js.map +0 -1
  139. package/dist/chunk-WTJ3AY33.js +0 -31
  140. package/dist/chunk-WTJ3AY33.js.map +0 -1
  141. package/dist/chunk-WVUDLKIO.js +0 -121
  142. package/dist/chunk-WVUDLKIO.js.map +0 -1
  143. package/dist/chunk-WWIFNPJG.js +0 -317
  144. package/dist/chunk-WWIFNPJG.js.map +0 -1
  145. package/dist/chunk-XQHZPINL.js +0 -89
  146. package/dist/chunk-XQHZPINL.js.map +0 -1
  147. package/dist/chunk-XZEVWPX6.js +0 -230
  148. package/dist/chunk-XZEVWPX6.js.map +0 -1
  149. package/dist/chunk-Y3VIRVVE.js.map +0 -1
  150. package/dist/chunk-Y47EV74W.js.map +0 -1
  151. package/dist/components/wizard/category-grid.js +0 -13
  152. package/dist/components/wizard/checkbox-grid.js +0 -12
  153. package/dist/components/wizard/domain-selection.js +0 -18
  154. package/dist/components/wizard/run-wizard-session.js +0 -40
  155. package/dist/components/wizard/run-wizard-session.js.map +0 -1
  156. package/dist/components/wizard/scroll-affordance.js +0 -9
  157. package/dist/components/wizard/skill-agent-summary.js +0 -13
  158. package/dist/components/wizard/source-grid.js +0 -16
  159. package/dist/components/wizard/source-grid.js.map +0 -1
  160. package/dist/components/wizard/stack-selection.js +0 -17
  161. package/dist/components/wizard/stack-selection.js.map +0 -1
  162. package/dist/components/wizard/step-agents.js +0 -18
  163. package/dist/components/wizard/step-agents.js.map +0 -1
  164. package/dist/components/wizard/step-build.js +0 -18
  165. package/dist/components/wizard/step-build.js.map +0 -1
  166. package/dist/components/wizard/step-confirm.js +0 -18
  167. package/dist/components/wizard/step-confirm.js.map +0 -1
  168. package/dist/components/wizard/step-sources.js +0 -19
  169. package/dist/components/wizard/step-sources.js.map +0 -1
  170. package/dist/components/wizard/step-stack.js +0 -18
  171. package/dist/components/wizard/step-stack.js.map +0 -1
  172. package/dist/components/wizard/summary-panel.js +0 -17
  173. package/dist/components/wizard/summary-panel.js.map +0 -1
  174. package/dist/components/wizard/toast.js +0 -9
  175. package/dist/components/wizard/toast.js.map +0 -1
  176. package/dist/components/wizard/wizard-layout.js +0 -22
  177. package/dist/components/wizard/wizard-layout.js.map +0 -1
  178. package/dist/components/wizard/wizard-tabs.js +0 -11
  179. package/dist/components/wizard/wizard-tabs.js.map +0 -1
  180. package/dist/components/wizard/wizard.js +0 -39
  181. package/dist/components/wizard/wizard.js.map +0 -1
  182. package/dist/load-agent-defs-3C27ENC7.js +0 -14
  183. package/dist/load-agent-defs-3C27ENC7.js.map +0 -1
  184. package/dist/recompile-project-agents-DGNBCU3N.js +0 -18
  185. package/dist/recompile-project-agents-DGNBCU3N.js.map +0 -1
  186. package/dist/source-loader-7KZ3MD5O.js.map +0 -1
  187. package/dist/stores/wizard-store.js +0 -24
  188. package/dist/stores/wizard-store.js.map +0 -1
  189. /package/assets/{demo.gif → legacy-wizard.gif} +0 -0
  190. /package/dist/{chunk-ZR4YPKXQ.js.map → chunk-3G7X2WKI.js.map} +0 -0
  191. /package/dist/{chunk-GE3WKJ6Q.js.map → chunk-BMRUNMPV.js.map} +0 -0
  192. /package/dist/{chunk-ZXKBERQU.js.map → chunk-F5EBEATU.js.map} +0 -0
  193. /package/dist/{chunk-PMJWD27C.js.map → chunk-HED2DAXZ.js.map} +0 -0
  194. /package/dist/{chunk-TODCQFRB.js.map → chunk-USVBYQSQ.js.map} +0 -0
  195. /package/dist/{chunk-PXWG7KFO.js.map → chunk-WTWMGH2C.js.map} +0 -0
  196. /package/dist/components/{wizard → common}/scroll-affordance.js.map +0 -0
  197. /package/dist/components/{wizard → common}/skill-agent-summary.js.map +0 -0
  198. /package/dist/{components/wizard/category-grid.js.map → load-agent-defs-YMDWBFDP.js.map} +0 -0
  199. /package/dist/{components/wizard/checkbox-grid.js.map → recompile-project-agents-SZ76WNTW.js.map} +0 -0
  200. /package/dist/{components/wizard/domain-selection.js.map → source-loader-C5SQXZXI.js.map} +0 -0
@@ -1,197 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- useMeasuredHeight
4
- } from "./chunk-TSIU7DME.js";
5
- import {
6
- useKeyboardNavigation
7
- } from "./chunk-JOEA52NR.js";
8
- import {
9
- useRowScroll
10
- } from "./chunk-TTY6DPJN.js";
11
- import {
12
- showWarningsAsToast,
13
- useWizardStore
14
- } from "./chunk-7JNJ52CD.js";
15
- import {
16
- matrix,
17
- typedKeys
18
- } from "./chunk-V5WXIM2F.js";
19
- import {
20
- CLI_COLORS,
21
- UI_SYMBOLS
22
- } from "./chunk-ENGYJCTF.js";
23
-
24
- // src/cli/components/wizard/stack-selection.tsx
25
- import { groupBy } from "remeda";
26
- import { Box, Text } from "ink";
27
- import { useMemo } from "react";
28
- import { jsx, jsxs } from "react/jsx-runtime";
29
- var OTHER_FRAMEWORKS_LABEL = "Other Frameworks";
30
- var GROUP_ORDER = ["React", "CLI"];
31
- var SCRATCH_LABEL = "Start from scratch";
32
- var SCRATCH_DESCRIPTION = "Select domains and skills manually";
33
- function toStackItem(stack) {
34
- return { id: stack.id, name: stack.name, description: stack.description };
35
- }
36
- function compareGroupLabels(a, b) {
37
- const ai = GROUP_ORDER.indexOf(a);
38
- const bi = GROUP_ORDER.indexOf(b);
39
- if (ai !== -1 && bi !== -1) return ai - bi;
40
- if (ai !== -1) return -1;
41
- if (bi !== -1) return 1;
42
- return a.localeCompare(b);
43
- }
44
- function groupStacks(stacks) {
45
- const byLabel = groupBy(stacks, (stack) => stack.group || void 0);
46
- const ungrouped = stacks.filter((stack) => !stack.group).map(toStackItem);
47
- const labelled = Object.entries(byLabel).sort(([a], [b]) => compareGroupLabels(a, b));
48
- if (labelled.length === 0) {
49
- return [{ label: "", items: ungrouped }];
50
- }
51
- const groups = labelled.map(([label, stacksInGroup]) => ({
52
- label,
53
- items: stacksInGroup.map(toStackItem)
54
- }));
55
- return ungrouped.length > 0 ? [...groups, { label: OTHER_FRAMEWORKS_LABEL, items: ungrouped }] : groups;
56
- }
57
- function buildFocusableIds(groups) {
58
- return [...groups.flatMap((g) => g.items.map((i) => i.id)), "scratch"];
59
- }
60
- function buildStackRows(groups) {
61
- const groupRows = groups.flatMap((group, groupIndex) => [
62
- ...groupIndex > 0 ? [{ type: "spacer" }] : [],
63
- ...group.label ? [{ type: "header", label: group.label }] : [],
64
- ...group.items.map((item) => ({ type: "stack", item }))
65
- ]);
66
- return [...groupRows, { type: "spacer" }, { type: "scratch" }];
67
- }
68
- function isRowFocused(row, focusedId) {
69
- if (row.type === "stack") return row.item.id === focusedId;
70
- return row.type === "scratch" && focusedId === "scratch";
71
- }
72
- var StackRow = ({ item, isFocused }) => {
73
- const pointer = isFocused ? UI_SYMBOLS.CHEVRON : UI_SYMBOLS.CHEVRON_SPACER;
74
- return /* @__PURE__ */ jsx(Box, { flexShrink: 0, children: /* @__PURE__ */ jsxs(Text, { children: [
75
- /* @__PURE__ */ jsx(Text, { ...isFocused && { color: CLI_COLORS.PRIMARY }, children: pointer }),
76
- /* @__PURE__ */ jsxs(Text, { ...isFocused && { color: CLI_COLORS.PRIMARY }, bold: isFocused, children: [
77
- " ",
78
- item.name
79
- ] }),
80
- /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
81
- " ",
82
- item.description
83
- ] })
84
- ] }) });
85
- };
86
- var ScratchRow = ({ isFocused }) => {
87
- const pointer = isFocused ? UI_SYMBOLS.CHEVRON : UI_SYMBOLS.CHEVRON_SPACER;
88
- return /* @__PURE__ */ jsx(Box, { flexShrink: 0, children: /* @__PURE__ */ jsxs(Text, { children: [
89
- /* @__PURE__ */ jsx(Text, { ...isFocused && { color: CLI_COLORS.PRIMARY }, children: pointer }),
90
- /* @__PURE__ */ jsxs(Text, { ...isFocused && { color: CLI_COLORS.PRIMARY }, bold: isFocused, children: [
91
- " ",
92
- SCRATCH_LABEL
93
- ] }),
94
- /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
95
- " ",
96
- SCRATCH_DESCRIPTION
97
- ] })
98
- ] }) });
99
- };
100
- var StackSelection = ({ onCancel }) => {
101
- const {
102
- selectStack,
103
- setApproach,
104
- setStackAction,
105
- populateFromSkillIds,
106
- preselectAgentsFromStack,
107
- startFromScratch,
108
- setStep
109
- } = useWizardStore();
110
- const stacks = matrix.suggestedStacks;
111
- const groups = useMemo(() => groupStacks(stacks), [stacks]);
112
- const rows = useMemo(() => buildStackRows(groups), [groups]);
113
- const focusableIds = useMemo(() => buildFocusableIds(groups), [groups]);
114
- const { focusedIndex } = useKeyboardNavigation(focusableIds.length, {
115
- ...onCancel !== void 0 && { onEscape: onCancel },
116
- onEnter: (index) => handleSelect(focusableIds[index] ?? "scratch")
117
- });
118
- const focusedId = focusableIds[focusedIndex] ?? "scratch";
119
- const { ref: listRef, measuredHeight: listHeight } = useMeasuredHeight();
120
- const focusedVisualRow = useMemo(
121
- () => rows.findIndex((row) => isRowFocused(row, focusedId)),
122
- [rows, focusedId]
123
- );
124
- const { scrollEnabled, scrollTop } = useRowScroll({
125
- focusedIndex: focusedVisualRow,
126
- itemCount: rows.length,
127
- availableHeight: listHeight
128
- });
129
- function applyStack(stack) {
130
- selectStack(stack.id);
131
- setStackAction("customize");
132
- const stackAgents = typedKeys(stack.skills);
133
- preselectAgentsFromStack(stackAgents);
134
- const globalPreselections = useWizardStore.getState().globalPreselections;
135
- const globalIds = globalPreselections?.map((s) => s.id) ?? [];
136
- const mergedIds = [.../* @__PURE__ */ new Set([...stack.allSkillIds, ...globalIds])];
137
- showWarningsAsToast(() => populateFromSkillIds(mergedIds, globalPreselections ?? void 0));
138
- setApproach("stack");
139
- setStep("domains");
140
- }
141
- function handleSelect(selectedId) {
142
- if (selectedId === "scratch") {
143
- showWarningsAsToast(startFromScratch);
144
- setStep("domains");
145
- return;
146
- }
147
- const focusedStack = stacks.find((s) => s.id === selectedId);
148
- if (focusedStack) applyStack(focusedStack);
149
- }
150
- return /* @__PURE__ */ jsx(Box, { ref: listRef, flexDirection: "column", flexGrow: 1, flexBasis: 0, children: /* @__PURE__ */ jsx(
151
- Box,
152
- {
153
- flexDirection: "column",
154
- flexGrow: 1,
155
- ...scrollEnabled && { overflow: "hidden" },
156
- children: /* @__PURE__ */ jsx(
157
- Box,
158
- {
159
- flexDirection: "column",
160
- marginTop: scrollTop > 0 ? -scrollTop : 0,
161
- ...scrollEnabled && { flexShrink: 0 },
162
- children: rows.map((row, index) => {
163
- switch (row.type) {
164
- case "spacer":
165
- return /* @__PURE__ */ jsx(Box, { flexShrink: 0, children: /* @__PURE__ */ jsx(Text, { children: " " }) }, `spacer-${index}`);
166
- case "header":
167
- return /* @__PURE__ */ jsx(Box, { flexShrink: 0, children: /* @__PURE__ */ jsxs(Text, { dimColor: true, bold: true, children: [
168
- " ",
169
- row.label
170
- ] }) }, `header-${row.label}`);
171
- case "stack":
172
- return /* @__PURE__ */ jsx(
173
- StackRow,
174
- {
175
- item: row.item,
176
- isFocused: row.item.id === focusedId
177
- },
178
- row.item.id
179
- );
180
- case "scratch":
181
- return /* @__PURE__ */ jsx(ScratchRow, { isFocused: focusedId === "scratch" }, "scratch");
182
- default: {
183
- const _exhaustive = row;
184
- return _exhaustive;
185
- }
186
- }
187
- })
188
- }
189
- )
190
- }
191
- ) });
192
- };
193
-
194
- export {
195
- StackSelection
196
- };
197
- //# sourceMappingURL=chunk-PNB3524H.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/cli/components/wizard/stack-selection.tsx"],"sourcesContent":["import { groupBy } from \"remeda\";\nimport { useKeyboardNavigation } from \"../hooks/use-keyboard-navigation.js\";\nimport { Box, Text } from \"ink\";\nimport React, { useMemo } from \"react\";\nimport { CLI_COLORS, UI_SYMBOLS } from \"../../consts.js\";\nimport { matrix } from \"../../lib/matrix/matrix-provider.js\";\nimport { showWarningsAsToast, useWizardStore } from \"../../stores/wizard-store.js\";\nimport { useMeasuredHeight } from \"../hooks/use-measured-height.js\";\nimport { useRowScroll } from \"../hooks/use-row-scroll.js\";\n\nimport type { AgentName, ResolvedStack } from \"../../types/index.js\";\nimport { typedKeys } from \"../../utils/typed-object.js\";\n\ntype StackItem = Pick<ResolvedStack, \"id\" | \"name\" | \"description\">;\ntype StackGroup = { label: string; items: StackItem[] };\n/** A focusable row id: a stack id, or the \"scratch\" sentinel for the \"Start from scratch\" row. */\ntype FocusId = string;\n\nconst OTHER_FRAMEWORKS_LABEL = \"Other Frameworks\";\nconst GROUP_ORDER: string[] = [\"React\", \"CLI\"];\nconst SCRATCH_LABEL = \"Start from scratch\";\nconst SCRATCH_DESCRIPTION = \"Select domains and skills manually\";\n\ntype GroupableStack = Pick<ResolvedStack, \"id\" | \"name\" | \"description\" | \"group\">;\n\nfunction toStackItem(stack: GroupableStack): StackItem {\n return { id: stack.id, name: stack.name, description: stack.description };\n}\n\n/** GROUP_ORDER labels first (in order), then unknown labels alphabetically. */\nfunction compareGroupLabels(a: string, b: string): number {\n const ai = GROUP_ORDER.indexOf(a);\n const bi = GROUP_ORDER.indexOf(b);\n if (ai !== -1 && bi !== -1) return ai - bi;\n if (ai !== -1) return -1;\n if (bi !== -1) return 1;\n return a.localeCompare(b);\n}\n\nfunction groupStacks(stacks: GroupableStack[]): StackGroup[] {\n // `|| undefined` keeps an empty-string group ungrouped; groupBy drops undefined keys.\n const byLabel = groupBy(stacks, (stack) => stack.group || undefined);\n const ungrouped = stacks.filter((stack) => !stack.group).map(toStackItem);\n\n // No explicit groups — flat list, no headers\n const labelled = Object.entries(byLabel).sort(([a], [b]) => compareGroupLabels(a, b));\n if (labelled.length === 0) {\n return [{ label: \"\", items: ungrouped }];\n }\n\n const groups = labelled.map(([label, stacksInGroup]) => ({\n label,\n items: stacksInGroup.map(toStackItem),\n }));\n return ungrouped.length > 0\n ? [...groups, { label: OTHER_FRAMEWORKS_LABEL, items: ungrouped }]\n : groups;\n}\n\nfunction buildFocusableIds(groups: StackGroup[]): FocusId[] {\n return [...groups.flatMap((g) => g.items.map((i) => i.id)), \"scratch\"];\n}\n\ntype StackListRow =\n | { type: \"header\"; label: string }\n | { type: \"spacer\" }\n | { type: \"stack\"; item: StackItem }\n | { type: \"scratch\" };\n\n/** One row per rendered line — headers, spacers, stack items, then the scratch row. */\nfunction buildStackRows(groups: StackGroup[]): StackListRow[] {\n const groupRows = groups.flatMap((group, groupIndex): StackListRow[] => [\n ...(groupIndex > 0 ? [{ type: \"spacer\" as const }] : []),\n ...(group.label ? [{ type: \"header\" as const, label: group.label }] : []),\n ...group.items.map((item): StackListRow => ({ type: \"stack\", item })),\n ]);\n return [...groupRows, { type: \"spacer\" }, { type: \"scratch\" }];\n}\n\nfunction isRowFocused(row: StackListRow, focusedId: FocusId): boolean {\n if (row.type === \"stack\") return row.item.id === focusedId;\n return row.type === \"scratch\" && focusedId === \"scratch\";\n}\n\nconst StackRow: React.FC<{ item: StackItem; isFocused: boolean }> = ({ item, isFocused }) => {\n const pointer = isFocused ? UI_SYMBOLS.CHEVRON : UI_SYMBOLS.CHEVRON_SPACER;\n return (\n <Box flexShrink={0}>\n <Text>\n <Text {...(isFocused && { color: CLI_COLORS.PRIMARY })}>{pointer}</Text>\n <Text {...(isFocused && { color: CLI_COLORS.PRIMARY })} bold={isFocused}>\n {\" \"}\n {item.name}\n </Text>\n <Text dimColor>\n {\" \"}\n {item.description}\n </Text>\n </Text>\n </Box>\n );\n};\n\nconst ScratchRow: React.FC<{ isFocused: boolean }> = ({ isFocused }) => {\n const pointer = isFocused ? UI_SYMBOLS.CHEVRON : UI_SYMBOLS.CHEVRON_SPACER;\n return (\n <Box flexShrink={0}>\n <Text>\n <Text {...(isFocused && { color: CLI_COLORS.PRIMARY })}>{pointer}</Text>\n <Text {...(isFocused && { color: CLI_COLORS.PRIMARY })} bold={isFocused}>\n {\" \"}\n {SCRATCH_LABEL}\n </Text>\n <Text dimColor>\n {\" \"}\n {SCRATCH_DESCRIPTION}\n </Text>\n </Text>\n </Box>\n );\n};\n\nexport type StackSelectionProps = {\n onCancel?: (() => void) | undefined;\n};\n\nexport const StackSelection: React.FC<StackSelectionProps> = ({ onCancel }) => {\n const {\n selectStack,\n setApproach,\n setStackAction,\n populateFromSkillIds,\n preselectAgentsFromStack,\n startFromScratch,\n setStep,\n } = useWizardStore();\n\n const stacks = matrix.suggestedStacks;\n const groups = useMemo(() => groupStacks(stacks), [stacks]);\n const rows = useMemo(() => buildStackRows(groups), [groups]);\n const focusableIds = useMemo(() => buildFocusableIds(groups), [groups]);\n\n const { focusedIndex } = useKeyboardNavigation(focusableIds.length, {\n ...(onCancel !== undefined && { onEscape: onCancel }),\n onEnter: (index) => handleSelect(focusableIds[index] ?? \"scratch\"),\n });\n const focusedId: FocusId = focusableIds[focusedIndex] ?? \"scratch\";\n const { ref: listRef, measuredHeight: listHeight } = useMeasuredHeight();\n\n const focusedVisualRow = useMemo(\n () => rows.findIndex((row) => isRowFocused(row, focusedId)),\n [rows, focusedId],\n );\n\n const { scrollEnabled, scrollTop } = useRowScroll({\n focusedIndex: focusedVisualRow,\n itemCount: rows.length,\n availableHeight: listHeight,\n });\n\n // The stack's own skills merged with the global preselections, and its agent\n // keys merged with the global agent preselections.\n //\n // The merge is the one population that runs while Ink owns the terminal: the global\n // preselections come from the global config, which can name a skill the loaded source does\n // not carry, so it warns from under a painted frame. `showWarningsAsToast` is what keeps that\n // off a stderr the next repaint would scroll away.\n function applyStack(stack: ResolvedStack): void {\n selectStack(stack.id);\n setStackAction(\"customize\");\n\n const stackAgents = typedKeys<AgentName>(stack.skills);\n preselectAgentsFromStack(stackAgents);\n\n const globalPreselections = useWizardStore.getState().globalPreselections;\n const globalIds = globalPreselections?.map((s) => s.id) ?? [];\n const mergedIds = [...new Set([...stack.allSkillIds, ...globalIds])];\n showWarningsAsToast(() => populateFromSkillIds(mergedIds, globalPreselections ?? undefined));\n\n setApproach(\"stack\");\n setStep(\"domains\");\n }\n\n function handleSelect(selectedId: FocusId): void {\n if (selectedId === \"scratch\") {\n // Same population, same frame: the scratch row applies the global preselections too.\n showWarningsAsToast(startFromScratch);\n setStep(\"domains\");\n return;\n }\n\n const focusedStack = stacks.find((s) => s.id === selectedId);\n if (focusedStack) applyStack(focusedStack);\n }\n\n return (\n <Box ref={listRef} flexDirection=\"column\" flexGrow={1} flexBasis={0}>\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n {...(scrollEnabled && { overflow: \"hidden\" as const })}\n >\n <Box\n flexDirection=\"column\"\n marginTop={scrollTop > 0 ? -scrollTop : 0}\n {...(scrollEnabled && { flexShrink: 0 })}\n >\n {rows.map((row, index) => {\n switch (row.type) {\n case \"spacer\":\n return (\n <Box key={`spacer-${index}`} flexShrink={0}>\n <Text> </Text>\n </Box>\n );\n case \"header\":\n return (\n <Box key={`header-${row.label}`} flexShrink={0}>\n <Text dimColor bold>\n {\" \"}\n {row.label}\n </Text>\n </Box>\n );\n case \"stack\":\n return (\n <StackRow\n key={row.item.id}\n item={row.item}\n isFocused={row.item.id === focusedId}\n />\n );\n case \"scratch\":\n return <ScratchRow key=\"scratch\" isFocused={focusedId === \"scratch\"} />;\n default: {\n const _exhaustive: never = row;\n return _exhaustive;\n }\n }\n })}\n </Box>\n </Box>\n </Box>\n );\n};\n"],"mappings":"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","names":[]}
@@ -1,35 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- isDomain
4
- } from "./chunk-A4KDXNOT.js";
5
- import {
6
- findStack
7
- } from "./chunk-V5WXIM2F.js";
8
-
9
- // src/cli/components/wizard/utils.ts
10
- var DOMAIN_DISPLAY_NAMES = {
11
- web: "Web",
12
- api: "API",
13
- ai: "AI",
14
- cli: "CLI",
15
- mobile: "Mobile",
16
- desktop: "Desktop",
17
- infra: "Infrastructure",
18
- meta: "Meta",
19
- shared: "Shared"
20
- };
21
- function getDomainDisplayName(domain) {
22
- return (isDomain(domain) ? DOMAIN_DISPLAY_NAMES[domain] : null) ?? domain.charAt(0).toUpperCase() + domain.slice(1);
23
- }
24
- function getStackName(stackId) {
25
- if (!stackId) return void 0;
26
- const stack = findStack(stackId);
27
- if (!stack) throw new Error(`Stack not found: ${stackId}`);
28
- return stack.name;
29
- }
30
-
31
- export {
32
- getDomainDisplayName,
33
- getStackName
34
- };
35
- //# sourceMappingURL=chunk-QHDPLLK6.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/cli/components/wizard/utils.ts"],"sourcesContent":["import { findStack } from \"../../lib/matrix/matrix-provider.js\";\nimport { orderDomains } from \"../../lib/wizard/index.js\";\nimport type { Domain } from \"../../types/index.js\";\nimport { isDomain } from \"../../utils/type-guards.js\";\n\nconst DOMAIN_DISPLAY_NAMES: Record<Domain, string> = {\n web: \"Web\",\n api: \"API\",\n ai: \"AI\",\n cli: \"CLI\",\n mobile: \"Mobile\",\n desktop: \"Desktop\",\n infra: \"Infrastructure\",\n meta: \"Meta\",\n shared: \"Shared\",\n};\n\nexport function getDomainDisplayName(domain: string): string {\n return (\n (isDomain(domain) ? DOMAIN_DISPLAY_NAMES[domain] : null) ??\n domain.charAt(0).toUpperCase() + domain.slice(1)\n );\n}\n\n/**\n * Display name of the selected stack, or `undefined` when the wizard is\n * building from scratch — the state each caller renders in its own words\n * (\"your custom stack\" in the tab dropdown, \"none\" in the summary panel).\n *\n * The lookup asserts. `selectedStackId` is written by `selectStack` and nothing\n * else: `createInitialState` starts it at `null`, neither hydration path\n * restores it from config, and `selectStack`'s only non-null argument is\n * `focusedStack.id` in `stack-selection.tsx`, taken from\n * `matrix.suggestedStacks` — the same array `findStack` searches. The matrix is\n * never rebuilt while the wizard is mounted (`initializeMatrix` runs during\n * startup loading; the wizard's own add/remove-source path writes config and\n * re-reads a summary). So a miss is a bug, not a stack to label with its raw id\n * — the same conclusion `wizard.tsx` already reaches for the same lookup.\n */\nexport function getStackName(stackId: string | null): string | undefined {\n if (!stackId) return undefined;\n const stack = findStack(stackId);\n if (!stack) throw new Error(`Stack not found: ${stackId}`);\n return stack.name;\n}\n\nexport { orderDomains };\n"],"mappings":";;;;;;;;;AAKA,IAAM,uBAA+C;AAAA,EACnD,KAAK;AAAA,EACL,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AAAA,EACN,QAAQ;AACV;AAEO,SAAS,qBAAqB,QAAwB;AAC3D,UACG,SAAS,MAAM,IAAI,qBAAqB,MAAM,IAAI,SACnD,OAAO,OAAO,CAAC,EAAE,YAAY,IAAI,OAAO,MAAM,CAAC;AAEnD;AAiBO,SAAS,aAAa,SAA4C;AACvE,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,QAAQ,UAAU,OAAO;AAC/B,MAAI,CAAC,MAAO,OAAM,IAAI,MAAM,oBAAoB,OAAO,EAAE;AACzD,SAAO,MAAM;AACf;","names":[]}
@@ -1,25 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- SummaryPanel
4
- } from "./chunk-2VUYFTUB.js";
5
-
6
- // src/cli/components/wizard/step-confirm.tsx
7
- import { useInput } from "ink";
8
- import "react";
9
- import { jsx } from "react/jsx-runtime";
10
- var StepConfirm = ({ onComplete, onBack }) => {
11
- useInput((_input, key) => {
12
- if (key.return) {
13
- onComplete();
14
- }
15
- if (key.escape) {
16
- onBack();
17
- }
18
- });
19
- return /* @__PURE__ */ jsx(SummaryPanel, {});
20
- };
21
-
22
- export {
23
- StepConfirm
24
- };
25
- //# sourceMappingURL=chunk-RAHSOJQ2.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/cli/components/wizard/step-confirm.tsx"],"sourcesContent":["import { useInput } from \"ink\";\nimport React from \"react\";\nimport { SummaryPanel } from \"./summary-panel.js\";\n\ntype StepConfirmProps = {\n onComplete: () => void;\n onBack: () => void;\n};\n\n/**\n * Final step: the shared `SummaryPanel`, which owns the scroll and the `↑`/`↓`\n * keys. This claims only the two keys that leave the step, so both `useInput`\n * hooks stay on disjoint keys.\n */\nexport const StepConfirm: React.FC<StepConfirmProps> = ({ onComplete, onBack }) => {\n useInput((_input, key) => {\n if (key.return) {\n onComplete();\n }\n if (key.escape) {\n onBack();\n }\n });\n\n return <SummaryPanel />;\n};\n"],"mappings":";;;;;;AAAA,SAAS,gBAAgB;AACzB,OAAkB;AAuBT;AAVF,IAAM,cAA0C,CAAC,EAAE,YAAY,OAAO,MAAM;AACjF,WAAS,CAAC,QAAQ,QAAQ;AACxB,QAAI,IAAI,QAAQ;AACd,iBAAW;AAAA,IACb;AACA,QAAI,IAAI,QAAQ;AACd,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,SAAO,oBAAC,gBAAa;AACvB;","names":[]}
@@ -1,23 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- MIN_TERMINAL_SIZE
4
- } from "./chunk-ENGYJCTF.js";
5
-
6
- // src/cli/utils/terminal.ts
7
- function clearTerminalScreen() {
8
- process.stdout.write("\x1B[H\x1B[2J\x1B[3J");
9
- }
10
- function isTerminalLargeEnough(columns, rows) {
11
- return columns >= MIN_TERMINAL_SIZE.COLS && rows >= MIN_TERMINAL_SIZE.ROWS;
12
- }
13
- function formatTerminalTooSmallMessage(columns) {
14
- const issue = columns < MIN_TERMINAL_SIZE.COLS ? `too narrow (need ${MIN_TERMINAL_SIZE.COLS})` : `too short (need ${MIN_TERMINAL_SIZE.ROWS})`;
15
- return `Terminal ${issue}. Please resize.`;
16
- }
17
-
18
- export {
19
- clearTerminalScreen,
20
- isTerminalLargeEnough,
21
- formatTerminalTooSmallMessage
22
- };
23
- //# sourceMappingURL=chunk-RZDXDMT6.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/cli/utils/terminal.ts"],"sourcesContent":["import { MIN_TERMINAL_SIZE } from \"../consts.js\";\n\n/**\n * Clears the terminal screen and scrollback, moving the cursor to the top.\n * Shared by BaseCommand.clearTerminal and the init dashboard.\n */\nexport function clearTerminalScreen(): void {\n process.stdout.write(\"\\x1b[H\\x1b[2J\\x1b[3J\");\n}\n\n/** Whether the terminal clears {@link MIN_TERMINAL_SIZE} in BOTH dimensions. */\nexport function isTerminalLargeEnough(columns: number, rows: number): boolean {\n return columns >= MIN_TERMINAL_SIZE.COLS && rows >= MIN_TERMINAL_SIZE.ROWS;\n}\n\n/**\n * The one resize prompt, worded in one place because two gates print it and they\n * must not drift: `BaseCommand.ensureTerminalSize` blocks a command from\n * launching too small, and `WizardLayout` replaces the wizard tree when the\n * terminal shrinks under a session already running. The E2E constants\n * `STEP_TEXT.TOO_NARROW` / `TOO_SHORT` key off this text, so a second wording\n * would leave one of the two gates unassertable.\n *\n * Precondition: {@link isTerminalLargeEnough} is false. Width is reported in\n * preference to height, so \"not too narrow\" here means \"too short\" — which is\n * why the height is not a parameter.\n */\nexport function formatTerminalTooSmallMessage(columns: number): string {\n const issue =\n columns < MIN_TERMINAL_SIZE.COLS\n ? `too narrow (need ${MIN_TERMINAL_SIZE.COLS})`\n : `too short (need ${MIN_TERMINAL_SIZE.ROWS})`;\n return `Terminal ${issue}. Please resize.`;\n}\n"],"mappings":";;;;;;AAMO,SAAS,sBAA4B;AAC1C,UAAQ,OAAO,MAAM,sBAAsB;AAC7C;AAGO,SAAS,sBAAsB,SAAiB,MAAuB;AAC5E,SAAO,WAAW,kBAAkB,QAAQ,QAAQ,kBAAkB;AACxE;AAcO,SAAS,8BAA8B,SAAyB;AACrE,QAAM,QACJ,UAAU,kBAAkB,OACxB,oBAAoB,kBAAkB,IAAI,MAC1C,mBAAmB,kBAAkB,IAAI;AAC/C,SAAO,YAAY,KAAK;AAC1B;","names":[]}
@@ -1,17 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- StackSelection
4
- } from "./chunk-PNB3524H.js";
5
-
6
- // src/cli/components/wizard/step-stack.tsx
7
- import { Box } from "ink";
8
- import "react";
9
- import { jsx } from "react/jsx-runtime";
10
- var StepStack = ({ onCancel }) => {
11
- return /* @__PURE__ */ jsx(Box, { flexDirection: "column", width: "100%", flexGrow: 1, flexBasis: 0, children: /* @__PURE__ */ jsx(Box, { flexGrow: 1, flexBasis: 0, children: /* @__PURE__ */ jsx(StackSelection, { onCancel }) }) });
12
- };
13
-
14
- export {
15
- StepStack
16
- };
17
- //# sourceMappingURL=chunk-SCOQ34YM.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/cli/components/wizard/step-stack.tsx"],"sourcesContent":["import { Box } from \"ink\";\nimport React from \"react\";\nimport { StackSelection } from \"./stack-selection.js\";\n\ntype StepStackProps = {\n onCancel?: () => void;\n};\n\n/**\n * First step of the wizard: select a stack or \"Start from scratch\".\n *\n * After selection, the wizard transitions to the \"domains\" step.\n */\nexport const StepStack: React.FC<StepStackProps> = ({ onCancel }) => {\n return (\n <Box flexDirection=\"column\" width=\"100%\" flexGrow={1} flexBasis={0}>\n <Box flexGrow={1} flexBasis={0}>\n <StackSelection onCancel={onCancel} />\n </Box>\n </Box>\n );\n};\n"],"mappings":";;;;;;AAAA,SAAS,WAAW;AACpB,OAAkB;AAgBV;AAJD,IAAM,YAAsC,CAAC,EAAE,SAAS,MAAM;AACnE,SACE,oBAAC,OAAI,eAAc,UAAS,OAAM,QAAO,UAAU,GAAG,WAAW,GAC/D,8BAAC,OAAI,UAAU,GAAG,WAAW,GAC3B,8BAAC,kBAAe,UAAoB,GACtC,GACF;AAEJ;","names":[]}
@@ -1,268 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- useFocusedListItem
4
- } from "./chunk-XQHZPINL.js";
5
- import {
6
- HOTKEY_TOGGLE_LABELS,
7
- KEY_SPACE,
8
- isHotkey
9
- } from "./chunk-WTJ3AY33.js";
10
- import {
11
- useSectionScroll
12
- } from "./chunk-WVUDLKIO.js";
13
- import {
14
- getSkillById
15
- } from "./chunk-V5WXIM2F.js";
16
- import {
17
- CLI_COLORS
18
- } from "./chunk-ENGYJCTF.js";
19
-
20
- // src/cli/components/wizard/category-grid.tsx
21
- import { useCallback as useCallback2, useEffect as useEffect2 } from "react";
22
- import { Box, Text } from "ink";
23
-
24
- // src/cli/components/hooks/use-category-grid-input.ts
25
- import { useCallback, useEffect, useMemo, useRef } from "react";
26
- import { useInput } from "ink";
27
- var findNextIndex = (items, currentIndex) => {
28
- const length = items.length;
29
- if (length === 0) return currentIndex;
30
- return (currentIndex + 1) % length;
31
- };
32
- function useCategoryGridInput({
33
- categories,
34
- focusedRow,
35
- focusedCol,
36
- currentFocus,
37
- setFocused,
38
- moveFocus,
39
- onToggle,
40
- onToggleLabels
41
- }) {
42
- const currentRow = categories[focusedRow];
43
- const currentOptions = useMemo(() => currentRow?.options ?? [], [currentRow]);
44
- useEffect(() => {
45
- if (!currentRow) return;
46
- const maxCol = currentOptions.length - 1;
47
- if (focusedCol > maxCol) {
48
- const newCol = Math.max(0, maxCol);
49
- setFocused(focusedRow, newCol);
50
- }
51
- }, [focusedRow, currentOptions, focusedCol, setFocused, currentRow]);
52
- const handlerRef = useRef(null);
53
- handlerRef.current = (input, key) => {
54
- if (key.tab && key.shift) {
55
- onToggleLabels();
56
- return;
57
- }
58
- if (key.tab && !key.shift) {
59
- const { row } = currentFocus();
60
- const nextSection = findNextIndex(categories, row);
61
- if (nextSection !== row) {
62
- setFocused(nextSection, 0);
63
- }
64
- return;
65
- }
66
- if (isHotkey(input, HOTKEY_TOGGLE_LABELS)) {
67
- onToggleLabels();
68
- return;
69
- }
70
- if (input === KEY_SPACE) {
71
- const { row, col } = currentFocus();
72
- const category = categories[row];
73
- const option = category?.options[col];
74
- if (category && option) {
75
- onToggle(category.id, option.id);
76
- }
77
- return;
78
- }
79
- const isLeft = key.leftArrow || input === "h";
80
- const isRight = key.rightArrow || input === "l";
81
- const isUp = key.upArrow || input === "k";
82
- const isDown = key.downArrow || input === "j";
83
- if (isLeft) {
84
- moveFocus("left");
85
- } else if (isRight) {
86
- moveFocus("right");
87
- } else if (isUp) {
88
- moveFocus("up");
89
- } else if (isDown) {
90
- moveFocus("down");
91
- }
92
- };
93
- const stableHandler = useCallback((input, key) => {
94
- handlerRef.current?.(input, key);
95
- }, []);
96
- useInput(stableHandler);
97
- }
98
-
99
- // src/cli/components/wizard/category-grid.tsx
100
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
101
- var wrapOptionIndex = (length, currentIndex, direction) => {
102
- if (length === 0) return currentIndex;
103
- return (currentIndex + direction + length) % length;
104
- };
105
- var advisoryAnnotation = (state) => state.status === "normal" ? null : `(${state.status}: ${state.reason})`;
106
- var getCompatibilityLabel = (option) => {
107
- if (option.selected && option.hasUnmetRequirements && option.unmetRequirementsReason) {
108
- return `(${option.unmetRequirementsReason})`;
109
- }
110
- if (option.selected) return null;
111
- if (option.requiredBy) return `(required by ${option.requiredBy})`;
112
- return advisoryAnnotation(option.state);
113
- };
114
- var STATUS_COLORS = {
115
- incompatible: CLI_COLORS.ERROR,
116
- discouraged: CLI_COLORS.WARNING
117
- };
118
- function resolveTagColor(option, fallback) {
119
- if (option.selected) return CLI_COLORS.PRIMARY;
120
- return STATUS_COLORS[option.state.status] ?? fallback;
121
- }
122
- var SkillTag = ({ option, isFocused, showLabels }) => {
123
- const textColor = resolveTagColor(option, CLI_COLORS.DIM);
124
- const hasRequiredBy = option.selected && !!option.requiredBy;
125
- const hasUnmetDeps = option.selected && !!option.hasUnmetRequirements;
126
- const isDimmed = hasUnmetDeps || hasRequiredBy;
127
- const showCompatibility = hasRequiredBy || hasUnmetDeps || showLabels && isFocused;
128
- const compatibilityLabel = showCompatibility ? getCompatibilityLabel(option) : null;
129
- return /* @__PURE__ */ jsx(
130
- Box,
131
- {
132
- marginRight: 1,
133
- borderColor: isFocused ? resolveTagColor(option, CLI_COLORS.UNFOCUSED) : textColor,
134
- borderDimColor: !isFocused,
135
- borderStyle: "single",
136
- flexShrink: 0,
137
- paddingLeft: 1,
138
- flexDirection: "row",
139
- children: /* @__PURE__ */ jsxs(Fragment, { children: [
140
- option.scope && /* @__PURE__ */ jsxs(Fragment, { children: [
141
- [option.scope, option.secondaryScope].filter(Boolean).map((badgeScope, i) => /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.WARNING, backgroundColor: CLI_COLORS.LABEL_BG, children: badgeScope === "global" ? " G " : " P " }, i)),
142
- /* @__PURE__ */ jsx(Text, { children: " " })
143
- ] }),
144
- /* @__PURE__ */ jsxs(Text, { color: textColor, bold: true, dimColor: isDimmed, children: [
145
- getSkillById(option.id).displayName,
146
- " "
147
- ] }),
148
- compatibilityLabel && /* @__PURE__ */ jsxs(Text, { color: textColor, dimColor: true, children: [
149
- compatibilityLabel,
150
- " "
151
- ] })
152
- ] })
153
- }
154
- );
155
- };
156
- var CategorySection = ({
157
- isFirst,
158
- category,
159
- isFocused,
160
- focusedOptionIndex,
161
- showLabels
162
- }) => {
163
- const { options } = category;
164
- const selectedCount = options.filter((o) => o.selected).length;
165
- const selectionCounter = category.exclusive ? `(${selectedCount} of 1)` : null;
166
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: isFirst ? 0 : 1, children: [
167
- /* @__PURE__ */ jsx(Box, { flexDirection: "row", children: isFocused ? /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.WHITE, backgroundColor: CLI_COLORS.LABEL_BG, children: ` ${category.displayName}${selectionCounter ? ` ${selectionCounter}` : ""} ` }) : /* @__PURE__ */ jsxs(Fragment, { children: [
168
- /* @__PURE__ */ jsx(Text, { color: CLI_COLORS.NEUTRAL, children: category.displayName }),
169
- selectionCounter && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
170
- " ",
171
- selectionCounter
172
- ] })
173
- ] }) }),
174
- /* @__PURE__ */ jsx(Box, { flexDirection: "row", flexWrap: "wrap", marginTop: 0, children: options.map((option, index) => /* @__PURE__ */ jsx(
175
- SkillTag,
176
- {
177
- option,
178
- isFocused: isFocused && index === focusedOptionIndex,
179
- showLabels
180
- },
181
- option.id
182
- )) })
183
- ] });
184
- };
185
- var CategoryGrid = ({
186
- categories,
187
- availableHeight = 0,
188
- showLabels,
189
- onToggle,
190
- onToggleLabels,
191
- defaultFocusedRow = 0,
192
- defaultFocusedCol = 0,
193
- onFocusChange,
194
- onFocusedSkillChange
195
- }) => {
196
- const getColCount = useCallback2(
197
- (row) => categories[row]?.options.length ?? 0,
198
- [categories]
199
- );
200
- const findValidCol = useCallback2(
201
- (row, currentCol, direction) => wrapOptionIndex(categories[row]?.options.length ?? 0, currentCol, direction),
202
- [categories]
203
- );
204
- const handleFocusChange = useCallback2(
205
- (row, col) => {
206
- if (showLabels) onToggleLabels();
207
- onFocusChange?.(row, col);
208
- },
209
- [showLabels, onToggleLabels, onFocusChange]
210
- );
211
- const { focusedRow, focusedCol, currentFocus, setFocused, moveFocus } = useFocusedListItem(
212
- categories.length,
213
- getColCount,
214
- {
215
- wrap: true,
216
- findValidCol,
217
- onChange: handleFocusChange,
218
- initialRow: defaultFocusedRow,
219
- initialCol: defaultFocusedCol
220
- }
221
- );
222
- useCategoryGridInput({
223
- categories,
224
- focusedRow,
225
- focusedCol,
226
- currentFocus,
227
- setFocused,
228
- moveFocus,
229
- onToggle,
230
- onToggleLabels
231
- });
232
- const focusedSkillId = categories[focusedRow]?.options[focusedCol]?.id ?? null;
233
- useEffect2(() => {
234
- onFocusedSkillChange?.(focusedSkillId);
235
- }, [focusedSkillId, onFocusedSkillChange]);
236
- const { setSectionRef, scrollEnabled, scrollTopPx } = useSectionScroll({
237
- sectionCount: categories.length,
238
- focusedIndex: focusedRow,
239
- availableHeight
240
- });
241
- if (categories.length === 0) {
242
- return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: "No categories to display." }) });
243
- }
244
- const noShrink = scrollEnabled ? { flexShrink: 0 } : {};
245
- const sectionElements = categories.map((category, index) => /* @__PURE__ */ jsx(Box, { ref: (el) => setSectionRef(index, el), ...noShrink, children: /* @__PURE__ */ jsx(
246
- CategorySection,
247
- {
248
- category,
249
- isFocused: index === focusedRow,
250
- focusedOptionIndex: focusedCol,
251
- showLabels,
252
- isFirst: index === 0
253
- }
254
- ) }, category.id));
255
- return /* @__PURE__ */ jsx(
256
- Box,
257
- {
258
- flexDirection: "column",
259
- ...scrollEnabled ? { height: availableHeight, overflow: "hidden" } : { flexGrow: 1 },
260
- children: /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginTop: scrollTopPx > 0 ? -scrollTopPx : 0, ...noShrink, children: sectionElements })
261
- }
262
- );
263
- };
264
-
265
- export {
266
- CategoryGrid
267
- };
268
- //# sourceMappingURL=chunk-SXVHSOTH.js.map