agents-inc 0.151.0 → 0.152.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 (254) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +25 -25
  3. package/dist/{chunk-YA4QQKKE.js → chunk-5GUOIJSG.js} +3 -7
  4. package/dist/{chunk-YA4QQKKE.js.map → chunk-5GUOIJSG.js.map} +1 -1
  5. package/dist/{chunk-44LLPS2N.js → chunk-5UWKOOIS.js} +6 -26
  6. package/dist/chunk-5UWKOOIS.js.map +1 -0
  7. package/dist/{chunk-O5ASLZ2K.js → chunk-76ADG7LQ.js} +1 -5
  8. package/dist/{chunk-O5ASLZ2K.js.map → chunk-76ADG7LQ.js.map} +1 -1
  9. package/dist/{chunk-WK4J2CHH.js → chunk-BNSRA6HL.js} +13 -18
  10. package/dist/{chunk-WK4J2CHH.js.map → chunk-BNSRA6HL.js.map} +1 -1
  11. package/dist/{chunk-FYPUUYSG.js → chunk-DTSG5XZB.js} +3 -7
  12. package/dist/{chunk-FYPUUYSG.js.map → chunk-DTSG5XZB.js.map} +1 -1
  13. package/dist/{chunk-NGLQ5W7U.js → chunk-E5X6RJ4E.js} +5 -15
  14. package/dist/chunk-E5X6RJ4E.js.map +1 -0
  15. package/dist/{chunk-TVHRMRD3.js → chunk-EEPELKOM.js} +4008 -4084
  16. package/dist/chunk-EEPELKOM.js.map +1 -0
  17. package/dist/{chunk-NIKUMXE7.js → chunk-F7T5AFFN.js} +1 -5
  18. package/dist/{chunk-NIKUMXE7.js.map → chunk-F7T5AFFN.js.map} +1 -1
  19. package/dist/{chunk-LAXAQ3PZ.js → chunk-FVDKAVOL.js} +10 -14
  20. package/dist/{chunk-LAXAQ3PZ.js.map → chunk-FVDKAVOL.js.map} +1 -1
  21. package/dist/{chunk-BNE4HHIH.js → chunk-GRVKW3CC.js} +2 -6
  22. package/dist/{chunk-BNE4HHIH.js.map → chunk-GRVKW3CC.js.map} +1 -1
  23. package/dist/{chunk-3XFUQ6OL.js → chunk-IHUY4M22.js} +4 -8
  24. package/dist/{chunk-3XFUQ6OL.js.map → chunk-IHUY4M22.js.map} +1 -1
  25. package/dist/{chunk-OZZGXBCN.js → chunk-IUQBOCSU.js} +1 -5
  26. package/dist/{chunk-OZZGXBCN.js.map → chunk-IUQBOCSU.js.map} +1 -1
  27. package/dist/{chunk-LYYXX2W5.js → chunk-J27W6TXS.js} +4 -6
  28. package/dist/{chunk-LYYXX2W5.js.map → chunk-J27W6TXS.js.map} +1 -1
  29. package/dist/chunk-JFLVEFFP.js +16 -0
  30. package/dist/chunk-JFLVEFFP.js.map +1 -0
  31. package/dist/{chunk-PV2HNW4I.js → chunk-KFB5CRXZ.js} +7 -12
  32. package/dist/{chunk-PV2HNW4I.js.map → chunk-KFB5CRXZ.js.map} +1 -1
  33. package/dist/{chunk-SYUOXSPU.js → chunk-KR65TPKC.js} +168 -14
  34. package/dist/chunk-KR65TPKC.js.map +1 -0
  35. package/dist/{chunk-KOPEM3Q7.js → chunk-KXYVJGJP.js} +2 -6
  36. package/dist/{chunk-KOPEM3Q7.js.map → chunk-KXYVJGJP.js.map} +1 -1
  37. package/dist/{chunk-TYJLR32W.js → chunk-L7SZXUBJ.js} +9 -14
  38. package/dist/{chunk-TYJLR32W.js.map → chunk-L7SZXUBJ.js.map} +1 -1
  39. package/dist/{chunk-NHCGC6DG.js → chunk-LASI35KT.js} +4 -9
  40. package/dist/{chunk-NHCGC6DG.js.map → chunk-LASI35KT.js.map} +1 -1
  41. package/dist/{chunk-VG2TVBFN.js → chunk-LDP5ASDM.js} +2 -6
  42. package/dist/{chunk-VG2TVBFN.js.map → chunk-LDP5ASDM.js.map} +1 -1
  43. package/dist/{chunk-5V2O6C3T.js → chunk-LZ52XEPR.js} +4 -8
  44. package/dist/{chunk-5V2O6C3T.js.map → chunk-LZ52XEPR.js.map} +1 -1
  45. package/dist/{chunk-WFWCZEMS.js → chunk-M7HO7NBK.js} +4 -8
  46. package/dist/{chunk-WFWCZEMS.js.map → chunk-M7HO7NBK.js.map} +1 -1
  47. package/dist/{chunk-XA57SX4T.js → chunk-MJ2KHG24.js} +4 -8
  48. package/dist/{chunk-XA57SX4T.js.map → chunk-MJ2KHG24.js.map} +1 -1
  49. package/dist/{chunk-DAG2ULNF.js → chunk-MM7CTTAV.js} +2 -6
  50. package/dist/chunk-MM7CTTAV.js.map +1 -0
  51. package/dist/{chunk-UFURYGD3.js → chunk-MQ7FLIYS.js} +2 -6
  52. package/dist/{chunk-UFURYGD3.js.map → chunk-MQ7FLIYS.js.map} +1 -1
  53. package/dist/{chunk-SI5FOARI.js → chunk-MVR3SYMN.js} +6 -8
  54. package/dist/chunk-MVR3SYMN.js.map +1 -0
  55. package/dist/{chunk-UTFN6UJS.js → chunk-MWG4VU64.js} +12 -17
  56. package/dist/{chunk-UTFN6UJS.js.map → chunk-MWG4VU64.js.map} +1 -1
  57. package/dist/{chunk-ES3NJZON.js → chunk-NR3OZGL4.js} +1 -5
  58. package/dist/{chunk-ES3NJZON.js.map → chunk-NR3OZGL4.js.map} +1 -1
  59. package/dist/{chunk-GYG5SE2D.js → chunk-ODNDXQH2.js} +2 -6
  60. package/dist/{chunk-GYG5SE2D.js.map → chunk-ODNDXQH2.js.map} +1 -1
  61. package/dist/{chunk-2RSNKBXC.js → chunk-P44SXVH3.js} +6 -10
  62. package/dist/{chunk-2RSNKBXC.js.map → chunk-P44SXVH3.js.map} +1 -1
  63. package/dist/{chunk-3LIU2ZEF.js → chunk-PMM2MYMA.js} +3 -16
  64. package/dist/{chunk-3LIU2ZEF.js.map → chunk-PMM2MYMA.js.map} +1 -1
  65. package/dist/{chunk-QTFQEYDA.js → chunk-PZIZNMHK.js} +24 -36
  66. package/dist/chunk-PZIZNMHK.js.map +1 -0
  67. package/dist/{chunk-C55DN7GE.js → chunk-Q2KG7UV3.js} +3 -5
  68. package/dist/chunk-Q2KG7UV3.js.map +1 -0
  69. package/dist/{chunk-QQLRX4KI.js → chunk-Q45ZU6HD.js} +2 -6
  70. package/dist/{chunk-QQLRX4KI.js.map → chunk-Q45ZU6HD.js.map} +1 -1
  71. package/dist/{chunk-6RBQBOBS.js → chunk-QRDTLVXG.js} +9 -14
  72. package/dist/{chunk-6RBQBOBS.js.map → chunk-QRDTLVXG.js.map} +1 -1
  73. package/dist/{chunk-YBVA7GPW.js → chunk-QZZJFYUQ.js} +3 -7
  74. package/dist/{chunk-YBVA7GPW.js.map → chunk-QZZJFYUQ.js.map} +1 -1
  75. package/dist/{chunk-OJIESW5B.js → chunk-R5NOI2LP.js} +13 -17
  76. package/dist/{chunk-OJIESW5B.js.map → chunk-R5NOI2LP.js.map} +1 -1
  77. package/dist/{chunk-DUVWGO6E.js → chunk-RNJWAKMO.js} +3 -7
  78. package/dist/{chunk-DUVWGO6E.js.map → chunk-RNJWAKMO.js.map} +1 -1
  79. package/dist/{chunk-4R6PGHQQ.js → chunk-SBHBBZKF.js} +7 -23
  80. package/dist/chunk-SBHBBZKF.js.map +1 -0
  81. package/dist/{chunk-NM3EDGB5.js → chunk-SKQWRUPX.js} +10 -14
  82. package/dist/{chunk-NM3EDGB5.js.map → chunk-SKQWRUPX.js.map} +1 -1
  83. package/dist/{chunk-Y4CXDA3I.js → chunk-STMHDOZD.js} +4 -21
  84. package/dist/chunk-STMHDOZD.js.map +1 -0
  85. package/dist/{chunk-SHHOMVWC.js → chunk-SX5H6TSC.js} +7 -11
  86. package/dist/chunk-SX5H6TSC.js.map +1 -0
  87. package/dist/{chunk-RBHYLCUB.js → chunk-TJJPWUMA.js} +2 -6
  88. package/dist/{chunk-RBHYLCUB.js.map → chunk-TJJPWUMA.js.map} +1 -1
  89. package/dist/{chunk-IOJR5TOY.js → chunk-TSIU7DME.js} +1 -5
  90. package/dist/{chunk-IOJR5TOY.js.map → chunk-TSIU7DME.js.map} +1 -1
  91. package/dist/{chunk-EVXG3X6G.js → chunk-TUPYW2IQ.js} +3 -7
  92. package/dist/{chunk-EVXG3X6G.js.map → chunk-TUPYW2IQ.js.map} +1 -1
  93. package/dist/{chunk-YU2VGX5R.js → chunk-UBEDZ4FD.js} +1 -8
  94. package/dist/{chunk-YU2VGX5R.js.map → chunk-UBEDZ4FD.js.map} +1 -1
  95. package/dist/{chunk-VEP23B5W.js → chunk-VASLW636.js} +1 -5
  96. package/dist/{chunk-VEP23B5W.js.map → chunk-VASLW636.js.map} +1 -1
  97. package/dist/{chunk-PG4G4IIK.js → chunk-VY6MNOXL.js} +2 -6
  98. package/dist/{chunk-PG4G4IIK.js.map → chunk-VY6MNOXL.js.map} +1 -1
  99. package/dist/{chunk-IHO75PMZ.js → chunk-WBCPLH66.js} +15 -13
  100. package/dist/chunk-WBCPLH66.js.map +1 -0
  101. package/dist/{chunk-DG2NGZ7S.js → chunk-WKTHWQKM.js} +2 -7
  102. package/dist/{chunk-DG2NGZ7S.js.map → chunk-WKTHWQKM.js.map} +1 -1
  103. package/dist/{chunk-EZ7STXUV.js → chunk-XHUODHZ4.js} +19 -25
  104. package/dist/{chunk-EZ7STXUV.js.map → chunk-XHUODHZ4.js.map} +1 -1
  105. package/dist/{chunk-KIR7VYQD.js → chunk-XVAQG2CV.js} +1 -5
  106. package/dist/{chunk-KIR7VYQD.js.map → chunk-XVAQG2CV.js.map} +1 -1
  107. package/dist/{chunk-P3PN5SVI.js → chunk-ZL7PFNHN.js} +2 -6
  108. package/dist/{chunk-P3PN5SVI.js.map → chunk-ZL7PFNHN.js.map} +1 -1
  109. package/dist/{chunk-3YGUHWLR.js → chunk-ZPPHXXAP.js} +9 -15
  110. package/dist/{chunk-3YGUHWLR.js.map → chunk-ZPPHXXAP.js.map} +1 -1
  111. package/dist/commands/build/marketplace.js +10 -15
  112. package/dist/commands/build/marketplace.js.map +1 -1
  113. package/dist/commands/build/plugins.js +9 -14
  114. package/dist/commands/build/plugins.js.map +1 -1
  115. package/dist/commands/compile.js +14 -19
  116. package/dist/commands/compile.js.map +1 -1
  117. package/dist/commands/doctor.js +13 -18
  118. package/dist/commands/doctor.js.map +1 -1
  119. package/dist/commands/edit.js +51 -55
  120. package/dist/commands/edit.js.map +1 -1
  121. package/dist/commands/eject.js +13 -18
  122. package/dist/commands/eject.js.map +1 -1
  123. package/dist/commands/import/skill.js +9 -14
  124. package/dist/commands/import/skill.js.map +1 -1
  125. package/dist/commands/init.js +50 -51
  126. package/dist/commands/list.js +14 -16
  127. package/dist/commands/list.js.map +1 -1
  128. package/dist/commands/new/agent.js +12 -16
  129. package/dist/commands/new/agent.js.map +1 -1
  130. package/dist/commands/new/marketplace.js +15 -20
  131. package/dist/commands/new/marketplace.js.map +1 -1
  132. package/dist/commands/new/skill.js +11 -13
  133. package/dist/commands/search.js +14 -19
  134. package/dist/commands/search.js.map +1 -1
  135. package/dist/commands/uninstall.js +17 -21
  136. package/dist/commands/uninstall.js.map +1 -1
  137. package/dist/commands/update.js +17 -21
  138. package/dist/commands/update.js.map +1 -1
  139. package/dist/commands/validate.js +10 -16
  140. package/dist/commands/validate.js.map +1 -1
  141. package/dist/components/common/confirm.js +1 -2
  142. package/dist/components/common/prompt-confirm.js +2 -2
  143. package/dist/components/common/select-list.js +3 -4
  144. package/dist/components/common/spinner.js +1 -2
  145. package/dist/components/wizard/category-grid.js +8 -9
  146. package/dist/components/wizard/checkbox-grid.js +6 -7
  147. package/dist/components/wizard/domain-selection.js +14 -15
  148. package/dist/components/wizard/run-wizard-session.js +40 -40
  149. package/dist/components/wizard/scroll-affordance.js +2 -3
  150. package/dist/components/wizard/search-modal.js +6 -7
  151. package/dist/components/wizard/selection-card.js +2 -3
  152. package/dist/components/wizard/skill-agent-summary.js +8 -9
  153. package/dist/components/wizard/source-grid.js +13 -14
  154. package/dist/components/wizard/stack-selection.js +12 -13
  155. package/dist/components/wizard/step-agents.js +14 -15
  156. package/dist/components/wizard/step-build.js +14 -15
  157. package/dist/components/wizard/step-confirm.js +13 -14
  158. package/dist/components/wizard/step-settings.js +11 -12
  159. package/dist/components/wizard/step-sources.js +20 -21
  160. package/dist/components/wizard/step-stack.js +13 -14
  161. package/dist/components/wizard/summary-panel.js +12 -13
  162. package/dist/components/wizard/toast.js +2 -3
  163. package/dist/components/wizard/wizard-layout.js +18 -19
  164. package/dist/components/wizard/wizard-tabs.js +8 -9
  165. package/dist/components/wizard/wizard.js +38 -39
  166. package/dist/config-exports.js +1 -7
  167. package/dist/config-exports.js.map +1 -1
  168. package/dist/copy-local-skills-6EMVN7RB.js +14 -0
  169. package/dist/hooks/init.js +50 -54
  170. package/dist/hooks/init.js.map +1 -1
  171. package/dist/index.js +0 -4
  172. package/dist/index.js.map +1 -1
  173. package/dist/load-agent-defs-BWOUVEAR.js +15 -0
  174. package/dist/{loader-E2ERJYVA.js → loader-5JP4S7CJ.js} +4 -5
  175. package/dist/recompile-project-agents-6DL45TDI.js +19 -0
  176. package/dist/{source-loader-5UNRU7EZ.js → source-loader-MZYCPL2S.js} +7 -8
  177. package/dist/stores/wizard-store.js +7 -8
  178. package/package.json +15 -14
  179. package/dist/chunk-44LLPS2N.js.map +0 -1
  180. package/dist/chunk-4R6PGHQQ.js.map +0 -1
  181. package/dist/chunk-7QIHKQL5.js +0 -181
  182. package/dist/chunk-7QIHKQL5.js.map +0 -1
  183. package/dist/chunk-C55DN7GE.js.map +0 -1
  184. package/dist/chunk-DAG2ULNF.js.map +0 -1
  185. package/dist/chunk-DIBCRIMR.js +0 -36
  186. package/dist/chunk-DIBCRIMR.js.map +0 -1
  187. package/dist/chunk-EKWAUOQB.js +0 -96
  188. package/dist/chunk-EKWAUOQB.js.map +0 -1
  189. package/dist/chunk-I3XKEGHM.js +0 -16383
  190. package/dist/chunk-I3XKEGHM.js.map +0 -1
  191. package/dist/chunk-IHO75PMZ.js.map +0 -1
  192. package/dist/chunk-K3OU6TGX.js +0 -77
  193. package/dist/chunk-K3OU6TGX.js.map +0 -1
  194. package/dist/chunk-KSZ6PCY4.js +0 -43
  195. package/dist/chunk-KSZ6PCY4.js.map +0 -1
  196. package/dist/chunk-NGLQ5W7U.js.map +0 -1
  197. package/dist/chunk-P56WJ5FA.js +0 -50
  198. package/dist/chunk-P56WJ5FA.js.map +0 -1
  199. package/dist/chunk-QTFQEYDA.js.map +0 -1
  200. package/dist/chunk-SHHOMVWC.js.map +0 -1
  201. package/dist/chunk-SI5FOARI.js.map +0 -1
  202. package/dist/chunk-SYUOXSPU.js.map +0 -1
  203. package/dist/chunk-THKIOI32.js +0 -939
  204. package/dist/chunk-THKIOI32.js.map +0 -1
  205. package/dist/chunk-TVHRMRD3.js.map +0 -1
  206. package/dist/chunk-V7QOSGQA.js +0 -298
  207. package/dist/chunk-V7QOSGQA.js.map +0 -1
  208. package/dist/chunk-Y4CXDA3I.js.map +0 -1
  209. package/dist/components/common/confirm.test.js +0 -203
  210. package/dist/components/common/confirm.test.js.map +0 -1
  211. package/dist/components/wizard/category-grid.test.js +0 -1253
  212. package/dist/components/wizard/category-grid.test.js.map +0 -1
  213. package/dist/components/wizard/checkbox-grid.test.js +0 -264
  214. package/dist/components/wizard/checkbox-grid.test.js.map +0 -1
  215. package/dist/components/wizard/search-modal.test.js +0 -212
  216. package/dist/components/wizard/search-modal.test.js.map +0 -1
  217. package/dist/components/wizard/source-grid.test.js +0 -1094
  218. package/dist/components/wizard/source-grid.test.js.map +0 -1
  219. package/dist/components/wizard/step-agents.test.js +0 -204
  220. package/dist/components/wizard/step-agents.test.js.map +0 -1
  221. package/dist/components/wizard/step-build.test.js +0 -552
  222. package/dist/components/wizard/step-build.test.js.map +0 -1
  223. package/dist/components/wizard/step-confirm.test.js +0 -744
  224. package/dist/components/wizard/step-confirm.test.js.map +0 -1
  225. package/dist/components/wizard/step-settings.test.js +0 -244
  226. package/dist/components/wizard/step-settings.test.js.map +0 -1
  227. package/dist/components/wizard/step-sources.test.js +0 -155
  228. package/dist/components/wizard/step-sources.test.js.map +0 -1
  229. package/dist/components/wizard/step-stack.test.js +0 -262
  230. package/dist/components/wizard/step-stack.test.js.map +0 -1
  231. package/dist/components/wizard/summary-panel.test.js +0 -317
  232. package/dist/components/wizard/summary-panel.test.js.map +0 -1
  233. package/dist/components/wizard/wizard-layout.test.js +0 -200
  234. package/dist/components/wizard/wizard-layout.test.js.map +0 -1
  235. package/dist/components/wizard/wizard-tabs.test.js +0 -290
  236. package/dist/components/wizard/wizard-tabs.test.js.map +0 -1
  237. package/dist/copy-local-skills-UPA2GUZV.js +0 -15
  238. package/dist/dist-VNJNNJK7.js +0 -550
  239. package/dist/dist-VNJNNJK7.js.map +0 -1
  240. package/dist/load-agent-defs-SB4XAOVB.js +0 -16
  241. package/dist/magic-string.es-5TV73NJD.js +0 -1316
  242. package/dist/magic-string.es-5TV73NJD.js.map +0 -1
  243. package/dist/recompile-project-agents-U4ZY2GDX.js +0 -20
  244. package/dist/source-manager-3O54SIIB.js +0 -18
  245. package/dist/source-manager-3O54SIIB.js.map +0 -1
  246. package/dist/stores/d227-same-scope-tombstone-duplicate.test.js +0 -118
  247. package/dist/stores/d227-same-scope-tombstone-duplicate.test.js.map +0 -1
  248. package/dist/stores/wizard-store.test.js +0 -3053
  249. package/dist/stores/wizard-store.test.js.map +0 -1
  250. /package/dist/{copy-local-skills-UPA2GUZV.js.map → copy-local-skills-6EMVN7RB.js.map} +0 -0
  251. /package/dist/{load-agent-defs-SB4XAOVB.js.map → load-agent-defs-BWOUVEAR.js.map} +0 -0
  252. /package/dist/{loader-E2ERJYVA.js.map → loader-5JP4S7CJ.js.map} +0 -0
  253. /package/dist/{recompile-project-agents-U4ZY2GDX.js.map → recompile-project-agents-6DL45TDI.js.map} +0 -0
  254. /package/dist/{source-loader-5UNRU7EZ.js.map → source-loader-MZYCPL2S.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/cli/components/wizard/source-grid.test.tsx"],"sourcesContent":["import chalk from \"chalk\";\nimport { 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, SkillScope } from \"../../types\";\nimport { CLI_COLORS, UI_SYMBOLS } from \"../../consts\";\nimport { getSkillById, initializeMatrix } from \"../../lib/matrix/matrix-provider\";\nimport { BUILT_IN_MATRIX } from \"../../types/generated/matrix\";\nimport { createMockSkill } from \"../../lib/__tests__/factories/skill-factories\";\nimport { createMockMatrix } from \"../../lib/__tests__/factories/matrix-factories\";\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\n/** chalk's truecolor level — the 24-bit mode that emits the hex colours CLI_COLORS declares. */\nconst TRUECOLOR_CHALK_LEVEL = 3;\n\nconst createSourceOption = (id: string, overrides: Partial<SourceOption> = {}): SourceOption => ({\n id,\n selected: false,\n installed: false,\n ...overrides,\n});\n\nconst createSourceRow = (\n skillId: SkillId,\n options: SourceOption[],\n scope?: SkillScope,\n readOnly?: boolean,\n): SourceRow => ({\n skillId,\n options,\n scope,\n ...(readOnly ? { readOnly } : {}),\n});\n\n/** A saved skill deselected this session: visible, inert, pending removal on save. */\nconst createRemovedRow = (\n skillId: SkillId,\n options: SourceOption[],\n scope: SkillScope,\n): SourceRow => ({\n ...createSourceRow(skillId, options, scope),\n disabled: true,\n});\n\n/** A skill selected this session but absent from the saved config: visible, editable, marked added. */\nconst createAddedRow = (\n skillId: SkillId,\n options: SourceOption[],\n scope: SkillScope,\n): SourceRow => ({\n ...createSourceRow(skillId, options, scope),\n added: true,\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(\"scope-grouped rendering\", () => {\n it(\"should head each scope block with its own row header and caption no column\", () => {\n const rows: SourceRow[] = [\n createSourceRow(\n \"web-framework-react\",\n [createSourceOption(\"public\", { selected: true })],\n \"global\",\n ),\n createSourceRow(\n \"web-state-zustand\",\n [createSourceOption(\"public\", { selected: true })],\n \"project\",\n ),\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(\"Zustand\");\n // The gutter's row headers are what name the scopes; a caption above them would only repeat\n // what every value in the column already says.\n expect(output).toContain(\"Global\");\n expect(output).toContain(\"Project\");\n expect(output).not.toContain(\"Scope\");\n });\n\n it(\"should show global rows before project rows\", () => {\n const rows: SourceRow[] = [\n createSourceRow(\n \"web-state-zustand\",\n [createSourceOption(\"public\", { selected: true })],\n \"project\",\n ),\n createSourceRow(\n \"web-framework-react\",\n [createSourceOption(\"public\", { selected: true })],\n \"global\",\n ),\n ];\n\n const { lastFrame, unmount } = renderGrid({ rows });\n cleanup = unmount;\n\n const output = lastFrame()!;\n const globalPos = output.indexOf(\"React\");\n const projectPos = output.indexOf(\"Zustand\");\n expect(globalPos).toBeGreaterThan(-1);\n expect(projectPos).toBeGreaterThan(-1);\n expect(globalPos).toBeLessThan(projectPos);\n });\n\n /**\n * Column geometry is the contract in a fixed-width table, and neither `toContain` nor a\n * relative-order check can express it: a name rendered one column family too far right\n * satisfies both. The whole-frame snapshot pins every column start at once — including the\n * two-column marker cell every row reserves, which is what keeps the focused row's name in the\n * same column as the unfocused row's.\n *\n * It also pins the two things the caption's removal must not have disturbed: the scope gutter\n * still heads each block on its first row only (the rest of the block indents under it), and\n * the source captions still sit above their cells even though nothing captions the gutter.\n *\n * Rows are deliberately lock-free — the 🔒 glyph is double-width, so a locked row would make\n * the name column read as ragged for reasons that have nothing to do with the layout.\n */\n it(\"heads each block in the gutter and lines the source captions up with their cells\", () => {\n const rows: SourceRow[] = [\n createSourceRow(\n \"web-framework-react\",\n [createSourceOption(\"eject\"), createSourceOption(\"agents-inc\", { selected: true })],\n \"global\",\n ),\n createSourceRow(\n \"web-state-zustand\",\n [createSourceOption(\"eject\", { selected: true }), createSourceOption(\"agents-inc\")],\n \"project\",\n ),\n ];\n\n const { lastFrame, unmount } = renderGrid({ rows });\n cleanup = unmount;\n\n expect(lastFrame()).toMatchInlineSnapshot(`\n \" Local Plugin\n\n Global React ❯ Eject Agents Inc\n\n Project Zustand Eject Agents Inc\"\n `);\n });\n\n /**\n * The flat branch renders one block, so it has nothing to head: no gutter, and every column\n * therefore starts SCOPE_COL_WIDTH to the left of where the grouped snapshot above puts it, with\n * no separating blank line between rows. Snapshotting both branches is what makes a gutter or a\n * block separator leaking into the flat layout (or vanishing from the grouped one) a visible\n * diff.\n */\n it(\"renders one unseparated block in the flat layout\", () => {\n const rows: SourceRow[] = [\n createSourceRow(\n \"web-framework-react\",\n [createSourceOption(\"eject\"), createSourceOption(\"agents-inc\", { selected: true })],\n \"project\",\n ),\n createSourceRow(\n \"web-state-zustand\",\n [createSourceOption(\"eject\", { selected: true }), createSourceOption(\"agents-inc\")],\n \"project\",\n ),\n ];\n\n const { lastFrame, unmount } = renderGrid({ rows });\n cleanup = unmount;\n\n expect(lastFrame()).toMatchInlineSnapshot(`\n \" Local Plugin\n\n React ❯ Eject Agents Inc\n Zustand Eject Agents Inc\"\n `);\n });\n\n /** A row with no scope at all takes the same flat branch as a single-scope grid. */\n it(\"renders one unseparated block when no row has a scope\", () => {\n const rows: SourceRow[] = [\n createSourceRow(\"web-framework-react\", [\n createSourceOption(\"eject\"),\n createSourceOption(\"agents-inc\", { selected: true }),\n ]),\n createSourceRow(\"web-state-zustand\", [\n createSourceOption(\"eject\", { selected: true }),\n createSourceOption(\"agents-inc\"),\n ]),\n ];\n\n const { lastFrame, unmount } = renderGrid({ rows });\n cleanup = unmount;\n\n expect(lastFrame()).toMatchInlineSnapshot(`\n \" Local Plugin\n\n React ❯ Eject Agents Inc\n Zustand Eject Agents Inc\"\n `);\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 // Vertical navigation clamps column to last valid index\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 describe(\"read-only rows\", () => {\n const readOnlyRows: SourceRow[] = [\n createSourceRow(\n \"web-framework-react\",\n [createSourceOption(\"public\", { selected: true }), createSourceOption(\"eject\")],\n \"global\",\n true,\n ),\n createSourceRow(\n \"web-state-zustand\",\n [createSourceOption(\"public\", { selected: true })],\n \"project\",\n ),\n ];\n\n it(\"should render read-only rows with lock indicator\", () => {\n const { lastFrame, unmount } = renderGrid({ rows: readOnlyRows });\n cleanup = unmount;\n\n const output = lastFrame()!;\n expect(output).toContain(UI_SYMBOLS.LOCK);\n });\n\n it(\"should render read-only rows with dimmed styling\", () => {\n const { lastFrame, unmount } = renderGrid({ rows: readOnlyRows });\n cleanup = unmount;\n\n const output = lastFrame()!;\n expect(output).toContain(\"React\");\n expect(output).toContain(\"Zustand\");\n });\n\n it(\"should not fire onSelect for read-only rows (defense-in-depth guard)\", async () => {\n const onSelect = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: readOnlyRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onSelect,\n });\n cleanup = unmount;\n\n // defaultFocusedRow 0 is readOnly, so focus adjusts to row 1\n // Pressing space on non-readOnly row 1 fires onSelect for that row\n await delay(RENDER_DELAY_MS);\n stdin.write(SPACE);\n await delay(INPUT_DELAY_MS);\n\n expect(onSelect).toHaveBeenCalledWith(\"web-state-zustand\", \"public\");\n });\n\n it(\"should skip read-only rows during navigation\", async () => {\n const threeRows: SourceRow[] = [\n createSourceRow(\n \"web-framework-react\",\n [createSourceOption(\"public\", { selected: true })],\n \"global\",\n true,\n ),\n createSourceRow(\n \"web-state-zustand\",\n [createSourceOption(\"public\", { selected: true })],\n \"project\",\n ),\n createSourceRow(\n \"web-testing-vitest\",\n [createSourceOption(\"public\", { selected: true })],\n \"global\",\n true,\n ),\n ];\n\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: threeRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n // Initial focus skips readOnly row 0, lands on row 1\n await delay(RENDER_DELAY_MS);\n\n // Pressing down from row 1 should skip readOnly row 2 and wrap back to row 1\n stdin.write(ARROW_DOWN);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenLastCalledWith(1, 0);\n });\n\n it(\"should allow selection on non-read-only rows after navigating past read-only\", async () => {\n const onSelect = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: readOnlyRows,\n defaultFocusedRow: 1,\n defaultFocusedCol: 0,\n onSelect,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(SPACE);\n await delay(INPUT_DELAY_MS);\n\n expect(onSelect).toHaveBeenCalledWith(\"web-state-zustand\", \"public\");\n });\n\n it(\"should not show search pill on read-only rows\", () => {\n const mockSearch = vi.fn<(alias: string) => Promise<BoundSkillCandidate[]>>();\n const { lastFrame, unmount } = renderGrid({\n rows: [\n createSourceRow(\n \"web-framework-react\",\n [createSourceOption(\"public\", { selected: true })],\n \"global\",\n true,\n ),\n ],\n onSearch: mockSearch,\n });\n cleanup = unmount;\n\n const output = lastFrame()!;\n expect(output).toContain(\"React\");\n expect(output).not.toContain(\"Search\");\n });\n\n it(\"should not show focus highlight on read-only rows\", () => {\n const allReadOnlyRows: SourceRow[] = [\n createSourceRow(\n \"web-framework-react\",\n [createSourceOption(\"public\", { selected: true })],\n \"global\",\n true,\n ),\n createSourceRow(\n \"web-state-zustand\",\n [createSourceOption(\"public\", { selected: true })],\n \"global\",\n true,\n ),\n ];\n\n const { lastFrame, unmount } = renderGrid({\n rows: allReadOnlyRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n });\n cleanup = unmount;\n\n const output = lastFrame()!;\n // Read-only rows should not have the chevron focus indicator\n expect(output).not.toContain(UI_SYMBOLS.CHEVRON);\n });\n\n it(\"should render re-scoped skill once per scope group\", () => {\n const reSccopedRows: SourceRow[] = [\n createSourceRow(\n \"web-framework-react\",\n [createSourceOption(\"eject\"), createSourceOption(\"public\", { selected: true })],\n \"global\",\n true,\n ),\n createSourceRow(\n \"web-framework-react\",\n [createSourceOption(\"eject\"), createSourceOption(\"public\", { selected: true })],\n \"project\",\n ),\n ];\n\n const { lastFrame, unmount } = renderGrid({ rows: reSccopedRows });\n cleanup = unmount;\n\n const output = lastFrame()!;\n // React should appear twice (once per scope group)\n const reactMatches = output.split(\"React\").length - 1;\n expect(reactMatches).toBe(2);\n // Global copy should have lock indicator\n expect(output).toContain(UI_SYMBOLS.LOCK);\n });\n });\n\n describe(\"removed (disabled) rows\", () => {\n const removedRows: SourceRow[] = [\n createSourceRow(\n \"web-framework-react\",\n [createSourceOption(\"public\", { selected: true })],\n \"project\",\n ),\n createRemovedRow(\n \"web-testing-vitest\",\n [createSourceOption(\"eject\", { selected: true }), createSourceOption(\"public\")],\n \"project\",\n ),\n ];\n\n it(\"should keep the removed skill visible\", () => {\n const { lastFrame, unmount } = renderGrid({ rows: removedRows });\n cleanup = unmount;\n\n expect(lastFrame()).toContain(\"Vitest\");\n });\n\n it(\"should mark the removed skill with the pending-removal marker and no lock\", () => {\n const { lastFrame, unmount } = renderGrid({ rows: removedRows });\n cleanup = unmount;\n\n const output = lastFrame()!;\n // Same marker the info panel prints for removals, so both surfaces read consistently.\n expect(output).toContain(`${UI_SYMBOLS.REMOVED} Vitest`);\n // A lock means \"installed globally, not editable here\" — the wrong message for a removal.\n expect(output).not.toContain(UI_SYMBOLS.LOCK);\n });\n\n it(\"should not fire onSelect when space is pressed with a removed row focused\", async () => {\n const onSelect = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: [removedRows[1]],\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onSelect,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(SPACE);\n await delay(INPUT_DELAY_MS);\n\n expect(onSelect).not.toHaveBeenCalled();\n });\n\n it(\"should skip removed rows during navigation\", async () => {\n const onFocusChange = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: removedRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onFocusChange,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n // Row 1 is removed, so moving down wraps straight back to the editable row 0.\n stdin.write(ARROW_DOWN);\n await delay(INPUT_DELAY_MS);\n\n expect(onFocusChange).toHaveBeenLastCalledWith(0, 0);\n });\n\n it(\"should not focus a removed row when it is the default focus target\", async () => {\n const onSelect = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: removedRows,\n defaultFocusedRow: 1, // The removed row — focus must fall back to the editable row.\n defaultFocusedCol: 0,\n onSelect,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(SPACE);\n await delay(INPUT_DELAY_MS);\n\n expect(onSelect).toHaveBeenCalledWith(\"web-framework-react\", \"public\");\n });\n\n it(\"should not show search pill on removed rows\", () => {\n const mockSearch = vi.fn<(alias: string) => Promise<BoundSkillCandidate[]>>();\n const { lastFrame, unmount } = renderGrid({\n rows: [removedRows[1]],\n onSearch: mockSearch,\n });\n cleanup = unmount;\n\n const output = lastFrame()!;\n expect(output).toContain(\"Vitest\");\n expect(output).not.toContain(\"Search\");\n });\n\n it(\"should not show focus highlight on removed rows\", () => {\n const { lastFrame, unmount } = renderGrid({\n rows: [removedRows[1]],\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n });\n cleanup = unmount;\n\n expect(lastFrame()).not.toContain(UI_SYMBOLS.CHEVRON);\n });\n\n /**\n * A skill installed at BOTH scopes whose project copy is removed this session: the surviving\n * global install renders as a locked row and the emptied project slot as a pending-removal\n * row, so ONE skill occupies TWO rows — the shape the confirm step already prints as `-` at\n * Project plus `•` at Global. Both rows are inert, and `groupRowsByScope` labels the sections\n * because both scopes are present.\n */\n describe(\"collapsed dual-scope pair\", () => {\n const COLLAPSED_SKILL_ID: SkillId = \"web-framework-react\";\n const UNTOUCHED_SKILL_ID: SkillId = \"web-state-zustand\";\n\n const collapsedPairRows: SourceRow[] = [\n createSourceRow(\n COLLAPSED_SKILL_ID,\n [createSourceOption(\"public\", { selected: true })],\n \"global\",\n true,\n ),\n createRemovedRow(\n COLLAPSED_SKILL_ID,\n [createSourceOption(\"public\", { selected: true })],\n \"project\",\n ),\n ];\n\n /**\n * Ink colourises through chalk, and chalk disables itself on vitest's non-TTY stdout — the\n * frame would come back stripped of colour, making a colour assertion unobservable. Forcing\n * truecolor for the duration of these tests renders what a user sees in a real terminal.\n */\n let previousChalkLevel: typeof chalk.level;\n\n beforeEach(() => {\n previousChalkLevel = chalk.level;\n chalk.level = TRUECOLOR_CHALK_LEVEL;\n });\n\n afterEach(() => {\n chalk.level = previousChalkLevel;\n });\n\n it(\"should render the same skill in both scope sections, locked at global and pending removal at project\", () => {\n const { lastFrame, unmount } = renderGrid({ rows: collapsedPairRows });\n cleanup = unmount;\n\n const output = lastFrame()!;\n const skillName = getSkillById(COLLAPSED_SKILL_ID).displayName;\n // The skill name appears once per scope section — proven by its two distinct role prefixes\n // rather than by counting occurrences.\n expect(\n output,\n `the surviving global install must keep its lock. Frame:\\n${JSON.stringify(output)}`,\n ).toContain(`${UI_SYMBOLS.LOCK} ${skillName}`);\n expect(\n output,\n `the emptied project slot must carry the removal marker. Frame:\\n${JSON.stringify(output)}`,\n ).toContain(`${UI_SYMBOLS.REMOVED} ${skillName}`);\n // Neither half is an addition, and the removal half is not a second lock.\n expect(output).not.toContain(`${UI_SYMBOLS.ADDED} ${skillName}`);\n });\n\n it(\"should render the project instance of the pair in the removed-diff colour\", () => {\n const { lastFrame, unmount } = renderGrid({ rows: collapsedPairRows });\n cleanup = unmount;\n\n const output = lastFrame()!;\n const skillName = getSkillById(COLLAPSED_SKILL_ID).displayName;\n // Same red the info panel prints removals in (DIFF_COLOR in skill-agent-summary.tsx), so\n // the pair reads as \"removed here, kept there\" on both surfaces. Unfocused: focus seeds on\n // the first FOCUSABLE row and every row here is inert, so no row paints its focus form.\n expect(\n output,\n `the pending-removal row must render in the removed-diff colour. Frame:\\n${JSON.stringify(output)}`,\n ).toContain(chalk.hex(CLI_COLORS.ERROR)(`${UI_SYMBOLS.REMOVED} ${skillName}`));\n });\n\n it(\"should not fire onSelect when space is pressed on an all-inert collapsed pair\", async () => {\n const onSelect = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: collapsedPairRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onSelect,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(SPACE);\n await delay(INPUT_DELAY_MS);\n\n expect(onSelect).not.toHaveBeenCalled();\n });\n\n it(\"should not show focus highlight on either row of the collapsed pair\", () => {\n const { lastFrame, unmount } = renderGrid({\n rows: collapsedPairRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n });\n cleanup = unmount;\n\n expect(lastFrame()).not.toContain(UI_SYMBOLS.CHEVRON);\n });\n\n it(\"should skip both rows of the collapsed pair and act on the editable row instead\", async () => {\n const onSelect = vi.fn();\n const { stdin, unmount } = renderGrid({\n rows: [\n ...collapsedPairRows,\n createSourceRow(\n UNTOUCHED_SKILL_ID,\n [createSourceOption(\"public\", { selected: true })],\n \"project\",\n ),\n ],\n // The locked half of the pair — focus must fall through it AND the pending-removal row.\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n onSelect,\n });\n cleanup = unmount;\n\n await delay(RENDER_DELAY_MS);\n stdin.write(SPACE);\n await delay(INPUT_DELAY_MS);\n\n expect(onSelect).toHaveBeenCalledWith(UNTOUCHED_SKILL_ID, \"public\");\n expect(onSelect).not.toHaveBeenCalledWith(COLLAPSED_SKILL_ID, \"public\");\n });\n });\n });\n\n describe(\"added rows\", () => {\n const ADDED_SKILL_ID: SkillId = \"web-framework-react\";\n\n const addedRows: SourceRow[] = [\n createAddedRow(ADDED_SKILL_ID, [createSourceOption(\"public\", { selected: true })], \"project\"),\n createSourceRow(\n \"web-state-zustand\",\n [createSourceOption(\"public\", { selected: true })],\n \"project\",\n ),\n ];\n\n /**\n * Ink colourises through chalk, and chalk disables itself on vitest's non-TTY stdout — every\n * frame would come back stripped of colour, making a colour assertion unobservable. Forcing\n * truecolor for the duration of these tests renders what a user sees in a real terminal.\n */\n let previousChalkLevel: typeof chalk.level;\n\n beforeEach(() => {\n previousChalkLevel = chalk.level;\n chalk.level = TRUECOLOR_CHALK_LEVEL;\n });\n\n afterEach(() => {\n chalk.level = previousChalkLevel;\n });\n\n it(\"should mark the added skill with the added marker\", () => {\n const { lastFrame, unmount } = renderGrid({\n rows: addedRows,\n defaultFocusedRow: 1,\n defaultFocusedCol: 0,\n });\n cleanup = unmount;\n\n const output = lastFrame()!;\n // Same marker the info panel prints for additions, so both surfaces read consistently.\n expect(output).toContain(`${UI_SYMBOLS.ADDED} ${getSkillById(ADDED_SKILL_ID).displayName}`);\n });\n\n it(\"should keep the added-diff colour on the added row while it is focused\", () => {\n const { lastFrame, unmount } = renderGrid({\n rows: addedRows,\n defaultFocusedRow: 0,\n defaultFocusedCol: 0,\n });\n cleanup = unmount;\n\n // The focused branch renders the two-column marker cell (`+ `) then the name and the\n // highlight's trailing pad, on the focus background — one space between marker and name.\n const focusedLabel = `${UI_SYMBOLS.ADDED} ${getSkillById(ADDED_SKILL_ID).displayName} `;\n const output = lastFrame()!;\n\n // Focus must stay visible (background highlight) AND the label must keep the added-diff\n // green the info panel uses (DIFF_COLOR in skill-agent-summary.tsx) — focus is not a\n // reason to lose the diff signal.\n expect(\n output,\n `a focused added row must keep its added-diff colour. Frame:\\n${JSON.stringify(output)}`,\n ).toContain(chalk.bgHex(CLI_COLORS.LABEL_BG)(chalk.hex(CLI_COLORS.SUCCESS)(focusedLabel)));\n\n // Today's rendering: focus overrides the label colour with plain white, so the row reads\n // as an ordinary focused row and the addition becomes invisible in colour terms.\n expect(\n output,\n \"a focused added row must not fall back to the plain white label colour\",\n ).not.toContain(chalk.bgHex(CLI_COLORS.LABEL_BG)(chalk.hex(CLI_COLORS.WHITE)(focusedLabel)));\n });\n });\n\n /**\n * Inert rows — `readOnly` (locked global) and `disabled` (pending removal) — express which source\n * is selected in the same vocabulary editable rows use: weight, plus brightness on the locked row\n * whose cells are otherwise dimmed. The prefix slot only ever holds a blank spacer, so the check\n * that used to live there appears nowhere in the grid; on a pending-removal row it ticked the\n * source the row was about to lose.\n */\n describe(\"inert row source selection\", () => {\n const LOCKED_ROW: SourceRow = createSourceRow(\n \"web-framework-react\",\n [createSourceOption(\"public\", { selected: true }), createSourceOption(\"eject\")],\n \"global\",\n true,\n );\n const REMOVAL_ROW: SourceRow = createRemovedRow(\n \"web-testing-vitest\",\n [createSourceOption(\"eject\", { selected: true }), createSourceOption(\"public\")],\n \"project\",\n );\n\n /** Prefix every inert source cell carries, selected or not — the blank chevron slot. */\n const INERT_PREFIX = `${UI_SYMBOLS.CHEVRON_SPACER} `;\n\n /**\n * Ink colourises through chalk, and chalk disables itself on vitest's non-TTY stdout — every\n * frame would come back stripped of colour, making a colour assertion unobservable. Forcing\n * truecolor for the duration of these tests renders what a user sees in a real terminal.\n */\n let previousChalkLevel: typeof chalk.level;\n\n beforeEach(() => {\n previousChalkLevel = chalk.level;\n chalk.level = TRUECOLOR_CHALK_LEVEL;\n });\n\n afterEach(() => {\n chalk.level = previousChalkLevel;\n });\n\n it(\"should carry the locked row's selection in weight and brightness, not a check\", () => {\n const { lastFrame, unmount } = renderGrid({ rows: [LOCKED_ROW] });\n cleanup = unmount;\n\n const output = lastFrame()!;\n // Ink applies dim, then colour, then background, then bold (components/Text.js), so a bold\n // undimmed cell is the selected one and a dimmed cell is not.\n expect(\n output,\n `the locked row's selected source must render bold. Frame:\\n${JSON.stringify(output)}`,\n ).toContain(chalk.bold(`${INERT_PREFIX}Public`));\n expect(\n output,\n `the locked row's unselected sources must stay dimmed. Frame:\\n${JSON.stringify(output)}`,\n ).toContain(chalk.dim(`${INERT_PREFIX}Eject`));\n expect(output).not.toContain(UI_SYMBOLS.SELECTED);\n });\n\n it(\"should carry the pending-removal row's selection in weight while keeping its removal colour\", () => {\n const { lastFrame, unmount } = renderGrid({ rows: [REMOVAL_ROW] });\n cleanup = unmount;\n\n const output = lastFrame()!;\n // Red says \"this row is going\"; bold says \"this is the source it is going from\". A check\n // there would say the opposite of both.\n expect(\n output,\n `the removal row's selected source must render bold in the removal colour. Frame:\\n${JSON.stringify(output)}`,\n ).toContain(chalk.bold(chalk.hex(CLI_COLORS.ERROR)(`${INERT_PREFIX}Eject`)));\n expect(\n output,\n `the removal row's unselected sources must keep the removal colour unbolded. Frame:\\n${JSON.stringify(output)}`,\n ).toContain(chalk.hex(CLI_COLORS.ERROR)(`${INERT_PREFIX}Public`));\n expect(output).not.toContain(UI_SYMBOLS.SELECTED);\n });\n });\n});\n"],"mappings":"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","names":[]}
@@ -1,204 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- ARROW_DOWN,
4
- ENTER,
5
- ESCAPE,
6
- INPUT_DELAY_MS,
7
- RENDER_DELAY_MS,
8
- SPACE,
9
- delay
10
- } from "../../chunk-KSZ6PCY4.js";
11
- import {
12
- render
13
- } from "../../chunk-EKWAUOQB.js";
14
- import {
15
- EMPTY_MATRIX
16
- } from "../../chunk-THKIOI32.js";
17
- import "../../chunk-K3OU6TGX.js";
18
- import "../../chunk-V7QOSGQA.js";
19
- import {
20
- afterEach,
21
- beforeEach,
22
- describe,
23
- globalExpect,
24
- it
25
- } from "../../chunk-I3XKEGHM.js";
26
- import {
27
- StepAgents
28
- } from "../../chunk-NM3EDGB5.js";
29
- import "../../chunk-IOJR5TOY.js";
30
- import "../../chunk-YA4QQKKE.js";
31
- import "../../chunk-FYPUUYSG.js";
32
- import "../../chunk-DAG2ULNF.js";
33
- import "../../chunk-VG2TVBFN.js";
34
- import "../../chunk-IHO75PMZ.js";
35
- import {
36
- useWizardStore
37
- } from "../../chunk-44LLPS2N.js";
38
- import "../../chunk-TVHRMRD3.js";
39
- import "../../chunk-3LIU2ZEF.js";
40
- import {
41
- initializeMatrix
42
- } from "../../chunk-DG2NGZ7S.js";
43
- import "../../chunk-VEP23B5W.js";
44
- import "../../chunk-O5ASLZ2K.js";
45
- import "../../chunk-YU2VGX5R.js";
46
- import {
47
- init_esm_shims
48
- } from "../../chunk-P56WJ5FA.js";
49
-
50
- // src/cli/components/wizard/step-agents.test.tsx
51
- init_esm_shims();
52
- import { jsx } from "react/jsx-runtime";
53
- describe("StepAgents component", () => {
54
- let cleanup;
55
- beforeEach(() => {
56
- initializeMatrix(EMPTY_MATRIX);
57
- });
58
- afterEach(() => {
59
- cleanup?.();
60
- cleanup = void 0;
61
- });
62
- describe("rendering", () => {
63
- it("should render agent group headers", () => {
64
- const { lastFrame, unmount } = render(/* @__PURE__ */ jsx(StepAgents, {}));
65
- cleanup = unmount;
66
- const output = lastFrame();
67
- globalExpect(output).toContain("Web");
68
- globalExpect(output).toContain("API");
69
- globalExpect(output).toContain("Meta");
70
- });
71
- it("should render all agents", () => {
72
- const { lastFrame, unmount } = render(/* @__PURE__ */ jsx(StepAgents, {}));
73
- cleanup = unmount;
74
- const output = lastFrame();
75
- globalExpect(output).toContain("Web Developer");
76
- globalExpect(output).toContain("API Developer");
77
- globalExpect(output).toContain("CLI Developer");
78
- globalExpect(output).toContain("Web Architecture");
79
- globalExpect(output).toContain("Web Reviewer");
80
- globalExpect(output).toContain("API Reviewer");
81
- globalExpect(output).toContain("CLI Reviewer");
82
- globalExpect(output).toContain("Web Researcher");
83
- globalExpect(output).toContain("API Researcher");
84
- globalExpect(output).toContain("Web Tester");
85
- globalExpect(output).toContain("CLI Tester");
86
- globalExpect(output).toContain("Web PM");
87
- globalExpect(output).toContain("Pattern Scout");
88
- globalExpect(output).toContain("Pattern Critique");
89
- globalExpect(output).toContain("Agent Summoner");
90
- globalExpect(output).toContain("Skill Summoner");
91
- globalExpect(output).toContain("Codex Keeper");
92
- });
93
- it("should render agent descriptions", () => {
94
- const { lastFrame, unmount } = render(/* @__PURE__ */ jsx(StepAgents, {}));
95
- cleanup = unmount;
96
- const output = lastFrame();
97
- globalExpect(output).toContain("Frontend features, components, TypeScript");
98
- globalExpect(output).toContain("Backend routes, database, middleware");
99
- globalExpect(output).toContain("CLI commands, interactive prompts");
100
- });
101
- it("should render group headers", () => {
102
- const { lastFrame, unmount } = render(/* @__PURE__ */ jsx(StepAgents, {}));
103
- cleanup = unmount;
104
- const output = lastFrame();
105
- globalExpect(output).toContain("Web");
106
- globalExpect(output).toContain("API");
107
- globalExpect(output).toContain("CLI");
108
- globalExpect(output).toContain("Meta");
109
- });
110
- it("should show continue arrow", () => {
111
- const { lastFrame, unmount } = render(/* @__PURE__ */ jsx(StepAgents, {}));
112
- cleanup = unmount;
113
- const output = lastFrame();
114
- globalExpect(output).toContain("\u2192");
115
- globalExpect(output).toContain("Continue");
116
- });
117
- it("should show continue option with agent count when agents selected", () => {
118
- const store = useWizardStore.getState();
119
- store.toggleAgent("web-developer");
120
- store.toggleAgent("api-developer");
121
- store.toggleAgent("web-reviewer");
122
- const { lastFrame, unmount } = render(/* @__PURE__ */ jsx(StepAgents, {}));
123
- cleanup = unmount;
124
- const output = lastFrame();
125
- globalExpect(output).toContain("Continue with 3 agent(s)");
126
- });
127
- it("should show 'Continue without agents' when no agents selected", () => {
128
- const { lastFrame, unmount } = render(/* @__PURE__ */ jsx(StepAgents, {}));
129
- cleanup = unmount;
130
- const output = lastFrame();
131
- globalExpect(output).toContain("Continue without agents");
132
- });
133
- });
134
- describe("keyboard interaction", () => {
135
- it("should toggle agent on SPACE", async () => {
136
- const { stdin, lastFrame, unmount } = render(/* @__PURE__ */ jsx(StepAgents, {}));
137
- cleanup = unmount;
138
- await delay(RENDER_DELAY_MS);
139
- await stdin.write(SPACE);
140
- await delay(INPUT_DELAY_MS);
141
- const store = useWizardStore.getState();
142
- globalExpect(store.selectedAgents).toContain("web-developer");
143
- globalExpect(lastFrame()).toContain("Continue with 1 agent(s)");
144
- });
145
- it("should toggle correct agent after navigation", async () => {
146
- const { stdin, unmount } = render(/* @__PURE__ */ jsx(StepAgents, {}));
147
- cleanup = unmount;
148
- await delay(RENDER_DELAY_MS);
149
- await stdin.write(ARROW_DOWN);
150
- await delay(INPUT_DELAY_MS);
151
- await stdin.write(SPACE);
152
- await delay(INPUT_DELAY_MS);
153
- const store = useWizardStore.getState();
154
- globalExpect(store.selectedAgents).toContain("web-reviewer");
155
- });
156
- it("should navigate to confirm on ENTER when agents selected", async () => {
157
- const store = useWizardStore.getState();
158
- store.toggleAgent("web-developer");
159
- store.setStep("agents");
160
- const { stdin, unmount } = render(/* @__PURE__ */ jsx(StepAgents, {}));
161
- cleanup = unmount;
162
- await delay(RENDER_DELAY_MS);
163
- await stdin.write(ENTER);
164
- await delay(INPUT_DELAY_MS);
165
- const updatedStore = useWizardStore.getState();
166
- globalExpect(updatedStore.step).toBe("confirm");
167
- });
168
- it("should navigate to confirm on ENTER even with no agents selected", async () => {
169
- const store = useWizardStore.getState();
170
- store.setStep("agents");
171
- const { stdin, unmount } = render(/* @__PURE__ */ jsx(StepAgents, {}));
172
- cleanup = unmount;
173
- await delay(RENDER_DELAY_MS);
174
- await stdin.write(ENTER);
175
- await delay(INPUT_DELAY_MS);
176
- const updatedStore = useWizardStore.getState();
177
- globalExpect(updatedStore.step).toBe("confirm");
178
- });
179
- it("should go back on ESC", async () => {
180
- const store = useWizardStore.getState();
181
- store.setStep("sources");
182
- store.setStep("agents");
183
- const { stdin, unmount } = render(/* @__PURE__ */ jsx(StepAgents, {}));
184
- cleanup = unmount;
185
- await delay(RENDER_DELAY_MS);
186
- await stdin.write(ESCAPE);
187
- await delay(INPUT_DELAY_MS);
188
- const updatedStore = useWizardStore.getState();
189
- globalExpect(updatedStore.step).toBe("sources");
190
- });
191
- it("should toggle agent off when already selected", async () => {
192
- const store = useWizardStore.getState();
193
- store.toggleAgent("web-developer");
194
- const { stdin, unmount } = render(/* @__PURE__ */ jsx(StepAgents, {}));
195
- cleanup = unmount;
196
- await delay(RENDER_DELAY_MS);
197
- await stdin.write(SPACE);
198
- await delay(INPUT_DELAY_MS);
199
- const updatedStore = useWizardStore.getState();
200
- globalExpect(updatedStore.selectedAgents).not.toContain("web-developer");
201
- });
202
- });
203
- });
204
- //# sourceMappingURL=step-agents.test.js.map
@@ -1 +0,0 @@
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 { EMPTY_MATRIX } from \"../../lib/__tests__/mock-data/mock-matrices\";\nimport {\n ARROW_DOWN,\n ENTER,\n ESCAPE,\n INPUT_DELAY_MS,\n RENDER_DELAY_MS,\n SPACE,\n delay,\n} from \"../../lib/__tests__/test-constants\";\nimport { initializeMatrix } from \"../../lib/matrix/matrix-provider\";\nimport { useWizardStore } from \"../../stores/wizard-store\";\nimport { StepAgents } from \"./step-agents\";\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 agent group headers\", () => {\n const { lastFrame, unmount } = render(<StepAgents />);\n cleanup = unmount;\n\n const output = lastFrame();\n // ViewTitle removed; verify agent groups render (title shown by wizard-layout)\n expect(output).toContain(\"Web\");\n expect(output).toContain(\"API\");\n expect(output).toContain(\"Meta\");\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(\"Codex Keeper\");\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 expect(lastFrame()).toContain(\"Continue with 1 agent(s)\");\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":[]}