@agents-inc/cli 0.72.0 → 0.73.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/{chunk-OODTDGEM.js → chunk-3K6FSET7.js} +6 -6
  3. package/dist/{chunk-LBTW5HSY.js → chunk-3REVX6S5.js} +11 -11
  4. package/dist/chunk-3REVX6S5.js.map +1 -0
  5. package/dist/{chunk-HMJGSAKV.js → chunk-3VNQPCOE.js} +2510 -2687
  6. package/dist/chunk-3VNQPCOE.js.map +1 -0
  7. package/dist/{chunk-V2XIWRHP.js → chunk-4KLUOFP6.js} +6 -7
  8. package/dist/chunk-4KLUOFP6.js.map +1 -0
  9. package/dist/{chunk-MGQVO357.js → chunk-6JRQPSKV.js} +2 -2
  10. package/dist/chunk-6JRQPSKV.js.map +1 -0
  11. package/dist/{chunk-ZYUASJUN.js → chunk-BH4LN7XV.js} +8 -6
  12. package/dist/chunk-BH4LN7XV.js.map +1 -0
  13. package/dist/{chunk-6YMW4HMX.js → chunk-DNPJ5GUK.js} +6 -6
  14. package/dist/chunk-DNPJ5GUK.js.map +1 -0
  15. package/dist/chunk-E74Q7GUE.js +5132 -0
  16. package/dist/chunk-E74Q7GUE.js.map +1 -0
  17. package/dist/{chunk-AHZ34QVK.js → chunk-EMWP363L.js} +8 -10
  18. package/dist/chunk-EMWP363L.js.map +1 -0
  19. package/dist/chunk-EMX7PA2I.js +39 -0
  20. package/dist/chunk-EMX7PA2I.js.map +1 -0
  21. package/dist/{chunk-SEAL43IR.js → chunk-G23HPF6K.js} +3 -3
  22. package/dist/chunk-GDUOOT3J.js +689 -0
  23. package/dist/chunk-GDUOOT3J.js.map +1 -0
  24. package/dist/{chunk-HJVWBSLM.js → chunk-GSFZDUV2.js} +4 -4
  25. package/dist/chunk-GSFZDUV2.js.map +1 -0
  26. package/dist/{chunk-LM5YQUBR.js → chunk-H4ETXZVL.js} +6 -6
  27. package/dist/{chunk-ZFRALAK5.js → chunk-JHMECCBN.js} +4 -5
  28. package/dist/chunk-JHMECCBN.js.map +1 -0
  29. package/dist/{chunk-UQTG4ZBA.js → chunk-K7WYMQQB.js} +18 -20
  30. package/dist/chunk-K7WYMQQB.js.map +1 -0
  31. package/dist/{chunk-RJOLQ7EK.js → chunk-KE2EAVFQ.js} +4 -4
  32. package/dist/{chunk-CKPJTMNC.js → chunk-KSMT5FVM.js} +4 -4
  33. package/dist/chunk-KSMT5FVM.js.map +1 -0
  34. package/dist/{chunk-52THXN5G.js → chunk-NUJHWYCR.js} +2 -2
  35. package/dist/{chunk-URAXGHF2.js → chunk-OLWGGD4G.js} +20 -15
  36. package/dist/chunk-OLWGGD4G.js.map +1 -0
  37. package/dist/{chunk-FKRYJOPC.js → chunk-PNZCVOCE.js} +5 -5
  38. package/dist/chunk-PNZCVOCE.js.map +1 -0
  39. package/dist/chunk-SRIH4U5Y.js +159 -0
  40. package/dist/chunk-SRIH4U5Y.js.map +1 -0
  41. package/dist/{chunk-J4TVAB5H.js → chunk-T7QY777F.js} +2 -2
  42. package/dist/{chunk-Q3YMO5YG.js → chunk-TNSVPZHP.js} +20 -2
  43. package/dist/chunk-TNSVPZHP.js.map +1 -0
  44. package/dist/{chunk-WWHDP5CP.js → chunk-V5HR77EY.js} +94 -13
  45. package/dist/chunk-V5HR77EY.js.map +1 -0
  46. package/dist/{chunk-ZEJIEC2A.js → chunk-WJL4KU5V.js} +66 -240
  47. package/dist/chunk-WJL4KU5V.js.map +1 -0
  48. package/dist/{chunk-G3LNIYZG.js → chunk-Y47CLMWE.js} +2 -2
  49. package/dist/{chunk-3SLO2QPW.js → chunk-Y4VUU5BT.js} +12 -14
  50. package/dist/chunk-Y4VUU5BT.js.map +1 -0
  51. package/dist/{chunk-F43WGOGN.js → chunk-ZBLSWJFM.js} +2 -2
  52. package/dist/chunk-ZBLSWJFM.js.map +1 -0
  53. package/dist/commands/build/marketplace.js +4 -3
  54. package/dist/commands/build/marketplace.js.map +1 -1
  55. package/dist/commands/build/plugins.js +8 -7
  56. package/dist/commands/build/plugins.js.map +1 -1
  57. package/dist/commands/build/stack.js +8 -7
  58. package/dist/commands/build/stack.js.map +1 -1
  59. package/dist/commands/compile.js +13 -9
  60. package/dist/commands/compile.js.map +1 -1
  61. package/dist/commands/config/index.js +8 -7
  62. package/dist/commands/config/index.js.map +1 -1
  63. package/dist/commands/config/path.js +7 -6
  64. package/dist/commands/config/path.js.map +1 -1
  65. package/dist/commands/config/show.js +8 -7
  66. package/dist/commands/diff.js +7 -6
  67. package/dist/commands/diff.js.map +1 -1
  68. package/dist/commands/doctor.js +12 -13
  69. package/dist/commands/doctor.js.map +1 -1
  70. package/dist/commands/edit.js +32 -34
  71. package/dist/commands/edit.js.map +1 -1
  72. package/dist/commands/eject.js +14 -12
  73. package/dist/commands/eject.js.map +1 -1
  74. package/dist/commands/import/skill.js +7 -6
  75. package/dist/commands/import/skill.js.map +1 -1
  76. package/dist/commands/info.js +11 -10
  77. package/dist/commands/info.js.map +1 -1
  78. package/dist/commands/init.js +27 -26
  79. package/dist/commands/list.js +7 -6
  80. package/dist/commands/list.js.map +1 -1
  81. package/dist/commands/new/agent.js +8 -7
  82. package/dist/commands/new/agent.js.map +1 -1
  83. package/dist/commands/new/marketplace.js +11 -14
  84. package/dist/commands/new/marketplace.js.map +1 -1
  85. package/dist/commands/new/skill.js +8 -7
  86. package/dist/commands/outdated.js +7 -6
  87. package/dist/commands/outdated.js.map +1 -1
  88. package/dist/commands/search.js +8 -9
  89. package/dist/commands/search.js.map +1 -1
  90. package/dist/commands/uninstall.js +7 -6
  91. package/dist/commands/uninstall.js.map +1 -1
  92. package/dist/commands/update.js +9 -9
  93. package/dist/commands/update.js.map +1 -1
  94. package/dist/commands/validate.js +15 -17
  95. package/dist/commands/validate.js.map +1 -1
  96. package/dist/components/wizard/category-grid.js +2 -2
  97. package/dist/components/wizard/category-grid.test.js +16 -65
  98. package/dist/components/wizard/category-grid.test.js.map +1 -1
  99. package/dist/components/wizard/domain-selection.js +9 -8
  100. package/dist/components/wizard/source-grid.js +4 -4
  101. package/dist/components/wizard/source-grid.test.js +18 -16
  102. package/dist/components/wizard/source-grid.test.js.map +1 -1
  103. package/dist/components/wizard/stack-selection.js +8 -7
  104. package/dist/components/wizard/step-agents.js +9 -8
  105. package/dist/components/wizard/step-agents.test.js +14 -13
  106. package/dist/components/wizard/step-agents.test.js.map +1 -1
  107. package/dist/components/wizard/step-build.js +10 -9
  108. package/dist/components/wizard/step-build.test.js +16 -15
  109. package/dist/components/wizard/step-build.test.js.map +1 -1
  110. package/dist/components/wizard/step-confirm.js +5 -4
  111. package/dist/components/wizard/step-confirm.test.js +10 -9
  112. package/dist/components/wizard/step-confirm.test.js.map +1 -1
  113. package/dist/components/wizard/step-settings.js +8 -7
  114. package/dist/components/wizard/step-settings.test.js +11 -10
  115. package/dist/components/wizard/step-settings.test.js.map +1 -1
  116. package/dist/components/wizard/step-sources.js +13 -12
  117. package/dist/components/wizard/step-sources.test.js +18 -17
  118. package/dist/components/wizard/step-sources.test.js.map +1 -1
  119. package/dist/components/wizard/step-stack.js +11 -10
  120. package/dist/components/wizard/step-stack.test.js +15 -14
  121. package/dist/components/wizard/step-stack.test.js.map +1 -1
  122. package/dist/components/wizard/wizard-layout.js +8 -7
  123. package/dist/components/wizard/wizard.js +25 -24
  124. package/dist/hooks/init.js +27 -26
  125. package/dist/hooks/init.js.map +1 -1
  126. package/dist/{loader-KVKSTKWX.js → loader-XQ3WBTVP.js} +4 -3
  127. package/dist/{source-loader-65IAJPNV.js → source-loader-F4PGP6LH.js} +7 -6
  128. package/dist/source-manager-QCIO4XZK.js +20 -0
  129. package/dist/stores/wizard-store.js +7 -6
  130. package/dist/stores/wizard-store.test.js +29 -28
  131. package/dist/stores/wizard-store.test.js.map +1 -1
  132. package/package.json +1 -1
  133. package/src/schemas/custom-metadata.schema.json +81 -0
  134. package/src/schemas/metadata.schema.json +127 -41
  135. package/src/schemas/stacks.schema.json +3 -45
  136. package/dist/chunk-3SLO2QPW.js.map +0 -1
  137. package/dist/chunk-6YMW4HMX.js.map +0 -1
  138. package/dist/chunk-AHZ34QVK.js.map +0 -1
  139. package/dist/chunk-BKL3DF2Q.js +0 -45
  140. package/dist/chunk-BKL3DF2Q.js.map +0 -1
  141. package/dist/chunk-CKPJTMNC.js.map +0 -1
  142. package/dist/chunk-D7FEORKC.js +0 -253
  143. package/dist/chunk-D7FEORKC.js.map +0 -1
  144. package/dist/chunk-F43WGOGN.js.map +0 -1
  145. package/dist/chunk-FKRYJOPC.js.map +0 -1
  146. package/dist/chunk-HJVWBSLM.js.map +0 -1
  147. package/dist/chunk-HMJGSAKV.js.map +0 -1
  148. package/dist/chunk-LBTW5HSY.js.map +0 -1
  149. package/dist/chunk-MGQVO357.js.map +0 -1
  150. package/dist/chunk-Q3YMO5YG.js.map +0 -1
  151. package/dist/chunk-T4EXUIBY.js +0 -19
  152. package/dist/chunk-T4EXUIBY.js.map +0 -1
  153. package/dist/chunk-UQTG4ZBA.js.map +0 -1
  154. package/dist/chunk-URAXGHF2.js.map +0 -1
  155. package/dist/chunk-V2XIWRHP.js.map +0 -1
  156. package/dist/chunk-WWHDP5CP.js.map +0 -1
  157. package/dist/chunk-ZEJIEC2A.js.map +0 -1
  158. package/dist/chunk-ZFRALAK5.js.map +0 -1
  159. package/dist/chunk-ZYUASJUN.js.map +0 -1
  160. package/dist/source-manager-LJH225GA.js +0 -19
  161. package/dist/stores/matrix-store.js +0 -15
  162. package/dist/stores/matrix-store.js.map +0 -1
  163. package/dist/stores/matrix-store.test.js +0 -127
  164. package/dist/stores/matrix-store.test.js.map +0 -1
  165. /package/dist/{chunk-OODTDGEM.js.map → chunk-3K6FSET7.js.map} +0 -0
  166. /package/dist/{chunk-SEAL43IR.js.map → chunk-G23HPF6K.js.map} +0 -0
  167. /package/dist/{chunk-LM5YQUBR.js.map → chunk-H4ETXZVL.js.map} +0 -0
  168. /package/dist/{chunk-RJOLQ7EK.js.map → chunk-KE2EAVFQ.js.map} +0 -0
  169. /package/dist/{chunk-52THXN5G.js.map → chunk-NUJHWYCR.js.map} +0 -0
  170. /package/dist/{chunk-J4TVAB5H.js.map → chunk-T7QY777F.js.map} +0 -0
  171. /package/dist/{chunk-G3LNIYZG.js.map → chunk-Y47CLMWE.js.map} +0 -0
  172. /package/dist/{loader-KVKSTKWX.js.map → loader-XQ3WBTVP.js.map} +0 -0
  173. /package/dist/{source-loader-65IAJPNV.js.map → source-loader-F4PGP6LH.js.map} +0 -0
  174. /package/dist/{source-manager-LJH225GA.js.map → source-manager-QCIO4XZK.js.map} +0 -0
@@ -16,12 +16,12 @@ import {
16
16
  } from "../../chunk-66UDJBF6.js";
17
17
  import {
18
18
  WEB_TRIO_MATRIX
19
- } from "../../chunk-D7FEORKC.js";
20
- import "../../chunk-Q3YMO5YG.js";
19
+ } from "../../chunk-GDUOOT3J.js";
20
+ import "../../chunk-TNSVPZHP.js";
21
21
  import {
22
22
  createMockMatrix,
23
23
  createMockSkill
24
- } from "../../chunk-WWHDP5CP.js";
24
+ } from "../../chunk-V5HR77EY.js";
25
25
  import {
26
26
  afterEach,
27
27
  beforeEach,
@@ -32,22 +32,24 @@ import {
32
32
  } from "../../chunk-XY3XDVMI.js";
33
33
  import {
34
34
  SourceGrid
35
- } from "../../chunk-6YMW4HMX.js";
35
+ } from "../../chunk-DNPJ5GUK.js";
36
36
  import "../../chunk-7SOPVGDV.js";
37
37
  import "../../chunk-2MHSOPIU.js";
38
- import "../../chunk-WF5PMBIR.js";
39
- import "../../chunk-KUV24B5M.js";
40
38
  import "../../chunk-GG4BSB6S.js";
41
39
  import "../../chunk-AUNBGZS4.js";
42
- import "../../chunk-URAXGHF2.js";
40
+ import "../../chunk-WF5PMBIR.js";
41
+ import "../../chunk-KUV24B5M.js";
42
+ import "../../chunk-OLWGGD4G.js";
43
43
  import "../../chunk-6VIOO74O.js";
44
- import "../../chunk-HMJGSAKV.js";
45
- import "../../chunk-F43WGOGN.js";
46
- import "../../chunk-T4EXUIBY.js";
44
+ import "../../chunk-3VNQPCOE.js";
45
+ import "../../chunk-ZBLSWJFM.js";
46
+ import "../../chunk-EMX7PA2I.js";
47
47
  import {
48
- useMatrixStore
49
- } from "../../chunk-BKL3DF2Q.js";
50
- import "../../chunk-ZEJIEC2A.js";
48
+ BUILT_IN_MATRIX,
49
+ initializeMatrix
50
+ } from "../../chunk-E74Q7GUE.js";
51
+ import "../../chunk-WJL4KU5V.js";
52
+ import "../../chunk-SRIH4U5Y.js";
51
53
  import "../../chunk-EGMQ3SXN.js";
52
54
  import "../../chunk-NKKYTCBH.js";
53
55
  import {
@@ -96,12 +98,12 @@ var renderGrid = (props = {}) => {
96
98
  describe("SourceGrid component", () => {
97
99
  let cleanup;
98
100
  beforeEach(() => {
99
- useMatrixStore.getState().setMatrix(WEB_TRIO_MATRIX);
101
+ initializeMatrix(WEB_TRIO_MATRIX);
100
102
  });
101
103
  afterEach(() => {
102
104
  cleanup?.();
103
105
  cleanup = void 0;
104
- useMatrixStore.getState().reset();
106
+ initializeMatrix(BUILT_IN_MATRIX);
105
107
  });
106
108
  describe("rendering", () => {
107
109
  it("should render all skill rows", () => {
@@ -345,7 +347,7 @@ describe("SourceGrid component", () => {
345
347
  "web-tooling-vite"
346
348
  ];
347
349
  const skills = Object.fromEntries(skillIds.map((id) => [id, createMockSkill(id)]));
348
- useMatrixStore.getState().setMatrix(createMockMatrix(skills));
350
+ initializeMatrix(createMockMatrix(skills));
349
351
  const rows = skillIds.map(
350
352
  (id) => createSourceRow(id, [createSourceOption("public", { selected: true })])
351
353
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/cli/components/wizard/source-grid.test.tsx"],"sourcesContent":["import { render } from \"ink-testing-library\";\nimport { describe, expect, it, afterEach, beforeEach, vi } from \"vitest\";\nimport { SourceGrid, type SourceGridProps, type SourceRow, type SourceOption } from \"./source-grid\";\nimport type { BoundSkillCandidate, SkillId } from \"../../types\";\nimport { useMatrixStore } from \"../../stores/matrix-store\";\nimport { createMockMatrix, createMockSkill } from \"../../lib/__tests__/helpers\";\nimport { WEB_TRIO_MATRIX } from \"../../lib/__tests__/mock-data/mock-matrices\";\nimport {\n ARROW_UP,\n ARROW_DOWN,\n ARROW_LEFT,\n ARROW_RIGHT,\n ENTER,\n SPACE,\n ESCAPE,\n RENDER_DELAY_MS,\n INPUT_DELAY_MS,\n delay,\n} from \"../../lib/__tests__/test-constants\";\n\nconst createSourceOption = (id: string, overrides: Partial<SourceOption> = {}): SourceOption => ({\n id,\n selected: false,\n installed: false,\n ...overrides,\n});\n\nconst createSourceRow = (skillId: SkillId, options: SourceOption[]): SourceRow => ({\n skillId,\n options,\n});\n\nconst defaultRows: SourceRow[] = [\n createSourceRow(\"web-framework-react\", [createSourceOption(\"public\", { selected: true })]),\n createSourceRow(\"web-state-zustand\", [createSourceOption(\"public\", { selected: true })]),\n createSourceRow(\"web-testing-vitest\", [createSourceOption(\"public\", { selected: true })]),\n];\n\nconst multiSourceRows: SourceRow[] = [\n createSourceRow(\"web-framework-react\", [\n createSourceOption(\"public\", { selected: true }),\n createSourceOption(\"acme-corp\"),\n ]),\n createSourceRow(\"web-state-zustand\", [\n createSourceOption(\"public\", { selected: true }),\n createSourceOption(\"acme-corp\"),\n createSourceOption(\"internal\"),\n ]),\n];\n\nconst defaultProps: SourceGridProps = {\n rows: defaultRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onSelect: vi.fn(),\n onFocusChange: vi.fn(),\n};\n\nconst renderGrid = (props: Partial<SourceGridProps> = {}) => {\n return render(<SourceGrid {...defaultProps} {...props} />);\n};\n\ndescribe(\"SourceGrid component\", () => {\n let cleanup: (() => void) | undefined;\n\n beforeEach(() => {\n useMatrixStore.getState().setMatrix(WEB_TRIO_MATRIX);\n });\n\n afterEach(() => {\n cleanup?.();\n cleanup = undefined;\n useMatrixStore.getState().reset();\n });\n\n describe(\"rendering\", () => {\n it(\"should render all skill rows\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"React\");\n expect(output).toContain(\"Zustand\");\n expect(output).toContain(\"Vitest\");\n });\n\n it(\"should render source option labels\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Public\");\n });\n\n it(\"should render multiple source options per row\", () => {\n const { lastFrame, unmount } = renderGrid({ rows: multiSourceRows });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Public\");\n expect(output).toContain(\"acme-corp\");\n });\n\n it(\"should handle empty rows array\", () => {\n const { lastFrame, unmount } = renderGrid({ rows: [] });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"No skills to display\");\n });\n\n it(\"should render single row\", () => {\n const rows: SourceRow[] = [\n createSourceRow(\"web-framework-react\", [createSourceOption(\"public\", { selected: true })]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ rows });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"React\");\n expect(output).toContain(\"Public\");\n });\n });\n\n describe(\"keyboard navigation - vertical\", () => {\n it(\"should move down with arrow down\", 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 stdin.write(ARROW_DOWN);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(1, 0);\n });\n\n it(\"should move up with arrow up\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n defaultFocusedRow: 1,\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(ARROW_UP);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should wrap down to first row from last row\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n defaultFocusedRow: 2, // Last row (Vitest)\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(ARROW_DOWN);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should wrap up to last row from first row\", 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 stdin.write(ARROW_UP);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(2, 0);\n });\n\n it(\"should clamp column when moving to row with fewer options\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: multiSourceRows,\n defaultFocusedRow: 1, // Zustand has 3 options\n defaultFocusedCol: 2, // Internal (index 2)\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(ARROW_UP);\n await delay(INPUT_DELAY_MS);\n\n // React only has 2 options, so col should be clamped to 1\n expect(onFocusChange).toHaveBeenCalledWith(0, 1);\n });\n });\n\n describe(\"keyboard navigation - horizontal\", () => {\n it(\"should move right with arrow right\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: multiSourceRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(ARROW_RIGHT);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 1);\n });\n\n it(\"should move left with arrow left\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: multiSourceRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 1,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(ARROW_LEFT);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should wrap right to first column from last column\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: multiSourceRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 1, // Last option in React row\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(ARROW_RIGHT);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should wrap left to last column from first column\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: multiSourceRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(ARROW_LEFT);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 1);\n });\n });\n\n describe(\"selection\", () => {\n it(\"should call onSelect when pressing space\", async () => {\n const onSelect = vi.fn();\n const { stdin, unmount } = renderGrid({\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onSelect,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(\" \");\n await delay(INPUT_DELAY_MS);\n\n expect(onSelect).toHaveBeenCalledWith(\"web-framework-react\", \"public\");\n });\n\n it(\"should call onSelect with correct skill and source IDs\", async () => {\n const onSelect = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: multiSourceRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 1, // Acme Corp\n onSelect,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(\" \");\n await delay(INPUT_DELAY_MS);\n\n expect(onSelect).toHaveBeenCalledWith(\"web-framework-react\", \"acme-corp\");\n });\n\n it(\"should call onSelect on second row\", async () => {\n const onSelect = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: multiSourceRows,\n defaultFocusedRow: 1,\n defaultFocusedCol: 2, // Internal\n onSelect,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(\" \");\n await delay(INPUT_DELAY_MS);\n\n expect(onSelect).toHaveBeenCalledWith(\"web-state-zustand\", \"internal\");\n });\n });\n\n describe(\"edge cases\", () => {\n it(\"should handle single option per row\", 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 stdin.write(ARROW_RIGHT);\n await delay(INPUT_DELAY_MS);\n\n // Should wrap to 0 (only one option)\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should handle many rows\", () => {\n const skillIds: SkillId[] = [\n \"web-framework-react\",\n \"web-framework-vue-composition-api\",\n \"web-styling-tailwind\",\n \"web-styling-scss-modules\",\n \"web-state-zustand\",\n \"web-state-mobx\",\n \"web-testing-vitest\",\n \"web-testing-playwright-e2e\",\n \"web-server-state-react-query\",\n \"web-tooling-vite\" as SkillId,\n ];\n const skills = Object.fromEntries(skillIds.map((id) => [id, createMockSkill(id)]));\n useMatrixStore.getState().setMatrix(createMockMatrix(skills));\n\n const rows: SourceRow[] = skillIds.map((id) =>\n createSourceRow(id, [createSourceOption(\"public\", { selected: true })]),\n );\n\n const { lastFrame, unmount } = renderGrid({ rows });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"React\");\n expect(output).toContain(\"Vite\");\n });\n });\n\n describe(\"search pill\", () => {\n const mockSearch = vi.fn<(alias: string) => Promise<BoundSkillCandidate[]>>();\n const mockBind = vi.fn();\n const mockSearchStateChange = vi.fn();\n\n const searchCandidates: BoundSkillCandidate[] = [\n {\n id: \"web-framework-react-pro\" as SkillId,\n sourceUrl: \"github:awesome-dev/skills\",\n sourceName: \"awesome-dev\",\n alias: \"react\",\n },\n {\n id: \"web-framework-react-strict\" as SkillId,\n sourceUrl: \"github:team-xyz/skills\",\n sourceName: \"team-xyz\",\n alias: \"react\",\n },\n ];\n\n afterEach(() => {\n mockSearch.mockReset();\n mockBind.mockReset();\n mockSearchStateChange.mockReset();\n });\n\n it(\"should render search pill at end of each row when onSearch is provided\", () => {\n const { lastFrame, unmount } = renderGrid({\n onSearch: mockSearch,\n });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Search\");\n });\n\n it(\"should not render search pill when onSearch is not provided\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).not.toContain(\"Search\");\n });\n\n it(\"should navigate to search pill with arrow right\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: defaultRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0, // On the only option (Public)\n onFocusChange,\n onSearch: mockSearch,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(ARROW_RIGHT);\n await delay(INPUT_DELAY_MS);\n\n // Public is at index 0, search pill at index 1\n expect(onFocusChange).toHaveBeenCalledWith(0, 1);\n });\n\n it(\"should not call onSelect when space is pressed on search pill\", async () => {\n const onSelect = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: defaultRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 1, // Search pill position (after Public)\n onSelect,\n onSearch: mockSearch,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(\" \");\n await delay(INPUT_DELAY_MS);\n\n expect(onSelect).not.toHaveBeenCalled();\n });\n\n it(\"should trigger search on Space when search pill is focused\", async () => {\n mockSearch.mockResolvedValue(searchCandidates);\n\n const { stdin, unmount } = renderGrid({\n rows: defaultRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 1, // Search pill position\n onSearch: mockSearch,\n onSearchStateChange: mockSearchStateChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(SPACE);\n await delay(INPUT_DELAY_MS);\n\n expect(mockSearch).toHaveBeenCalledWith(\"react\");\n expect(mockSearchStateChange).toHaveBeenCalledWith(true);\n });\n\n it(\"should render modal with results after search completes\", async () => {\n mockSearch.mockResolvedValue(searchCandidates);\n\n const { stdin, lastFrame, unmount } = renderGrid({\n rows: defaultRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 1,\n onSearch: mockSearch,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(SPACE);\n // Wait for async search to resolve\n await delay(RENDER_DELAY_MS);\n\n const output = lastFrame();\n expect(output).toContain(\"react\");\n expect(output).toContain(\"awesome-dev\");\n expect(output).toContain(\"team-xyz\");\n });\n\n it(\"should close modal on Escape without binding\", async () => {\n mockSearch.mockResolvedValue(searchCandidates);\n\n const { stdin, lastFrame, unmount } = renderGrid({\n rows: defaultRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 1,\n onSearch: mockSearch,\n onBind: mockBind,\n onSearchStateChange: mockSearchStateChange,\n });\n cleanup = unmount;\n\n // Open modal\n await delay(RENDER_DELAY_MS);\n stdin.write(SPACE);\n await delay(RENDER_DELAY_MS);\n\n // Close modal\n stdin.write(ESCAPE);\n await delay(INPUT_DELAY_MS);\n\n expect(mockBind).not.toHaveBeenCalled();\n expect(mockSearchStateChange).toHaveBeenLastCalledWith(false);\n\n const output = lastFrame();\n expect(output).not.toContain(\"awesome-dev\");\n });\n\n it(\"should not respond to grid navigation while modal is open\", async () => {\n mockSearch.mockResolvedValue(searchCandidates);\n const onFocusChange = vi.fn();\n\n const { stdin, unmount } = renderGrid({\n rows: defaultRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 1,\n onSearch: mockSearch,\n onFocusChange,\n });\n cleanup = unmount;\n\n // Open modal\n await delay(RENDER_DELAY_MS);\n stdin.write(SPACE);\n await delay(RENDER_DELAY_MS);\n\n // Try grid navigation while modal is open\n onFocusChange.mockClear();\n stdin.write(ARROW_LEFT);\n await delay(INPUT_DELAY_MS);\n stdin.write(ARROW_RIGHT);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).not.toHaveBeenCalled();\n });\n\n it(\"should bind result on Enter in modal\", async () => {\n mockSearch.mockResolvedValue(searchCandidates);\n\n const { stdin, unmount } = renderGrid({\n rows: defaultRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 1,\n onSearch: mockSearch,\n onBind: mockBind,\n onSearchStateChange: mockSearchStateChange,\n });\n cleanup = unmount;\n\n // Open modal with Space\n await delay(RENDER_DELAY_MS);\n stdin.write(SPACE);\n await delay(RENDER_DELAY_MS);\n\n // Bind first result\n stdin.write(ENTER);\n await delay(INPUT_DELAY_MS);\n\n expect(mockBind).toHaveBeenCalledWith(searchCandidates[0]);\n expect(mockSearchStateChange).toHaveBeenLastCalledWith(false);\n });\n });\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/cli/components/wizard/source-grid.test.tsx"],"sourcesContent":["import { render } from \"ink-testing-library\";\nimport { describe, expect, it, afterEach, beforeEach, vi } from \"vitest\";\nimport { SourceGrid, type SourceGridProps, type SourceRow, type SourceOption } from \"./source-grid\";\nimport type { BoundSkillCandidate, SkillId } from \"../../types\";\nimport { initializeMatrix } from \"../../lib/matrix/matrix-provider\";\nimport { BUILT_IN_MATRIX } from \"../../types/generated/matrix\";\nimport { createMockMatrix, createMockSkill } from \"../../lib/__tests__/helpers\";\nimport { WEB_TRIO_MATRIX } from \"../../lib/__tests__/mock-data/mock-matrices\";\nimport {\n ARROW_UP,\n ARROW_DOWN,\n ARROW_LEFT,\n ARROW_RIGHT,\n ENTER,\n SPACE,\n ESCAPE,\n RENDER_DELAY_MS,\n INPUT_DELAY_MS,\n delay,\n} from \"../../lib/__tests__/test-constants\";\n\nconst createSourceOption = (id: string, overrides: Partial<SourceOption> = {}): SourceOption => ({\n id,\n selected: false,\n installed: false,\n ...overrides,\n});\n\nconst createSourceRow = (skillId: SkillId, options: SourceOption[]): SourceRow => ({\n skillId,\n options,\n});\n\nconst defaultRows: SourceRow[] = [\n createSourceRow(\"web-framework-react\", [createSourceOption(\"public\", { selected: true })]),\n createSourceRow(\"web-state-zustand\", [createSourceOption(\"public\", { selected: true })]),\n createSourceRow(\"web-testing-vitest\", [createSourceOption(\"public\", { selected: true })]),\n];\n\nconst multiSourceRows: SourceRow[] = [\n createSourceRow(\"web-framework-react\", [\n createSourceOption(\"public\", { selected: true }),\n createSourceOption(\"acme-corp\"),\n ]),\n createSourceRow(\"web-state-zustand\", [\n createSourceOption(\"public\", { selected: true }),\n createSourceOption(\"acme-corp\"),\n createSourceOption(\"internal\"),\n ]),\n];\n\nconst defaultProps: SourceGridProps = {\n rows: defaultRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onSelect: vi.fn(),\n onFocusChange: vi.fn(),\n};\n\nconst renderGrid = (props: Partial<SourceGridProps> = {}) => {\n return render(<SourceGrid {...defaultProps} {...props} />);\n};\n\ndescribe(\"SourceGrid component\", () => {\n let cleanup: (() => void) | undefined;\n\n beforeEach(() => {\n initializeMatrix(WEB_TRIO_MATRIX);\n });\n\n afterEach(() => {\n cleanup?.();\n cleanup = undefined;\n initializeMatrix(BUILT_IN_MATRIX);\n });\n\n describe(\"rendering\", () => {\n it(\"should render all skill rows\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"React\");\n expect(output).toContain(\"Zustand\");\n expect(output).toContain(\"Vitest\");\n });\n\n it(\"should render source option labels\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Public\");\n });\n\n it(\"should render multiple source options per row\", () => {\n const { lastFrame, unmount } = renderGrid({ rows: multiSourceRows });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Public\");\n expect(output).toContain(\"acme-corp\");\n });\n\n it(\"should handle empty rows array\", () => {\n const { lastFrame, unmount } = renderGrid({ rows: [] });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"No skills to display\");\n });\n\n it(\"should render single row\", () => {\n const rows: SourceRow[] = [\n createSourceRow(\"web-framework-react\", [createSourceOption(\"public\", { selected: true })]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ rows });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"React\");\n expect(output).toContain(\"Public\");\n });\n });\n\n describe(\"keyboard navigation - vertical\", () => {\n it(\"should move down with arrow down\", 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 stdin.write(ARROW_DOWN);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(1, 0);\n });\n\n it(\"should move up with arrow up\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n defaultFocusedRow: 1,\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(ARROW_UP);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should wrap down to first row from last row\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n defaultFocusedRow: 2, // Last row (Vitest)\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(ARROW_DOWN);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should wrap up to last row from first row\", 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 stdin.write(ARROW_UP);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(2, 0);\n });\n\n it(\"should clamp column when moving to row with fewer options\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: multiSourceRows,\n defaultFocusedRow: 1, // Zustand has 3 options\n defaultFocusedCol: 2, // Internal (index 2)\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(ARROW_UP);\n await delay(INPUT_DELAY_MS);\n\n // React only has 2 options, so col should be clamped to 1\n expect(onFocusChange).toHaveBeenCalledWith(0, 1);\n });\n });\n\n describe(\"keyboard navigation - horizontal\", () => {\n it(\"should move right with arrow right\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: multiSourceRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(ARROW_RIGHT);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 1);\n });\n\n it(\"should move left with arrow left\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: multiSourceRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 1,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(ARROW_LEFT);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should wrap right to first column from last column\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: multiSourceRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 1, // Last option in React row\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(ARROW_RIGHT);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should wrap left to last column from first column\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: multiSourceRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(ARROW_LEFT);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenCalledWith(0, 1);\n });\n });\n\n describe(\"selection\", () => {\n it(\"should call onSelect when pressing space\", async () => {\n const onSelect = vi.fn();\n const { stdin, unmount } = renderGrid({\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onSelect,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(\" \");\n await delay(INPUT_DELAY_MS);\n\n expect(onSelect).toHaveBeenCalledWith(\"web-framework-react\", \"public\");\n });\n\n it(\"should call onSelect with correct skill and source IDs\", async () => {\n const onSelect = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: multiSourceRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 1, // Acme Corp\n onSelect,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(\" \");\n await delay(INPUT_DELAY_MS);\n\n expect(onSelect).toHaveBeenCalledWith(\"web-framework-react\", \"acme-corp\");\n });\n\n it(\"should call onSelect on second row\", async () => {\n const onSelect = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: multiSourceRows,\n defaultFocusedRow: 1,\n defaultFocusedCol: 2, // Internal\n onSelect,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(\" \");\n await delay(INPUT_DELAY_MS);\n\n expect(onSelect).toHaveBeenCalledWith(\"web-state-zustand\", \"internal\");\n });\n });\n\n describe(\"edge cases\", () => {\n it(\"should handle single option per row\", 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 stdin.write(ARROW_RIGHT);\n await delay(INPUT_DELAY_MS);\n\n // Should wrap to 0 (only one option)\n expect(onFocusChange).toHaveBeenCalledWith(0, 0);\n });\n\n it(\"should handle many rows\", () => {\n const skillIds: SkillId[] = [\n \"web-framework-react\",\n \"web-framework-vue-composition-api\",\n \"web-styling-tailwind\",\n \"web-styling-scss-modules\",\n \"web-state-zustand\",\n \"web-state-mobx\",\n \"web-testing-vitest\",\n \"web-testing-playwright-e2e\",\n \"web-server-state-react-query\",\n \"web-tooling-vite\" as SkillId,\n ];\n const skills = Object.fromEntries(skillIds.map((id) => [id, createMockSkill(id)]));\n initializeMatrix(createMockMatrix(skills));\n\n const rows: SourceRow[] = skillIds.map((id) =>\n createSourceRow(id, [createSourceOption(\"public\", { selected: true })]),\n );\n\n const { lastFrame, unmount } = renderGrid({ rows });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"React\");\n expect(output).toContain(\"Vite\");\n });\n });\n\n describe(\"search pill\", () => {\n const mockSearch = vi.fn<(alias: string) => Promise<BoundSkillCandidate[]>>();\n const mockBind = vi.fn();\n const mockSearchStateChange = vi.fn();\n\n const searchCandidates: BoundSkillCandidate[] = [\n {\n id: \"web-framework-react-pro\" as SkillId,\n sourceUrl: \"github:awesome-dev/skills\",\n sourceName: \"awesome-dev\",\n alias: \"react\",\n },\n {\n id: \"web-framework-react-strict\" as SkillId,\n sourceUrl: \"github:team-xyz/skills\",\n sourceName: \"team-xyz\",\n alias: \"react\",\n },\n ];\n\n afterEach(() => {\n mockSearch.mockReset();\n mockBind.mockReset();\n mockSearchStateChange.mockReset();\n });\n\n it(\"should render search pill at end of each row when onSearch is provided\", () => {\n const { lastFrame, unmount } = renderGrid({\n onSearch: mockSearch,\n });\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Search\");\n });\n\n it(\"should not render search pill when onSearch is not provided\", () => {\n const { lastFrame, unmount } = renderGrid();\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).not.toContain(\"Search\");\n });\n\n it(\"should navigate to search pill with arrow right\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: defaultRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0, // On the only option (Public)\n onFocusChange,\n onSearch: mockSearch,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(ARROW_RIGHT);\n await delay(INPUT_DELAY_MS);\n\n // Public is at index 0, search pill at index 1\n expect(onFocusChange).toHaveBeenCalledWith(0, 1);\n });\n\n it(\"should not call onSelect when space is pressed on search pill\", async () => {\n const onSelect = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: defaultRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 1, // Search pill position (after Public)\n onSelect,\n onSearch: mockSearch,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(\" \");\n await delay(INPUT_DELAY_MS);\n\n expect(onSelect).not.toHaveBeenCalled();\n });\n\n it(\"should trigger search on Space when search pill is focused\", async () => {\n mockSearch.mockResolvedValue(searchCandidates);\n\n const { stdin, unmount } = renderGrid({\n rows: defaultRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 1, // Search pill position\n onSearch: mockSearch,\n onSearchStateChange: mockSearchStateChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(SPACE);\n await delay(INPUT_DELAY_MS);\n\n expect(mockSearch).toHaveBeenCalledWith(\"react\");\n expect(mockSearchStateChange).toHaveBeenCalledWith(true);\n });\n\n it(\"should render modal with results after search completes\", async () => {\n mockSearch.mockResolvedValue(searchCandidates);\n\n const { stdin, lastFrame, unmount } = renderGrid({\n rows: defaultRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 1,\n onSearch: mockSearch,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(SPACE);\n // Wait for async search to resolve\n await delay(RENDER_DELAY_MS);\n\n const output = lastFrame();\n expect(output).toContain(\"react\");\n expect(output).toContain(\"awesome-dev\");\n expect(output).toContain(\"team-xyz\");\n });\n\n it(\"should close modal on Escape without binding\", async () => {\n mockSearch.mockResolvedValue(searchCandidates);\n\n const { stdin, lastFrame, unmount } = renderGrid({\n rows: defaultRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 1,\n onSearch: mockSearch,\n onBind: mockBind,\n onSearchStateChange: mockSearchStateChange,\n });\n cleanup = unmount;\n\n // Open modal\n await delay(RENDER_DELAY_MS);\n stdin.write(SPACE);\n await delay(RENDER_DELAY_MS);\n\n // Close modal\n stdin.write(ESCAPE);\n await delay(INPUT_DELAY_MS);\n\n expect(mockBind).not.toHaveBeenCalled();\n expect(mockSearchStateChange).toHaveBeenLastCalledWith(false);\n\n const output = lastFrame();\n expect(output).not.toContain(\"awesome-dev\");\n });\n\n it(\"should not respond to grid navigation while modal is open\", async () => {\n mockSearch.mockResolvedValue(searchCandidates);\n const onFocusChange = vi.fn();\n\n const { stdin, unmount } = renderGrid({\n rows: defaultRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 1,\n onSearch: mockSearch,\n onFocusChange,\n });\n cleanup = unmount;\n\n // Open modal\n await delay(RENDER_DELAY_MS);\n stdin.write(SPACE);\n await delay(RENDER_DELAY_MS);\n\n // Try grid navigation while modal is open\n onFocusChange.mockClear();\n stdin.write(ARROW_LEFT);\n await delay(INPUT_DELAY_MS);\n stdin.write(ARROW_RIGHT);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).not.toHaveBeenCalled();\n });\n\n it(\"should bind result on Enter in modal\", async () => {\n mockSearch.mockResolvedValue(searchCandidates);\n\n const { stdin, unmount } = renderGrid({\n rows: defaultRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 1,\n onSearch: mockSearch,\n onBind: mockBind,\n onSearchStateChange: mockSearchStateChange,\n });\n cleanup = unmount;\n\n // Open modal with Space\n await delay(RENDER_DELAY_MS);\n stdin.write(SPACE);\n await delay(RENDER_DELAY_MS);\n\n // Bind first result\n stdin.write(ENTER);\n await delay(INPUT_DELAY_MS);\n\n expect(mockBind).toHaveBeenCalledWith(searchCandidates[0]);\n expect(mockSearchStateChange).toHaveBeenLastCalledWith(false);\n });\n });\n});\n"],"mappings":"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","names":[]}
@@ -1,15 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  StackSelection
4
- } from "../../chunk-ZFRALAK5.js";
4
+ } from "../../chunk-JHMECCBN.js";
5
5
  import "../../chunk-MWGDG4QN.js";
6
6
  import "../../chunk-AUNBGZS4.js";
7
- import "../../chunk-URAXGHF2.js";
8
- import "../../chunk-HMJGSAKV.js";
9
- import "../../chunk-F43WGOGN.js";
10
- import "../../chunk-T4EXUIBY.js";
11
- import "../../chunk-BKL3DF2Q.js";
12
- import "../../chunk-ZEJIEC2A.js";
7
+ import "../../chunk-OLWGGD4G.js";
8
+ import "../../chunk-3VNQPCOE.js";
9
+ import "../../chunk-ZBLSWJFM.js";
10
+ import "../../chunk-EMX7PA2I.js";
11
+ import "../../chunk-E74Q7GUE.js";
12
+ import "../../chunk-WJL4KU5V.js";
13
+ import "../../chunk-SRIH4U5Y.js";
13
14
  import "../../chunk-EGMQ3SXN.js";
14
15
  import "../../chunk-NKKYTCBH.js";
15
16
  import "../../chunk-DHET7RCE.js";
@@ -1,18 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  StepAgents
4
- } from "../../chunk-LBTW5HSY.js";
4
+ } from "../../chunk-3REVX6S5.js";
5
5
  import "../../chunk-K77I4XGL.js";
6
- import "../../chunk-ZYUASJUN.js";
6
+ import "../../chunk-BH4LN7XV.js";
7
7
  import "../../chunk-XMLCXRTS.js";
8
8
  import "../../chunk-AQYAVLZK.js";
9
9
  import "../../chunk-AUNBGZS4.js";
10
- import "../../chunk-URAXGHF2.js";
11
- import "../../chunk-HMJGSAKV.js";
12
- import "../../chunk-F43WGOGN.js";
13
- import "../../chunk-T4EXUIBY.js";
14
- import "../../chunk-BKL3DF2Q.js";
15
- import "../../chunk-ZEJIEC2A.js";
10
+ import "../../chunk-OLWGGD4G.js";
11
+ import "../../chunk-3VNQPCOE.js";
12
+ import "../../chunk-ZBLSWJFM.js";
13
+ import "../../chunk-EMX7PA2I.js";
14
+ import "../../chunk-E74Q7GUE.js";
15
+ import "../../chunk-WJL4KU5V.js";
16
+ import "../../chunk-SRIH4U5Y.js";
16
17
  import "../../chunk-EGMQ3SXN.js";
17
18
  import "../../chunk-NKKYTCBH.js";
18
19
  import "../../chunk-DHET7RCE.js";
@@ -13,9 +13,9 @@ import {
13
13
  } from "../../chunk-66UDJBF6.js";
14
14
  import {
15
15
  EMPTY_MATRIX
16
- } from "../../chunk-D7FEORKC.js";
17
- import "../../chunk-Q3YMO5YG.js";
18
- import "../../chunk-WWHDP5CP.js";
16
+ } from "../../chunk-GDUOOT3J.js";
17
+ import "../../chunk-TNSVPZHP.js";
18
+ import "../../chunk-V5HR77EY.js";
19
19
  import {
20
20
  afterEach,
21
21
  beforeEach,
@@ -25,22 +25,23 @@ import {
25
25
  } from "../../chunk-XY3XDVMI.js";
26
26
  import {
27
27
  StepAgents
28
- } from "../../chunk-LBTW5HSY.js";
28
+ } from "../../chunk-3REVX6S5.js";
29
29
  import "../../chunk-K77I4XGL.js";
30
- import "../../chunk-ZYUASJUN.js";
30
+ import "../../chunk-BH4LN7XV.js";
31
31
  import "../../chunk-XMLCXRTS.js";
32
32
  import "../../chunk-AQYAVLZK.js";
33
33
  import "../../chunk-AUNBGZS4.js";
34
34
  import {
35
35
  useWizardStore
36
- } from "../../chunk-URAXGHF2.js";
37
- import "../../chunk-HMJGSAKV.js";
38
- import "../../chunk-F43WGOGN.js";
39
- import "../../chunk-T4EXUIBY.js";
36
+ } from "../../chunk-OLWGGD4G.js";
37
+ import "../../chunk-3VNQPCOE.js";
38
+ import "../../chunk-ZBLSWJFM.js";
39
+ import "../../chunk-EMX7PA2I.js";
40
40
  import {
41
- useMatrixStore
42
- } from "../../chunk-BKL3DF2Q.js";
43
- import "../../chunk-ZEJIEC2A.js";
41
+ initializeMatrix
42
+ } from "../../chunk-E74Q7GUE.js";
43
+ import "../../chunk-WJL4KU5V.js";
44
+ import "../../chunk-SRIH4U5Y.js";
44
45
  import "../../chunk-EGMQ3SXN.js";
45
46
  import "../../chunk-NKKYTCBH.js";
46
47
  import {
@@ -53,7 +54,7 @@ import { jsx } from "react/jsx-runtime";
53
54
  describe("StepAgents component", () => {
54
55
  let cleanup;
55
56
  beforeEach(() => {
56
- useMatrixStore.getState().setMatrix(EMPTY_MATRIX);
57
+ initializeMatrix(EMPTY_MATRIX);
57
58
  });
58
59
  afterEach(() => {
59
60
  cleanup?.();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/cli/components/wizard/step-agents.test.tsx"],"sourcesContent":["import { render } from \"ink-testing-library\";\nimport { afterEach, beforeEach, describe, expect, it } from \"vitest\";\nimport { StepAgents } from \"./step-agents\";\nimport { useWizardStore } from \"../../stores/wizard-store\";\nimport { useMatrixStore } from \"../../stores/matrix-store\";\nimport {\n ARROW_DOWN,\n ENTER,\n ESCAPE,\n SPACE,\n RENDER_DELAY_MS,\n INPUT_DELAY_MS,\n delay,\n} from \"../../lib/__tests__/test-constants\";\nimport { EMPTY_MATRIX } from \"../../lib/__tests__/mock-data/mock-matrices\";\n\nconst EXPECTED_AGENT_COUNT = 18;\n\ndescribe(\"StepAgents component\", () => {\n let cleanup: (() => void) | undefined;\n\n beforeEach(() => {\n useMatrixStore.getState().setMatrix(EMPTY_MATRIX);\n });\n\n afterEach(() => {\n cleanup?.();\n cleanup = undefined;\n });\n\n describe(\"rendering\", () => {\n it(\"should render title\", () => {\n const { lastFrame, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Select agents to compile:\");\n });\n\n it(\"should render all agents\", () => {\n const { lastFrame, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Web Developer\");\n expect(output).toContain(\"API Developer\");\n expect(output).toContain(\"CLI Developer\");\n expect(output).toContain(\"Web Architecture\");\n expect(output).toContain(\"Web Reviewer\");\n expect(output).toContain(\"API Reviewer\");\n expect(output).toContain(\"CLI Reviewer\");\n expect(output).toContain(\"Web Researcher\");\n expect(output).toContain(\"API Researcher\");\n expect(output).toContain(\"Web Tester\");\n expect(output).toContain(\"CLI Tester\");\n expect(output).toContain(\"Web PM\");\n expect(output).toContain(\"Pattern Scout\");\n expect(output).toContain(\"Pattern Critique\");\n expect(output).toContain(\"Agent Summoner\");\n expect(output).toContain(\"Skill Summoner\");\n expect(output).toContain(\"Documentor\");\n });\n\n it(\"should render agent descriptions\", () => {\n const { lastFrame, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Frontend features, components, TypeScript\");\n expect(output).toContain(\"Backend routes, database, middleware\");\n expect(output).toContain(\"CLI commands, interactive prompts\");\n });\n\n it(\"should render group headers\", () => {\n const { lastFrame, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Web\");\n expect(output).toContain(\"API\");\n expect(output).toContain(\"CLI\");\n expect(output).toContain(\"Meta\");\n });\n\n it(\"should show continue arrow\", () => {\n const { lastFrame, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"\\u2192\");\n expect(output).toContain(\"Continue\");\n });\n\n it(\"should show continue option with agent count when agents selected\", () => {\n const store = useWizardStore.getState();\n store.toggleAgent(\"web-developer\");\n store.toggleAgent(\"api-developer\");\n store.toggleAgent(\"web-reviewer\");\n\n const { lastFrame, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Continue with 3 agent(s)\");\n });\n\n it(\"should show 'Continue without agents' when no agents selected\", () => {\n const { lastFrame, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Continue without agents\");\n });\n });\n\n describe(\"keyboard interaction\", () => {\n it(\"should toggle agent on SPACE\", async () => {\n const { stdin, lastFrame, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(SPACE);\n await delay(INPUT_DELAY_MS);\n\n const store = useWizardStore.getState();\n expect(store.selectedAgents).toContain(\"web-developer\");\n });\n\n it(\"should toggle correct agent after navigation\", async () => {\n const { stdin, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_DOWN);\n await delay(INPUT_DELAY_MS);\n await stdin.write(SPACE);\n await delay(INPUT_DELAY_MS);\n\n const store = useWizardStore.getState();\n expect(store.selectedAgents).toContain(\"web-reviewer\");\n });\n\n it(\"should navigate to confirm on ENTER when agents selected\", async () => {\n const store = useWizardStore.getState();\n store.toggleAgent(\"web-developer\");\n // Set step to agents so setStep(\"confirm\") actually navigates\n store.setStep(\"agents\");\n\n const { stdin, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ENTER);\n await delay(INPUT_DELAY_MS);\n\n const updatedStore = useWizardStore.getState();\n expect(updatedStore.step).toBe(\"confirm\");\n });\n\n it(\"should navigate to confirm on ENTER even with no agents selected\", async () => {\n const store = useWizardStore.getState();\n store.setStep(\"agents\");\n\n const { stdin, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ENTER);\n await delay(INPUT_DELAY_MS);\n\n const updatedStore = useWizardStore.getState();\n expect(updatedStore.step).toBe(\"confirm\");\n });\n\n it(\"should go back on ESC\", async () => {\n const store = useWizardStore.getState();\n store.setStep(\"sources\");\n store.setStep(\"agents\");\n\n const { stdin, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ESCAPE);\n await delay(INPUT_DELAY_MS);\n\n const updatedStore = useWizardStore.getState();\n expect(updatedStore.step).toBe(\"sources\");\n });\n\n it(\"should toggle agent off when already selected\", async () => {\n const store = useWizardStore.getState();\n store.toggleAgent(\"web-developer\");\n\n const { stdin, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n // First item is web-developer, toggle it off\n await stdin.write(SPACE);\n await delay(INPUT_DELAY_MS);\n\n const updatedStore = useWizardStore.getState();\n expect(updatedStore.selectedAgents).not.toContain(\"web-developer\");\n });\n });\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/cli/components/wizard/step-agents.test.tsx"],"sourcesContent":["import { render } from \"ink-testing-library\";\nimport { afterEach, beforeEach, describe, expect, it } from \"vitest\";\nimport { StepAgents } from \"./step-agents\";\nimport { useWizardStore } from \"../../stores/wizard-store\";\nimport { initializeMatrix } from \"../../lib/matrix/matrix-provider\";\nimport {\n ARROW_DOWN,\n ENTER,\n ESCAPE,\n SPACE,\n RENDER_DELAY_MS,\n INPUT_DELAY_MS,\n delay,\n} from \"../../lib/__tests__/test-constants\";\nimport { EMPTY_MATRIX } from \"../../lib/__tests__/mock-data/mock-matrices\";\n\nconst EXPECTED_AGENT_COUNT = 18;\n\ndescribe(\"StepAgents component\", () => {\n let cleanup: (() => void) | undefined;\n\n beforeEach(() => {\n initializeMatrix(EMPTY_MATRIX);\n });\n\n afterEach(() => {\n cleanup?.();\n cleanup = undefined;\n });\n\n describe(\"rendering\", () => {\n it(\"should render title\", () => {\n const { lastFrame, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Select agents to compile:\");\n });\n\n it(\"should render all agents\", () => {\n const { lastFrame, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Web Developer\");\n expect(output).toContain(\"API Developer\");\n expect(output).toContain(\"CLI Developer\");\n expect(output).toContain(\"Web Architecture\");\n expect(output).toContain(\"Web Reviewer\");\n expect(output).toContain(\"API Reviewer\");\n expect(output).toContain(\"CLI Reviewer\");\n expect(output).toContain(\"Web Researcher\");\n expect(output).toContain(\"API Researcher\");\n expect(output).toContain(\"Web Tester\");\n expect(output).toContain(\"CLI Tester\");\n expect(output).toContain(\"Web PM\");\n expect(output).toContain(\"Pattern Scout\");\n expect(output).toContain(\"Pattern Critique\");\n expect(output).toContain(\"Agent Summoner\");\n expect(output).toContain(\"Skill Summoner\");\n expect(output).toContain(\"Documentor\");\n });\n\n it(\"should render agent descriptions\", () => {\n const { lastFrame, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Frontend features, components, TypeScript\");\n expect(output).toContain(\"Backend routes, database, middleware\");\n expect(output).toContain(\"CLI commands, interactive prompts\");\n });\n\n it(\"should render group headers\", () => {\n const { lastFrame, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Web\");\n expect(output).toContain(\"API\");\n expect(output).toContain(\"CLI\");\n expect(output).toContain(\"Meta\");\n });\n\n it(\"should show continue arrow\", () => {\n const { lastFrame, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"\\u2192\");\n expect(output).toContain(\"Continue\");\n });\n\n it(\"should show continue option with agent count when agents selected\", () => {\n const store = useWizardStore.getState();\n store.toggleAgent(\"web-developer\");\n store.toggleAgent(\"api-developer\");\n store.toggleAgent(\"web-reviewer\");\n\n const { lastFrame, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Continue with 3 agent(s)\");\n });\n\n it(\"should show 'Continue without agents' when no agents selected\", () => {\n const { lastFrame, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n const output = lastFrame();\n expect(output).toContain(\"Continue without agents\");\n });\n });\n\n describe(\"keyboard interaction\", () => {\n it(\"should toggle agent on SPACE\", async () => {\n const { stdin, lastFrame, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(SPACE);\n await delay(INPUT_DELAY_MS);\n\n const store = useWizardStore.getState();\n expect(store.selectedAgents).toContain(\"web-developer\");\n });\n\n it(\"should toggle correct agent after navigation\", async () => {\n const { stdin, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ARROW_DOWN);\n await delay(INPUT_DELAY_MS);\n await stdin.write(SPACE);\n await delay(INPUT_DELAY_MS);\n\n const store = useWizardStore.getState();\n expect(store.selectedAgents).toContain(\"web-reviewer\");\n });\n\n it(\"should navigate to confirm on ENTER when agents selected\", async () => {\n const store = useWizardStore.getState();\n store.toggleAgent(\"web-developer\");\n // Set step to agents so setStep(\"confirm\") actually navigates\n store.setStep(\"agents\");\n\n const { stdin, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ENTER);\n await delay(INPUT_DELAY_MS);\n\n const updatedStore = useWizardStore.getState();\n expect(updatedStore.step).toBe(\"confirm\");\n });\n\n it(\"should navigate to confirm on ENTER even with no agents selected\", async () => {\n const store = useWizardStore.getState();\n store.setStep(\"agents\");\n\n const { stdin, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ENTER);\n await delay(INPUT_DELAY_MS);\n\n const updatedStore = useWizardStore.getState();\n expect(updatedStore.step).toBe(\"confirm\");\n });\n\n it(\"should go back on ESC\", async () => {\n const store = useWizardStore.getState();\n store.setStep(\"sources\");\n store.setStep(\"agents\");\n\n const { stdin, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n await stdin.write(ESCAPE);\n await delay(INPUT_DELAY_MS);\n\n const updatedStore = useWizardStore.getState();\n expect(updatedStore.step).toBe(\"sources\");\n });\n\n it(\"should toggle agent off when already selected\", async () => {\n const store = useWizardStore.getState();\n store.toggleAgent(\"web-developer\");\n\n const { stdin, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n // First item is web-developer, toggle it off\n await stdin.write(SPACE);\n await delay(INPUT_DELAY_MS);\n\n const updatedStore = useWizardStore.getState();\n expect(updatedStore.selectedAgents).not.toContain(\"web-developer\");\n });\n });\n});\n"],"mappings":"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","names":[]}
@@ -1,20 +1,21 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  StepBuild
4
- } from "../../chunk-3SLO2QPW.js";
4
+ } from "../../chunk-Y4VUU5BT.js";
5
5
  import "../../chunk-K77I4XGL.js";
6
- import "../../chunk-ZYUASJUN.js";
7
- import "../../chunk-CKPJTMNC.js";
6
+ import "../../chunk-KSMT5FVM.js";
8
7
  import "../../chunk-GG4BSB6S.js";
8
+ import "../../chunk-BH4LN7XV.js";
9
9
  import "../../chunk-AQYAVLZK.js";
10
10
  import "../../chunk-AUNBGZS4.js";
11
- import "../../chunk-URAXGHF2.js";
11
+ import "../../chunk-OLWGGD4G.js";
12
12
  import "../../chunk-6VIOO74O.js";
13
- import "../../chunk-HMJGSAKV.js";
14
- import "../../chunk-F43WGOGN.js";
15
- import "../../chunk-T4EXUIBY.js";
16
- import "../../chunk-BKL3DF2Q.js";
17
- import "../../chunk-ZEJIEC2A.js";
13
+ import "../../chunk-3VNQPCOE.js";
14
+ import "../../chunk-ZBLSWJFM.js";
15
+ import "../../chunk-EMX7PA2I.js";
16
+ import "../../chunk-E74Q7GUE.js";
17
+ import "../../chunk-WJL4KU5V.js";
18
+ import "../../chunk-SRIH4U5Y.js";
18
19
  import "../../chunk-EGMQ3SXN.js";
19
20
  import "../../chunk-NKKYTCBH.js";
20
21
  import "../../chunk-DHET7RCE.js";
@@ -16,12 +16,12 @@ import {
16
16
  WEB_FRAMEWORK_CATEGORY,
17
17
  WEB_STATE_CATEGORY,
18
18
  WEB_STYLING_CATEGORY
19
- } from "../../chunk-Q3YMO5YG.js";
19
+ } from "../../chunk-TNSVPZHP.js";
20
20
  import {
21
21
  SKILLS,
22
22
  createMockMatrix,
23
23
  createMockSkill
24
- } from "../../chunk-WWHDP5CP.js";
24
+ } from "../../chunk-V5HR77EY.js";
25
25
  import {
26
26
  afterEach,
27
27
  beforeEach,
@@ -33,24 +33,25 @@ import {
33
33
  import {
34
34
  StepBuild,
35
35
  validateBuildStep
36
- } from "../../chunk-3SLO2QPW.js";
36
+ } from "../../chunk-Y4VUU5BT.js";
37
37
  import "../../chunk-K77I4XGL.js";
38
+ import "../../chunk-KSMT5FVM.js";
39
+ import "../../chunk-GG4BSB6S.js";
38
40
  import {
39
41
  orderDomains
40
- } from "../../chunk-ZYUASJUN.js";
41
- import "../../chunk-CKPJTMNC.js";
42
- import "../../chunk-GG4BSB6S.js";
42
+ } from "../../chunk-BH4LN7XV.js";
43
43
  import "../../chunk-AQYAVLZK.js";
44
44
  import "../../chunk-AUNBGZS4.js";
45
- import "../../chunk-URAXGHF2.js";
45
+ import "../../chunk-OLWGGD4G.js";
46
46
  import "../../chunk-6VIOO74O.js";
47
- import "../../chunk-HMJGSAKV.js";
48
- import "../../chunk-F43WGOGN.js";
49
- import "../../chunk-T4EXUIBY.js";
47
+ import "../../chunk-3VNQPCOE.js";
48
+ import "../../chunk-ZBLSWJFM.js";
49
+ import "../../chunk-EMX7PA2I.js";
50
50
  import {
51
- useMatrixStore
52
- } from "../../chunk-BKL3DF2Q.js";
53
- import "../../chunk-ZEJIEC2A.js";
51
+ initializeMatrix
52
+ } from "../../chunk-E74Q7GUE.js";
53
+ import "../../chunk-WJL4KU5V.js";
54
+ import "../../chunk-SRIH4U5Y.js";
54
55
  import "../../chunk-EGMQ3SXN.js";
55
56
  import "../../chunk-NKKYTCBH.js";
56
57
  import {
@@ -100,7 +101,7 @@ var renderStepBuild = (props = {}) => {
100
101
  describe("StepBuild component", () => {
101
102
  let cleanup;
102
103
  beforeEach(() => {
103
- useMatrixStore.getState().setMatrix(defaultMatrix);
104
+ initializeMatrix(defaultMatrix);
104
105
  });
105
106
  afterEach(() => {
106
107
  cleanup?.();
@@ -398,7 +399,7 @@ describe("StepBuild component", () => {
398
399
  commanderSkill
399
400
  ]
400
401
  );
401
- useMatrixStore.getState().setMatrix(matrixWithCli);
402
+ initializeMatrix(matrixWithCli);
402
403
  const { lastFrame, unmount } = renderStepBuild({
403
404
  domain: "api",
404
405
  selectedDomains: ["web", "api", "cli"]