@agents-inc/cli 0.35.0 → 0.41.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/CHANGELOG.md +103 -0
  2. package/config/skills-matrix.yaml +124 -132
  3. package/config/stacks.yaml +687 -687
  4. package/dist/{chunk-BLLXNFWP.js → chunk-2D6LKRHW.js} +2 -2
  5. package/dist/{chunk-KWF6D7ZP.js → chunk-342YB6TQ.js} +27 -19
  6. package/dist/chunk-342YB6TQ.js.map +1 -0
  7. package/dist/{chunk-OGXSTJP2.js → chunk-423MJ6DT.js} +66 -36
  8. package/dist/chunk-423MJ6DT.js.map +1 -0
  9. package/dist/{chunk-5LPPIT6H.js → chunk-4LT6RXMY.js} +4 -4
  10. package/dist/{chunk-LFHZBF6N.js → chunk-4SYXPG7L.js} +4 -3
  11. package/dist/chunk-4SYXPG7L.js.map +1 -0
  12. package/dist/{chunk-CXWPUVA7.js → chunk-4UTPJXUX.js} +9 -9
  13. package/dist/{chunk-CEWNZQMH.js → chunk-5TMB53BV.js} +9 -3
  14. package/dist/chunk-5TMB53BV.js.map +1 -0
  15. package/dist/chunk-7FBM7V3E.js +144 -0
  16. package/dist/chunk-7FBM7V3E.js.map +1 -0
  17. package/dist/chunk-ACVJVYMC.js +111 -0
  18. package/dist/chunk-ACVJVYMC.js.map +1 -0
  19. package/dist/{chunk-YN35L5NE.js → chunk-AH7XHAKN.js} +12 -12
  20. package/dist/chunk-AH7XHAKN.js.map +1 -0
  21. package/dist/{chunk-5YNZJ5TP.js → chunk-AVVYFEMF.js} +2 -2
  22. package/dist/{chunk-U36YCEBK.js → chunk-BFISETQG.js} +32 -23
  23. package/dist/chunk-BFISETQG.js.map +1 -0
  24. package/dist/{chunk-YCS7GF6Y.js → chunk-BK7TANUV.js} +6 -2
  25. package/dist/chunk-BK7TANUV.js.map +1 -0
  26. package/dist/{chunk-OGJ7DFCL.js → chunk-DV4ALU5I.js} +6 -6
  27. package/dist/{chunk-NJ775OJ4.js → chunk-FHBICUXB.js} +7 -7
  28. package/dist/chunk-FHBICUXB.js.map +1 -0
  29. package/dist/{chunk-OKILA27U.js → chunk-GEDWVX6Y.js} +87 -100
  30. package/dist/chunk-GEDWVX6Y.js.map +1 -0
  31. package/dist/{chunk-DC5AK3LW.js → chunk-GG4BSB6S.js} +5 -11
  32. package/dist/chunk-GG4BSB6S.js.map +1 -0
  33. package/dist/{chunk-BPD4VUAU.js → chunk-H6H3COI5.js} +5 -5
  34. package/dist/{chunk-AQQVSNUX.js → chunk-K77I4XGL.js} +20 -6
  35. package/dist/chunk-K77I4XGL.js.map +1 -0
  36. package/dist/chunk-KC2SIUIA.js +46 -0
  37. package/dist/chunk-KC2SIUIA.js.map +1 -0
  38. package/dist/{chunk-HTTPKSL6.js → chunk-KXM7KOPE.js} +2 -2
  39. package/dist/{chunk-GGHH3KR2.js → chunk-LJRP4SWY.js} +6 -5
  40. package/dist/chunk-LJRP4SWY.js.map +1 -0
  41. package/dist/{chunk-PKUIO2Z7.js → chunk-MNPPGIZQ.js} +8 -8
  42. package/dist/chunk-MNPPGIZQ.js.map +1 -0
  43. package/dist/{chunk-IG7CUREJ.js → chunk-NYP5SB2V.js} +2 -2
  44. package/dist/{chunk-JXMRTHDT.js → chunk-NZYKDVRL.js} +2 -2
  45. package/dist/{chunk-XNQJBQ5X.js → chunk-PURJZ72D.js} +2 -2
  46. package/dist/{chunk-VEZ2GZEK.js → chunk-R52N7DBG.js} +2 -2
  47. package/dist/chunk-SILUTTV7.js +113 -0
  48. package/dist/chunk-SILUTTV7.js.map +1 -0
  49. package/dist/{chunk-YIKBNGE3.js → chunk-TJAZ7QCF.js} +7 -7
  50. package/dist/chunk-TJAZ7QCF.js.map +1 -0
  51. package/dist/{chunk-WMVGRAFB.js → chunk-TTXV55NQ.js} +235 -117
  52. package/dist/chunk-TTXV55NQ.js.map +1 -0
  53. package/dist/{chunk-ZE355C6C.js → chunk-UKTYDNWJ.js} +9 -4
  54. package/dist/chunk-UKTYDNWJ.js.map +1 -0
  55. package/dist/{chunk-YPJKOM42.js → chunk-WS6OQIEN.js} +2 -2
  56. package/dist/{chunk-OI4WBRC7.js → chunk-XJXJZ2MJ.js} +113 -150
  57. package/dist/chunk-XJXJZ2MJ.js.map +1 -0
  58. package/dist/chunk-YLJYAQSG.js +210 -0
  59. package/dist/chunk-YLJYAQSG.js.map +1 -0
  60. package/dist/{chunk-MZB3GGOH.js → chunk-YRVTXSXP.js} +1 -2
  61. package/dist/chunk-YRVTXSXP.js.map +1 -0
  62. package/dist/{chunk-XYCN2GCV.js → chunk-ZLHGJSRK.js} +3 -3
  63. package/dist/cli/defaults/agent-mappings.yaml +16 -72
  64. package/dist/commands/build/marketplace.js +3 -3
  65. package/dist/commands/build/plugins.js +5 -5
  66. package/dist/commands/build/stack.js +5 -5
  67. package/dist/commands/compile.js +14 -18
  68. package/dist/commands/compile.js.map +1 -1
  69. package/dist/commands/config/get.js +8 -8
  70. package/dist/commands/config/get.js.map +1 -1
  71. package/dist/commands/config/index.js +5 -5
  72. package/dist/commands/config/path.js +4 -4
  73. package/dist/commands/config/set-project.js +7 -7
  74. package/dist/commands/config/set-project.js.map +1 -1
  75. package/dist/commands/config/show.js +5 -5
  76. package/dist/commands/config/unset-project.js +5 -5
  77. package/dist/commands/config/unset-project.js.map +1 -1
  78. package/dist/commands/diff.js +12 -9
  79. package/dist/commands/diff.js.map +1 -1
  80. package/dist/commands/doctor.js +8 -7
  81. package/dist/commands/doctor.js.map +1 -1
  82. package/dist/commands/edit.js +35 -29
  83. package/dist/commands/edit.js.map +1 -1
  84. package/dist/commands/eject.js +6 -6
  85. package/dist/commands/eject.js.map +1 -1
  86. package/dist/commands/import/skill.js +16 -16
  87. package/dist/commands/import/skill.js.map +1 -1
  88. package/dist/commands/info.js +7 -6
  89. package/dist/commands/info.js.map +1 -1
  90. package/dist/commands/init.js +42 -31
  91. package/dist/commands/init.js.map +1 -1
  92. package/dist/commands/list.js +6 -5
  93. package/dist/commands/list.js.map +1 -1
  94. package/dist/commands/new/agent.js +5 -5
  95. package/dist/commands/new/skill.js +12 -9
  96. package/dist/commands/new/skill.js.map +1 -1
  97. package/dist/commands/outdated.js +8 -5
  98. package/dist/commands/outdated.js.map +1 -1
  99. package/dist/commands/search.js +7 -7
  100. package/dist/commands/uninstall.js +122 -103
  101. package/dist/commands/uninstall.js.map +1 -1
  102. package/dist/commands/update.js +8 -7
  103. package/dist/commands/update.js.map +1 -1
  104. package/dist/commands/validate.js +5 -5
  105. package/dist/commands/version/bump.js +4 -4
  106. package/dist/commands/version/index.js +4 -4
  107. package/dist/commands/version/set.js +4 -4
  108. package/dist/commands/version/show.js +4 -4
  109. package/dist/components/skill-search/skill-search.js +3 -3
  110. package/dist/components/wizard/category-grid.js +3 -3
  111. package/dist/components/wizard/category-grid.test.js +79 -58
  112. package/dist/components/wizard/category-grid.test.js.map +1 -1
  113. package/dist/components/wizard/checkbox-grid.js +10 -0
  114. package/dist/components/wizard/checkbox-grid.test.js +270 -0
  115. package/dist/components/wizard/checkbox-grid.test.js.map +1 -0
  116. package/dist/components/wizard/domain-selection.js +7 -5
  117. package/dist/components/wizard/help-modal.js +2 -2
  118. package/dist/components/wizard/menu-item.js +2 -2
  119. package/dist/components/wizard/search-modal.js +2 -2
  120. package/dist/components/wizard/search-modal.test.js +2 -2
  121. package/dist/components/wizard/section-progress.js +2 -2
  122. package/dist/components/wizard/section-progress.test.js +2 -2
  123. package/dist/components/wizard/source-grid.js +4 -4
  124. package/dist/components/wizard/source-grid.test.js +4 -4
  125. package/dist/components/wizard/stack-selection.js +9 -8
  126. package/dist/components/wizard/step-agents.js +16 -0
  127. package/dist/components/wizard/step-agents.js.map +1 -0
  128. package/dist/components/wizard/step-agents.test.js +190 -0
  129. package/dist/components/wizard/step-agents.test.js.map +1 -0
  130. package/dist/components/wizard/step-build.js +10 -9
  131. package/dist/components/wizard/step-build.test.js +56 -53
  132. package/dist/components/wizard/step-build.test.js.map +1 -1
  133. package/dist/components/wizard/step-confirm.js +3 -3
  134. package/dist/components/wizard/step-confirm.test.js +19 -12
  135. package/dist/components/wizard/step-confirm.test.js.map +1 -1
  136. package/dist/components/wizard/step-refine.js +2 -2
  137. package/dist/components/wizard/step-refine.test.js +2 -2
  138. package/dist/components/wizard/step-settings.js +5 -5
  139. package/dist/components/wizard/step-settings.test.js +8 -8
  140. package/dist/components/wizard/step-sources.js +11 -10
  141. package/dist/components/wizard/step-sources.test.js +16 -15
  142. package/dist/components/wizard/step-sources.test.js.map +1 -1
  143. package/dist/components/wizard/step-stack.js +12 -10
  144. package/dist/components/wizard/step-stack.test.js +19 -19
  145. package/dist/components/wizard/step-stack.test.js.map +1 -1
  146. package/dist/components/wizard/view-title.js +2 -2
  147. package/dist/components/wizard/wizard-layout.js +8 -7
  148. package/dist/components/wizard/wizard-tabs.js +2 -2
  149. package/dist/components/wizard/wizard-tabs.test.js +6 -4
  150. package/dist/components/wizard/wizard-tabs.test.js.map +1 -1
  151. package/dist/components/wizard/wizard.js +27 -24
  152. package/dist/config/skills-matrix.yaml +124 -132
  153. package/dist/config/stacks.yaml +687 -687
  154. package/dist/hooks/init.js +3 -3
  155. package/dist/{source-manager-PTK4P6BF.js → source-manager-PPABS6BC.js} +4 -4
  156. package/dist/source-manager-PPABS6BC.js.map +1 -0
  157. package/dist/stores/wizard-store.js +5 -4
  158. package/dist/stores/wizard-store.test.js +336 -136
  159. package/dist/stores/wizard-store.test.js.map +1 -1
  160. package/package.json +1 -1
  161. package/src/schemas/agent.schema.json +3 -3
  162. package/src/schemas/metadata.schema.json +55 -15
  163. package/src/schemas/project-config.schema.json +42 -2
  164. package/src/schemas/project-source-config.schema.json +5 -5
  165. package/src/schemas/skills-matrix.schema.json +103 -104
  166. package/src/schemas/stack.schema.json +1 -1
  167. package/src/schemas/stacks.schema.json +41 -1
  168. package/dist/chunk-AQQVSNUX.js.map +0 -1
  169. package/dist/chunk-CEWNZQMH.js.map +0 -1
  170. package/dist/chunk-DC5AK3LW.js.map +0 -1
  171. package/dist/chunk-GGHH3KR2.js.map +0 -1
  172. package/dist/chunk-KWF6D7ZP.js.map +0 -1
  173. package/dist/chunk-LFHZBF6N.js.map +0 -1
  174. package/dist/chunk-MZB3GGOH.js.map +0 -1
  175. package/dist/chunk-NJ775OJ4.js.map +0 -1
  176. package/dist/chunk-NVQEHRJY.js +0 -120
  177. package/dist/chunk-NVQEHRJY.js.map +0 -1
  178. package/dist/chunk-OGXSTJP2.js.map +0 -1
  179. package/dist/chunk-OI4WBRC7.js.map +0 -1
  180. package/dist/chunk-OKILA27U.js.map +0 -1
  181. package/dist/chunk-PKUIO2Z7.js.map +0 -1
  182. package/dist/chunk-U36YCEBK.js.map +0 -1
  183. package/dist/chunk-UFUQUFV6.js +0 -256
  184. package/dist/chunk-UFUQUFV6.js.map +0 -1
  185. package/dist/chunk-WMVGRAFB.js.map +0 -1
  186. package/dist/chunk-YCS7GF6Y.js.map +0 -1
  187. package/dist/chunk-YIKBNGE3.js.map +0 -1
  188. package/dist/chunk-YN35L5NE.js.map +0 -1
  189. package/dist/chunk-ZE355C6C.js.map +0 -1
  190. /package/dist/{chunk-BLLXNFWP.js.map → chunk-2D6LKRHW.js.map} +0 -0
  191. /package/dist/{chunk-5LPPIT6H.js.map → chunk-4LT6RXMY.js.map} +0 -0
  192. /package/dist/{chunk-CXWPUVA7.js.map → chunk-4UTPJXUX.js.map} +0 -0
  193. /package/dist/{chunk-5YNZJ5TP.js.map → chunk-AVVYFEMF.js.map} +0 -0
  194. /package/dist/{chunk-OGJ7DFCL.js.map → chunk-DV4ALU5I.js.map} +0 -0
  195. /package/dist/{chunk-BPD4VUAU.js.map → chunk-H6H3COI5.js.map} +0 -0
  196. /package/dist/{chunk-HTTPKSL6.js.map → chunk-KXM7KOPE.js.map} +0 -0
  197. /package/dist/{chunk-IG7CUREJ.js.map → chunk-NYP5SB2V.js.map} +0 -0
  198. /package/dist/{chunk-JXMRTHDT.js.map → chunk-NZYKDVRL.js.map} +0 -0
  199. /package/dist/{chunk-XNQJBQ5X.js.map → chunk-PURJZ72D.js.map} +0 -0
  200. /package/dist/{chunk-VEZ2GZEK.js.map → chunk-R52N7DBG.js.map} +0 -0
  201. /package/dist/{chunk-YPJKOM42.js.map → chunk-WS6OQIEN.js.map} +0 -0
  202. /package/dist/{chunk-XYCN2GCV.js.map → chunk-ZLHGJSRK.js.map} +0 -0
  203. /package/dist/{source-manager-PTK4P6BF.js.map → components/wizard/checkbox-grid.js.map} +0 -0
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- createMockCategory
4
- } from "../chunk-YN35L5NE.js";
3
+ createMockMatrix,
4
+ createMockSkill
5
+ } from "../chunk-AH7XHAKN.js";
5
6
  import {
6
7
  beforeEach,
7
8
  describe,
@@ -10,13 +11,16 @@ import {
10
11
  } from "../chunk-XY3XDVMI.js";
11
12
  import {
12
13
  useWizardStore
13
- } from "../chunk-OGXSTJP2.js";
14
- import "../chunk-WMVGRAFB.js";
15
- import "../chunk-T4EXUIBY.js";
16
- import "../chunk-OI4WBRC7.js";
14
+ } from "../chunk-423MJ6DT.js";
15
+ import "../chunk-SILUTTV7.js";
16
+ import "../chunk-TTXV55NQ.js";
17
+ import {
18
+ typedKeys
19
+ } from "../chunk-T4EXUIBY.js";
20
+ import "../chunk-XJXJZ2MJ.js";
17
21
  import {
18
22
  DEFAULT_PRESELECTED_SKILLS
19
- } from "../chunk-YCS7GF6Y.js";
23
+ } from "../chunk-BK7TANUV.js";
20
24
  import {
21
25
  init_esm_shims
22
26
  } from "../chunk-DHET7RCE.js";
@@ -151,41 +155,41 @@ describe("WizardStore", () => {
151
155
  describe("technology selection", () => {
152
156
  it("should toggle technology in exclusive mode", () => {
153
157
  const store = useWizardStore.getState();
154
- store.toggleTechnology("web", "framework", "web-framework-react", true);
158
+ store.toggleTechnology("web", "web-framework", "web-framework-react", true);
155
159
  const { domainSelections } = useWizardStore.getState();
156
- globalExpect(domainSelections.web.framework).toEqual(["web-framework-react"]);
160
+ globalExpect(domainSelections.web["web-framework"]).toEqual(["web-framework-react"]);
157
161
  });
158
162
  it("should replace technology in exclusive mode", () => {
159
163
  const store = useWizardStore.getState();
160
- store.toggleTechnology("web", "framework", "web-framework-react", true);
161
- store.toggleTechnology("web", "framework", "web-framework-vue", true);
164
+ store.toggleTechnology("web", "web-framework", "web-framework-react", true);
165
+ store.toggleTechnology("web", "web-framework", "web-framework-vue", true);
162
166
  const { domainSelections } = useWizardStore.getState();
163
- globalExpect(domainSelections.web.framework).toEqual(["web-framework-vue"]);
167
+ globalExpect(domainSelections.web["web-framework"]).toEqual(["web-framework-vue"]);
164
168
  });
165
169
  it("should toggle off technology in exclusive mode", () => {
166
170
  const store = useWizardStore.getState();
167
- store.toggleTechnology("web", "framework", "web-framework-react", true);
168
- store.toggleTechnology("web", "framework", "web-framework-react", true);
171
+ store.toggleTechnology("web", "web-framework", "web-framework-react", true);
172
+ store.toggleTechnology("web", "web-framework", "web-framework-react", true);
169
173
  const { domainSelections } = useWizardStore.getState();
170
- globalExpect(domainSelections.web.framework).toEqual([]);
174
+ globalExpect(domainSelections.web["web-framework"]).toEqual([]);
171
175
  });
172
176
  it("should allow multiple selections in non-exclusive mode", () => {
173
177
  const store = useWizardStore.getState();
174
- store.toggleTechnology("web", "testing", "web-testing-vitest", false);
175
- store.toggleTechnology("web", "testing", "web-testing-playwright-e2e", false);
178
+ store.toggleTechnology("web", "web-testing", "web-testing-vitest", false);
179
+ store.toggleTechnology("web", "web-testing", "web-testing-playwright-e2e", false);
176
180
  const { domainSelections } = useWizardStore.getState();
177
- globalExpect(domainSelections.web.testing).toEqual([
181
+ globalExpect(domainSelections.web["web-testing"]).toEqual([
178
182
  "web-testing-vitest",
179
183
  "web-testing-playwright-e2e"
180
184
  ]);
181
185
  });
182
186
  it("should toggle off technology in non-exclusive mode", () => {
183
187
  const store = useWizardStore.getState();
184
- store.toggleTechnology("web", "testing", "web-testing-vitest", false);
185
- store.toggleTechnology("web", "testing", "web-testing-playwright-e2e", false);
186
- store.toggleTechnology("web", "testing", "web-testing-vitest", false);
188
+ store.toggleTechnology("web", "web-testing", "web-testing-vitest", false);
189
+ store.toggleTechnology("web", "web-testing", "web-testing-playwright-e2e", false);
190
+ store.toggleTechnology("web", "web-testing", "web-testing-vitest", false);
187
191
  const { domainSelections } = useWizardStore.getState();
188
- globalExpect(domainSelections.web.testing).toEqual(["web-testing-playwright-e2e"]);
192
+ globalExpect(domainSelections.web["web-testing"]).toEqual(["web-testing-playwright-e2e"]);
189
193
  });
190
194
  });
191
195
  describe("domain navigation", () => {
@@ -261,11 +265,11 @@ describe("WizardStore", () => {
261
265
  const { installMode } = useWizardStore.getState();
262
266
  globalExpect(installMode).toBe("local");
263
267
  });
264
- it("should toggle show descriptions", () => {
268
+ it("should toggle show labels", () => {
265
269
  const store = useWizardStore.getState();
266
- store.toggleShowDescriptions();
267
- const { showDescriptions } = useWizardStore.getState();
268
- globalExpect(showDescriptions).toBe(true);
270
+ store.toggleShowLabels();
271
+ const { showLabels } = useWizardStore.getState();
272
+ globalExpect(showLabels).toBe(true);
269
273
  });
270
274
  it("should toggle help on", () => {
271
275
  const store = useWizardStore.getState();
@@ -343,9 +347,9 @@ describe("WizardStore", () => {
343
347
  describe("computed getters", () => {
344
348
  it("should get all selected technologies", () => {
345
349
  const store = useWizardStore.getState();
346
- store.toggleTechnology("web", "framework", "web-framework-react", true);
347
- store.toggleTechnology("web", "styling", "web-styling-scss-modules", true);
348
- store.toggleTechnology("api", "api", "api-framework-hono", true);
350
+ store.toggleTechnology("web", "web-framework", "web-framework-react", true);
351
+ store.toggleTechnology("web", "web-styling", "web-styling-scss-modules", true);
352
+ store.toggleTechnology("api", "api-api", "api-framework-hono", true);
349
353
  const technologies = store.getAllSelectedTechnologies();
350
354
  globalExpect(technologies).toContain("web-framework-react");
351
355
  globalExpect(technologies).toContain("web-styling-scss-modules");
@@ -360,9 +364,9 @@ describe("WizardStore", () => {
360
364
  });
361
365
  it("should get selected technologies per domain", () => {
362
366
  const store = useWizardStore.getState();
363
- store.toggleTechnology("web", "framework", "web-framework-react", true);
364
- store.toggleTechnology("web", "styling", "web-styling-scss-modules", true);
365
- store.toggleTechnology("api", "api", "api-framework-hono", true);
367
+ store.toggleTechnology("web", "web-framework", "web-framework-react", true);
368
+ store.toggleTechnology("web", "web-styling", "web-styling-scss-modules", true);
369
+ store.toggleTechnology("api", "api-api", "api-framework-hono", true);
366
370
  const perDomain = store.getSelectedTechnologiesPerDomain();
367
371
  globalExpect(perDomain.web).toEqual(["web-framework-react", "web-styling-scss-modules"]);
368
372
  globalExpect(perDomain.api).toEqual(["api-framework-hono"]);
@@ -375,16 +379,16 @@ describe("WizardStore", () => {
375
379
  });
376
380
  it("should omit domains with empty subcategory arrays from getSelectedTechnologiesPerDomain", () => {
377
381
  const store = useWizardStore.getState();
378
- store.toggleTechnology("web", "framework", "web-framework-react", true);
379
- store.toggleTechnology("web", "framework", "web-framework-react", true);
382
+ store.toggleTechnology("web", "web-framework", "web-framework-react", true);
383
+ store.toggleTechnology("web", "web-framework", "web-framework-react", true);
380
384
  const perDomain = store.getSelectedTechnologiesPerDomain();
381
385
  globalExpect(perDomain.web).toBeUndefined();
382
386
  });
383
387
  it("should get technology count", () => {
384
388
  const store = useWizardStore.getState();
385
- store.toggleTechnology("web", "framework", "web-framework-react", true);
386
- store.toggleTechnology("web", "styling", "web-styling-scss-modules", true);
387
- store.toggleTechnology("api", "api", "api-framework-hono", true);
389
+ store.toggleTechnology("web", "web-framework", "web-framework-react", true);
390
+ store.toggleTechnology("web", "web-styling", "web-styling-scss-modules", true);
391
+ store.toggleTechnology("api", "api-api", "api-framework-hono", true);
388
392
  globalExpect(store.getTechnologyCount()).toBe(3);
389
393
  });
390
394
  it("should return 0 for getTechnologyCount with no selections", () => {
@@ -426,65 +430,6 @@ describe("WizardStore", () => {
426
430
  globalExpect(store.canGoToPreviousDomain()).toBe(false);
427
431
  });
428
432
  });
429
- describe("parent domain selectors", () => {
430
- const matrixWithParentDomain = {
431
- categories: {
432
- "error-handling": createMockCategory("error-handling", "Error Handling", {
433
- domain: "web-extras",
434
- parent_domain: "web",
435
- exclusive: false
436
- }),
437
- framework: createMockCategory("framework", "Framework", {
438
- domain: "web"
439
- })
440
- }
441
- };
442
- const matrixWithoutParent = {
443
- categories: {
444
- framework: createMockCategory("framework", "Framework", {
445
- domain: "web"
446
- })
447
- }
448
- };
449
- it("should find parent domain for a domain with parent_domain", () => {
450
- const store = useWizardStore.getState();
451
- const parent = store.getParentDomain(
452
- "web-extras",
453
- matrixWithParentDomain
454
- );
455
- globalExpect(parent).toBe("web");
456
- });
457
- it("should return undefined for a domain without parent_domain", () => {
458
- const store = useWizardStore.getState();
459
- const parent = store.getParentDomain("web", matrixWithoutParent);
460
- globalExpect(parent).toBeUndefined();
461
- });
462
- it("should get parent domain selections when parent exists", () => {
463
- const store = useWizardStore.getState();
464
- store.toggleTechnology("web", "framework", "web-framework-react", true);
465
- const parentSelections = store.getParentDomainSelections(
466
- "web-extras",
467
- matrixWithParentDomain
468
- );
469
- globalExpect(parentSelections).toEqual({ framework: ["web-framework-react"] });
470
- });
471
- it("should return undefined for getParentDomainSelections when no parent", () => {
472
- const store = useWizardStore.getState();
473
- const parentSelections = store.getParentDomainSelections(
474
- "web",
475
- matrixWithoutParent
476
- );
477
- globalExpect(parentSelections).toBeUndefined();
478
- });
479
- it("should return undefined for getParentDomainSelections when parent has no selections", () => {
480
- const store = useWizardStore.getState();
481
- const parentSelections = store.getParentDomainSelections(
482
- "web-extras",
483
- matrixWithParentDomain
484
- );
485
- globalExpect(parentSelections).toBeUndefined();
486
- });
487
- });
488
433
  describe("reset", () => {
489
434
  it("should reset to initial state", () => {
490
435
  const store = useWizardStore.getState();
@@ -509,17 +454,17 @@ describe("WizardStore", () => {
509
454
  const store = useWizardStore.getState();
510
455
  const stack = {
511
456
  agents: {
512
- web: { framework: [sa("web-framework-react", true)] }
457
+ web: { "web-framework": [sa("web-framework-react", true)] }
513
458
  }
514
459
  };
515
460
  const categories = {
516
- framework: { domain: "web" }
461
+ "web-framework": { domain: "web" }
517
462
  };
518
463
  store.populateFromStack(stack, categories);
519
464
  const { selectedDomains, domainSelections } = useWizardStore.getState();
520
- globalExpect(selectedDomains).toEqual(["web", "web-extras", "api", "cli", "mobile", "shared"]);
465
+ globalExpect(selectedDomains).toEqual(["web", "api", "cli", "mobile", "shared"]);
521
466
  globalExpect(domainSelections.web).toBeDefined();
522
- globalExpect(domainSelections.web.framework).toEqual(["web-framework-react"]);
467
+ globalExpect(domainSelections.web["web-framework"]).toEqual(["web-framework-react"]);
523
468
  globalExpect(domainSelections.api).toBeUndefined();
524
469
  });
525
470
  it("should populate domainSelections from stack agents", () => {
@@ -527,43 +472,43 @@ describe("WizardStore", () => {
527
472
  const stack = {
528
473
  agents: {
529
474
  web: {
530
- framework: [sa("web-framework-react", true)],
531
- "client-state": [sa("web-state-zustand")]
475
+ "web-framework": [sa("web-framework-react", true)],
476
+ "web-client-state": [sa("web-state-zustand")]
532
477
  },
533
- api: { api: [sa("api-framework-hono", true)] }
478
+ api: { "api-api": [sa("api-framework-hono", true)] }
534
479
  }
535
480
  };
536
481
  const categories = {
537
- framework: { domain: "web" },
538
- "client-state": { domain: "web" },
539
- api: { domain: "api" }
482
+ "web-framework": { domain: "web" },
483
+ "web-client-state": { domain: "web" },
484
+ "api-api": { domain: "api" }
540
485
  };
541
486
  store.populateFromStack(stack, categories);
542
487
  const { domainSelections } = useWizardStore.getState();
543
- globalExpect(domainSelections.web.framework).toEqual(["web-framework-react"]);
544
- globalExpect(domainSelections.web["client-state"]).toEqual(["web-state-zustand"]);
545
- globalExpect(domainSelections.api.api).toEqual(["api-framework-hono"]);
488
+ globalExpect(domainSelections.web["web-framework"]).toEqual(["web-framework-react"]);
489
+ globalExpect(domainSelections.web["web-client-state"]).toEqual(["web-state-zustand"]);
490
+ globalExpect(domainSelections.api["api-api"]).toEqual(["api-framework-hono"]);
546
491
  });
547
492
  it("should skip entries without a domain", () => {
548
493
  const store = useWizardStore.getState();
549
494
  const stack = {
550
495
  agents: {
551
- misc: { methodology: [sa("meta-methodology-vitest")] }
496
+ misc: { "shared-methodology": [sa("meta-methodology-vitest")] }
552
497
  }
553
498
  };
554
499
  const categories = {
555
- methodology: {}
500
+ "shared-methodology": {}
556
501
  };
557
502
  store.populateFromStack(stack, categories);
558
503
  const { domainSelections } = useWizardStore.getState();
559
- globalExpect(Object.keys(domainSelections)).toHaveLength(0);
504
+ globalExpect(typedKeys(domainSelections)).toHaveLength(0);
560
505
  });
561
506
  it("should populate multiple skills from array-valued subcategories", () => {
562
507
  const store = useWizardStore.getState();
563
508
  const stack = {
564
509
  agents: {
565
510
  "pattern-scout": {
566
- methodology: [
511
+ "shared-methodology": [
567
512
  sa("meta-methodology-investigation-requirements", true),
568
513
  sa("meta-methodology-anti-over-engineering", true),
569
514
  sa("meta-methodology-success-criteria", true)
@@ -572,11 +517,11 @@ describe("WizardStore", () => {
572
517
  }
573
518
  };
574
519
  const categories = {
575
- methodology: { domain: "shared" }
520
+ "shared-methodology": { domain: "shared" }
576
521
  };
577
522
  store.populateFromStack(stack, categories);
578
523
  const { domainSelections } = useWizardStore.getState();
579
- globalExpect(domainSelections.shared.methodology).toEqual([
524
+ globalExpect(domainSelections.shared["shared-methodology"]).toEqual([
580
525
  "meta-methodology-investigation-requirements",
581
526
  "meta-methodology-anti-over-engineering",
582
527
  "meta-methodology-success-criteria"
@@ -587,41 +532,41 @@ describe("WizardStore", () => {
587
532
  const stack = {
588
533
  agents: {
589
534
  web: {
590
- framework: [sa("web-framework-react", true)],
591
- methodology: [
535
+ "web-framework": [sa("web-framework-react", true)],
536
+ "shared-methodology": [
592
537
  sa("meta-methodology-investigation-requirements", true),
593
538
  sa("meta-methodology-anti-over-engineering", true)
594
539
  ]
595
540
  },
596
- api: { api: [sa("api-framework-hono", true)] }
541
+ api: { "api-api": [sa("api-framework-hono", true)] }
597
542
  }
598
543
  };
599
544
  const categories = {
600
- framework: { domain: "web" },
601
- methodology: { domain: "shared" },
602
- api: { domain: "api" }
545
+ "web-framework": { domain: "web" },
546
+ "shared-methodology": { domain: "shared" },
547
+ "api-api": { domain: "api" }
603
548
  };
604
549
  store.populateFromStack(stack, categories);
605
550
  const { domainSelections } = useWizardStore.getState();
606
- globalExpect(domainSelections.web.framework).toEqual(["web-framework-react"]);
607
- globalExpect(domainSelections.shared.methodology).toEqual([
551
+ globalExpect(domainSelections.web["web-framework"]).toEqual(["web-framework-react"]);
552
+ globalExpect(domainSelections.shared["shared-methodology"]).toEqual([
608
553
  "meta-methodology-investigation-requirements",
609
554
  "meta-methodology-anti-over-engineering"
610
555
  ]);
611
- globalExpect(domainSelections.api.api).toEqual(["api-framework-hono"]);
556
+ globalExpect(domainSelections.api["api-api"]).toEqual(["api-framework-hono"]);
612
557
  });
613
558
  it("should deduplicate skills from arrays across multiple agents", () => {
614
559
  const store = useWizardStore.getState();
615
560
  const stack = {
616
561
  agents: {
617
562
  agent1: {
618
- methodology: [
563
+ "shared-methodology": [
619
564
  sa("meta-methodology-investigation-requirements", true),
620
565
  sa("meta-methodology-anti-over-engineering", true)
621
566
  ]
622
567
  },
623
568
  agent2: {
624
- methodology: [
569
+ "shared-methodology": [
625
570
  sa("meta-methodology-anti-over-engineering", true),
626
571
  sa("meta-methodology-success-criteria", true)
627
572
  ]
@@ -629,11 +574,11 @@ describe("WizardStore", () => {
629
574
  }
630
575
  };
631
576
  const categories = {
632
- methodology: { domain: "shared" }
577
+ "shared-methodology": { domain: "shared" }
633
578
  };
634
579
  store.populateFromStack(stack, categories);
635
580
  const { domainSelections } = useWizardStore.getState();
636
- globalExpect(domainSelections.shared.methodology).toEqual([
581
+ globalExpect(domainSelections.shared["shared-methodology"]).toEqual([
637
582
  "meta-methodology-investigation-requirements",
638
583
  "meta-methodology-anti-over-engineering",
639
584
  "meta-methodology-success-criteria"
@@ -661,28 +606,283 @@ describe("WizardStore", () => {
661
606
  store.toggleDomain("web");
662
607
  store.toggleDomain("api");
663
608
  store.setStep("build");
664
- store.toggleTechnology("web", "framework", "web-framework-react", true);
665
- store.toggleTechnology("web", "styling", "web-styling-scss-modules", true);
666
- store.toggleTechnology("api", "api", "api-framework-hono", true);
609
+ store.toggleTechnology("web", "web-framework", "web-framework-react", true);
610
+ store.toggleTechnology("web", "web-styling", "web-styling-scss-modules", true);
611
+ store.toggleTechnology("api", "api-api", "api-framework-hono", true);
667
612
  store.setStep("confirm");
668
613
  const state = useWizardStore.getState();
669
614
  globalExpect(state.step).toBe("confirm");
670
615
  globalExpect(state.approach).toBe("scratch");
671
616
  globalExpect(state.selectedDomains).toEqual(["web", "api"]);
672
- globalExpect(state.domainSelections.web.framework).toEqual(["web-framework-react"]);
673
- globalExpect(state.domainSelections.web.styling).toEqual(["web-styling-scss-modules"]);
674
- globalExpect(state.domainSelections.api.api).toEqual(["api-framework-hono"]);
617
+ globalExpect(state.domainSelections.web["web-framework"]).toEqual(["web-framework-react"]);
618
+ globalExpect(state.domainSelections.web["web-styling"]).toEqual(["web-styling-scss-modules"]);
619
+ globalExpect(state.domainSelections.api["api-api"]).toEqual(["api-framework-hono"]);
675
620
  });
676
621
  it("should preserve selections when going back", () => {
677
622
  const store = useWizardStore.getState();
678
623
  store.setApproach("scratch");
679
624
  store.toggleDomain("web");
680
625
  store.setStep("build");
681
- store.toggleTechnology("web", "framework", "web-framework-react", true);
626
+ store.toggleTechnology("web", "web-framework", "web-framework-react", true);
682
627
  store.goBack();
683
628
  const state = useWizardStore.getState();
684
629
  globalExpect(state.selectedDomains).toContain("web");
685
- globalExpect(state.domainSelections.web.framework).toEqual(["web-framework-react"]);
630
+ globalExpect(state.domainSelections.web["web-framework"]).toEqual(["web-framework-react"]);
631
+ });
632
+ });
633
+ describe("buildSourceRows sort order", () => {
634
+ function makeSource(overrides) {
635
+ return {
636
+ type: "private",
637
+ installed: false,
638
+ ...overrides
639
+ };
640
+ }
641
+ it("should sort local sources before scoped marketplace sources", () => {
642
+ const store = useWizardStore.getState();
643
+ const skill = createMockSkill("web-framework-react", "web-framework", {
644
+ displayName: "react",
645
+ availableSources: [
646
+ makeSource({ name: "Photoroom", type: "private", primary: true }),
647
+ makeSource({ name: "local", type: "local", installed: true, installMode: "local" })
648
+ ]
649
+ });
650
+ const matrix = createMockMatrix(
651
+ { "web-framework-react": skill },
652
+ {
653
+ displayNames: { "web-framework-react": "react" }
654
+ }
655
+ );
656
+ store.toggleTechnology("web", "web-framework", "web-framework-react", true);
657
+ const rows = store.buildSourceRows(matrix);
658
+ globalExpect(rows).toHaveLength(1);
659
+ globalExpect(rows[0].options[0].id).toBe("local");
660
+ globalExpect(rows[0].options[1].id).toBe("Photoroom");
661
+ });
662
+ it("should sort scoped marketplace before default public marketplace", () => {
663
+ const store = useWizardStore.getState();
664
+ const skill = createMockSkill("web-framework-react", "web-framework", {
665
+ displayName: "react",
666
+ availableSources: [
667
+ makeSource({ name: "Agents Inc", type: "public" }),
668
+ makeSource({ name: "Photoroom", type: "private", primary: true })
669
+ ]
670
+ });
671
+ const matrix = createMockMatrix(
672
+ { "web-framework-react": skill },
673
+ {
674
+ displayNames: { "web-framework-react": "react" }
675
+ }
676
+ );
677
+ store.toggleTechnology("web", "web-framework", "web-framework-react", true);
678
+ const rows = store.buildSourceRows(matrix);
679
+ globalExpect(rows).toHaveLength(1);
680
+ globalExpect(rows[0].options[0].id).toBe("Photoroom");
681
+ globalExpect(rows[0].options[1].id).toBe("Agents Inc");
682
+ });
683
+ it("should sort default public marketplace before third-party sources", () => {
684
+ const store = useWizardStore.getState();
685
+ const skill = createMockSkill("web-framework-react", "web-framework", {
686
+ displayName: "react",
687
+ availableSources: [
688
+ makeSource({ name: "Extra Corp", type: "private" }),
689
+ makeSource({ name: "Agents Inc", type: "public" })
690
+ ]
691
+ });
692
+ const matrix = createMockMatrix(
693
+ { "web-framework-react": skill },
694
+ {
695
+ displayNames: { "web-framework-react": "react" }
696
+ }
697
+ );
698
+ store.toggleTechnology("web", "web-framework", "web-framework-react", true);
699
+ const rows = store.buildSourceRows(matrix);
700
+ globalExpect(rows).toHaveLength(1);
701
+ globalExpect(rows[0].options[0].id).toBe("Agents Inc");
702
+ globalExpect(rows[0].options[1].id).toBe("Extra Corp");
703
+ });
704
+ it("should sort all four tiers in correct order", () => {
705
+ const store = useWizardStore.getState();
706
+ const skill = createMockSkill("web-framework-react", "web-framework", {
707
+ displayName: "react",
708
+ availableSources: [
709
+ makeSource({ name: "Extra Corp", type: "private" }),
710
+ makeSource({ name: "Agents Inc", type: "public" }),
711
+ makeSource({ name: "Photoroom", type: "private", primary: true }),
712
+ makeSource({ name: "local", type: "local", installed: true, installMode: "local" })
713
+ ]
714
+ });
715
+ const matrix = createMockMatrix(
716
+ { "web-framework-react": skill },
717
+ {
718
+ displayNames: { "web-framework-react": "react" }
719
+ }
720
+ );
721
+ store.toggleTechnology("web", "web-framework", "web-framework-react", true);
722
+ const rows = store.buildSourceRows(matrix);
723
+ globalExpect(rows).toHaveLength(1);
724
+ const sourceNames = rows[0].options.map((opt) => opt.id);
725
+ globalExpect(sourceNames).toEqual(["local", "Photoroom", "Agents Inc", "Extra Corp"]);
726
+ });
727
+ });
728
+ describe("agent selection", () => {
729
+ it("should start with empty selectedAgents", () => {
730
+ const { selectedAgents } = useWizardStore.getState();
731
+ globalExpect(selectedAgents).toEqual([]);
732
+ });
733
+ it("should toggle agent on", () => {
734
+ const store = useWizardStore.getState();
735
+ store.toggleAgent("web-developer");
736
+ const { selectedAgents } = useWizardStore.getState();
737
+ globalExpect(selectedAgents).toContain("web-developer");
738
+ });
739
+ it("should toggle agent off", () => {
740
+ const store = useWizardStore.getState();
741
+ store.toggleAgent("web-developer");
742
+ store.toggleAgent("web-developer");
743
+ const { selectedAgents } = useWizardStore.getState();
744
+ globalExpect(selectedAgents).not.toContain("web-developer");
745
+ });
746
+ it("should allow multiple agents to be selected", () => {
747
+ const store = useWizardStore.getState();
748
+ store.toggleAgent("web-developer");
749
+ store.toggleAgent("api-developer");
750
+ store.toggleAgent("web-reviewer");
751
+ const { selectedAgents } = useWizardStore.getState();
752
+ globalExpect(selectedAgents).toEqual(["web-developer", "api-developer", "web-reviewer"]);
753
+ });
754
+ it("should reset selectedAgents on reset", () => {
755
+ const store = useWizardStore.getState();
756
+ store.toggleAgent("web-developer");
757
+ store.reset();
758
+ const { selectedAgents } = useWizardStore.getState();
759
+ globalExpect(selectedAgents).toEqual([]);
760
+ });
761
+ });
762
+ describe("preselectAgentsFromDomains", () => {
763
+ it("should preselect web-related agents when web domain is selected", () => {
764
+ const store = useWizardStore.getState();
765
+ store.toggleDomain("web");
766
+ store.preselectAgentsFromDomains();
767
+ const { selectedAgents } = useWizardStore.getState();
768
+ globalExpect(selectedAgents).toContain("web-developer");
769
+ globalExpect(selectedAgents).toContain("web-reviewer");
770
+ globalExpect(selectedAgents).toContain("web-researcher");
771
+ globalExpect(selectedAgents).toContain("web-tester");
772
+ globalExpect(selectedAgents).toContain("web-pm");
773
+ globalExpect(selectedAgents).toContain("web-architecture");
774
+ });
775
+ it("should preselect api-related agents when api domain is selected", () => {
776
+ const store = useWizardStore.getState();
777
+ store.toggleDomain("api");
778
+ store.preselectAgentsFromDomains();
779
+ const { selectedAgents } = useWizardStore.getState();
780
+ globalExpect(selectedAgents).toContain("api-developer");
781
+ globalExpect(selectedAgents).toContain("api-reviewer");
782
+ globalExpect(selectedAgents).toContain("api-researcher");
783
+ globalExpect(selectedAgents).not.toContain("web-developer");
784
+ });
785
+ it("should preselect cli agents when cli domain is selected", () => {
786
+ const store = useWizardStore.getState();
787
+ store.toggleDomain("cli");
788
+ store.preselectAgentsFromDomains();
789
+ const { selectedAgents } = useWizardStore.getState();
790
+ globalExpect(selectedAgents).toContain("cli-developer");
791
+ globalExpect(selectedAgents).toContain("cli-tester");
792
+ globalExpect(selectedAgents).toContain("cli-reviewer");
793
+ globalExpect(selectedAgents).toContain("cli-migrator");
794
+ });
795
+ it("should never include optional agents regardless of domains", () => {
796
+ const store = useWizardStore.getState();
797
+ store.toggleDomain("web");
798
+ store.toggleDomain("api");
799
+ store.toggleDomain("cli");
800
+ store.preselectAgentsFromDomains();
801
+ const { selectedAgents } = useWizardStore.getState();
802
+ globalExpect(selectedAgents).not.toContain("agent-summoner");
803
+ globalExpect(selectedAgents).not.toContain("skill-summoner");
804
+ globalExpect(selectedAgents).not.toContain("documentor");
805
+ globalExpect(selectedAgents).not.toContain("pattern-scout");
806
+ globalExpect(selectedAgents).not.toContain("web-pattern-critique");
807
+ });
808
+ it("should return empty agents when no domains are selected", () => {
809
+ const store = useWizardStore.getState();
810
+ store.preselectAgentsFromDomains();
811
+ const { selectedAgents } = useWizardStore.getState();
812
+ globalExpect(selectedAgents).toEqual([]);
813
+ });
814
+ it("should produce union of agents for multiple domains", () => {
815
+ const store = useWizardStore.getState();
816
+ store.toggleDomain("web");
817
+ store.toggleDomain("api");
818
+ store.preselectAgentsFromDomains();
819
+ const { selectedAgents } = useWizardStore.getState();
820
+ globalExpect(selectedAgents).toContain("web-developer");
821
+ globalExpect(selectedAgents).toContain("api-developer");
822
+ globalExpect(selectedAgents).toContain("web-reviewer");
823
+ globalExpect(selectedAgents).toContain("api-reviewer");
824
+ });
825
+ it("should not preselect api agents when only web domain is selected", () => {
826
+ const store = useWizardStore.getState();
827
+ store.toggleDomain("web");
828
+ store.preselectAgentsFromDomains();
829
+ const { selectedAgents } = useWizardStore.getState();
830
+ globalExpect(selectedAgents).toContain("web-developer");
831
+ globalExpect(selectedAgents).not.toContain("api-developer");
832
+ globalExpect(selectedAgents).not.toContain("api-reviewer");
833
+ });
834
+ it("should return sorted agents", () => {
835
+ const store = useWizardStore.getState();
836
+ store.toggleDomain("web");
837
+ store.toggleDomain("api");
838
+ store.preselectAgentsFromDomains();
839
+ const { selectedAgents } = useWizardStore.getState();
840
+ const sorted = [...selectedAgents].sort();
841
+ globalExpect(selectedAgents).toEqual(sorted);
842
+ });
843
+ it("should replace previous agent selection", () => {
844
+ const store = useWizardStore.getState();
845
+ store.toggleAgent("documentor");
846
+ store.toggleDomain("web");
847
+ store.preselectAgentsFromDomains();
848
+ const { selectedAgents } = useWizardStore.getState();
849
+ globalExpect(selectedAgents).not.toContain("documentor");
850
+ });
851
+ });
852
+ describe("step progress with agents step", () => {
853
+ it("should include agents in completed steps when on confirm", () => {
854
+ const store = useWizardStore.getState();
855
+ store.setApproach("scratch");
856
+ store.setStep("build");
857
+ store.setStep("sources");
858
+ store.setStep("agents");
859
+ store.setStep("confirm");
860
+ const { completedSteps } = store.getStepProgress();
861
+ globalExpect(completedSteps).toContain("agents");
862
+ globalExpect(completedSteps).toContain("sources");
863
+ globalExpect(completedSteps).toContain("build");
864
+ });
865
+ it("should include sources in completed steps when on agents step", () => {
866
+ const store = useWizardStore.getState();
867
+ store.setApproach("scratch");
868
+ store.setStep("build");
869
+ store.setStep("sources");
870
+ store.setStep("agents");
871
+ const { completedSteps } = store.getStepProgress();
872
+ globalExpect(completedSteps).toContain("build");
873
+ globalExpect(completedSteps).toContain("sources");
874
+ globalExpect(completedSteps).not.toContain("agents");
875
+ });
876
+ it("should skip agents step when using stack defaults", () => {
877
+ const store = useWizardStore.getState();
878
+ store.setApproach("stack");
879
+ store.selectStack("nextjs-fullstack");
880
+ store.setStackAction("defaults");
881
+ store.setStep("confirm");
882
+ const { skippedSteps } = store.getStepProgress();
883
+ globalExpect(skippedSteps).toContain("agents");
884
+ globalExpect(skippedSteps).toContain("build");
885
+ globalExpect(skippedSteps).toContain("sources");
686
886
  });
687
887
  });
688
888
  });