@claude-collective/cli 0.26.1 → 0.29.5
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.
- package/CHANGELOG.md +123 -0
- package/README.md +47 -13
- package/config/skills-matrix.yaml +1 -1
- package/config/stacks.yaml +331 -94
- package/dist/{chunk-NT4K647L.js → chunk-4DX47646.js} +97 -76
- package/dist/chunk-4DX47646.js.map +1 -0
- package/dist/{chunk-KWYO3M5Q.js → chunk-4JSKL5SD.js} +25 -24
- package/dist/chunk-4JSKL5SD.js.map +1 -0
- package/dist/chunk-52XVP55K.js +165 -0
- package/dist/chunk-52XVP55K.js.map +1 -0
- package/dist/{chunk-OBXAY23Y.js → chunk-5I6VY2E7.js} +5 -5
- package/dist/chunk-5I6VY2E7.js.map +1 -0
- package/dist/{chunk-324DM2L6.js → chunk-5WIHSJRO.js} +230 -65
- package/dist/chunk-5WIHSJRO.js.map +1 -0
- package/dist/chunk-73E5CQUK.js +142 -0
- package/dist/chunk-73E5CQUK.js.map +1 -0
- package/dist/{chunk-DBRUQQUF.js → chunk-7GHTQSWI.js} +5 -1
- package/dist/{chunk-DBRUQQUF.js.map → chunk-7GHTQSWI.js.map} +1 -1
- package/dist/chunk-7ICBJZV2.js +63 -0
- package/dist/chunk-7ICBJZV2.js.map +1 -0
- package/dist/{chunk-CQ7657GA.js → chunk-ABK6CSWI.js} +1248 -735
- package/dist/chunk-ABK6CSWI.js.map +1 -0
- package/dist/{chunk-ZW2PELOH.js → chunk-AGNT3FUE.js} +106 -69
- package/dist/chunk-AGNT3FUE.js.map +1 -0
- package/dist/{chunk-F4RD5FYM.js → chunk-AGQRRJSY.js} +5 -2
- package/dist/chunk-AGQRRJSY.js.map +1 -0
- package/dist/{chunk-GGFOD5PK.js → chunk-AXND7NCM.js} +122 -66
- package/dist/chunk-AXND7NCM.js.map +1 -0
- package/dist/{chunk-NQJ47R4N.js → chunk-CQZAKMPJ.js} +66 -14
- package/dist/chunk-CQZAKMPJ.js.map +1 -0
- package/dist/{chunk-XENOESJZ.js → chunk-DALU3Y3U.js} +10 -67
- package/dist/chunk-DALU3Y3U.js.map +1 -0
- package/dist/chunk-DDNK5UNE.js +366 -0
- package/dist/chunk-DDNK5UNE.js.map +1 -0
- package/dist/chunk-DIRH4PDF.js +24 -0
- package/dist/chunk-DIRH4PDF.js.map +1 -0
- package/dist/{chunk-VVYNZZUX.js → chunk-DTFEFLUU.js} +9 -5
- package/dist/chunk-DTFEFLUU.js.map +1 -0
- package/dist/chunk-F23LEXMC.js +81 -0
- package/dist/chunk-F23LEXMC.js.map +1 -0
- package/dist/chunk-FUPBGSRA.js +66 -0
- package/dist/chunk-FUPBGSRA.js.map +1 -0
- package/dist/{chunk-U7HFKR74.js → chunk-H2NM6BDH.js} +5 -2
- package/dist/chunk-H2NM6BDH.js.map +1 -0
- package/dist/chunk-HJS2FWLA.js +75 -0
- package/dist/chunk-HJS2FWLA.js.map +1 -0
- package/dist/{chunk-MCTSHLAF.js → chunk-I6YQDA2J.js} +41 -14
- package/dist/chunk-I6YQDA2J.js.map +1 -0
- package/dist/{chunk-G35SYE6Z.js → chunk-J3J2WPI2.js} +37 -104
- package/dist/chunk-J3J2WPI2.js.map +1 -0
- package/dist/{chunk-HIQGK5XJ.js → chunk-JDQDYGGC.js} +123 -86
- package/dist/chunk-JDQDYGGC.js.map +1 -0
- package/dist/chunk-JWIH7YQE.js +88 -0
- package/dist/chunk-JWIH7YQE.js.map +1 -0
- package/dist/{chunk-4S4FCAA2.js → chunk-KFL72CWK.js} +26 -31
- package/dist/chunk-KFL72CWK.js.map +1 -0
- package/dist/{chunk-H7SSBSPR.js → chunk-LY5HM34M.js} +8 -5
- package/dist/chunk-LY5HM34M.js.map +1 -0
- package/dist/{chunk-2YMMJP4Z.js → chunk-PRY6MLN3.js} +92 -29
- package/dist/chunk-PRY6MLN3.js.map +1 -0
- package/dist/{chunk-3X5D7RM5.js → chunk-RFW2RIM7.js} +15 -4
- package/dist/chunk-RFW2RIM7.js.map +1 -0
- package/dist/chunk-RXC7AF7N.js +31 -0
- package/dist/chunk-RXC7AF7N.js.map +1 -0
- package/dist/chunk-VBOBVQQW.js +29 -0
- package/dist/chunk-VBOBVQQW.js.map +1 -0
- package/dist/{chunk-ETCVEV3S.js → chunk-VIBOSHRL.js} +242 -155
- package/dist/chunk-VIBOSHRL.js.map +1 -0
- package/dist/chunk-WPED6CL3.js +105 -0
- package/dist/chunk-WPED6CL3.js.map +1 -0
- package/dist/chunk-Z6UK6MI2.js +233 -0
- package/dist/chunk-Z6UK6MI2.js.map +1 -0
- package/dist/{chunk-CZBNDP5B.js → chunk-ZCIWRQQ4.js} +3 -3
- package/dist/commands/build/marketplace.js +21 -20
- package/dist/commands/build/marketplace.js.map +1 -1
- package/dist/commands/build/plugins.js +7 -11
- package/dist/commands/build/plugins.js.map +1 -1
- package/dist/commands/build/stack.js +8 -13
- package/dist/commands/build/stack.js.map +1 -1
- package/dist/commands/compile.js +109 -135
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/config/get.js +4 -5
- package/dist/commands/config/get.js.map +1 -1
- package/dist/commands/config/index.js +5 -6
- package/dist/commands/config/index.js.map +1 -1
- package/dist/commands/config/path.js +4 -5
- package/dist/commands/config/path.js.map +1 -1
- package/dist/commands/config/set-project.js +4 -5
- package/dist/commands/config/set-project.js.map +1 -1
- package/dist/commands/config/show.js +5 -6
- package/dist/commands/config/unset-project.js +4 -5
- package/dist/commands/config/unset-project.js.map +1 -1
- package/dist/commands/diff.js +26 -11
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/doctor.js +13 -16
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/edit.js +71 -42
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/eject.js +34 -14
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/import/skill.js +93 -52
- package/dist/commands/import/skill.js.map +1 -1
- package/dist/commands/info.js +27 -9
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/init.js +98 -48
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/list.js +10 -5
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/new/agent.js +8 -11
- package/dist/commands/new/agent.js.map +1 -1
- package/dist/commands/new/skill.js +17 -18
- package/dist/commands/new/skill.js.map +1 -1
- package/dist/commands/outdated.js +23 -9
- package/dist/commands/outdated.js.map +1 -1
- package/dist/commands/search.js +23 -20
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/uninstall.js +28 -21
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.js +30 -22
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/validate.js +103 -39
- package/dist/commands/validate.js.map +1 -1
- package/dist/commands/version/bump.js +4 -5
- package/dist/commands/version/bump.js.map +1 -1
- package/dist/commands/version/index.js +4 -5
- package/dist/commands/version/index.js.map +1 -1
- package/dist/commands/version/set.js +4 -5
- package/dist/commands/version/set.js.map +1 -1
- package/dist/commands/version/show.js +4 -5
- package/dist/commands/version/show.js.map +1 -1
- package/dist/components/common/confirm.test.js +2 -2
- package/dist/components/common/confirm.test.js.map +1 -1
- package/dist/components/skill-search/skill-search.js +4 -2
- package/dist/components/wizard/category-grid.js +3 -1
- package/dist/components/wizard/category-grid.test.js +63 -64
- package/dist/components/wizard/category-grid.test.js.map +1 -1
- package/dist/components/wizard/domain-selection.js +13 -0
- package/dist/components/wizard/help-modal.js +10 -0
- package/dist/components/wizard/help-modal.js.map +1 -0
- package/dist/components/wizard/menu-item.js +2 -1
- package/dist/components/wizard/search-modal.js +3 -1
- package/dist/components/wizard/search-modal.test.js +4 -2
- package/dist/components/wizard/search-modal.test.js.map +1 -1
- package/dist/components/wizard/section-progress.js +2 -1
- package/dist/components/wizard/section-progress.test.js +2 -1
- package/dist/components/wizard/section-progress.test.js.map +1 -1
- package/dist/components/wizard/source-grid.js +6 -2
- package/dist/components/wizard/source-grid.test.js +49 -45
- package/dist/components/wizard/source-grid.test.js.map +1 -1
- package/dist/components/wizard/stack-selection.js +15 -0
- package/dist/components/wizard/stack-selection.js.map +1 -0
- package/dist/components/wizard/step-approach.js +8 -6
- package/dist/components/wizard/step-approach.test.js +11 -9
- package/dist/components/wizard/step-approach.test.js.map +1 -1
- package/dist/components/wizard/step-build.js +9 -13
- package/dist/components/wizard/step-build.test.js +27 -45
- package/dist/components/wizard/step-build.test.js.map +1 -1
- package/dist/components/wizard/step-confirm.js +2 -1
- package/dist/components/wizard/step-confirm.test.js +6 -5
- package/dist/components/wizard/step-confirm.test.js.map +1 -1
- package/dist/components/wizard/step-refine.js +2 -1
- package/dist/components/wizard/step-refine.test.js +3 -2
- package/dist/components/wizard/step-refine.test.js.map +1 -1
- package/dist/components/wizard/step-settings.js +8 -6
- package/dist/components/wizard/step-settings.test.js +12 -10
- package/dist/components/wizard/step-settings.test.js.map +1 -1
- package/dist/components/wizard/step-sources.js +11 -9
- package/dist/components/wizard/step-sources.test.js +16 -15
- package/dist/components/wizard/step-sources.test.js.map +1 -1
- package/dist/components/wizard/step-stack.js +9 -6
- package/dist/components/wizard/step-stack.test.js +15 -12
- package/dist/components/wizard/step-stack.test.js.map +1 -1
- package/dist/components/wizard/view-title.js +2 -1
- package/dist/components/wizard/wizard-layout.js +7 -9
- package/dist/components/wizard/wizard-tabs.js +2 -1
- package/dist/components/wizard/wizard-tabs.test.js +2 -1
- package/dist/components/wizard/wizard-tabs.test.js.map +1 -1
- package/dist/components/wizard/wizard.js +26 -20
- package/dist/config/skills-matrix.yaml +1 -1
- package/dist/config/stacks.yaml +331 -94
- package/dist/hooks/init.js +3 -4
- package/dist/hooks/init.js.map +1 -1
- package/dist/source-manager-JUPEIBMY.js +15 -0
- package/dist/source-manager-JUPEIBMY.js.map +1 -0
- package/dist/src/agents/developer/api-developer/agent.yaml +1 -1
- package/dist/src/agents/developer/cli-developer/agent.yaml +1 -1
- package/dist/src/agents/developer/web-architecture/agent.yaml +1 -1
- package/dist/src/agents/developer/web-developer/agent.yaml +1 -1
- package/dist/src/agents/meta/agent-summoner/agent.yaml +1 -1
- package/dist/src/agents/meta/documentor/agent.yaml +1 -1
- package/dist/src/agents/meta/skill-summoner/agent.yaml +1 -1
- package/dist/src/agents/meta/skill-summoner/output-format.md +1 -1
- package/dist/src/agents/migration/cli-migrator/agent.yaml +1 -1
- package/dist/src/agents/pattern/pattern-scout/agent.yaml +1 -1
- package/dist/src/agents/pattern/web-pattern-critique/agent.yaml +1 -1
- package/dist/src/agents/planning/web-pm/agent.yaml +1 -1
- package/dist/src/agents/researcher/api-researcher/agent.yaml +1 -1
- package/dist/src/agents/researcher/web-researcher/agent.yaml +1 -1
- package/dist/src/agents/reviewer/api-reviewer/agent.yaml +1 -1
- package/dist/src/agents/reviewer/cli-reviewer/agent.yaml +1 -1
- package/dist/src/agents/reviewer/web-reviewer/agent.yaml +1 -1
- package/dist/src/agents/tester/cli-tester/agent.yaml +1 -1
- package/dist/src/agents/tester/web-tester/agent.yaml +1 -1
- package/dist/stores/wizard-store.js +4 -3
- package/dist/stores/wizard-store.test.js +272 -25
- package/dist/stores/wizard-store.test.js.map +1 -1
- package/package.json +2 -1
- package/src/agents/developer/api-developer/agent.yaml +1 -1
- package/src/agents/developer/cli-developer/agent.yaml +1 -1
- package/src/agents/developer/web-architecture/agent.yaml +1 -1
- package/src/agents/developer/web-developer/agent.yaml +1 -1
- package/src/agents/meta/agent-summoner/agent.yaml +1 -1
- package/src/agents/meta/documentor/agent.yaml +1 -1
- package/src/agents/meta/skill-summoner/agent.yaml +1 -1
- package/src/agents/meta/skill-summoner/output-format.md +1 -1
- package/src/agents/migration/cli-migrator/agent.yaml +1 -1
- package/src/agents/pattern/pattern-scout/agent.yaml +1 -1
- package/src/agents/pattern/web-pattern-critique/agent.yaml +1 -1
- package/src/agents/planning/web-pm/agent.yaml +1 -1
- package/src/agents/researcher/api-researcher/agent.yaml +1 -1
- package/src/agents/researcher/web-researcher/agent.yaml +1 -1
- package/src/agents/reviewer/api-reviewer/agent.yaml +1 -1
- package/src/agents/reviewer/cli-reviewer/agent.yaml +1 -1
- package/src/agents/reviewer/web-reviewer/agent.yaml +1 -1
- package/src/agents/tester/cli-tester/agent.yaml +1 -1
- package/src/agents/tester/web-tester/agent.yaml +1 -1
- package/src/schemas/agent-frontmatter.schema.json +84 -0
- package/src/schemas/agent.schema.json +93 -0
- package/src/schemas/hooks.schema.json +47 -0
- package/src/schemas/marketplace.schema.json +119 -0
- package/src/schemas/metadata.schema.json +113 -0
- package/src/schemas/plugin.schema.json +130 -0
- package/src/schemas/project-config.schema.json +125 -0
- package/src/schemas/project-source-config.schema.json +81 -0
- package/src/schemas/skill-frontmatter.schema.json +42 -0
- package/src/schemas/skills-matrix.schema.json +467 -0
- package/src/schemas/stack.schema.json +191 -0
- package/src/schemas/stacks.schema.json +111 -0
- package/dist/chunk-2OW7FCIF.js +0 -197
- package/dist/chunk-2OW7FCIF.js.map +0 -1
- package/dist/chunk-2YMMJP4Z.js.map +0 -1
- package/dist/chunk-324DM2L6.js.map +0 -1
- package/dist/chunk-3X5D7RM5.js.map +0 -1
- package/dist/chunk-4S4FCAA2.js.map +0 -1
- package/dist/chunk-CQ7657GA.js.map +0 -1
- package/dist/chunk-ETCVEV3S.js.map +0 -1
- package/dist/chunk-F4RD5FYM.js.map +0 -1
- package/dist/chunk-G35SYE6Z.js.map +0 -1
- package/dist/chunk-GGFOD5PK.js.map +0 -1
- package/dist/chunk-H7SSBSPR.js.map +0 -1
- package/dist/chunk-HIQGK5XJ.js.map +0 -1
- package/dist/chunk-HWD32NP7.js +0 -19
- package/dist/chunk-HWD32NP7.js.map +0 -1
- package/dist/chunk-KWYO3M5Q.js.map +0 -1
- package/dist/chunk-MCTSHLAF.js.map +0 -1
- package/dist/chunk-NQJ47R4N.js.map +0 -1
- package/dist/chunk-NT4K647L.js.map +0 -1
- package/dist/chunk-O6ZTD7ZI.js +0 -70
- package/dist/chunk-O6ZTD7ZI.js.map +0 -1
- package/dist/chunk-OBXAY23Y.js.map +0 -1
- package/dist/chunk-TMED5DQ2.js +0 -210
- package/dist/chunk-TMED5DQ2.js.map +0 -1
- package/dist/chunk-U7HFKR74.js.map +0 -1
- package/dist/chunk-UEMRJI2K.js +0 -146
- package/dist/chunk-UEMRJI2K.js.map +0 -1
- package/dist/chunk-UNN7523L.js +0 -78
- package/dist/chunk-UNN7523L.js.map +0 -1
- package/dist/chunk-VVYNZZUX.js.map +0 -1
- package/dist/chunk-XENOESJZ.js.map +0 -1
- package/dist/chunk-ZW2PELOH.js.map +0 -1
- package/dist/source-manager-VWIIDTK5.js +0 -16
- /package/dist/{chunk-CZBNDP5B.js.map → chunk-ZCIWRQQ4.js.map} +0 -0
- /package/dist/{source-manager-VWIIDTK5.js.map → components/wizard/domain-selection.js.map} +0 -0
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
RENDER_DELAY_MS,
|
|
9
9
|
TAB,
|
|
10
10
|
delay
|
|
11
|
-
} from "../../chunk-
|
|
11
|
+
} from "../../chunk-7GHTQSWI.js";
|
|
12
12
|
import {
|
|
13
13
|
render
|
|
14
14
|
} from "../../chunk-REJGRCVQ.js";
|
|
@@ -21,7 +21,9 @@ import {
|
|
|
21
21
|
} from "../../chunk-QR2EBWL2.js";
|
|
22
22
|
import {
|
|
23
23
|
CategoryGrid
|
|
24
|
-
} from "../../chunk-
|
|
24
|
+
} from "../../chunk-VIBOSHRL.js";
|
|
25
|
+
import "../../chunk-WPED6CL3.js";
|
|
26
|
+
import "../../chunk-52XVP55K.js";
|
|
25
27
|
import {
|
|
26
28
|
init_esm_shims
|
|
27
29
|
} from "../../chunk-AWKZ5BDL.js";
|
|
@@ -123,8 +125,8 @@ var categoriesWithFramework = [
|
|
|
123
125
|
];
|
|
124
126
|
var defaultProps = {
|
|
125
127
|
categories: defaultCategories,
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
defaultFocusedRow: 0,
|
|
129
|
+
defaultFocusedCol: 0,
|
|
128
130
|
showDescriptions: false,
|
|
129
131
|
expertMode: false,
|
|
130
132
|
onToggle: vi.fn(),
|
|
@@ -266,8 +268,8 @@ describe("CategoryGrid component", () => {
|
|
|
266
268
|
describe("focus indicator", () => {
|
|
267
269
|
it("should render focused option with label text", () => {
|
|
268
270
|
const { lastFrame, unmount } = renderGrid({
|
|
269
|
-
|
|
270
|
-
|
|
271
|
+
defaultFocusedRow: 0,
|
|
272
|
+
defaultFocusedCol: 0
|
|
271
273
|
});
|
|
272
274
|
cleanup = unmount;
|
|
273
275
|
const output = lastFrame();
|
|
@@ -276,15 +278,15 @@ describe("CategoryGrid component", () => {
|
|
|
276
278
|
it("should render correctly when focusedRow changes", () => {
|
|
277
279
|
const { lastFrame: frame1, unmount: unmount1 } = renderGrid({
|
|
278
280
|
categories: categoriesWithFramework,
|
|
279
|
-
|
|
280
|
-
|
|
281
|
+
defaultFocusedRow: 0,
|
|
282
|
+
defaultFocusedCol: 0
|
|
281
283
|
});
|
|
282
284
|
const output1 = frame1();
|
|
283
285
|
unmount1();
|
|
284
286
|
const { lastFrame: frame2, unmount: unmount2 } = renderGrid({
|
|
285
287
|
categories: categoriesWithFramework,
|
|
286
|
-
|
|
287
|
-
|
|
288
|
+
defaultFocusedRow: 1,
|
|
289
|
+
defaultFocusedCol: 0
|
|
288
290
|
});
|
|
289
291
|
cleanup = unmount2;
|
|
290
292
|
const output2 = frame2();
|
|
@@ -294,8 +296,8 @@ describe("CategoryGrid component", () => {
|
|
|
294
296
|
it("should highlight focused category name", () => {
|
|
295
297
|
const { lastFrame, unmount } = renderGrid({
|
|
296
298
|
categories: categoriesWithFramework,
|
|
297
|
-
|
|
298
|
-
|
|
299
|
+
defaultFocusedRow: 1,
|
|
300
|
+
defaultFocusedCol: 0
|
|
299
301
|
});
|
|
300
302
|
cleanup = unmount;
|
|
301
303
|
const output = lastFrame();
|
|
@@ -306,8 +308,8 @@ describe("CategoryGrid component", () => {
|
|
|
306
308
|
it("should call onFocusChange when pressing left arrow", async () => {
|
|
307
309
|
const onFocusChange = vi.fn();
|
|
308
310
|
const { stdin, unmount } = renderGrid({
|
|
309
|
-
|
|
310
|
-
|
|
311
|
+
defaultFocusedRow: 0,
|
|
312
|
+
defaultFocusedCol: 1,
|
|
311
313
|
onFocusChange
|
|
312
314
|
});
|
|
313
315
|
cleanup = unmount;
|
|
@@ -319,8 +321,8 @@ describe("CategoryGrid component", () => {
|
|
|
319
321
|
it("should call onFocusChange when pressing right arrow", async () => {
|
|
320
322
|
const onFocusChange = vi.fn();
|
|
321
323
|
const { stdin, unmount } = renderGrid({
|
|
322
|
-
|
|
323
|
-
|
|
324
|
+
defaultFocusedRow: 0,
|
|
325
|
+
defaultFocusedCol: 0,
|
|
324
326
|
onFocusChange
|
|
325
327
|
});
|
|
326
328
|
cleanup = unmount;
|
|
@@ -332,8 +334,8 @@ describe("CategoryGrid component", () => {
|
|
|
332
334
|
it("should call onFocusChange when pressing up arrow (wraps to framework when locked)", async () => {
|
|
333
335
|
const onFocusChange = vi.fn();
|
|
334
336
|
const { stdin, unmount } = renderGrid({
|
|
335
|
-
|
|
336
|
-
|
|
337
|
+
defaultFocusedRow: 0,
|
|
338
|
+
defaultFocusedCol: 0,
|
|
337
339
|
onFocusChange
|
|
338
340
|
});
|
|
339
341
|
cleanup = unmount;
|
|
@@ -346,8 +348,8 @@ describe("CategoryGrid component", () => {
|
|
|
346
348
|
const onFocusChange = vi.fn();
|
|
347
349
|
const { stdin, unmount } = renderGrid({
|
|
348
350
|
categories: categoriesWithFramework,
|
|
349
|
-
|
|
350
|
-
|
|
351
|
+
defaultFocusedRow: 0,
|
|
352
|
+
defaultFocusedCol: 0,
|
|
351
353
|
onFocusChange
|
|
352
354
|
});
|
|
353
355
|
cleanup = unmount;
|
|
@@ -359,8 +361,8 @@ describe("CategoryGrid component", () => {
|
|
|
359
361
|
it("should wrap horizontally when pressing left at first column", async () => {
|
|
360
362
|
const onFocusChange = vi.fn();
|
|
361
363
|
const { stdin, unmount } = renderGrid({
|
|
362
|
-
|
|
363
|
-
|
|
364
|
+
defaultFocusedRow: 0,
|
|
365
|
+
defaultFocusedCol: 0,
|
|
364
366
|
onFocusChange
|
|
365
367
|
});
|
|
366
368
|
cleanup = unmount;
|
|
@@ -372,8 +374,8 @@ describe("CategoryGrid component", () => {
|
|
|
372
374
|
it("should wrap horizontally when pressing right at last column", async () => {
|
|
373
375
|
const onFocusChange = vi.fn();
|
|
374
376
|
const { stdin, unmount } = renderGrid({
|
|
375
|
-
|
|
376
|
-
|
|
377
|
+
defaultFocusedRow: 0,
|
|
378
|
+
defaultFocusedCol: 3,
|
|
377
379
|
// Last option in framework
|
|
378
380
|
onFocusChange
|
|
379
381
|
});
|
|
@@ -387,8 +389,8 @@ describe("CategoryGrid component", () => {
|
|
|
387
389
|
const onFocusChange = vi.fn();
|
|
388
390
|
const { stdin, unmount } = renderGrid({
|
|
389
391
|
categories: categoriesWithFramework,
|
|
390
|
-
|
|
391
|
-
|
|
392
|
+
defaultFocusedRow: 0,
|
|
393
|
+
defaultFocusedCol: 0,
|
|
392
394
|
onFocusChange
|
|
393
395
|
});
|
|
394
396
|
cleanup = unmount;
|
|
@@ -402,8 +404,8 @@ describe("CategoryGrid component", () => {
|
|
|
402
404
|
it("should move left with h key", async () => {
|
|
403
405
|
const onFocusChange = vi.fn();
|
|
404
406
|
const { stdin, unmount } = renderGrid({
|
|
405
|
-
|
|
406
|
-
|
|
407
|
+
defaultFocusedRow: 0,
|
|
408
|
+
defaultFocusedCol: 1,
|
|
407
409
|
onFocusChange
|
|
408
410
|
});
|
|
409
411
|
cleanup = unmount;
|
|
@@ -415,8 +417,8 @@ describe("CategoryGrid component", () => {
|
|
|
415
417
|
it("should move right with l key", async () => {
|
|
416
418
|
const onFocusChange = vi.fn();
|
|
417
419
|
const { stdin, unmount } = renderGrid({
|
|
418
|
-
|
|
419
|
-
|
|
420
|
+
defaultFocusedRow: 0,
|
|
421
|
+
defaultFocusedCol: 0,
|
|
420
422
|
onFocusChange
|
|
421
423
|
});
|
|
422
424
|
cleanup = unmount;
|
|
@@ -429,8 +431,8 @@ describe("CategoryGrid component", () => {
|
|
|
429
431
|
const onFocusChange = vi.fn();
|
|
430
432
|
const { stdin, unmount } = renderGrid({
|
|
431
433
|
categories: categoriesWithFramework,
|
|
432
|
-
|
|
433
|
-
|
|
434
|
+
defaultFocusedRow: 1,
|
|
435
|
+
defaultFocusedCol: 0,
|
|
434
436
|
onFocusChange
|
|
435
437
|
});
|
|
436
438
|
cleanup = unmount;
|
|
@@ -443,8 +445,8 @@ describe("CategoryGrid component", () => {
|
|
|
443
445
|
const onFocusChange = vi.fn();
|
|
444
446
|
const { stdin, unmount } = renderGrid({
|
|
445
447
|
categories: categoriesWithFramework,
|
|
446
|
-
|
|
447
|
-
|
|
448
|
+
defaultFocusedRow: 0,
|
|
449
|
+
defaultFocusedCol: 0,
|
|
448
450
|
onFocusChange
|
|
449
451
|
});
|
|
450
452
|
cleanup = unmount;
|
|
@@ -458,8 +460,8 @@ describe("CategoryGrid component", () => {
|
|
|
458
460
|
it("should call onToggle when pressing space on a normal option", async () => {
|
|
459
461
|
const onToggle = vi.fn();
|
|
460
462
|
const { stdin, unmount } = renderGrid({
|
|
461
|
-
|
|
462
|
-
|
|
463
|
+
defaultFocusedRow: 0,
|
|
464
|
+
defaultFocusedCol: 1,
|
|
463
465
|
// vue (normal state)
|
|
464
466
|
onToggle
|
|
465
467
|
});
|
|
@@ -484,8 +486,8 @@ describe("CategoryGrid component", () => {
|
|
|
484
486
|
];
|
|
485
487
|
const { stdin, unmount } = renderGrid({
|
|
486
488
|
categories,
|
|
487
|
-
|
|
488
|
-
|
|
489
|
+
defaultFocusedRow: 0,
|
|
490
|
+
defaultFocusedCol: 0,
|
|
489
491
|
// react (selected)
|
|
490
492
|
expertMode: true,
|
|
491
493
|
onToggle
|
|
@@ -496,19 +498,18 @@ describe("CategoryGrid component", () => {
|
|
|
496
498
|
await delay(INPUT_DELAY_MS);
|
|
497
499
|
globalExpect(onToggle).toHaveBeenCalledWith("framework", "web-test-react");
|
|
498
500
|
});
|
|
499
|
-
it("should NOT call onToggle when
|
|
501
|
+
it("should NOT call onToggle when all options in a category are disabled", async () => {
|
|
500
502
|
const onToggle = vi.fn();
|
|
501
503
|
const categories = [
|
|
502
504
|
createCategory("testing", "Test", [
|
|
503
505
|
createOption("web-test-opt1", "Option 1", { state: "disabled" }),
|
|
504
|
-
createOption("web-test-opt2", "Option 2")
|
|
506
|
+
createOption("web-test-opt2", "Option 2", { state: "disabled" })
|
|
505
507
|
])
|
|
506
508
|
];
|
|
507
509
|
const { stdin, unmount } = renderGrid({
|
|
508
510
|
categories,
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
// Disabled option (first in expert mode)
|
|
511
|
+
defaultFocusedRow: 0,
|
|
512
|
+
defaultFocusedCol: 0,
|
|
512
513
|
expertMode: true,
|
|
513
514
|
onToggle
|
|
514
515
|
});
|
|
@@ -518,19 +519,17 @@ describe("CategoryGrid component", () => {
|
|
|
518
519
|
await delay(INPUT_DELAY_MS);
|
|
519
520
|
globalExpect(onToggle).not.toHaveBeenCalled();
|
|
520
521
|
});
|
|
521
|
-
it("should
|
|
522
|
-
const
|
|
523
|
-
const {
|
|
524
|
-
|
|
522
|
+
it("should bounce focus away from locked sections on mount", async () => {
|
|
523
|
+
const onFocusChange = vi.fn();
|
|
524
|
+
const { unmount } = renderGrid({
|
|
525
|
+
defaultFocusedRow: 1,
|
|
525
526
|
// Styling (locked)
|
|
526
|
-
|
|
527
|
-
|
|
527
|
+
defaultFocusedCol: 0,
|
|
528
|
+
onFocusChange
|
|
528
529
|
});
|
|
529
530
|
cleanup = unmount;
|
|
530
531
|
await delay(RENDER_DELAY_MS);
|
|
531
|
-
|
|
532
|
-
await delay(INPUT_DELAY_MS);
|
|
533
|
-
globalExpect(onToggle).not.toHaveBeenCalled();
|
|
532
|
+
globalExpect(onFocusChange).toHaveBeenCalledWith(0, 0);
|
|
534
533
|
});
|
|
535
534
|
});
|
|
536
535
|
describe("disabled options navigation", () => {
|
|
@@ -545,8 +544,8 @@ describe("CategoryGrid component", () => {
|
|
|
545
544
|
];
|
|
546
545
|
const { stdin, unmount } = renderGrid({
|
|
547
546
|
categories,
|
|
548
|
-
|
|
549
|
-
|
|
547
|
+
defaultFocusedRow: 0,
|
|
548
|
+
defaultFocusedCol: 0,
|
|
550
549
|
expertMode: true,
|
|
551
550
|
onFocusChange
|
|
552
551
|
});
|
|
@@ -567,8 +566,8 @@ describe("CategoryGrid component", () => {
|
|
|
567
566
|
];
|
|
568
567
|
const { stdin, unmount } = renderGrid({
|
|
569
568
|
categories,
|
|
570
|
-
|
|
571
|
-
|
|
569
|
+
defaultFocusedRow: 0,
|
|
570
|
+
defaultFocusedCol: 2,
|
|
572
571
|
// Start at opt3
|
|
573
572
|
expertMode: true,
|
|
574
573
|
onFocusChange
|
|
@@ -589,8 +588,8 @@ describe("CategoryGrid component", () => {
|
|
|
589
588
|
];
|
|
590
589
|
const { stdin, unmount } = renderGrid({
|
|
591
590
|
categories,
|
|
592
|
-
|
|
593
|
-
|
|
591
|
+
defaultFocusedRow: 0,
|
|
592
|
+
defaultFocusedCol: 0,
|
|
594
593
|
expertMode: true,
|
|
595
594
|
onFocusChange
|
|
596
595
|
});
|
|
@@ -614,8 +613,8 @@ describe("CategoryGrid component", () => {
|
|
|
614
613
|
const onFocusChange = vi.fn();
|
|
615
614
|
const { stdin, unmount } = renderGrid({
|
|
616
615
|
categories: categoriesWithFramework,
|
|
617
|
-
|
|
618
|
-
|
|
616
|
+
defaultFocusedRow: 0,
|
|
617
|
+
defaultFocusedCol: 0,
|
|
619
618
|
onFocusChange
|
|
620
619
|
});
|
|
621
620
|
cleanup = unmount;
|
|
@@ -627,8 +626,8 @@ describe("CategoryGrid component", () => {
|
|
|
627
626
|
it("should only jump to unlocked sections", async () => {
|
|
628
627
|
const onFocusChange = vi.fn();
|
|
629
628
|
const { stdin, unmount } = renderGrid({
|
|
630
|
-
|
|
631
|
-
|
|
629
|
+
defaultFocusedRow: 0,
|
|
630
|
+
defaultFocusedCol: 0,
|
|
632
631
|
onFocusChange
|
|
633
632
|
});
|
|
634
633
|
cleanup = unmount;
|
|
@@ -778,8 +777,8 @@ describe("CategoryGrid component", () => {
|
|
|
778
777
|
];
|
|
779
778
|
const { stdin, unmount } = renderGrid({
|
|
780
779
|
categories,
|
|
781
|
-
|
|
782
|
-
|
|
780
|
+
defaultFocusedRow: 0,
|
|
781
|
+
defaultFocusedCol: 2,
|
|
783
782
|
// Last option in first row
|
|
784
783
|
onFocusChange
|
|
785
784
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/components/wizard/category-grid.test.tsx"],"sourcesContent":["import React from \"react\";\nimport { render } from \"ink-testing-library\";\nimport { describe, expect, it, afterEach, vi } from \"vitest\";\nimport {\n CategoryGrid,\n type CategoryGridProps,\n type CategoryRow,\n type CategoryOption,\n} from \"./category-grid\";\nimport type { SkillId, Subcategory } from \"../../types\";\nimport {\n ARROW_UP,\n ARROW_DOWN,\n ARROW_LEFT,\n ARROW_RIGHT,\n TAB,\n RENDER_DELAY_MS,\n INPUT_DELAY_MS,\n delay,\n} from \"../../lib/__tests__/test-constants\";\n\nconst createOption = (\n id: SkillId,\n label: string,\n overrides: Partial<CategoryOption> = {},\n): CategoryOption => ({\n id,\n label,\n state: \"normal\",\n selected: false,\n ...overrides,\n});\n\nconst createCategory = (\n id: Subcategory,\n displayName: string,\n options: CategoryOption[],\n overrides: Partial<CategoryRow> = {},\n): CategoryRow => ({\n id,\n displayName,\n required: false,\n exclusive: true,\n options,\n ...overrides,\n});\n\nconst defaultCategories: CategoryRow[] = [\n createCategory(\n \"framework\",\n \"Framework\",\n [\n createOption(\"web-test-react\", \"React\", {\n state: \"recommended\",\n stateReason: \"Popular choice\",\n }),\n createOption(\"web-test-vue\", \"Vue\"),\n createOption(\"web-test-angular\", \"Angular\"),\n createOption(\"web-test-svelte\", \"Svelte\"),\n ],\n { required: true },\n ),\n createCategory(\n \"styling\",\n \"Styling\",\n [\n createOption(\"web-scss-mod\", \"SCSS Modules\", { selected: true }),\n createOption(\"web-test-tailwind\", \"Tailwind\", { state: \"recommended\" }),\n createOption(\"web-test-styled\", \"Styled Components\"),\n createOption(\"web-test-vanilla\", \"Vanilla CSS\"),\n ],\n { required: true },\n ),\n createCategory(\"client-state\", \"Client State\", [\n createOption(\"web-test-zustand\", \"Zustand\", { state: \"recommended\" }),\n createOption(\"web-test-jotai\", \"Jotai\"),\n createOption(\"web-test-redux\", \"Redux\", {\n state: \"discouraged\",\n stateReason: \"Complex for most apps\",\n }),\n createOption(\"web-test-mobx\", \"MobX\"),\n ]),\n createCategory(\"server-state\", \"Server State\", [\n createOption(\"web-react-query\", \"React Query\", { selected: true }),\n createOption(\"web-test-swr\", \"SWR\"),\n createOption(\"web-test-apollo\", \"Apollo\"),\n ]),\n createCategory(\"analytics\", \"Analytics\", [createOption(\"web-test-posthog\", \"PostHog\")]),\n];\n\nconst categoriesWithFramework: CategoryRow[] = [\n createCategory(\n \"framework\",\n \"Framework\",\n [\n createOption(\"web-test-react\", \"React\", {\n state: \"recommended\",\n stateReason: \"Popular choice\",\n selected: true, // Framework selected\n }),\n createOption(\"web-test-vue\", \"Vue\"),\n createOption(\"web-test-angular\", \"Angular\"),\n createOption(\"web-test-svelte\", \"Svelte\"),\n ],\n { required: true },\n ),\n createCategory(\n \"styling\",\n \"Styling\",\n [\n createOption(\"web-scss-mod\", \"SCSS Modules\"),\n createOption(\"web-test-tailwind\", \"Tailwind\", { state: \"recommended\" }),\n createOption(\"web-test-styled\", \"Styled Components\"),\n createOption(\"web-test-vanilla\", \"Vanilla CSS\"),\n ],\n { required: true },\n ),\n createCategory(\"client-state\", \"Client State\", [\n createOption(\"web-test-zustand\", \"Zustand\", { state: \"recommended\" }),\n createOption(\"web-test-jotai\", \"Jotai\"),\n createOption(\"web-test-redux\", \"Redux\", { state: \"discouraged\" }),\n createOption(\"web-test-mobx\", \"MobX\"),\n ]),\n];\n\nconst defaultProps: CategoryGridProps = {\n categories: defaultCategories,\n focusedRow: 0,\n focusedCol: 0,\n showDescriptions: false,\n expertMode: false,\n onToggle: vi.fn(),\n onFocusChange: vi.fn(),\n onToggleDescriptions: vi.fn(),\n};\n\nconst renderGrid = (props: Partial<CategoryGridProps> = {}) => {\n return render(<CategoryGrid {...defaultProps} {...props} />);\n};\n\ndescribe(\"CategoryGrid component\", () => {\n let cleanup: (() => void) | undefined;\n\n afterEach(() => {\n cleanup?.();\n cleanup = undefined;\n });\n\n describe(\"rendering\", () => {\n it(\"should render all categories as sections\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Framework\");\n expect(output).toContain(\"Styling\");\n expect(output).toContain(\"Client State\");\n expect(output).toContain(\"Server State\");\n expect(output).toContain(\"Analytics\");\n });\n\n it(\"should render all options in each category\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n // Framework options\n expect(output).toContain(\"React\");\n expect(output).toContain(\"Vue\");\n expect(output).toContain(\"Angular\");\n expect(output).toContain(\"Svelte\");\n // Styling options\n expect(output).toContain(\"SCSS Modules\");\n expect(output).toContain(\"Tailwind\");\n });\n\n it(\"should show required indicator (*) for required categories\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n // Framework and Styling are required\n // The * should appear after their names\n expect(output).toContain(\"*\");\n });\n\n it(\"should NOT show (optional) for non-required categories\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n // Optional is assumed by default, so we don't show the label\n expect(output).not.toContain(\"(optional)\");\n });\n\n it(\"should handle empty categories array\", () => {\n const { lastFrame, unmount } = renderGrid({ categories: [] });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"No categories to display\");\n });\n\n it(\"should render section underlines\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n // Unicode horizontal line character used for underlines\n expect(output).toContain(\"\\u2500\");\n });\n });\n\n describe(\"visual states\", () => {\n it(\"should show selected options with label text\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n // scss-mod and react-query are selected in defaultCategories\n expect(output).toContain(\"SCSS Modules\");\n expect(output).toContain(\"React Query\");\n });\n\n it(\"should show unselected options with label text\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n // Unselected options should display their labels\n expect(output).toContain(\"Vue\");\n expect(output).toContain(\"Angular\");\n });\n\n it(\"should NOT show star indicator for recommended options (uses background instead)\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n // Should NOT contain star (⭐) for recommended\n expect(output).not.toContain(\"\\u2B50\");\n });\n\n it(\"should NOT show warning indicator for discouraged options (uses color instead)\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n // Should NOT contain warning (⚠) for discouraged\n expect(output).not.toContain(\"\\u26A0\");\n });\n\n it(\"should show disabled options with dimmed styling\", () => {\n const categories: CategoryRow[] = [\n createCategory(\"testing\", \"Test\", [\n createOption(\"web-test-opt1\", \"Option 1\"),\n createOption(\"web-test-opt2\", \"Option 2\", { state: \"disabled\" }),\n ]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ categories });\n cleanup = unmount;\n\n const output = lastFrame();\n // Disabled options should show label (dimmed text)\n expect(output).toContain(\"Option 2\");\n });\n });\n\n describe(\"locked sections\", () => {\n it(\"should show all categories including locked ones\", () => {\n // No framework selected, so non-framework sections should be locked but visible\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Framework\");\n expect(output).toContain(\"Styling\");\n expect(output).toContain(\"Client State\");\n });\n\n it(\"should unlock sections when framework is selected\", () => {\n const { lastFrame, unmount } = renderGrid({\n categories: categoriesWithFramework,\n });\n cleanup = unmount;\n\n const output = lastFrame();\n // All sections should be visible and navigable\n expect(output).toContain(\"Framework\");\n expect(output).toContain(\"Styling\");\n expect(output).toContain(\"Client State\");\n });\n\n it(\"should not lock any sections when no framework category exists\", () => {\n const categoriesNoFramework: CategoryRow[] = [\n createCategory(\"styling\", \"Styling\", [\n createOption(\"web-test-scss\", \"SCSS\"),\n createOption(\"web-test-tailwind\", \"Tailwind\"),\n ]),\n createCategory(\"client-state\", \"State\", [createOption(\"web-test-zustand\", \"Zustand\")]),\n ];\n\n const { lastFrame, unmount } = renderGrid({\n categories: categoriesNoFramework,\n });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Styling\");\n expect(output).toContain(\"State\");\n });\n });\n\n describe(\"focus indicator\", () => {\n it(\"should render focused option with label text\", () => {\n const { lastFrame, unmount } = renderGrid({\n focusedRow: 0,\n focusedCol: 0,\n });\n cleanup = unmount;\n\n const output = lastFrame();\n // Focused option should be visible (background highlighting is visual-only)\n expect(output).toContain(\"React\");\n });\n\n it(\"should render correctly when focusedRow changes\", () => {\n const { lastFrame: frame1, unmount: unmount1 } = renderGrid({\n categories: categoriesWithFramework,\n focusedRow: 0,\n focusedCol: 0,\n });\n const output1 = frame1();\n unmount1();\n\n const { lastFrame: frame2, unmount: unmount2 } = renderGrid({\n categories: categoriesWithFramework,\n focusedRow: 1,\n focusedCol: 0,\n });\n cleanup = unmount2;\n const output2 = frame2();\n\n // Both should render the focused category options\n expect(output1).toContain(\"Framework\");\n expect(output2).toContain(\"Styling\");\n });\n\n it(\"should highlight focused category name\", () => {\n const { lastFrame, unmount } = renderGrid({\n categories: categoriesWithFramework,\n focusedRow: 1,\n focusedCol: 0,\n });\n cleanup = unmount;\n\n const output = lastFrame();\n // Styling row should be focused (index 1)\n expect(output).toContain(\"Styling\");\n });\n });\n\n describe(\"keyboard navigation - arrow keys\", () => {\n it(\"should call onFocusChange when pressing left arrow\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n focusedRow: 0,\n focusedCol: 1,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_LEFT);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should call onFocusChange when pressing right arrow\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n focusedRow: 0,\n focusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_RIGHT);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 1);\n });\n\n it(\"should call onFocusChange when pressing up arrow (wraps to framework when locked)\", async () => {\n const onFocusChange = vi.fn();\n // No framework selected, so navigation stays on framework row\n const { stdin, unmount } = renderGrid({\n focusedRow: 0,\n focusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_UP);\n await delay(INPUT_DELAY_MS);\n\n // Should stay on row 0 (framework) since other rows are locked\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should navigate between sections when unlocked\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n categories: categoriesWithFramework,\n focusedRow: 0,\n focusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_DOWN);\n await delay(INPUT_DELAY_MS);\n\n // Should move to row 1 (Styling) since framework is selected\n expect(onFocusChange).toHaveBeenCalledWith(1, 0);\n });\n\n it(\"should wrap horizontally when pressing left at first column\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n focusedRow: 0,\n focusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_LEFT);\n await delay(INPUT_DELAY_MS);\n\n // Should wrap to last column (index 3 for framework with 4 options)\n expect(onFocusChange).toHaveBeenCalledWith(0, 3);\n });\n\n it(\"should wrap horizontally when pressing right at last column\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n focusedRow: 0,\n focusedCol: 3, // Last option in framework\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_RIGHT);\n await delay(INPUT_DELAY_MS);\n\n // Should wrap to first column\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should wrap vertically when all sections are unlocked\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n categories: categoriesWithFramework,\n focusedRow: 0,\n focusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_UP);\n await delay(INPUT_DELAY_MS);\n\n // Should wrap to last row (index 2 for 3 categories)\n expect(onFocusChange).toHaveBeenCalledWith(2, 0);\n });\n });\n\n describe(\"keyboard navigation - vim keys\", () => {\n it(\"should move left with h key\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n focusedRow: 0,\n focusedCol: 1,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(\"h\");\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should move right with l key\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n focusedRow: 0,\n focusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(\"l\");\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 1);\n });\n\n it(\"should move up with k key\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n categories: categoriesWithFramework,\n focusedRow: 1,\n focusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(\"k\");\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should move down with j key\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n categories: categoriesWithFramework,\n focusedRow: 0,\n focusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(\"j\");\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(1, 0);\n });\n });\n\n describe(\"selection toggle\", () => {\n it(\"should call onToggle when pressing space on a normal option\", async () => {\n const onToggle = vi.fn();\n const { stdin, unmount } = renderGrid({\n focusedRow: 0,\n focusedCol: 1, // vue (normal state)\n onToggle,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(\" \"); // Space\n await delay(INPUT_DELAY_MS);\n\n expect(onToggle).toHaveBeenCalledWith(\"framework\", \"web-test-vue\");\n });\n\n it(\"should call onToggle when pressing space on a selected option\", async () => {\n const onToggle = vi.fn();\n // Use expertMode to preserve original option order\n const categories: CategoryRow[] = [\n createCategory(\n \"framework\",\n \"Framework\",\n [\n createOption(\"web-test-react\", \"React\", { selected: true }),\n createOption(\"web-test-vue\", \"Vue\"),\n ],\n { required: true },\n ),\n ];\n const { stdin, unmount } = renderGrid({\n categories,\n focusedRow: 0,\n focusedCol: 0, // react (selected)\n expertMode: true,\n onToggle,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(\" \");\n await delay(INPUT_DELAY_MS);\n\n expect(onToggle).toHaveBeenCalledWith(\"framework\", \"web-test-react\");\n });\n\n it(\"should NOT call onToggle when pressing space on a disabled option\", async () => {\n const onToggle = vi.fn();\n const categories: CategoryRow[] = [\n createCategory(\"testing\", \"Test\", [\n createOption(\"web-test-opt1\", \"Option 1\", { state: \"disabled\" }),\n createOption(\"web-test-opt2\", \"Option 2\"),\n ]),\n ];\n\n // Use expertMode to preserve original option order (disabled at index 0)\n const { stdin, unmount } = renderGrid({\n categories,\n focusedRow: 0,\n focusedCol: 0, // Disabled option (first in expert mode)\n expertMode: true,\n onToggle,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(\" \");\n await delay(INPUT_DELAY_MS);\n\n expect(onToggle).not.toHaveBeenCalled();\n });\n\n it(\"should NOT call onToggle when section is locked\", async () => {\n const onToggle = vi.fn();\n // No framework selected, styling section is locked\n const { stdin, unmount } = renderGrid({\n focusedRow: 1, // Styling (locked)\n focusedCol: 0,\n onToggle,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(\" \");\n await delay(INPUT_DELAY_MS);\n\n expect(onToggle).not.toHaveBeenCalled();\n });\n });\n\n describe(\"disabled options navigation\", () => {\n it(\"should skip disabled options when navigating right\", async () => {\n const onFocusChange = vi.fn();\n const categories: CategoryRow[] = [\n createCategory(\"testing\", \"Test\", [\n createOption(\"web-test-opt1\", \"Option 1\"),\n createOption(\"web-test-opt2\", \"Option 2\", { state: \"disabled\" }),\n createOption(\"web-test-opt3\", \"Option 3\"),\n ]),\n ];\n\n // Use expertMode to preserve original option order\n const { stdin, unmount } = renderGrid({\n categories,\n focusedRow: 0,\n focusedCol: 0,\n expertMode: true,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_RIGHT);\n await delay(INPUT_DELAY_MS);\n\n // Should skip opt2 (disabled) and go to opt3 (index 2)\n expect(onFocusChange).toHaveBeenCalledWith(0, 2);\n });\n\n it(\"should skip disabled options when navigating left\", async () => {\n const onFocusChange = vi.fn();\n const categories: CategoryRow[] = [\n createCategory(\"testing\", \"Test\", [\n createOption(\"web-test-opt1\", \"Option 1\"),\n createOption(\"web-test-opt2\", \"Option 2\", { state: \"disabled\" }),\n createOption(\"web-test-opt3\", \"Option 3\"),\n ]),\n ];\n\n // Use expertMode to preserve original option order\n const { stdin, unmount } = renderGrid({\n categories,\n focusedRow: 0,\n focusedCol: 2, // Start at opt3\n expertMode: true,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_LEFT);\n await delay(INPUT_DELAY_MS);\n\n // Should skip opt2 (disabled) and go to opt1 (index 0)\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should handle all options disabled in a row\", async () => {\n const onFocusChange = vi.fn();\n const categories: CategoryRow[] = [\n createCategory(\"testing\", \"Test\", [\n createOption(\"web-test-opt1\", \"Option 1\", { state: \"disabled\" }),\n createOption(\"web-test-opt2\", \"Option 2\", { state: \"disabled\" }),\n ]),\n ];\n\n // Use expertMode to preserve original option order\n const { stdin, unmount } = renderGrid({\n categories,\n focusedRow: 0,\n focusedCol: 0,\n expertMode: true,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_RIGHT);\n await delay(INPUT_DELAY_MS);\n\n // Should stay at current position when all disabled\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n });\n\n describe(\"exclusive categories\", () => {\n it(\"should render exclusive category correctly\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n // All default categories are exclusive, should render normally\n expect(output).toContain(\"Framework\");\n });\n\n // Note: The actual exclusivity logic (only one selection) is handled\n // by the parent component via onToggle. CategoryGrid just displays\n // the current state.\n });\n\n describe(\"tab navigation\", () => {\n it(\"should jump to next section when pressing Tab\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n categories: categoriesWithFramework,\n focusedRow: 0,\n focusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(TAB);\n await delay(INPUT_DELAY_MS);\n\n // Should jump to next section (row 1)\n expect(onFocusChange).toHaveBeenCalledWith(1, 0);\n });\n\n it(\"should only jump to unlocked sections\", async () => {\n const onFocusChange = vi.fn();\n // No framework selected, so Tab should stay on framework\n const { stdin, unmount } = renderGrid({\n focusedRow: 0,\n focusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(TAB);\n await delay(INPUT_DELAY_MS);\n\n // Should NOT call onFocusChange since there's nowhere to go (all others locked)\n expect(onFocusChange).not.toHaveBeenCalled();\n });\n });\n\n describe(\"show descriptions toggle\", () => {\n it(\"should call onToggleDescriptions when pressing d key\", async () => {\n const onToggleDescriptions = vi.fn();\n const { stdin, unmount } = renderGrid({\n onToggleDescriptions,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(\"d\");\n await delay(INPUT_DELAY_MS);\n\n expect(onToggleDescriptions).toHaveBeenCalled();\n });\n\n it(\"should show descriptions when showDescriptions is true\", () => {\n const { lastFrame, unmount } = renderGrid({ showDescriptions: true });\n cleanup = unmount;\n\n const output = lastFrame();\n // Should show state reasons\n expect(output).toContain(\"Popular choice\"); // react's stateReason\n });\n\n it(\"should hide descriptions when showDescriptions is false\", () => {\n const { lastFrame, unmount } = renderGrid({ showDescriptions: false });\n cleanup = unmount;\n\n const output = lastFrame();\n // stateReasons should not be visible (though they might still be in DOM)\n // At minimum, the display should be different\n expect(output).toBeDefined();\n });\n\n it(\"should show descriptions when enabled\", () => {\n const { lastFrame, unmount } = renderGrid({\n showDescriptions: true,\n });\n cleanup = unmount;\n\n const output = lastFrame();\n // Should show state reasons when descriptions are enabled\n expect(output).toContain(\"Popular choice\"); // react's stateReason\n });\n });\n\n describe(\"expert mode\", () => {\n it(\"should not handle expert mode toggle locally (handled globally)\", () => {\n // Expert mode toggle is now handled at wizard.tsx level via global useInput\n // CategoryGrid no longer has onToggleExpertMode prop\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n // Header should not show expert mode toggle hint\n expect(output).not.toContain(\"[e] Expert Mode\");\n });\n });\n\n describe(\"option ordering\", () => {\n it(\"should sort options by state when expertMode is false\", () => {\n // In non-expert mode, recommended should come first\n // The default categories have recommended options at various positions\n const { lastFrame, unmount } = renderGrid({ expertMode: false });\n cleanup = unmount;\n\n const output = lastFrame();\n // This test verifies the component renders - sorting happens internally\n expect(output).toBeDefined();\n });\n\n it(\"should preserve original order when expertMode is true\", () => {\n const { lastFrame, unmount } = renderGrid({ expertMode: true });\n cleanup = unmount;\n\n const output = lastFrame();\n // This test verifies the component renders with expert mode\n expect(output).toBeDefined();\n });\n });\n\n describe(\"edge cases\", () => {\n it(\"should handle single category\", () => {\n const categories: CategoryRow[] = [\n createCategory(\"forms\", \"Single Category\", [createOption(\"web-test-opt1\", \"Option 1\")]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ categories });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Single Category\");\n expect(output).toContain(\"Option 1\");\n });\n\n it(\"should handle single option in category\", () => {\n const categories: CategoryRow[] = [\n createCategory(\"forms\", \"Single\", [createOption(\"web-test-only\", \"Only Option\")]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ categories });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Only Option\");\n });\n\n it(\"should handle category with many options (flows naturally)\", () => {\n const options = Array.from({ length: 10 }, (_, i) =>\n createOption(`web-test-opt${i}`, `Option ${i}`),\n );\n const categories: CategoryRow[] = [createCategory(\"mocking\", \"Many Options\", options)];\n\n const { lastFrame, unmount } = renderGrid({ categories });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Many Options\");\n // All options should be present (no fixed row limit)\n expect(output).toContain(\"Option 0\");\n expect(output).toContain(\"Option 9\");\n });\n\n it(\"should handle long option labels\", () => {\n const categories: CategoryRow[] = [\n createCategory(\"i18n\", \"Long Labels\", [\n createOption(\"web-test-long1\", \"Very Long Option Name\"),\n createOption(\"web-test-long2\", \"Another Long Name\"),\n ]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ categories });\n cleanup = unmount;\n\n const output = lastFrame();\n // Labels should be rendered (flowing layout handles long labels)\n expect(output).toContain(\"Very Long Option Name\");\n });\n\n it(\"should handle categories with different option counts\", () => {\n const categories: CategoryRow[] = [\n createCategory(\"framework\", \"Category 1\", [\n createOption(\"web-test-opt1\", \"Option 1\"),\n createOption(\"web-test-opt2\", \"Option 2\"),\n ]),\n createCategory(\"styling\", \"Category 2\", [createOption(\"web-test-opt3\", \"Option 3\")]),\n createCategory(\"client-state\", \"Category 3\", [\n createOption(\"web-test-opt4\", \"Option 4\"),\n createOption(\"web-test-opt5\", \"Option 5\"),\n createOption(\"web-test-opt6\", \"Option 6\"),\n ]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ categories });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Category 1\");\n expect(output).toContain(\"Category 2\");\n expect(output).toContain(\"Category 3\");\n });\n });\n\n describe(\"column adjustment\", () => {\n it(\"should adjust focusedCol when changing to row with fewer options\", async () => {\n const onFocusChange = vi.fn();\n const categories: CategoryRow[] = [\n createCategory(\n \"framework\",\n \"Framework\",\n [\n createOption(\"web-test-opt1\", \"Option 1\", { selected: true }), // Framework selected\n createOption(\"web-test-opt2\", \"Option 2\"),\n createOption(\"web-test-opt3\", \"Option 3\"),\n ],\n { required: true },\n ),\n createCategory(\"styling\", \"Category 2\", [createOption(\"web-test-opt4\", \"Option 4\")]),\n ];\n\n const { stdin, unmount } = renderGrid({\n categories,\n focusedRow: 0,\n focusedCol: 2, // Last option in first row\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_DOWN);\n await delay(INPUT_DELAY_MS);\n\n // Should move to row 1, and col should be clamped to 0 (only option)\n expect(onFocusChange).toHaveBeenCalledWith(1, 0);\n });\n });\n\n describe(\"installed indicator\", () => {\n it(\"should show checkmark for installed skill\", () => {\n const categories: CategoryRow[] = [\n createCategory(\"forms\", \"Forms\", [\n createOption(\"web-test-opt1\", \"Option 1\", { installed: true }),\n ]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ categories });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"✓\");\n expect(output).toContain(\"Option 1\");\n });\n\n it(\"should NOT show checkmark for non-installed skill\", () => {\n const categories: CategoryRow[] = [\n createCategory(\"forms\", \"Forms\", [createOption(\"web-test-opt1\", \"Option 1\")]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ categories });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).not.toContain(\"✓\");\n expect(output).toContain(\"Option 1\");\n });\n\n it(\"should show both checkmark and cyan styling when installed and selected\", () => {\n const categories: CategoryRow[] = [\n createCategory(\"forms\", \"Forms\", [\n createOption(\"web-test-opt1\", \"Option 1\", { installed: true, selected: true }),\n ]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ categories });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"✓\");\n expect(output).toContain(\"Option 1\");\n });\n\n it(\"should show both L badge and checkmark when local and installed\", () => {\n const categories: CategoryRow[] = [\n createCategory(\"forms\", \"Forms\", [\n createOption(\"web-test-opt1\", \"Option 1\", { local: true, installed: true }),\n ]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ categories });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"L\");\n expect(output).toContain(\"✓\");\n expect(output).toContain(\"Option 1\");\n });\n });\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAyIgB;AApHhB,IAAM,eAAe,CACnB,IACA,OACA,YAAqC,CAAC,OAClB;AAAA,EACpB;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,GAAG;AACL;AAEA,IAAM,iBAAiB,CACrB,IACA,aACA,SACA,YAAkC,CAAC,OAClB;AAAA,EACjB;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,WAAW;AAAA,EACX;AAAA,EACA,GAAG;AACL;AAEA,IAAM,oBAAmC;AAAA,EACvC;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,MACE,aAAa,kBAAkB,SAAS;AAAA,QACtC,OAAO;AAAA,QACP,aAAa;AAAA,MACf,CAAC;AAAA,MACD,aAAa,gBAAgB,KAAK;AAAA,MAClC,aAAa,oBAAoB,SAAS;AAAA,MAC1C,aAAa,mBAAmB,QAAQ;AAAA,IAC1C;AAAA,IACA,EAAE,UAAU,KAAK;AAAA,EACnB;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,MACE,aAAa,gBAAgB,gBAAgB,EAAE,UAAU,KAAK,CAAC;AAAA,MAC/D,aAAa,qBAAqB,YAAY,EAAE,OAAO,cAAc,CAAC;AAAA,MACtE,aAAa,mBAAmB,mBAAmB;AAAA,MACnD,aAAa,oBAAoB,aAAa;AAAA,IAChD;AAAA,IACA,EAAE,UAAU,KAAK;AAAA,EACnB;AAAA,EACA,eAAe,gBAAgB,gBAAgB;AAAA,IAC7C,aAAa,oBAAoB,WAAW,EAAE,OAAO,cAAc,CAAC;AAAA,IACpE,aAAa,kBAAkB,OAAO;AAAA,IACtC,aAAa,kBAAkB,SAAS;AAAA,MACtC,OAAO;AAAA,MACP,aAAa;AAAA,IACf,CAAC;AAAA,IACD,aAAa,iBAAiB,MAAM;AAAA,EACtC,CAAC;AAAA,EACD,eAAe,gBAAgB,gBAAgB;AAAA,IAC7C,aAAa,mBAAmB,eAAe,EAAE,UAAU,KAAK,CAAC;AAAA,IACjE,aAAa,gBAAgB,KAAK;AAAA,IAClC,aAAa,mBAAmB,QAAQ;AAAA,EAC1C,CAAC;AAAA,EACD,eAAe,aAAa,aAAa,CAAC,aAAa,oBAAoB,SAAS,CAAC,CAAC;AACxF;AAEA,IAAM,0BAAyC;AAAA,EAC7C;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,MACE,aAAa,kBAAkB,SAAS;AAAA,QACtC,OAAO;AAAA,QACP,aAAa;AAAA,QACb,UAAU;AAAA;AAAA,MACZ,CAAC;AAAA,MACD,aAAa,gBAAgB,KAAK;AAAA,MAClC,aAAa,oBAAoB,SAAS;AAAA,MAC1C,aAAa,mBAAmB,QAAQ;AAAA,IAC1C;AAAA,IACA,EAAE,UAAU,KAAK;AAAA,EACnB;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,MACE,aAAa,gBAAgB,cAAc;AAAA,MAC3C,aAAa,qBAAqB,YAAY,EAAE,OAAO,cAAc,CAAC;AAAA,MACtE,aAAa,mBAAmB,mBAAmB;AAAA,MACnD,aAAa,oBAAoB,aAAa;AAAA,IAChD;AAAA,IACA,EAAE,UAAU,KAAK;AAAA,EACnB;AAAA,EACA,eAAe,gBAAgB,gBAAgB;AAAA,IAC7C,aAAa,oBAAoB,WAAW,EAAE,OAAO,cAAc,CAAC;AAAA,IACpE,aAAa,kBAAkB,OAAO;AAAA,IACtC,aAAa,kBAAkB,SAAS,EAAE,OAAO,cAAc,CAAC;AAAA,IAChE,aAAa,iBAAiB,MAAM;AAAA,EACtC,CAAC;AACH;AAEA,IAAM,eAAkC;AAAA,EACtC,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,YAAY;AAAA,EACZ,UAAU,GAAG,GAAG;AAAA,EAChB,eAAe,GAAG,GAAG;AAAA,EACrB,sBAAsB,GAAG,GAAG;AAC9B;AAEA,IAAM,aAAa,CAAC,QAAoC,CAAC,MAAM;AAC7D,SAAO,OAAO,oBAAC,gBAAc,GAAG,cAAe,GAAG,OAAO,CAAE;AAC7D;AAEA,SAAS,0BAA0B,MAAM;AACvC,MAAI;AAEJ,YAAU,MAAM;AACd,cAAU;AACV,cAAU;AAAA,EACZ,CAAC;AAED,WAAS,aAAa,MAAM;AAC1B,OAAG,4CAA4C,MAAM;AACnD,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW;AAC1C,gBAAU;AAEV,YAAM,SAAS,UAAU;AACzB,mBAAO,MAAM,EAAE,UAAU,WAAW;AACpC,mBAAO,MAAM,EAAE,UAAU,SAAS;AAClC,mBAAO,MAAM,EAAE,UAAU,cAAc;AACvC,mBAAO,MAAM,EAAE,UAAU,cAAc;AACvC,mBAAO,MAAM,EAAE,UAAU,WAAW;AAAA,IACtC,CAAC;AAED,OAAG,8CAA8C,MAAM;AACrD,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW;AAC1C,gBAAU;AAEV,YAAM,SAAS,UAAU;AAEzB,mBAAO,MAAM,EAAE,UAAU,OAAO;AAChC,mBAAO,MAAM,EAAE,UAAU,KAAK;AAC9B,mBAAO,MAAM,EAAE,UAAU,SAAS;AAClC,mBAAO,MAAM,EAAE,UAAU,QAAQ;AAEjC,mBAAO,MAAM,EAAE,UAAU,cAAc;AACvC,mBAAO,MAAM,EAAE,UAAU,UAAU;AAAA,IACrC,CAAC;AAED,OAAG,8DAA8D,MAAM;AACrE,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW;AAC1C,gBAAU;AAEV,YAAM,SAAS,UAAU;AAGzB,mBAAO,MAAM,EAAE,UAAU,GAAG;AAAA,IAC9B,CAAC;AAED,OAAG,0DAA0D,MAAM;AACjE,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW;AAC1C,gBAAU;AAEV,YAAM,SAAS,UAAU;AAEzB,mBAAO,MAAM,EAAE,IAAI,UAAU,YAAY;AAAA,IAC3C,CAAC;AAED,OAAG,wCAAwC,MAAM;AAC/C,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW,EAAE,YAAY,CAAC,EAAE,CAAC;AAC5D,gBAAU;AAEV,YAAM,SAAS,UAAU;AACzB,mBAAO,MAAM,EAAE,UAAU,0BAA0B;AAAA,IACrD,CAAC;AAED,OAAG,oCAAoC,MAAM;AAC3C,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW;AAC1C,gBAAU;AAEV,YAAM,SAAS,UAAU;AAEzB,mBAAO,MAAM,EAAE,UAAU,QAAQ;AAAA,IACnC,CAAC;AAAA,EACH,CAAC;AAED,WAAS,iBAAiB,MAAM;AAC9B,OAAG,gDAAgD,MAAM;AACvD,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW;AAC1C,gBAAU;AAEV,YAAM,SAAS,UAAU;AAEzB,mBAAO,MAAM,EAAE,UAAU,cAAc;AACvC,mBAAO,MAAM,EAAE,UAAU,aAAa;AAAA,IACxC,CAAC;AAED,OAAG,kDAAkD,MAAM;AACzD,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW;AAC1C,gBAAU;AAEV,YAAM,SAAS,UAAU;AAEzB,mBAAO,MAAM,EAAE,UAAU,KAAK;AAC9B,mBAAO,MAAM,EAAE,UAAU,SAAS;AAAA,IACpC,CAAC;AAED,OAAG,oFAAoF,MAAM;AAC3F,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW;AAC1C,gBAAU;AAEV,YAAM,SAAS,UAAU;AAEzB,mBAAO,MAAM,EAAE,IAAI,UAAU,QAAQ;AAAA,IACvC,CAAC;AAED,OAAG,kFAAkF,MAAM;AACzF,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW;AAC1C,gBAAU;AAEV,YAAM,SAAS,UAAU;AAEzB,mBAAO,MAAM,EAAE,IAAI,UAAU,QAAQ;AAAA,IACvC,CAAC;AAED,OAAG,oDAAoD,MAAM;AAC3D,YAAM,aAA4B;AAAA,QAChC,eAAe,WAAW,QAAQ;AAAA,UAChC,aAAa,iBAAiB,UAAU;AAAA,UACxC,aAAa,iBAAiB,YAAY,EAAE,OAAO,WAAW,CAAC;AAAA,QACjE,CAAC;AAAA,MACH;AAEA,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW,EAAE,WAAW,CAAC;AACxD,gBAAU;AAEV,YAAM,SAAS,UAAU;AAEzB,mBAAO,MAAM,EAAE,UAAU,UAAU;AAAA,IACrC,CAAC;AAAA,EACH,CAAC;AAED,WAAS,mBAAmB,MAAM;AAChC,OAAG,oDAAoD,MAAM;AAE3D,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW;AAC1C,gBAAU;AAEV,YAAM,SAAS,UAAU;AACzB,mBAAO,MAAM,EAAE,UAAU,WAAW;AACpC,mBAAO,MAAM,EAAE,UAAU,SAAS;AAClC,mBAAO,MAAM,EAAE,UAAU,cAAc;AAAA,IACzC,CAAC;AAED,OAAG,qDAAqD,MAAM;AAC5D,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW;AAAA,QACxC,YAAY;AAAA,MACd,CAAC;AACD,gBAAU;AAEV,YAAM,SAAS,UAAU;AAEzB,mBAAO,MAAM,EAAE,UAAU,WAAW;AACpC,mBAAO,MAAM,EAAE,UAAU,SAAS;AAClC,mBAAO,MAAM,EAAE,UAAU,cAAc;AAAA,IACzC,CAAC;AAED,OAAG,kEAAkE,MAAM;AACzE,YAAM,wBAAuC;AAAA,QAC3C,eAAe,WAAW,WAAW;AAAA,UACnC,aAAa,iBAAiB,MAAM;AAAA,UACpC,aAAa,qBAAqB,UAAU;AAAA,QAC9C,CAAC;AAAA,QACD,eAAe,gBAAgB,SAAS,CAAC,aAAa,oBAAoB,SAAS,CAAC,CAAC;AAAA,MACvF;AAEA,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW;AAAA,QACxC,YAAY;AAAA,MACd,CAAC;AACD,gBAAU;AAEV,YAAM,SAAS,UAAU;AACzB,mBAAO,MAAM,EAAE,UAAU,SAAS;AAClC,mBAAO,MAAM,EAAE,UAAU,OAAO;AAAA,IAClC,CAAC;AAAA,EACH,CAAC;AAED,WAAS,mBAAmB,MAAM;AAChC,OAAG,gDAAgD,MAAM;AACvD,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW;AAAA,QACxC,YAAY;AAAA,QACZ,YAAY;AAAA,MACd,CAAC;AACD,gBAAU;AAEV,YAAM,SAAS,UAAU;AAEzB,mBAAO,MAAM,EAAE,UAAU,OAAO;AAAA,IAClC,CAAC;AAED,OAAG,mDAAmD,MAAM;AAC1D,YAAM,EAAE,WAAW,QAAQ,SAAS,SAAS,IAAI,WAAW;AAAA,QAC1D,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,YAAY;AAAA,MACd,CAAC;AACD,YAAM,UAAU,OAAO;AACvB,eAAS;AAET,YAAM,EAAE,WAAW,QAAQ,SAAS,SAAS,IAAI,WAAW;AAAA,QAC1D,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,YAAY;AAAA,MACd,CAAC;AACD,gBAAU;AACV,YAAM,UAAU,OAAO;AAGvB,mBAAO,OAAO,EAAE,UAAU,WAAW;AACrC,mBAAO,OAAO,EAAE,UAAU,SAAS;AAAA,IACrC,CAAC;AAED,OAAG,0CAA0C,MAAM;AACjD,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW;AAAA,QACxC,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,YAAY;AAAA,MACd,CAAC;AACD,gBAAU;AAEV,YAAM,SAAS,UAAU;AAEzB,mBAAO,MAAM,EAAE,UAAU,SAAS;AAAA,IACpC,CAAC;AAAA,EACH,CAAC;AAED,WAAS,oCAAoC,MAAM;AACjD,OAAG,sDAAsD,YAAY;AACnE,YAAM,gBAAgB,GAAG,GAAG;AAC5B,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,UAAU;AAC5B,YAAM,MAAM,cAAc;AAE1B,mBAAO,aAAa,EAAE,qBAAqB,GAAG,CAAC;AAAA,IACjD,CAAC;AAED,OAAG,uDAAuD,YAAY;AACpE,YAAM,gBAAgB,GAAG,GAAG;AAC5B,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,WAAW;AAC7B,YAAM,MAAM,cAAc;AAE1B,mBAAO,aAAa,EAAE,qBAAqB,GAAG,CAAC;AAAA,IACjD,CAAC;AAED,OAAG,qFAAqF,YAAY;AAClG,YAAM,gBAAgB,GAAG,GAAG;AAE5B,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,QAAQ;AAC1B,YAAM,MAAM,cAAc;AAG1B,mBAAO,aAAa,EAAE,qBAAqB,GAAG,CAAC;AAAA,IACjD,CAAC;AAED,OAAG,kDAAkD,YAAY;AAC/D,YAAM,gBAAgB,GAAG,GAAG;AAC5B,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,UAAU;AAC5B,YAAM,MAAM,cAAc;AAG1B,mBAAO,aAAa,EAAE,qBAAqB,GAAG,CAAC;AAAA,IACjD,CAAC;AAED,OAAG,+DAA+D,YAAY;AAC5E,YAAM,gBAAgB,GAAG,GAAG;AAC5B,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,UAAU;AAC5B,YAAM,MAAM,cAAc;AAG1B,mBAAO,aAAa,EAAE,qBAAqB,GAAG,CAAC;AAAA,IACjD,CAAC;AAED,OAAG,+DAA+D,YAAY;AAC5E,YAAM,gBAAgB,GAAG,GAAG;AAC5B,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC,YAAY;AAAA,QACZ,YAAY;AAAA;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,WAAW;AAC7B,YAAM,MAAM,cAAc;AAG1B,mBAAO,aAAa,EAAE,qBAAqB,GAAG,CAAC;AAAA,IACjD,CAAC;AAED,OAAG,yDAAyD,YAAY;AACtE,YAAM,gBAAgB,GAAG,GAAG;AAC5B,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,QAAQ;AAC1B,YAAM,MAAM,cAAc;AAG1B,mBAAO,aAAa,EAAE,qBAAqB,GAAG,CAAC;AAAA,IACjD,CAAC;AAAA,EACH,CAAC;AAED,WAAS,kCAAkC,MAAM;AAC/C,OAAG,+BAA+B,YAAY;AAC5C,YAAM,gBAAgB,GAAG,GAAG;AAC5B,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,GAAG;AACrB,YAAM,MAAM,cAAc;AAE1B,mBAAO,aAAa,EAAE,qBAAqB,GAAG,CAAC;AAAA,IACjD,CAAC;AAED,OAAG,gCAAgC,YAAY;AAC7C,YAAM,gBAAgB,GAAG,GAAG;AAC5B,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,GAAG;AACrB,YAAM,MAAM,cAAc;AAE1B,mBAAO,aAAa,EAAE,qBAAqB,GAAG,CAAC;AAAA,IACjD,CAAC;AAED,OAAG,6BAA6B,YAAY;AAC1C,YAAM,gBAAgB,GAAG,GAAG;AAC5B,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,GAAG;AACrB,YAAM,MAAM,cAAc;AAE1B,mBAAO,aAAa,EAAE,qBAAqB,GAAG,CAAC;AAAA,IACjD,CAAC;AAED,OAAG,+BAA+B,YAAY;AAC5C,YAAM,gBAAgB,GAAG,GAAG;AAC5B,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,GAAG;AACrB,YAAM,MAAM,cAAc;AAE1B,mBAAO,aAAa,EAAE,qBAAqB,GAAG,CAAC;AAAA,IACjD,CAAC;AAAA,EACH,CAAC;AAED,WAAS,oBAAoB,MAAM;AACjC,OAAG,+DAA+D,YAAY;AAC5E,YAAM,WAAW,GAAG,GAAG;AACvB,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC,YAAY;AAAA,QACZ,YAAY;AAAA;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,GAAG;AACrB,YAAM,MAAM,cAAc;AAE1B,mBAAO,QAAQ,EAAE,qBAAqB,aAAa,cAAc;AAAA,IACnE,CAAC;AAED,OAAG,iEAAiE,YAAY;AAC9E,YAAM,WAAW,GAAG,GAAG;AAEvB,YAAM,aAA4B;AAAA,QAChC;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,YACE,aAAa,kBAAkB,SAAS,EAAE,UAAU,KAAK,CAAC;AAAA,YAC1D,aAAa,gBAAgB,KAAK;AAAA,UACpC;AAAA,UACA,EAAE,UAAU,KAAK;AAAA,QACnB;AAAA,MACF;AACA,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC;AAAA,QACA,YAAY;AAAA,QACZ,YAAY;AAAA;AAAA,QACZ,YAAY;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,GAAG;AACrB,YAAM,MAAM,cAAc;AAE1B,mBAAO,QAAQ,EAAE,qBAAqB,aAAa,gBAAgB;AAAA,IACrE,CAAC;AAED,OAAG,qEAAqE,YAAY;AAClF,YAAM,WAAW,GAAG,GAAG;AACvB,YAAM,aAA4B;AAAA,QAChC,eAAe,WAAW,QAAQ;AAAA,UAChC,aAAa,iBAAiB,YAAY,EAAE,OAAO,WAAW,CAAC;AAAA,UAC/D,aAAa,iBAAiB,UAAU;AAAA,QAC1C,CAAC;AAAA,MACH;AAGA,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC;AAAA,QACA,YAAY;AAAA,QACZ,YAAY;AAAA;AAAA,QACZ,YAAY;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,GAAG;AACrB,YAAM,MAAM,cAAc;AAE1B,mBAAO,QAAQ,EAAE,IAAI,iBAAiB;AAAA,IACxC,CAAC;AAED,OAAG,mDAAmD,YAAY;AAChE,YAAM,WAAW,GAAG,GAAG;AAEvB,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC,YAAY;AAAA;AAAA,QACZ,YAAY;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,GAAG;AACrB,YAAM,MAAM,cAAc;AAE1B,mBAAO,QAAQ,EAAE,IAAI,iBAAiB;AAAA,IACxC,CAAC;AAAA,EACH,CAAC;AAED,WAAS,+BAA+B,MAAM;AAC5C,OAAG,sDAAsD,YAAY;AACnE,YAAM,gBAAgB,GAAG,GAAG;AAC5B,YAAM,aAA4B;AAAA,QAChC,eAAe,WAAW,QAAQ;AAAA,UAChC,aAAa,iBAAiB,UAAU;AAAA,UACxC,aAAa,iBAAiB,YAAY,EAAE,OAAO,WAAW,CAAC;AAAA,UAC/D,aAAa,iBAAiB,UAAU;AAAA,QAC1C,CAAC;AAAA,MACH;AAGA,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC;AAAA,QACA,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,WAAW;AAC7B,YAAM,MAAM,cAAc;AAG1B,mBAAO,aAAa,EAAE,qBAAqB,GAAG,CAAC;AAAA,IACjD,CAAC;AAED,OAAG,qDAAqD,YAAY;AAClE,YAAM,gBAAgB,GAAG,GAAG;AAC5B,YAAM,aAA4B;AAAA,QAChC,eAAe,WAAW,QAAQ;AAAA,UAChC,aAAa,iBAAiB,UAAU;AAAA,UACxC,aAAa,iBAAiB,YAAY,EAAE,OAAO,WAAW,CAAC;AAAA,UAC/D,aAAa,iBAAiB,UAAU;AAAA,QAC1C,CAAC;AAAA,MACH;AAGA,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC;AAAA,QACA,YAAY;AAAA,QACZ,YAAY;AAAA;AAAA,QACZ,YAAY;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,UAAU;AAC5B,YAAM,MAAM,cAAc;AAG1B,mBAAO,aAAa,EAAE,qBAAqB,GAAG,CAAC;AAAA,IACjD,CAAC;AAED,OAAG,+CAA+C,YAAY;AAC5D,YAAM,gBAAgB,GAAG,GAAG;AAC5B,YAAM,aAA4B;AAAA,QAChC,eAAe,WAAW,QAAQ;AAAA,UAChC,aAAa,iBAAiB,YAAY,EAAE,OAAO,WAAW,CAAC;AAAA,UAC/D,aAAa,iBAAiB,YAAY,EAAE,OAAO,WAAW,CAAC;AAAA,QACjE,CAAC;AAAA,MACH;AAGA,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC;AAAA,QACA,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,WAAW;AAC7B,YAAM,MAAM,cAAc;AAG1B,mBAAO,aAAa,EAAE,qBAAqB,GAAG,CAAC;AAAA,IACjD,CAAC;AAAA,EACH,CAAC;AAED,WAAS,wBAAwB,MAAM;AACrC,OAAG,8CAA8C,MAAM;AACrD,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW;AAC1C,gBAAU;AAEV,YAAM,SAAS,UAAU;AAEzB,mBAAO,MAAM,EAAE,UAAU,WAAW;AAAA,IACtC,CAAC;AAAA,EAKH,CAAC;AAED,WAAS,kBAAkB,MAAM;AAC/B,OAAG,iDAAiD,YAAY;AAC9D,YAAM,gBAAgB,GAAG,GAAG;AAC5B,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,GAAG;AACrB,YAAM,MAAM,cAAc;AAG1B,mBAAO,aAAa,EAAE,qBAAqB,GAAG,CAAC;AAAA,IACjD,CAAC;AAED,OAAG,yCAAyC,YAAY;AACtD,YAAM,gBAAgB,GAAG,GAAG;AAE5B,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,GAAG;AACrB,YAAM,MAAM,cAAc;AAG1B,mBAAO,aAAa,EAAE,IAAI,iBAAiB;AAAA,IAC7C,CAAC;AAAA,EACH,CAAC;AAED,WAAS,4BAA4B,MAAM;AACzC,OAAG,wDAAwD,YAAY;AACrE,YAAM,uBAAuB,GAAG,GAAG;AACnC,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,GAAG;AACrB,YAAM,MAAM,cAAc;AAE1B,mBAAO,oBAAoB,EAAE,iBAAiB;AAAA,IAChD,CAAC;AAED,OAAG,0DAA0D,MAAM;AACjE,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW,EAAE,kBAAkB,KAAK,CAAC;AACpE,gBAAU;AAEV,YAAM,SAAS,UAAU;AAEzB,mBAAO,MAAM,EAAE,UAAU,gBAAgB;AAAA,IAC3C,CAAC;AAED,OAAG,2DAA2D,MAAM;AAClE,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW,EAAE,kBAAkB,MAAM,CAAC;AACrE,gBAAU;AAEV,YAAM,SAAS,UAAU;AAGzB,mBAAO,MAAM,EAAE,YAAY;AAAA,IAC7B,CAAC;AAED,OAAG,yCAAyC,MAAM;AAChD,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW;AAAA,QACxC,kBAAkB;AAAA,MACpB,CAAC;AACD,gBAAU;AAEV,YAAM,SAAS,UAAU;AAEzB,mBAAO,MAAM,EAAE,UAAU,gBAAgB;AAAA,IAC3C,CAAC;AAAA,EACH,CAAC;AAED,WAAS,eAAe,MAAM;AAC5B,OAAG,mEAAmE,MAAM;AAG1E,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW;AAC1C,gBAAU;AAEV,YAAM,SAAS,UAAU;AAEzB,mBAAO,MAAM,EAAE,IAAI,UAAU,iBAAiB;AAAA,IAChD,CAAC;AAAA,EACH,CAAC;AAED,WAAS,mBAAmB,MAAM;AAChC,OAAG,yDAAyD,MAAM;AAGhE,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW,EAAE,YAAY,MAAM,CAAC;AAC/D,gBAAU;AAEV,YAAM,SAAS,UAAU;AAEzB,mBAAO,MAAM,EAAE,YAAY;AAAA,IAC7B,CAAC;AAED,OAAG,0DAA0D,MAAM;AACjE,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW,EAAE,YAAY,KAAK,CAAC;AAC9D,gBAAU;AAEV,YAAM,SAAS,UAAU;AAEzB,mBAAO,MAAM,EAAE,YAAY;AAAA,IAC7B,CAAC;AAAA,EACH,CAAC;AAED,WAAS,cAAc,MAAM;AAC3B,OAAG,iCAAiC,MAAM;AACxC,YAAM,aAA4B;AAAA,QAChC,eAAe,SAAS,mBAAmB,CAAC,aAAa,iBAAiB,UAAU,CAAC,CAAC;AAAA,MACxF;AAEA,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW,EAAE,WAAW,CAAC;AACxD,gBAAU;AAEV,YAAM,SAAS,UAAU;AACzB,mBAAO,MAAM,EAAE,UAAU,iBAAiB;AAC1C,mBAAO,MAAM,EAAE,UAAU,UAAU;AAAA,IACrC,CAAC;AAED,OAAG,2CAA2C,MAAM;AAClD,YAAM,aAA4B;AAAA,QAChC,eAAe,SAAS,UAAU,CAAC,aAAa,iBAAiB,aAAa,CAAC,CAAC;AAAA,MAClF;AAEA,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW,EAAE,WAAW,CAAC;AACxD,gBAAU;AAEV,YAAM,SAAS,UAAU;AACzB,mBAAO,MAAM,EAAE,UAAU,aAAa;AAAA,IACxC,CAAC;AAED,OAAG,8DAA8D,MAAM;AACrE,YAAM,UAAU,MAAM;AAAA,QAAK,EAAE,QAAQ,GAAG;AAAA,QAAG,CAAC,GAAG,MAC7C,aAAa,eAAe,CAAC,IAAI,UAAU,CAAC,EAAE;AAAA,MAChD;AACA,YAAM,aAA4B,CAAC,eAAe,WAAW,gBAAgB,OAAO,CAAC;AAErF,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW,EAAE,WAAW,CAAC;AACxD,gBAAU;AAEV,YAAM,SAAS,UAAU;AACzB,mBAAO,MAAM,EAAE,UAAU,cAAc;AAEvC,mBAAO,MAAM,EAAE,UAAU,UAAU;AACnC,mBAAO,MAAM,EAAE,UAAU,UAAU;AAAA,IACrC,CAAC;AAED,OAAG,oCAAoC,MAAM;AAC3C,YAAM,aAA4B;AAAA,QAChC,eAAe,QAAQ,eAAe;AAAA,UACpC,aAAa,kBAAkB,uBAAuB;AAAA,UACtD,aAAa,kBAAkB,mBAAmB;AAAA,QACpD,CAAC;AAAA,MACH;AAEA,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW,EAAE,WAAW,CAAC;AACxD,gBAAU;AAEV,YAAM,SAAS,UAAU;AAEzB,mBAAO,MAAM,EAAE,UAAU,uBAAuB;AAAA,IAClD,CAAC;AAED,OAAG,yDAAyD,MAAM;AAChE,YAAM,aAA4B;AAAA,QAChC,eAAe,aAAa,cAAc;AAAA,UACxC,aAAa,iBAAiB,UAAU;AAAA,UACxC,aAAa,iBAAiB,UAAU;AAAA,QAC1C,CAAC;AAAA,QACD,eAAe,WAAW,cAAc,CAAC,aAAa,iBAAiB,UAAU,CAAC,CAAC;AAAA,QACnF,eAAe,gBAAgB,cAAc;AAAA,UAC3C,aAAa,iBAAiB,UAAU;AAAA,UACxC,aAAa,iBAAiB,UAAU;AAAA,UACxC,aAAa,iBAAiB,UAAU;AAAA,QAC1C,CAAC;AAAA,MACH;AAEA,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW,EAAE,WAAW,CAAC;AACxD,gBAAU;AAEV,YAAM,SAAS,UAAU;AACzB,mBAAO,MAAM,EAAE,UAAU,YAAY;AACrC,mBAAO,MAAM,EAAE,UAAU,YAAY;AACrC,mBAAO,MAAM,EAAE,UAAU,YAAY;AAAA,IACvC,CAAC;AAAA,EACH,CAAC;AAED,WAAS,qBAAqB,MAAM;AAClC,OAAG,oEAAoE,YAAY;AACjF,YAAM,gBAAgB,GAAG,GAAG;AAC5B,YAAM,aAA4B;AAAA,QAChC;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,YACE,aAAa,iBAAiB,YAAY,EAAE,UAAU,KAAK,CAAC;AAAA;AAAA,YAC5D,aAAa,iBAAiB,UAAU;AAAA,YACxC,aAAa,iBAAiB,UAAU;AAAA,UAC1C;AAAA,UACA,EAAE,UAAU,KAAK;AAAA,QACnB;AAAA,QACA,eAAe,WAAW,cAAc,CAAC,aAAa,iBAAiB,UAAU,CAAC,CAAC;AAAA,MACrF;AAEA,YAAM,EAAE,OAAO,QAAQ,IAAI,WAAW;AAAA,QACpC;AAAA,QACA,YAAY;AAAA,QACZ,YAAY;AAAA;AAAA,QACZ;AAAA,MACF,CAAC;AACD,gBAAU;AAEV,YAAM,MAAM,eAAe;AAC3B,YAAM,MAAM,MAAM,UAAU;AAC5B,YAAM,MAAM,cAAc;AAG1B,mBAAO,aAAa,EAAE,qBAAqB,GAAG,CAAC;AAAA,IACjD,CAAC;AAAA,EACH,CAAC;AAED,WAAS,uBAAuB,MAAM;AACpC,OAAG,6CAA6C,MAAM;AACpD,YAAM,aAA4B;AAAA,QAChC,eAAe,SAAS,SAAS;AAAA,UAC/B,aAAa,iBAAiB,YAAY,EAAE,WAAW,KAAK,CAAC;AAAA,QAC/D,CAAC;AAAA,MACH;AAEA,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW,EAAE,WAAW,CAAC;AACxD,gBAAU;AAEV,YAAM,SAAS,UAAU;AACzB,mBAAO,MAAM,EAAE,UAAU,QAAG;AAC5B,mBAAO,MAAM,EAAE,UAAU,UAAU;AAAA,IACrC,CAAC;AAED,OAAG,qDAAqD,MAAM;AAC5D,YAAM,aAA4B;AAAA,QAChC,eAAe,SAAS,SAAS,CAAC,aAAa,iBAAiB,UAAU,CAAC,CAAC;AAAA,MAC9E;AAEA,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW,EAAE,WAAW,CAAC;AACxD,gBAAU;AAEV,YAAM,SAAS,UAAU;AACzB,mBAAO,MAAM,EAAE,IAAI,UAAU,QAAG;AAChC,mBAAO,MAAM,EAAE,UAAU,UAAU;AAAA,IACrC,CAAC;AAED,OAAG,2EAA2E,MAAM;AAClF,YAAM,aAA4B;AAAA,QAChC,eAAe,SAAS,SAAS;AAAA,UAC/B,aAAa,iBAAiB,YAAY,EAAE,WAAW,MAAM,UAAU,KAAK,CAAC;AAAA,QAC/E,CAAC;AAAA,MACH;AAEA,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW,EAAE,WAAW,CAAC;AACxD,gBAAU;AAEV,YAAM,SAAS,UAAU;AACzB,mBAAO,MAAM,EAAE,UAAU,QAAG;AAC5B,mBAAO,MAAM,EAAE,UAAU,UAAU;AAAA,IACrC,CAAC;AAED,OAAG,mEAAmE,MAAM;AAC1E,YAAM,aAA4B;AAAA,QAChC,eAAe,SAAS,SAAS;AAAA,UAC/B,aAAa,iBAAiB,YAAY,EAAE,OAAO,MAAM,WAAW,KAAK,CAAC;AAAA,QAC5E,CAAC;AAAA,MACH;AAEA,YAAM,EAAE,WAAW,QAAQ,IAAI,WAAW,EAAE,WAAW,CAAC;AACxD,gBAAU;AAEV,YAAM,SAAS,UAAU;AACzB,mBAAO,MAAM,EAAE,UAAU,GAAG;AAC5B,mBAAO,MAAM,EAAE,UAAU,QAAG;AAC5B,mBAAO,MAAM,EAAE,UAAU,UAAU;AAAA,IACrC,CAAC;AAAA,EACH,CAAC;AACH,CAAC;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/components/wizard/category-grid.test.tsx"],"sourcesContent":["import { render } from \"ink-testing-library\";\nimport { describe, expect, it, afterEach, vi } from \"vitest\";\nimport {\n CategoryGrid,\n type CategoryGridProps,\n type CategoryRow,\n type CategoryOption,\n} from \"./category-grid\";\nimport type { SkillId, Subcategory } from \"../../types\";\nimport {\n ARROW_UP,\n ARROW_DOWN,\n ARROW_LEFT,\n ARROW_RIGHT,\n TAB,\n RENDER_DELAY_MS,\n INPUT_DELAY_MS,\n delay,\n} from \"../../lib/__tests__/test-constants\";\n\nconst createOption = (\n id: SkillId,\n label: string,\n overrides: Partial<CategoryOption> = {},\n): CategoryOption => ({\n id,\n label,\n state: \"normal\",\n selected: false,\n ...overrides,\n});\n\nconst createCategory = (\n id: Subcategory,\n displayName: string,\n options: CategoryOption[],\n overrides: Partial<CategoryRow> = {},\n): CategoryRow => ({\n id,\n displayName,\n required: false,\n exclusive: true,\n options,\n ...overrides,\n});\n\nconst defaultCategories: CategoryRow[] = [\n createCategory(\n \"framework\",\n \"Framework\",\n [\n createOption(\"web-test-react\", \"React\", {\n state: \"recommended\",\n stateReason: \"Popular choice\",\n }),\n createOption(\"web-test-vue\", \"Vue\"),\n createOption(\"web-test-angular\", \"Angular\"),\n createOption(\"web-test-svelte\", \"Svelte\"),\n ],\n { required: true },\n ),\n createCategory(\n \"styling\",\n \"Styling\",\n [\n createOption(\"web-scss-mod\", \"SCSS Modules\", { selected: true }),\n createOption(\"web-test-tailwind\", \"Tailwind\", { state: \"recommended\" }),\n createOption(\"web-test-styled\", \"Styled Components\"),\n createOption(\"web-test-vanilla\", \"Vanilla CSS\"),\n ],\n { required: true },\n ),\n createCategory(\"client-state\", \"Client State\", [\n createOption(\"web-test-zustand\", \"Zustand\", { state: \"recommended\" }),\n createOption(\"web-test-jotai\", \"Jotai\"),\n createOption(\"web-test-redux\", \"Redux\", {\n state: \"discouraged\",\n stateReason: \"Complex for most apps\",\n }),\n createOption(\"web-test-mobx\", \"MobX\"),\n ]),\n createCategory(\"server-state\", \"Server State\", [\n createOption(\"web-react-query\", \"React Query\", { selected: true }),\n createOption(\"web-test-swr\", \"SWR\"),\n createOption(\"web-test-apollo\", \"Apollo\"),\n ]),\n createCategory(\"analytics\", \"Analytics\", [createOption(\"web-test-posthog\", \"PostHog\")]),\n];\n\nconst categoriesWithFramework: CategoryRow[] = [\n createCategory(\n \"framework\",\n \"Framework\",\n [\n createOption(\"web-test-react\", \"React\", {\n state: \"recommended\",\n stateReason: \"Popular choice\",\n selected: true, // Framework selected\n }),\n createOption(\"web-test-vue\", \"Vue\"),\n createOption(\"web-test-angular\", \"Angular\"),\n createOption(\"web-test-svelte\", \"Svelte\"),\n ],\n { required: true },\n ),\n createCategory(\n \"styling\",\n \"Styling\",\n [\n createOption(\"web-scss-mod\", \"SCSS Modules\"),\n createOption(\"web-test-tailwind\", \"Tailwind\", { state: \"recommended\" }),\n createOption(\"web-test-styled\", \"Styled Components\"),\n createOption(\"web-test-vanilla\", \"Vanilla CSS\"),\n ],\n { required: true },\n ),\n createCategory(\"client-state\", \"Client State\", [\n createOption(\"web-test-zustand\", \"Zustand\", { state: \"recommended\" }),\n createOption(\"web-test-jotai\", \"Jotai\"),\n createOption(\"web-test-redux\", \"Redux\", { state: \"discouraged\" }),\n createOption(\"web-test-mobx\", \"MobX\"),\n ]),\n];\n\nconst defaultProps: CategoryGridProps = {\n categories: defaultCategories,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n showDescriptions: false,\n expertMode: false,\n onToggle: vi.fn(),\n onFocusChange: vi.fn(),\n onToggleDescriptions: vi.fn(),\n};\n\nconst renderGrid = (props: Partial<CategoryGridProps> = {}) => {\n return render(<CategoryGrid {...defaultProps} {...props} />);\n};\n\ndescribe(\"CategoryGrid component\", () => {\n let cleanup: (() => void) | undefined;\n\n afterEach(() => {\n cleanup?.();\n cleanup = undefined;\n });\n\n describe(\"rendering\", () => {\n it(\"should render all categories as sections\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Framework\");\n expect(output).toContain(\"Styling\");\n expect(output).toContain(\"Client State\");\n expect(output).toContain(\"Server State\");\n expect(output).toContain(\"Analytics\");\n });\n\n it(\"should render all options in each category\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n // Framework options\n expect(output).toContain(\"React\");\n expect(output).toContain(\"Vue\");\n expect(output).toContain(\"Angular\");\n expect(output).toContain(\"Svelte\");\n // Styling options\n expect(output).toContain(\"SCSS Modules\");\n expect(output).toContain(\"Tailwind\");\n });\n\n it(\"should show required indicator (*) for required categories\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n // Framework and Styling are required\n // The * should appear after their names\n expect(output).toContain(\"*\");\n });\n\n it(\"should NOT show (optional) for non-required categories\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n // Optional is assumed by default, so we don't show the label\n expect(output).not.toContain(\"(optional)\");\n });\n\n it(\"should handle empty categories array\", () => {\n const { lastFrame, unmount } = renderGrid({ categories: [] });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"No categories to display\");\n });\n\n it(\"should render section underlines\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n // Unicode horizontal line character used for underlines\n expect(output).toContain(\"\\u2500\");\n });\n });\n\n describe(\"visual states\", () => {\n it(\"should show selected options with label text\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n // scss-mod and react-query are selected in defaultCategories\n expect(output).toContain(\"SCSS Modules\");\n expect(output).toContain(\"React Query\");\n });\n\n it(\"should show unselected options with label text\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n // Unselected options should display their labels\n expect(output).toContain(\"Vue\");\n expect(output).toContain(\"Angular\");\n });\n\n it(\"should NOT show star indicator for recommended options (uses background instead)\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n // Should NOT contain star (⭐) for recommended\n expect(output).not.toContain(\"\\u2B50\");\n });\n\n it(\"should NOT show warning indicator for discouraged options (uses color instead)\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n // Should NOT contain warning (⚠) for discouraged\n expect(output).not.toContain(\"\\u26A0\");\n });\n\n it(\"should show disabled options with dimmed styling\", () => {\n const categories: CategoryRow[] = [\n createCategory(\"testing\", \"Test\", [\n createOption(\"web-test-opt1\", \"Option 1\"),\n createOption(\"web-test-opt2\", \"Option 2\", { state: \"disabled\" }),\n ]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ categories });\n cleanup = unmount;\n\n const output = lastFrame();\n // Disabled options should show label (dimmed text)\n expect(output).toContain(\"Option 2\");\n });\n });\n\n describe(\"locked sections\", () => {\n it(\"should show all categories including locked ones\", () => {\n // No framework selected, so non-framework sections should be locked but visible\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Framework\");\n expect(output).toContain(\"Styling\");\n expect(output).toContain(\"Client State\");\n });\n\n it(\"should unlock sections when framework is selected\", () => {\n const { lastFrame, unmount } = renderGrid({\n categories: categoriesWithFramework,\n });\n cleanup = unmount;\n\n const output = lastFrame();\n // All sections should be visible and navigable\n expect(output).toContain(\"Framework\");\n expect(output).toContain(\"Styling\");\n expect(output).toContain(\"Client State\");\n });\n\n it(\"should not lock any sections when no framework category exists\", () => {\n const categoriesNoFramework: CategoryRow[] = [\n createCategory(\"styling\", \"Styling\", [\n createOption(\"web-test-scss\", \"SCSS\"),\n createOption(\"web-test-tailwind\", \"Tailwind\"),\n ]),\n createCategory(\"client-state\", \"State\", [createOption(\"web-test-zustand\", \"Zustand\")]),\n ];\n\n const { lastFrame, unmount } = renderGrid({\n categories: categoriesNoFramework,\n });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Styling\");\n expect(output).toContain(\"State\");\n });\n });\n\n describe(\"focus indicator\", () => {\n it(\"should render focused option with label text\", () => {\n const { lastFrame, unmount } = renderGrid({\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n });\n cleanup = unmount;\n\n const output = lastFrame();\n // Focused option should be visible (background highlighting is visual-only)\n expect(output).toContain(\"React\");\n });\n\n it(\"should render correctly when focusedRow changes\", () => {\n const { lastFrame: frame1, unmount: unmount1 } = renderGrid({\n categories: categoriesWithFramework,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n });\n const output1 = frame1();\n unmount1();\n\n const { lastFrame: frame2, unmount: unmount2 } = renderGrid({\n categories: categoriesWithFramework,\n defaultFocusedRow: 1,\n defaultFocusedCol: 0,\n });\n cleanup = unmount2;\n const output2 = frame2();\n\n // Both should render the focused category options\n expect(output1).toContain(\"Framework\");\n expect(output2).toContain(\"Styling\");\n });\n\n it(\"should highlight focused category name\", () => {\n const { lastFrame, unmount } = renderGrid({\n categories: categoriesWithFramework,\n defaultFocusedRow: 1,\n defaultFocusedCol: 0,\n });\n cleanup = unmount;\n\n const output = lastFrame();\n // Styling row should be focused (index 1)\n expect(output).toContain(\"Styling\");\n });\n });\n\n describe(\"keyboard navigation - arrow keys\", () => {\n it(\"should call onFocusChange when pressing left arrow\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n defaultFocusedRow: 0,\n defaultFocusedCol: 1,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_LEFT);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should call onFocusChange when pressing right arrow\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_RIGHT);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 1);\n });\n\n it(\"should call onFocusChange when pressing up arrow (wraps to framework when locked)\", async () => {\n const onFocusChange = vi.fn();\n // No framework selected, so navigation stays on framework row\n const { stdin, unmount } = renderGrid({\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_UP);\n await delay(INPUT_DELAY_MS);\n\n // Should stay on row 0 (framework) since other rows are locked\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should navigate between sections when unlocked\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n categories: categoriesWithFramework,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_DOWN);\n await delay(INPUT_DELAY_MS);\n\n // Should move to row 1 (Styling) since framework is selected\n expect(onFocusChange).toHaveBeenCalledWith(1, 0);\n });\n\n it(\"should wrap horizontally when pressing left at first column\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_LEFT);\n await delay(INPUT_DELAY_MS);\n\n // Should wrap to last column (index 3 for framework with 4 options)\n expect(onFocusChange).toHaveBeenCalledWith(0, 3);\n });\n\n it(\"should wrap horizontally when pressing right at last column\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n defaultFocusedRow: 0,\n defaultFocusedCol: 3, // Last option in framework\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_RIGHT);\n await delay(INPUT_DELAY_MS);\n\n // Should wrap to first column\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should wrap vertically when all sections are unlocked\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n categories: categoriesWithFramework,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_UP);\n await delay(INPUT_DELAY_MS);\n\n // Should wrap to last row (index 2 for 3 categories)\n expect(onFocusChange).toHaveBeenCalledWith(2, 0);\n });\n });\n\n describe(\"keyboard navigation - vim keys\", () => {\n it(\"should move left with h key\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n defaultFocusedRow: 0,\n defaultFocusedCol: 1,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(\"h\");\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should move right with l key\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(\"l\");\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 1);\n });\n\n it(\"should move up with k key\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n categories: categoriesWithFramework,\n defaultFocusedRow: 1,\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(\"k\");\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should move down with j key\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n categories: categoriesWithFramework,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(\"j\");\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(1, 0);\n });\n });\n\n describe(\"selection toggle\", () => {\n it(\"should call onToggle when pressing space on a normal option\", async () => {\n const onToggle = vi.fn();\n const { stdin, unmount } = renderGrid({\n defaultFocusedRow: 0,\n defaultFocusedCol: 1, // vue (normal state)\n onToggle,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(\" \"); // Space\n await delay(INPUT_DELAY_MS);\n\n expect(onToggle).toHaveBeenCalledWith(\"framework\", \"web-test-vue\");\n });\n\n it(\"should call onToggle when pressing space on a selected option\", async () => {\n const onToggle = vi.fn();\n // Use expertMode to preserve original option order\n const categories: CategoryRow[] = [\n createCategory(\n \"framework\",\n \"Framework\",\n [\n createOption(\"web-test-react\", \"React\", { selected: true }),\n createOption(\"web-test-vue\", \"Vue\"),\n ],\n { required: true },\n ),\n ];\n const { stdin, unmount } = renderGrid({\n categories,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0, // react (selected)\n expertMode: true,\n onToggle,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(\" \");\n await delay(INPUT_DELAY_MS);\n\n expect(onToggle).toHaveBeenCalledWith(\"framework\", \"web-test-react\");\n });\n\n it(\"should NOT call onToggle when all options in a category are disabled\", async () => {\n const onToggle = vi.fn();\n const categories: CategoryRow[] = [\n createCategory(\"testing\", \"Test\", [\n createOption(\"web-test-opt1\", \"Option 1\", { state: \"disabled\" }),\n createOption(\"web-test-opt2\", \"Option 2\", { state: \"disabled\" }),\n ]),\n ];\n\n const { stdin, unmount } = renderGrid({\n categories,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n expertMode: true,\n onToggle,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(\" \");\n await delay(INPUT_DELAY_MS);\n\n expect(onToggle).not.toHaveBeenCalled();\n });\n\n it(\"should bounce focus away from locked sections on mount\", async () => {\n const onFocusChange = vi.fn();\n // No framework selected, styling section is locked\n const { unmount } = renderGrid({\n defaultFocusedRow: 1, // Styling (locked)\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n\n // Focus should have bounced from locked row 1 to unlocked row 0 (framework)\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n });\n\n describe(\"disabled options navigation\", () => {\n it(\"should skip disabled options when navigating right\", async () => {\n const onFocusChange = vi.fn();\n const categories: CategoryRow[] = [\n createCategory(\"testing\", \"Test\", [\n createOption(\"web-test-opt1\", \"Option 1\"),\n createOption(\"web-test-opt2\", \"Option 2\", { state: \"disabled\" }),\n createOption(\"web-test-opt3\", \"Option 3\"),\n ]),\n ];\n\n // Use expertMode to preserve original option order\n const { stdin, unmount } = renderGrid({\n categories,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n expertMode: true,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_RIGHT);\n await delay(INPUT_DELAY_MS);\n\n // Should skip opt2 (disabled) and go to opt3 (index 2)\n expect(onFocusChange).toHaveBeenCalledWith(0, 2);\n });\n\n it(\"should skip disabled options when navigating left\", async () => {\n const onFocusChange = vi.fn();\n const categories: CategoryRow[] = [\n createCategory(\"testing\", \"Test\", [\n createOption(\"web-test-opt1\", \"Option 1\"),\n createOption(\"web-test-opt2\", \"Option 2\", { state: \"disabled\" }),\n createOption(\"web-test-opt3\", \"Option 3\"),\n ]),\n ];\n\n // Use expertMode to preserve original option order\n const { stdin, unmount } = renderGrid({\n categories,\n defaultFocusedRow: 0,\n defaultFocusedCol: 2, // Start at opt3\n expertMode: true,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_LEFT);\n await delay(INPUT_DELAY_MS);\n\n // Should skip opt2 (disabled) and go to opt1 (index 0)\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should handle all options disabled in a row\", async () => {\n const onFocusChange = vi.fn();\n const categories: CategoryRow[] = [\n createCategory(\"testing\", \"Test\", [\n createOption(\"web-test-opt1\", \"Option 1\", { state: \"disabled\" }),\n createOption(\"web-test-opt2\", \"Option 2\", { state: \"disabled\" }),\n ]),\n ];\n\n // Use expertMode to preserve original option order\n const { stdin, unmount } = renderGrid({\n categories,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n expertMode: true,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_RIGHT);\n await delay(INPUT_DELAY_MS);\n\n // Should stay at current position when all disabled\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n });\n\n describe(\"exclusive categories\", () => {\n it(\"should render exclusive category correctly\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n // All default categories are exclusive, should render normally\n expect(output).toContain(\"Framework\");\n });\n\n // Note: The actual exclusivity logic (only one selection) is handled\n // by the parent component via onToggle. CategoryGrid just displays\n // the current state.\n });\n\n describe(\"tab navigation\", () => {\n it(\"should jump to next section when pressing Tab\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n categories: categoriesWithFramework,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(TAB);\n await delay(INPUT_DELAY_MS);\n\n // Should jump to next section (row 1)\n expect(onFocusChange).toHaveBeenCalledWith(1, 0);\n });\n\n it(\"should only jump to unlocked sections\", async () => {\n const onFocusChange = vi.fn();\n // No framework selected, so Tab should stay on framework\n const { stdin, unmount } = renderGrid({\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(TAB);\n await delay(INPUT_DELAY_MS);\n\n // Should NOT call onFocusChange since there's nowhere to go (all others locked)\n expect(onFocusChange).not.toHaveBeenCalled();\n });\n });\n\n describe(\"show descriptions toggle\", () => {\n it(\"should call onToggleDescriptions when pressing d key\", async () => {\n const onToggleDescriptions = vi.fn();\n const { stdin, unmount } = renderGrid({\n onToggleDescriptions,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(\"d\");\n await delay(INPUT_DELAY_MS);\n\n expect(onToggleDescriptions).toHaveBeenCalled();\n });\n\n it(\"should show descriptions when showDescriptions is true\", () => {\n const { lastFrame, unmount } = renderGrid({ showDescriptions: true });\n cleanup = unmount;\n\n const output = lastFrame();\n // Should show state reasons\n expect(output).toContain(\"Popular choice\"); // react's stateReason\n });\n\n it(\"should hide descriptions when showDescriptions is false\", () => {\n const { lastFrame, unmount } = renderGrid({ showDescriptions: false });\n cleanup = unmount;\n\n const output = lastFrame();\n // stateReasons should not be visible (though they might still be in DOM)\n // At minimum, the display should be different\n expect(output).toBeDefined();\n });\n\n it(\"should show descriptions when enabled\", () => {\n const { lastFrame, unmount } = renderGrid({\n showDescriptions: true,\n });\n cleanup = unmount;\n\n const output = lastFrame();\n // Should show state reasons when descriptions are enabled\n expect(output).toContain(\"Popular choice\"); // react's stateReason\n });\n });\n\n describe(\"expert mode\", () => {\n it(\"should not handle expert mode toggle locally (handled globally)\", () => {\n // Expert mode toggle is now handled at wizard.tsx level via global useInput\n // CategoryGrid no longer has onToggleExpertMode prop\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n // Header should not show expert mode toggle hint\n expect(output).not.toContain(\"[e] Expert Mode\");\n });\n });\n\n describe(\"option ordering\", () => {\n it(\"should sort options by state when expertMode is false\", () => {\n // In non-expert mode, recommended should come first\n // The default categories have recommended options at various positions\n const { lastFrame, unmount } = renderGrid({ expertMode: false });\n cleanup = unmount;\n\n const output = lastFrame();\n // This test verifies the component renders - sorting happens internally\n expect(output).toBeDefined();\n });\n\n it(\"should preserve original order when expertMode is true\", () => {\n const { lastFrame, unmount } = renderGrid({ expertMode: true });\n cleanup = unmount;\n\n const output = lastFrame();\n // This test verifies the component renders with expert mode\n expect(output).toBeDefined();\n });\n });\n\n describe(\"edge cases\", () => {\n it(\"should handle single category\", () => {\n const categories: CategoryRow[] = [\n createCategory(\"forms\", \"Single Category\", [createOption(\"web-test-opt1\", \"Option 1\")]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ categories });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Single Category\");\n expect(output).toContain(\"Option 1\");\n });\n\n it(\"should handle single option in category\", () => {\n const categories: CategoryRow[] = [\n createCategory(\"forms\", \"Single\", [createOption(\"web-test-only\", \"Only Option\")]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ categories });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Only Option\");\n });\n\n it(\"should handle category with many options (flows naturally)\", () => {\n const options = Array.from({ length: 10 }, (_, i) =>\n createOption(`web-test-opt${i}`, `Option ${i}`),\n );\n const categories: CategoryRow[] = [createCategory(\"mocking\", \"Many Options\", options)];\n\n const { lastFrame, unmount } = renderGrid({ categories });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Many Options\");\n // All options should be present (no fixed row limit)\n expect(output).toContain(\"Option 0\");\n expect(output).toContain(\"Option 9\");\n });\n\n it(\"should handle long option labels\", () => {\n const categories: CategoryRow[] = [\n createCategory(\"i18n\", \"Long Labels\", [\n createOption(\"web-test-long1\", \"Very Long Option Name\"),\n createOption(\"web-test-long2\", \"Another Long Name\"),\n ]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ categories });\n cleanup = unmount;\n\n const output = lastFrame();\n // Labels should be rendered (flowing layout handles long labels)\n expect(output).toContain(\"Very Long Option Name\");\n });\n\n it(\"should handle categories with different option counts\", () => {\n const categories: CategoryRow[] = [\n createCategory(\"framework\", \"Category 1\", [\n createOption(\"web-test-opt1\", \"Option 1\"),\n createOption(\"web-test-opt2\", \"Option 2\"),\n ]),\n createCategory(\"styling\", \"Category 2\", [createOption(\"web-test-opt3\", \"Option 3\")]),\n createCategory(\"client-state\", \"Category 3\", [\n createOption(\"web-test-opt4\", \"Option 4\"),\n createOption(\"web-test-opt5\", \"Option 5\"),\n createOption(\"web-test-opt6\", \"Option 6\"),\n ]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ categories });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Category 1\");\n expect(output).toContain(\"Category 2\");\n expect(output).toContain(\"Category 3\");\n });\n });\n\n describe(\"column adjustment\", () => {\n it(\"should adjust focusedCol when changing to row with fewer options\", async () => {\n const onFocusChange = vi.fn();\n const categories: CategoryRow[] = [\n createCategory(\n \"framework\",\n \"Framework\",\n [\n createOption(\"web-test-opt1\", \"Option 1\", { selected: true }), // Framework selected\n createOption(\"web-test-opt2\", \"Option 2\"),\n createOption(\"web-test-opt3\", \"Option 3\"),\n ],\n { required: true },\n ),\n createCategory(\"styling\", \"Category 2\", [createOption(\"web-test-opt4\", \"Option 4\")]),\n ];\n\n const { stdin, unmount } = renderGrid({\n categories,\n defaultFocusedRow: 0,\n defaultFocusedCol: 2, // Last option in first row\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_DOWN);\n await delay(INPUT_DELAY_MS);\n\n // Should move to row 1, and col should be clamped to 0 (only option)\n expect(onFocusChange).toHaveBeenCalledWith(1, 0);\n });\n });\n\n describe(\"installed indicator\", () => {\n it(\"should show checkmark for installed skill\", () => {\n const categories: CategoryRow[] = [\n createCategory(\"forms\", \"Forms\", [\n createOption(\"web-test-opt1\", \"Option 1\", { installed: true }),\n ]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ categories });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"✓\");\n expect(output).toContain(\"Option 1\");\n });\n\n it(\"should NOT show checkmark for non-installed skill\", () => {\n const categories: CategoryRow[] = [\n createCategory(\"forms\", \"Forms\", [createOption(\"web-test-opt1\", \"Option 1\")]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ categories });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).not.toContain(\"✓\");\n expect(output).toContain(\"Option 1\");\n });\n\n it(\"should show both checkmark and cyan styling when installed and selected\", () => {\n const categories: CategoryRow[] = [\n createCategory(\"forms\", \"Forms\", [\n createOption(\"web-test-opt1\", \"Option 1\", { installed: true, selected: true }),\n ]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ categories });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"✓\");\n expect(output).toContain(\"Option 1\");\n });\n\n it(\"should show both L badge and checkmark when local and installed\", () => {\n const categories: CategoryRow[] = [\n createCategory(\"forms\", \"Forms\", [\n createOption(\"web-test-opt1\", \"Option 1\", { local: true, installed: true }),\n ]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ categories });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"L\");\n expect(output).toContain(\"✓\");\n expect(output).toContain(\"Option 1\");\n });\n });\n});\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
DomainSelection
|
|
4
|
+
} from "../../chunk-DALU3Y3U.js";
|
|
5
|
+
import "../../chunk-DDNK5UNE.js";
|
|
6
|
+
import "../../chunk-ABK6CSWI.js";
|
|
7
|
+
import "../../chunk-5WIHSJRO.js";
|
|
8
|
+
import "../../chunk-52XVP55K.js";
|
|
9
|
+
import "../../chunk-AWKZ5BDL.js";
|
|
10
|
+
export {
|
|
11
|
+
DomainSelection
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=domain-selection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|