create-harness-vibe-coding 0.8.19 → 0.9.3

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 (656) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README-CN.md +4 -2
  3. package/README.md +23 -4
  4. package/package.json +17 -2
  5. package/src/generator.js +19 -6
  6. package/src/index.js +531 -38
  7. package/src/prompts.js +4 -4
  8. package/src/ui/dist/assets/AgentsRoute-BGGs90wH.js +7 -0
  9. package/src/ui/dist/assets/Assistant-Bold-gm-uSS1B.woff2 +0 -0
  10. package/src/ui/dist/assets/Assistant-Medium-DrcxCXg3.woff2 +0 -0
  11. package/src/ui/dist/assets/Assistant-Regular-DVxZuzxb.woff2 +0 -0
  12. package/src/ui/dist/assets/Assistant-SemiBold-SCI4bEL9.woff2 +0 -0
  13. package/src/ui/dist/assets/Combination-DhBLEmof.js +42 -0
  14. package/src/ui/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  15. package/src/ui/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  16. package/src/ui/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  17. package/src/ui/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  18. package/src/ui/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  19. package/src/ui/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  20. package/src/ui/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  21. package/src/ui/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  22. package/src/ui/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  23. package/src/ui/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  24. package/src/ui/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  25. package/src/ui/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  26. package/src/ui/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  27. package/src/ui/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  28. package/src/ui/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  29. package/src/ui/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  30. package/src/ui/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  31. package/src/ui/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  32. package/src/ui/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  33. package/src/ui/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  34. package/src/ui/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  35. package/src/ui/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  36. package/src/ui/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  37. package/src/ui/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  38. package/src/ui/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  39. package/src/ui/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  40. package/src/ui/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  41. package/src/ui/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  42. package/src/ui/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  43. package/src/ui/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  44. package/src/ui/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  45. package/src/ui/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  46. package/src/ui/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  47. package/src/ui/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  48. package/src/ui/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  49. package/src/ui/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  50. package/src/ui/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  51. package/src/ui/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  52. package/src/ui/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  53. package/src/ui/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  54. package/src/ui/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  55. package/src/ui/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  56. package/src/ui/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  57. package/src/ui/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  58. package/src/ui/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  59. package/src/ui/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  60. package/src/ui/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  61. package/src/ui/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  62. package/src/ui/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  63. package/src/ui/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  64. package/src/ui/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  65. package/src/ui/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  66. package/src/ui/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  67. package/src/ui/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  68. package/src/ui/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  69. package/src/ui/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  70. package/src/ui/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  71. package/src/ui/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  72. package/src/ui/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  73. package/src/ui/dist/assets/RolesRoute-DnodCSz0.js +2 -0
  74. package/src/ui/dist/assets/RuntimePicker-CucD8TGn.js +7 -0
  75. package/src/ui/dist/assets/SettingsRoute-DquMWjac.js +2 -0
  76. package/src/ui/dist/assets/TaskList-Bxc0Uktx.js +7 -0
  77. package/src/ui/dist/assets/TerminalDrawer-CDusYltc.js +36 -0
  78. package/src/ui/dist/assets/WorkflowRoute-BN8yHmUs.css +1 -0
  79. package/src/ui/dist/assets/WorkflowRoute-D-0wVDpY.js +334 -0
  80. package/src/ui/dist/assets/abnfDiagram-VRR7QNED-zkRKkaxO.js +2 -0
  81. package/src/ui/dist/assets/apl-B4CMkyY2.js +2 -0
  82. package/src/ui/dist/assets/ar-SA-G6X2FPQ2-BiHaArx5.js +11 -0
  83. package/src/ui/dist/assets/arc-CBnLtOFO.js +2 -0
  84. package/src/ui/dist/assets/architectureDiagram-ZJ3FMSHR-DWXRXsh1.js +37 -0
  85. package/src/ui/dist/assets/asciiarmor-Df11BRmG.js +2 -0
  86. package/src/ui/dist/assets/asn1-EdZsLKOL.js +2 -0
  87. package/src/ui/dist/assets/asterisk-B-8jnY81.js +2 -0
  88. package/src/ui/dist/assets/az-AZ-76LH7QW2-CiT05voO.js +2 -0
  89. package/src/ui/dist/assets/bg-BG-XCXSNQG7-L-UM9tNf.js +6 -0
  90. package/src/ui/dist/assets/blockDiagram-677ZJIJ3-BIyh3Bry.js +133 -0
  91. package/src/ui/dist/assets/bn-BD-2XOGV67Q-NdgbA0bC.js +6 -0
  92. package/src/ui/dist/assets/brainfuck-C4LP7Hcl.js +2 -0
  93. package/src/ui/dist/assets/c4Diagram-LMCZKHZV-CA54vWWM.js +11 -0
  94. package/src/ui/dist/assets/ca-ES-6MX7JW3Y-BKZZsQ5J.js +9 -0
  95. package/src/ui/dist/assets/channel-Da_-zcAu.js +2 -0
  96. package/src/ui/dist/assets/chunk-2Q5K7J3B-DE4cxr1v.js +2 -0
  97. package/src/ui/dist/assets/chunk-32BRIVSS-i7FwbEU9.js +2 -0
  98. package/src/ui/dist/assets/chunk-5VM5RSS4-BhIcOYSu.js +16 -0
  99. package/src/ui/dist/assets/chunk-EX3LRPZG-Ci9zZRIs.js +232 -0
  100. package/src/ui/dist/assets/chunk-JWPE2WC7-BFdkcz-G.js +2 -0
  101. package/src/ui/dist/assets/chunk-MOJQB5TN-Dzmapl_S.js +89 -0
  102. package/src/ui/dist/assets/chunk-RYQCIY6F-RTmp7FOy.js +2 -0
  103. package/src/ui/dist/assets/chunk-V7JOEXUC-DInU3v3D.js +207 -0
  104. package/src/ui/dist/assets/chunk-VR4S4FIN-BHoyGBQO.js +2 -0
  105. package/src/ui/dist/assets/chunk-XXDRQBXY-DfeLZNZx.js +2 -0
  106. package/src/ui/dist/assets/classDiagram-OUVF2IWQ-FKbUS0bu.js +2 -0
  107. package/src/ui/dist/assets/classDiagram-v2-EOCWNBFH-FKbUS0bu.js +2 -0
  108. package/src/ui/dist/assets/clike-B9uivgTg.js +2 -0
  109. package/src/ui/dist/assets/clojure-BMjYHr_A.js +2 -0
  110. package/src/ui/dist/assets/cmake-BQqOBYOt.js +2 -0
  111. package/src/ui/dist/assets/cobol-CWcv1MsR.js +2 -0
  112. package/src/ui/dist/assets/coffeescript-S37ZYGWr.js +2 -0
  113. package/src/ui/dist/assets/commonlisp-DBKNyK5s.js +2 -0
  114. package/src/ui/dist/assets/cose-bilkent-JH36ORCC-_5PUJ615.js +2 -0
  115. package/src/ui/dist/assets/crystal-SjHAIU92.js +2 -0
  116. package/src/ui/dist/assets/cs-CZ-2BRQDIVT-DnkfnhDU.js +12 -0
  117. package/src/ui/dist/assets/css-BnMrqG3P.js +2 -0
  118. package/src/ui/dist/assets/cynefin-VYW2F7L2-CmkcFv-b.js +179 -0
  119. package/src/ui/dist/assets/cynefinDiagram-TSTJHNR4-D72VZn8H.js +63 -0
  120. package/src/ui/dist/assets/cypher-C_CwsFkJ.js +2 -0
  121. package/src/ui/dist/assets/cytoscape.esm-DTSO7Bv0.js +332 -0
  122. package/src/ui/dist/assets/d-pRatUO7H.js +2 -0
  123. package/src/ui/dist/assets/da-DK-5WZEPLOC-C54tQUgd.js +6 -0
  124. package/src/ui/dist/assets/dagre-VKFMJZFB-0BsAkrmo.js +5 -0
  125. package/src/ui/dist/assets/de-DE-XR44H4JA-DGfZlR10.js +9 -0
  126. package/src/ui/dist/assets/defaultLocale-DX6XiGOO.js +2 -0
  127. package/src/ui/dist/assets/diagram-FQU43EPY-C1ZJDOca.js +4 -0
  128. package/src/ui/dist/assets/diagram-G47NLZAW-D3pr3FSP.js +25 -0
  129. package/src/ui/dist/assets/diagram-NH7WQ7WH-Bwry0NV-.js +25 -0
  130. package/src/ui/dist/assets/diagram-OA4YK3LP-L6g09cmV.js +31 -0
  131. package/src/ui/dist/assets/diagram-WEI45ONY-Bh1puYVX.js +42 -0
  132. package/src/ui/dist/assets/diff-DbItnlRl.js +2 -0
  133. package/src/ui/dist/assets/directory-open-01563666-DWU9wJ6I.js +2 -0
  134. package/src/ui/dist/assets/directory-open-4ed118d0-CunoC1EB.js +2 -0
  135. package/src/ui/dist/assets/dockerfile-BKs6k2Af.js +2 -0
  136. package/src/ui/dist/assets/dtd-DF_7sFjM.js +2 -0
  137. package/src/ui/dist/assets/dylan-DwRh75JA.js +2 -0
  138. package/src/ui/dist/assets/ebnf-CDyGwa7X.js +2 -0
  139. package/src/ui/dist/assets/ebnfDiagram-CCIWWBDH-BC_mBRR5.js +2 -0
  140. package/src/ui/dist/assets/ecl-Cabwm37j.js +2 -0
  141. package/src/ui/dist/assets/eiffel-CnydiIhH.js +2 -0
  142. package/src/ui/dist/assets/el-GR-BZB4AONW-DsnwWweL.js +11 -0
  143. package/src/ui/dist/assets/elm-vLlmbW-K.js +2 -0
  144. package/src/ui/dist/assets/erDiagram-Q63AITRT-Bkxam36l.js +86 -0
  145. package/src/ui/dist/assets/erlang-BNw1qcRV.js +2 -0
  146. package/src/ui/dist/assets/es-ES-U4NZUMDT-CRxBcQgC.js +10 -0
  147. package/src/ui/dist/assets/eu-ES-A7QVB2H4-CTd_E7YR.js +12 -0
  148. package/src/ui/dist/assets/excalidraw-default-bMWIgNCy.svg +1 -0
  149. package/src/ui/dist/assets/fa-IR-HGAKTJCU-DO56k7eG.js +9 -0
  150. package/src/ui/dist/assets/factor-kuTfRLto.js +2 -0
  151. package/src/ui/dist/assets/fcl-Kvtd6kyn.js +2 -0
  152. package/src/ui/dist/assets/fi-FI-Z5N7JZ37-DEDCF9WB.js +7 -0
  153. package/src/ui/dist/assets/file-open-002ab408-DIuFHtCF.js +2 -0
  154. package/src/ui/dist/assets/file-open-7c801643-684qeFg4.js +2 -0
  155. package/src/ui/dist/assets/file-save-3189631c-C1wFhQhH.js +2 -0
  156. package/src/ui/dist/assets/file-save-745eba88-Bb9F9Kg7.js +2 -0
  157. package/src/ui/dist/assets/flowDiagram-23GEKE2U-C3SAEao7.js +157 -0
  158. package/src/ui/dist/assets/forth-Ffai-XNe.js +2 -0
  159. package/src/ui/dist/assets/fortran-DYz_wnZ1.js +2 -0
  160. package/src/ui/dist/assets/fr-FR-RHASNOE6-DE2nPyDt.js +10 -0
  161. package/src/ui/dist/assets/ganttDiagram-NO4QXBWP-U-J_Xi-_.js +293 -0
  162. package/src/ui/dist/assets/gas-Bneqetm1.js +2 -0
  163. package/src/ui/dist/assets/gherkin-heZmZLOM.js +2 -0
  164. package/src/ui/dist/assets/gitGraphDiagram-IHSO6WYX-BADVbD-a.js +107 -0
  165. package/src/ui/dist/assets/gl-ES-HMX3MZ6V-mCqVgQHC.js +11 -0
  166. package/src/ui/dist/assets/graph-C9eacEi8.js +2 -0
  167. package/src/ui/dist/assets/groovy-D9Dt4D0W.js +2 -0
  168. package/src/ui/dist/assets/haskell-Cw1EW3IL.js +2 -0
  169. package/src/ui/dist/assets/haxe-H-WmDvRZ.js +2 -0
  170. package/src/ui/dist/assets/he-IL-6SHJWFNN-KnaLrCzw.js +11 -0
  171. package/src/ui/dist/assets/hi-IN-IWLTKZ5I-wuqiaaWt.js +5 -0
  172. package/src/ui/dist/assets/http-DBlCnlav.js +2 -0
  173. package/src/ui/dist/assets/hu-HU-A5ZG7DT2-DLg_zm22.js +8 -0
  174. package/src/ui/dist/assets/id-ID-SAP4L64H-MB2mXqcR.js +11 -0
  175. package/src/ui/dist/assets/idl-BEugSyMb.js +2 -0
  176. package/src/ui/dist/assets/image-blob-reduce.esm-HwCm7IZ0.js +8 -0
  177. package/src/ui/dist/assets/index-39SJtrt0.js +2 -0
  178. package/src/ui/dist/assets/index-BQ0LIrW-.js +2 -0
  179. package/src/ui/dist/assets/index-BcAUh2Nm.css +1 -0
  180. package/src/ui/dist/assets/index-BcThOK-i.js +331 -0
  181. package/src/ui/dist/assets/index-BnxV3k_S.js +3 -0
  182. package/src/ui/dist/assets/index-C7MZBHbT.js +117 -0
  183. package/src/ui/dist/assets/index-CCvKI2rM.js +2 -0
  184. package/src/ui/dist/assets/index-CZvmcCab.js +8 -0
  185. package/src/ui/dist/assets/index-Cp3hLKNl.js +2 -0
  186. package/src/ui/dist/assets/index-D7ayFxcx.js +2 -0
  187. package/src/ui/dist/assets/index-DAYxSQGU.js +2 -0
  188. package/src/ui/dist/assets/index-DD-HeMV0.css +1 -0
  189. package/src/ui/dist/assets/index-DPMxd3Qn.js +2 -0
  190. package/src/ui/dist/assets/index-DSe2jx3k.js +4 -0
  191. package/src/ui/dist/assets/index-DUirCkgW.js +2 -0
  192. package/src/ui/dist/assets/index-DaKPQ2hN.js +159 -0
  193. package/src/ui/dist/assets/index-DzpuR0Jg.js +2 -0
  194. package/src/ui/dist/assets/index-POndwsCI.js +2 -0
  195. package/src/ui/dist/assets/index-R8NM9I_9.js +2 -0
  196. package/src/ui/dist/assets/index-TCDuDhBj.js +2 -0
  197. package/src/ui/dist/assets/index-TckzASdM.js +2 -0
  198. package/src/ui/dist/assets/index-Yi5ytFFr.js +2 -0
  199. package/src/ui/dist/assets/infoDiagram-FWYZ7A6U-CiGBlFqH.js +3 -0
  200. package/src/ui/dist/assets/init-Gi6I4Gst.js +2 -0
  201. package/src/ui/dist/assets/ishikawaDiagram-FXEZZL3T-B1aheRbz.js +71 -0
  202. package/src/ui/dist/assets/it-IT-JPQ66NNP-DT3HSU7X.js +12 -0
  203. package/src/ui/dist/assets/ja-JP-DBVTYXUO-CsfJjjWt.js +9 -0
  204. package/src/ui/dist/assets/javascript-iXu5QeM3.js +2 -0
  205. package/src/ui/dist/assets/journeyDiagram-5HDEW3XC-DtnJPxub.js +140 -0
  206. package/src/ui/dist/assets/julia-DuME0IfC.js +2 -0
  207. package/src/ui/dist/assets/kaa-6HZHGXH3-DQz-1-Gn.js +2 -0
  208. package/src/ui/dist/assets/kab-KAB-ZGHBKWFO-CaH-LSoK.js +9 -0
  209. package/src/ui/dist/assets/kanban-definition-HUTT4EX6-CZatSm3e.js +90 -0
  210. package/src/ui/dist/assets/katex-C5jXJg4s.js +258 -0
  211. package/src/ui/dist/assets/kk-KZ-P5N5QNE5-BMXmcm55.js +2 -0
  212. package/src/ui/dist/assets/km-KH-HSX4SM5Z-ZeoJNBpN.js +12 -0
  213. package/src/ui/dist/assets/ko-KR-MTYHY66A-BeaLRKph.js +10 -0
  214. package/src/ui/dist/assets/ku-TR-6OUDTVRD-B_28KrkR.js +10 -0
  215. package/src/ui/dist/assets/layout-DEXfKzaS.js +2 -0
  216. package/src/ui/dist/assets/linear-CpEDnQRC.js +2 -0
  217. package/src/ui/dist/assets/livescript-BwQOo05w.js +2 -0
  218. package/src/ui/dist/assets/lt-LT-XHIRWOB4-BxDcnUhp.js +4 -0
  219. package/src/ui/dist/assets/lua-VAEuO923.js +2 -0
  220. package/src/ui/dist/assets/lv-LV-5QDEKY6T-DpKDl1_y.js +8 -0
  221. package/src/ui/dist/assets/map-Czzmt4hB.js +2 -0
  222. package/src/ui/dist/assets/mathematica-DTrFuWx2.js +2 -0
  223. package/src/ui/dist/assets/mbox-CNhZ1qSd.js +2 -0
  224. package/src/ui/dist/assets/mermaidLoader-CBO31t0J.js +305 -0
  225. package/src/ui/dist/assets/mermaidLoader-CEK31ho9.css +1 -0
  226. package/src/ui/dist/assets/mindmap-definition-LN4V7U3C-CQ0TccEr.js +97 -0
  227. package/src/ui/dist/assets/mirc-CjQqDB4T.js +2 -0
  228. package/src/ui/dist/assets/mllike-CXdrOF99.js +2 -0
  229. package/src/ui/dist/assets/modelica-Dc1JOy9r.js +2 -0
  230. package/src/ui/dist/assets/mr-IN-CRQNXWMA-BKCZT58p.js +14 -0
  231. package/src/ui/dist/assets/mscgen-BA5vi2Kp.js +2 -0
  232. package/src/ui/dist/assets/mumps-BT43cFF4.js +2 -0
  233. package/src/ui/dist/assets/my-MM-5M5IBNSE-D34k0G9T.js +2 -0
  234. package/src/ui/dist/assets/nb-NO-T6EIAALU-DXr_KW8J.js +11 -0
  235. package/src/ui/dist/assets/nginx-DdIZxoE0.js +2 -0
  236. package/src/ui/dist/assets/nl-NL-IS3SIHDZ-C1L0aVDR.js +9 -0
  237. package/src/ui/dist/assets/nn-NO-6E72VCQL-CLWVSxbZ.js +9 -0
  238. package/src/ui/dist/assets/nsis-LdVXkNf5.js +2 -0
  239. package/src/ui/dist/assets/ntriples-BfvgReVJ.js +2 -0
  240. package/src/ui/dist/assets/oc-FR-POXYY2M6-nf8_J3eR.js +9 -0
  241. package/src/ui/dist/assets/octave-Ck1zUtKM.js +2 -0
  242. package/src/ui/dist/assets/ordinal-Cboi1Yqb.js +2 -0
  243. package/src/ui/dist/assets/oz-BzwKVEFT.js +2 -0
  244. package/src/ui/dist/assets/pa-IN-N4M65BXN-CAMJ-xd6.js +5 -0
  245. package/src/ui/dist/assets/pascal--L3eBynH.js +2 -0
  246. package/src/ui/dist/assets/pegDiagram-2B236MQR-Bj2RcmRd.js +2 -0
  247. package/src/ui/dist/assets/percentages-BXMCSKIN-s9yWFdr6.js +160 -0
  248. package/src/ui/dist/assets/perl-CdXCOZ3F.js +2 -0
  249. package/src/ui/dist/assets/pica-BGv_AhAB.js +8 -0
  250. package/src/ui/dist/assets/pieDiagram-ENE6RG2P-obpzz8dC.js +40 -0
  251. package/src/ui/dist/assets/pig-CevX1Tat.js +2 -0
  252. package/src/ui/dist/assets/pl-PL-T2D74RX3-DKJ5H85v.js +10 -0
  253. package/src/ui/dist/assets/powershell-CFHJl5sT.js +2 -0
  254. package/src/ui/dist/assets/properties-C78fOPTZ.js +2 -0
  255. package/src/ui/dist/assets/protobuf-ChK-085T.js +2 -0
  256. package/src/ui/dist/assets/{proxy-D0vUbds5.js → proxy-BSmwef4H.js} +2 -2
  257. package/src/ui/dist/assets/pt-BR-5N22H2LF-B5kow-kN.js +10 -0
  258. package/src/ui/dist/assets/pt-PT-UZXXM6DQ-B2G34fso.js +10 -0
  259. package/src/ui/dist/assets/pug-DeIclll2.js +2 -0
  260. package/src/ui/dist/assets/puppet-DMA9R1ak.js +2 -0
  261. package/src/ui/dist/assets/python-BuPzkPfP.js +2 -0
  262. package/src/ui/dist/assets/q-pXgVlZs6.js +2 -0
  263. package/src/ui/dist/assets/quadrantDiagram-ABIIQ3AL-Cl-T7NkJ.js +8 -0
  264. package/src/ui/dist/assets/r-B6wPVr8A.js +2 -0
  265. package/src/ui/dist/assets/railroadDiagram-RFXS5EU6-DMq82RHg.js +2 -0
  266. package/src/ui/dist/assets/{refresh-cw-JNmExijd.js → refresh-cw-CbFd7guV.js} +2 -2
  267. package/src/ui/dist/assets/requirementDiagram-TGXJPOKE-tGInMDgU.js +85 -0
  268. package/src/ui/dist/assets/ro-RO-JPDTUUEW-BwLdZW91.js +12 -0
  269. package/src/ui/dist/assets/roundRect-0PYZxl1G.js +2 -0
  270. package/src/ui/dist/assets/rpm-CTu-6PCP.js +2 -0
  271. package/src/ui/dist/assets/ru-RU-B4JR7IUQ-DpdAgIJc.js +10 -0
  272. package/src/ui/dist/assets/ruby-B2Rjki9n.js +2 -0
  273. package/src/ui/dist/assets/runtimeBrand-BoKPimsz.js +2 -0
  274. package/src/ui/dist/assets/sankeyDiagram-HTMAVEWB-C7X-ET4m.js +41 -0
  275. package/src/ui/dist/assets/sas-B4kiWyti.js +2 -0
  276. package/src/ui/dist/assets/save-D1CXHwBw.js +12 -0
  277. package/src/ui/dist/assets/scheme-C41bIUwD.js +2 -0
  278. package/src/ui/dist/assets/sequenceDiagram-DBY2YBRQ-Bn24i_nY.js +163 -0
  279. package/src/ui/dist/assets/settings-2-DtSNAAcU.js +22 -0
  280. package/src/ui/dist/assets/shell-CjFT_Tl9.js +2 -0
  281. package/src/ui/dist/assets/shield-check-BVbJ8T_N.js +7 -0
  282. package/src/ui/dist/assets/si-LK-N5RQ5JYF-naJaUy5u.js +2 -0
  283. package/src/ui/dist/assets/sieve-C3Gn_uJK.js +2 -0
  284. package/src/ui/dist/assets/simple-mode-GW_nhZxv.js +2 -0
  285. package/src/ui/dist/assets/sizeCapture-X5ZJPWSS-DAQHfm82.js +2 -0
  286. package/src/ui/dist/assets/sk-SK-C5VTKIMK-1NPz1J_d.js +7 -0
  287. package/src/ui/dist/assets/sl-SI-NN7IZMDC-D8RfmNQw.js +7 -0
  288. package/src/ui/dist/assets/smalltalk-CnHTOXQT.js +2 -0
  289. package/src/ui/dist/assets/solr-DehyRSwq.js +2 -0
  290. package/src/ui/dist/assets/sparql-DkYu6x3z.js +2 -0
  291. package/src/ui/dist/assets/spreadsheet-BCZA_wO0.js +2 -0
  292. package/src/ui/dist/assets/sql-D0XecflT.js +2 -0
  293. package/src/ui/dist/assets/stateDiagram-2N3HPSRC-Ck48D1ck.js +2 -0
  294. package/src/ui/dist/assets/stateDiagram-v2-6OUMAXLB-CdfRCJAJ.js +2 -0
  295. package/src/ui/dist/assets/stex-C3f8Ysf7.js +2 -0
  296. package/src/ui/dist/assets/style-C3QI7VPf.css +1 -0
  297. package/src/ui/dist/assets/stylus-B533Al4x.js +2 -0
  298. package/src/ui/dist/assets/subset-shared.chunk-eAtLHmbi.js +85 -0
  299. package/src/ui/dist/assets/subset-worker.chunk-DeHCTnTk.js +2 -0
  300. package/src/ui/dist/assets/sv-SE-XGPEYMSR-BeOYCU-8.js +11 -0
  301. package/src/ui/dist/assets/swift-BzpIVaGY.js +2 -0
  302. package/src/ui/dist/assets/swimlanes-5IMT3BWC-DOy22UjP.js +3 -0
  303. package/src/ui/dist/assets/swimlanesDiagram-G3AALYLV-sicPbVOg.js +9 -0
  304. package/src/ui/dist/assets/ta-IN-2NMHFXQM-CtS68WDd.js +10 -0
  305. package/src/ui/dist/assets/tcl-DVfN8rqt.js +2 -0
  306. package/src/ui/dist/assets/{terminal-BBQvnOAK.js → terminal-DEby5Y_P.js} +2 -2
  307. package/src/ui/dist/assets/terminalControl-BkFeDVXo.js +134 -0
  308. package/src/ui/dist/assets/textile-CnDTJFAw.js +2 -0
  309. package/src/ui/dist/assets/th-TH-HPSO5L25-DCHY9-Co.js +3 -0
  310. package/src/ui/dist/assets/tiddlywiki-DO-Gjzrf.js +2 -0
  311. package/src/ui/dist/assets/tiki-DGYXhP31.js +2 -0
  312. package/src/ui/dist/assets/timeline-definition-FHXFAJF6-DVkG72qO.js +121 -0
  313. package/src/ui/dist/assets/toml-Bm5Em-hy.js +2 -0
  314. package/src/ui/dist/assets/tr-TR-DEFEU3FU-y5-vjTv8.js +8 -0
  315. package/src/ui/dist/assets/troff-wAsdV37c.js +2 -0
  316. package/src/ui/dist/assets/ttcn-CfJYG6tj.js +2 -0
  317. package/src/ui/dist/assets/ttcn-cfg-B9xdYoR4.js +2 -0
  318. package/src/ui/dist/assets/turtle-B1tBg_DP.js +2 -0
  319. package/src/ui/dist/assets/uk-UA-QMV73CPH-BRbR5It6.js +7 -0
  320. package/src/ui/dist/assets/useReducedMotion-D07XP52Q.js +12 -0
  321. package/src/ui/dist/assets/vb-CmGdzxic.js +2 -0
  322. package/src/ui/dist/assets/vbscript-BuJXcnF6.js +2 -0
  323. package/src/ui/dist/assets/velocity-D8B20fx6.js +2 -0
  324. package/src/ui/dist/assets/vennDiagram-L72KCM5P-DwMwBlf-.js +35 -0
  325. package/src/ui/dist/assets/verilog-C6RDOZhf.js +2 -0
  326. package/src/ui/dist/assets/vhdl-lSbBsy5d.js +2 -0
  327. package/src/ui/dist/assets/vi-VN-M7AON7JQ-s6wSBv2s.js +6 -0
  328. package/src/ui/dist/assets/wardleyDiagram-EHGQE667-CNuuvzEg.js +79 -0
  329. package/src/ui/dist/assets/webidl-ZXfAyPTL.js +2 -0
  330. package/src/ui/dist/assets/{x-DoIOGAJz.js → x-B84wq78k.js} +2 -2
  331. package/src/ui/dist/assets/xquery-DzFWVndE.js +2 -0
  332. package/src/ui/dist/assets/xychartDiagram-FW5EYKEG-dUpZxmn6.js +8 -0
  333. package/src/ui/dist/assets/yacas-BJ4BC0dw.js +2 -0
  334. package/src/ui/dist/assets/z80-Hz9HOZM7.js +2 -0
  335. package/src/ui/dist/assets/zh-CN-LNUGB5OW-Cu_-POQN.js +11 -0
  336. package/src/ui/dist/assets/zh-HK-E62DVLB3-BCx4W4qZ.js +2 -0
  337. package/src/ui/dist/assets/zh-TW-RAJ6MFWO-02wx_Mrj.js +10 -0
  338. package/src/ui/dist/icons/excalidraw.svg +1 -0
  339. package/src/ui/dist/icons/markdown.svg +1 -0
  340. package/src/ui/dist/index.html +2 -2
  341. package/src/ui/package.json +10 -0
  342. package/src/ui/playwright.config.ts +36 -0
  343. package/src/ui/pnpm-workspace.yaml +2 -0
  344. package/src/ui/public/icons/excalidraw.svg +1 -0
  345. package/src/ui/public/icons/markdown.svg +1 -0
  346. package/src/ui/tsconfig.json +2 -1
  347. package/src/ui/vite.config.ts +1 -0
  348. package/src/wf-ui-server/__tests__/a2a-store.test.mjs +432 -15
  349. package/src/wf-ui-server/__tests__/action-registry-loader.test.mjs +156 -0
  350. package/src/wf-ui-server/__tests__/claude-stream-json.test.mjs +397 -0
  351. package/src/wf-ui-server/__tests__/codex-appserver.test.mjs +392 -0
  352. package/src/wf-ui-server/__tests__/component-node-api.test.mjs +881 -0
  353. package/src/wf-ui-server/__tests__/component-node-store.test.mjs +401 -0
  354. package/src/wf-ui-server/__tests__/control-plane-acceptance.test.mjs +2027 -0
  355. package/src/wf-ui-server/__tests__/control-plane-cli-smoke.test.mjs +1014 -0
  356. package/src/wf-ui-server/__tests__/dispatch-lifecycle.test.mjs +330 -0
  357. package/src/wf-ui-server/__tests__/effort-compatibility-red-092.test.mjs +151 -0
  358. package/src/wf-ui-server/__tests__/graph-layout-agent-tree.test.mjs +254 -0
  359. package/src/wf-ui-server/__tests__/graph-layout-tidy.test.mjs +260 -0
  360. package/src/wf-ui-server/__tests__/graph-layout.test.mjs +84 -0
  361. package/src/wf-ui-server/__tests__/node-config-api.test.mjs +384 -0
  362. package/src/wf-ui-server/__tests__/opencode-server.test.mjs +526 -0
  363. package/src/wf-ui-server/__tests__/peer-capsule.test.mjs +2 -2
  364. package/src/wf-ui-server/__tests__/pty-adapter.test.mjs +71 -1
  365. package/src/wf-ui-server/__tests__/runtime-config.test.mjs +3 -3
  366. package/src/wf-ui-server/__tests__/runtime-detector.test.mjs +21 -0
  367. package/src/wf-ui-server/__tests__/runtime-review.test.mjs +828 -0
  368. package/src/wf-ui-server/__tests__/server.integration.test.mjs +1463 -11
  369. package/src/wf-ui-server/__tests__/session-cleanup.test.mjs +159 -0
  370. package/src/wf-ui-server/__tests__/session-registry.test.mjs +52 -3
  371. package/src/wf-ui-server/__tests__/settings.test.mjs +12 -2
  372. package/src/wf-ui-server/__tests__/spawn-gate.test.mjs +78 -0
  373. package/src/wf-ui-server/__tests__/task-group-parser.test.mjs +120 -0
  374. package/src/wf-ui-server/__tests__/task-group-tag.test.mjs +264 -0
  375. package/src/wf-ui-server/__tests__/task-parser.test.mjs +49 -3
  376. package/src/wf-ui-server/__tests__/terminal-context-hardening.test.mjs +122 -0
  377. package/src/wf-ui-server/__tests__/terminal-context.test.mjs +164 -0
  378. package/src/wf-ui-server/__tests__/terminal-store.test.mjs +4 -4
  379. package/src/wf-ui-server/__tests__/wf-browser-api.test.mjs +599 -0
  380. package/src/wf-ui-server/__tests__/wf-browser-store.test.mjs +184 -0
  381. package/src/wf-ui-server/__tests__/workflow-action-registry.test.mjs +282 -0
  382. package/src/wf-ui-server/__tests__/workflow-agent-communication.test.mjs +411 -0
  383. package/src/wf-ui-server/__tests__/workflow-agent-context.test.mjs +323 -0
  384. package/src/wf-ui-server/__tests__/workflow-agent-cooperation-permissions.test.mjs +318 -0
  385. package/src/wf-ui-server/__tests__/workflow-agent-messages-structured.test.mjs +458 -0
  386. package/src/wf-ui-server/__tests__/workflow-agent-routing.test.mjs +434 -0
  387. package/src/wf-ui-server/__tests__/workflow-agent-runtime.test.mjs +324 -0
  388. package/src/wf-ui-server/__tests__/workflow-api-integration.test.mjs +263 -0
  389. package/src/wf-ui-server/__tests__/workflow-api-phase3.test.mjs +1213 -0
  390. package/src/wf-ui-server/__tests__/workflow-claude-materialize.test.mjs +209 -0
  391. package/src/wf-ui-server/__tests__/workflow-cli-registry-manuals.test.mjs +173 -0
  392. package/src/wf-ui-server/__tests__/workflow-cli-surface.test.mjs +176 -0
  393. package/src/wf-ui-server/__tests__/workflow-codex-resume-id.test.mjs +556 -0
  394. package/src/wf-ui-server/__tests__/workflow-cooperation-enforcement.test.mjs +553 -0
  395. package/src/wf-ui-server/__tests__/workflow-depth-resume-dock.test.mjs +846 -0
  396. package/src/wf-ui-server/__tests__/workflow-display-node.test.mjs +150 -0
  397. package/src/wf-ui-server/__tests__/workflow-edge-update.test.mjs +296 -0
  398. package/src/wf-ui-server/__tests__/workflow-file-cache-lock-watch.test.mjs +380 -0
  399. package/src/wf-ui-server/__tests__/workflow-file-formats.test.mjs +994 -0
  400. package/src/wf-ui-server/__tests__/workflow-file-node-actions.test.mjs +294 -0
  401. package/src/wf-ui-server/__tests__/workflow-goal-actions.test.mjs +357 -0
  402. package/src/wf-ui-server/__tests__/workflow-goal-task-autoclose.test.mjs +256 -0
  403. package/src/wf-ui-server/__tests__/workflow-graceful-stop.test.mjs +108 -0
  404. package/src/wf-ui-server/__tests__/workflow-graph-undo.test.mjs +524 -0
  405. package/src/wf-ui-server/__tests__/workflow-layout.test.mjs +732 -0
  406. package/src/wf-ui-server/__tests__/workflow-magnetic-topology.test.mjs +222 -0
  407. package/src/wf-ui-server/__tests__/workflow-markdown-lock.test.mjs +359 -0
  408. package/src/wf-ui-server/__tests__/workflow-mcp-hub.test.mjs +174 -0
  409. package/src/wf-ui-server/__tests__/workflow-node-manual-schema.test.mjs +241 -0
  410. package/src/wf-ui-server/__tests__/workflow-node-runtime.test.mjs +1991 -0
  411. package/src/wf-ui-server/__tests__/workflow-node-store-utils.test.mjs +125 -0
  412. package/src/wf-ui-server/__tests__/workflow-registry-drift.test.mjs +296 -0
  413. package/src/wf-ui-server/__tests__/workflow-resource-handle-four-side.test.mjs +217 -0
  414. package/src/wf-ui-server/__tests__/workflow-role-profile.test.mjs +234 -0
  415. package/src/wf-ui-server/__tests__/workflow-set-model.test.mjs +261 -0
  416. package/src/wf-ui-server/__tests__/workflow-skill-group-context-enabled.test.mjs +131 -0
  417. package/src/wf-ui-server/__tests__/workflow-skill-group-enable-disable.test.mjs +186 -0
  418. package/src/wf-ui-server/__tests__/workflow-skills-hub.test.mjs +125 -0
  419. package/src/wf-ui-server/__tests__/workflow-state-reconcile.test.mjs +139 -0
  420. package/src/wf-ui-server/__tests__/workflow-subagent-strategy-matrix.test.mjs +529 -0
  421. package/src/wf-ui-server/__tests__/workflow-team-flow.test.mjs +278 -0
  422. package/src/wf-ui-server/__tests__/workflow-terminal-control-live.test.mjs +294 -0
  423. package/src/wf-ui-server/__tests__/workflow-terminal-control.test.mjs +631 -0
  424. package/src/wf-ui-server/__tests__/workflow-timer-wakeup.test.mjs +318 -0
  425. package/src/wf-ui-server/__tests__/workflow-unified-resume.test.mjs +537 -0
  426. package/src/wf-ui-server/__tests__/workspace-api-hardening.test.mjs +187 -0
  427. package/src/wf-ui-server/__tests__/workspace-api.test.mjs +382 -0
  428. package/src/wf-ui-server/__tests__/workspace-reveal.test.mjs +138 -0
  429. package/src/wf-ui-server/__tests__/workspace-store-hardening.test.mjs +255 -0
  430. package/src/wf-ui-server/__tests__/workspace-store.test.mjs +208 -0
  431. package/src/wf-ui-server/__tests__/ws-events.integration.test.mjs +52 -25
  432. package/src/wf-ui-server/__tests__/ws-terminal.integration.test.mjs +12 -6
  433. package/src/wf-ui-server/__tests__/ws-wf-browser.integration.test.mjs +488 -0
  434. package/src/wf-ui-server/a2a-store.mjs +3007 -89
  435. package/src/wf-ui-server/action-registry.mjs +277 -0
  436. package/src/wf-ui-server/bridge-store.mjs +276 -0
  437. package/src/wf-ui-server/chat-driver.mjs +220 -0
  438. package/src/wf-ui-server/chat-store.mjs +109 -0
  439. package/src/wf-ui-server/claude-transcript-materializer.mjs +235 -0
  440. package/src/wf-ui-server/codex-update-prompt.mjs +53 -0
  441. package/src/wf-ui-server/component-node-store.mjs +689 -0
  442. package/src/wf-ui-server/composition-api.mjs +436 -0
  443. package/src/wf-ui-server/control-plane-token.mjs +17 -0
  444. package/src/wf-ui-server/dispatch-contract.mjs +150 -0
  445. package/src/wf-ui-server/drivers/claude-stream-json.mjs +371 -0
  446. package/src/wf-ui-server/drivers/codex-appserver.mjs +513 -0
  447. package/src/wf-ui-server/drivers/opencode-server.mjs +486 -0
  448. package/src/wf-ui-server/excalidraw-svg.mjs +141 -0
  449. package/src/wf-ui-server/file-format-adapters.mjs +511 -0
  450. package/src/wf-ui-server/file-watcher.mjs +215 -0
  451. package/src/wf-ui-server/graph-layout.mjs +778 -0
  452. package/src/wf-ui-server/harness-env.mjs +46 -0
  453. package/src/wf-ui-server/json-store-utils.mjs +48 -0
  454. package/src/wf-ui-server/model-capability.mjs +773 -0
  455. package/src/wf-ui-server/node-config-store.mjs +233 -0
  456. package/src/wf-ui-server/node-store-utils.mjs +88 -0
  457. package/src/wf-ui-server/peer-capsule.mjs +56 -1
  458. package/src/wf-ui-server/pty-adapter.mjs +513 -11
  459. package/src/wf-ui-server/reveal-foreground.mjs +69 -0
  460. package/src/wf-ui-server/runtime-detector.mjs +52 -6
  461. package/src/wf-ui-server/server.mjs +5613 -403
  462. package/src/wf-ui-server/session-cleanup.mjs +363 -0
  463. package/src/wf-ui-server/session-registry.mjs +179 -3
  464. package/src/wf-ui-server/settings.mjs +25 -0
  465. package/src/wf-ui-server/spawn-gate.mjs +46 -0
  466. package/src/wf-ui-server/task-parser.mjs +88 -3
  467. package/src/wf-ui-server/terminal-store.mjs +225 -11
  468. package/src/wf-ui-server/timer-wakeup-scheduler.mjs +226 -0
  469. package/src/wf-ui-server/wf-browser-store.mjs +733 -0
  470. package/src/wf-ui-server/workflow-agent-context.mjs +1731 -0
  471. package/src/wf-ui-server/workflow-capability-node-store.mjs +676 -0
  472. package/src/wf-ui-server/workflow-event-node-store.mjs +623 -0
  473. package/src/wf-ui-server/workflow-goal-node-store.mjs +328 -0
  474. package/src/wf-ui-server/workflow-graph-store.mjs +623 -0
  475. package/src/wf-ui-server/workflow-mcp-hub.mjs +286 -0
  476. package/src/wf-ui-server/workflow-node-runtime.mjs +1767 -0
  477. package/src/wf-ui-server/workflow-node-settings-store.mjs +339 -0
  478. package/src/wf-ui-server/workflow-node-types/agent-node.mjs +920 -0
  479. package/src/wf-ui-server/workflow-node-types/display-node.mjs +151 -0
  480. package/src/wf-ui-server/workflow-node-types/excalidraw-node.mjs +145 -0
  481. package/src/wf-ui-server/workflow-node-types/file-node.mjs +484 -0
  482. package/src/wf-ui-server/workflow-node-types/github-trigger-node.mjs +207 -0
  483. package/src/wf-ui-server/workflow-node-types/goal-node.mjs +491 -0
  484. package/src/wf-ui-server/workflow-node-types/markdown-node.mjs +225 -0
  485. package/src/wf-ui-server/workflow-node-types/mcp-connector-node.mjs +71 -0
  486. package/src/wf-ui-server/workflow-node-types/role-profile-store.mjs +191 -0
  487. package/src/wf-ui-server/workflow-node-types/skill-group-node.mjs +98 -0
  488. package/src/wf-ui-server/workflow-node-types/timer-node.mjs +607 -0
  489. package/src/wf-ui-server/workflow-ontology.mjs +681 -0
  490. package/src/wf-ui-server/workflow-operation-store.mjs +115 -0
  491. package/src/wf-ui-server/workflow-skills-hub.mjs +366 -0
  492. package/src/wf-ui-server/workflow-skills-market.mjs +723 -0
  493. package/src/wf-ui-server/workspace-store.mjs +951 -0
  494. package/src/wf-ui-server/ws-chat.mjs +299 -0
  495. package/src/wf-ui-server/ws-events.mjs +45 -20
  496. package/src/wf-ui-server/ws-terminal.mjs +165 -22
  497. package/src/wf-ui-server/ws-wf-browser.mjs +419 -0
  498. package/templates/common/.claude/agents/review-manager.md +33 -29
  499. package/templates/common/.claude/commands/wf-browser.md +1 -1
  500. package/templates/common/.claude/commands/wf-help.md +5 -3
  501. package/templates/common/.claude/commands/wf-init.md +44 -0
  502. package/templates/common/.claude/commands/wf-learn.md +34 -8
  503. package/templates/common/.claude/commands/wf-max.md +19 -9
  504. package/templates/common/.claude/commands/wf-review.md +3 -3
  505. package/templates/common/.claude/commands/wf-search.md +55 -0
  506. package/templates/common/.claude/commands/wf-task-archive.md +5 -4
  507. package/templates/common/.claude/commands/wf-task-list.md +6 -3
  508. package/templates/common/.claude/commands/wf-task-record.md +10 -2
  509. package/templates/common/.claude/commands/wf-ui.md +12 -5
  510. package/templates/common/.claude/commands/wf-update.md +4 -0
  511. package/templates/common/.claude/commands/wf.md +12 -1
  512. package/templates/common/.claude/rules/ecc/common.md +10 -1
  513. package/templates/common/.claude/skills/wf/SKILL.md +36 -0
  514. package/templates/common/.claude/skills/wf-browser/SKILL.md +427 -122
  515. package/templates/common/.claude/skills/wf-browser/references/BROWSER_CONTROL_PATTERNS.md +43 -0
  516. package/templates/common/.claude/skills/wf-init/SKILL.md +33 -0
  517. package/templates/common/.claude/skills/wf-learn/SKILL.md +106 -26
  518. package/templates/common/.claude/skills/wf-max/SKILL.md +45 -11
  519. package/templates/common/.claude/skills/wf-review/SKILL.md +26 -54
  520. package/templates/common/.claude/skills/wf-search/SKILL.md +122 -0
  521. package/templates/common/.claude/skills/wf-search/references/evidence-contract.md +77 -0
  522. package/templates/common/.claude/skills/wf-search/references/policies/compare.md +38 -0
  523. package/templates/common/.claude/skills/wf-search/references/policies/fact.md +39 -0
  524. package/templates/common/.claude/skills/wf-search/references/policies/troubleshoot.md +39 -0
  525. package/templates/common/.claude/skills/wf-search/references/policies/verify.md +44 -0
  526. package/templates/common/.claude/skills/wf-search/references/source-routing.md +40 -0
  527. package/templates/common/.claude/skills/wf-search/references/tool-adapters.md +38 -0
  528. package/templates/common/.claude/skills/wf-ui/SKILL.md +146 -12
  529. package/templates/common/.claude/skills/wf-update/SKILL.md +5 -1
  530. package/templates/common/.harness-version +188 -85
  531. package/templates/common/.opencode/agents/review-manager.md +31 -27
  532. package/templates/common/.opencode/commands/wf-browser.md +1 -1
  533. package/templates/common/.opencode/commands/wf-help.md +5 -3
  534. package/templates/common/.opencode/commands/wf-init.md +44 -0
  535. package/templates/common/.opencode/commands/wf-learn.md +34 -8
  536. package/templates/common/.opencode/commands/wf-max.md +19 -9
  537. package/templates/common/.opencode/commands/wf-review.md +3 -3
  538. package/templates/common/.opencode/commands/wf-search.md +55 -0
  539. package/templates/common/.opencode/commands/wf-task-archive.md +5 -7
  540. package/templates/common/.opencode/commands/wf-task-list.md +6 -6
  541. package/templates/common/.opencode/commands/wf-task-record.md +10 -5
  542. package/templates/common/.opencode/commands/wf-ui.md +12 -5
  543. package/templates/common/.opencode/commands/wf-update.md +4 -0
  544. package/templates/common/.opencode/commands/wf.md +12 -1
  545. package/templates/common/CLAUDE.md +61 -3
  546. package/templates/common/Harness/MEMORY.md +8 -5
  547. package/templates/common/Harness/README.md +14 -10
  548. package/templates/common/Harness/a2a/action-registry.json +4397 -0
  549. package/templates/common/Harness/a2a/role-graph.json +16 -3
  550. package/templates/common/Harness/a2a/skills/terminal-control.json +45 -1
  551. package/templates/common/Harness/a2a/skills/wf-ui-map.json +50 -0
  552. package/templates/common/Harness/a2a/skills/workflow-agent-node.json +143 -0
  553. package/templates/common/Harness/a2a/skills/workflow-context.json +95 -0
  554. package/templates/common/Harness/a2a/skills/workflow-diagram-node.json +60 -0
  555. package/templates/common/Harness/a2a/skills/workflow-display-node.json +69 -0
  556. package/templates/common/Harness/a2a/skills/workflow-file-node.json +92 -0
  557. package/templates/common/Harness/a2a/skills/workflow-goal-node.json +76 -0
  558. package/templates/common/Harness/a2a/skills/workflow-markdown-node.json +79 -0
  559. package/templates/common/Harness/a2a/skills/workflow-mcp-connector-node.json +59 -0
  560. package/templates/common/Harness/a2a/skills/workflow-node-actions.json +105 -0
  561. package/templates/common/Harness/a2a/skills/workflow-node-map.json +71 -0
  562. package/templates/common/Harness/a2a/skills/workflow-ontology.json +54 -0
  563. package/templates/common/Harness/a2a/skills/workflow-resource-node.json +68 -0
  564. package/templates/common/Harness/a2a/skills/workflow-skill-group-node.json +56 -0
  565. package/templates/common/Harness/a2a/skills/workflow-timer-node.json +81 -0
  566. package/templates/common/Harness/a2a/workflows.json +33 -0
  567. package/templates/common/Harness/ownership.manifest.json +263 -2
  568. package/templates/common/Harness/project/architecture.md +499 -0
  569. package/templates/common/Harness/research/README.md +20 -0
  570. package/templates/common/Harness/scripts/README.md +70 -6
  571. package/templates/common/Harness/scripts/a2a-terminal.mjs +12 -4
  572. package/templates/common/Harness/scripts/context-budget.mjs +7 -3
  573. package/templates/common/Harness/scripts/lib/memory-context.mjs +400 -0
  574. package/templates/common/Harness/scripts/lib/path-scope.mjs +77 -0
  575. package/templates/common/Harness/scripts/lib/research-policy.mjs +99 -0
  576. package/templates/common/Harness/scripts/lib/wf-search.mjs +189 -0
  577. package/templates/common/Harness/scripts/memory-context.mjs +63 -0
  578. package/templates/common/Harness/scripts/research-policy.mjs +27 -0
  579. package/templates/common/Harness/scripts/task-context.mjs +547 -0
  580. package/templates/common/Harness/scripts/task-group-index.mjs +242 -0
  581. package/templates/common/Harness/scripts/task-state.mjs +659 -95
  582. package/templates/common/Harness/scripts/validate-harness.mjs +70 -28
  583. package/templates/common/Harness/scripts/wf-auto-update-prompt.mjs +24 -0
  584. package/templates/common/Harness/scripts/wf-remove.mjs +10 -0
  585. package/templates/common/Harness/scripts/wf-search.mjs +10 -0
  586. package/templates/common/Harness/scripts/wf-ui-control.mjs +3144 -0
  587. package/templates/common/Harness/scripts/wf-update-check.mjs +274 -51
  588. package/templates/common/Harness/scripts/wf-update-runner.mjs +53 -16
  589. package/templates/common/Harness/settings.json +10 -0
  590. package/templates/common/Harness/specs/guides/SETUP.md +4 -3
  591. package/templates/common/Harness/specs/protocols/HARNESS_BRIDGE.md +429 -48
  592. package/templates/common/Harness/specs/protocols/MEMORY_PROTOCOL.md +24 -0
  593. package/templates/common/Harness/specs/protocols/TASK_ARCHIVE.md +14 -11
  594. package/templates/common/Harness/specs/runtime/command-surface.json +28 -0
  595. package/templates/common/Harness/specs/runtime/context-loading.md +6 -0
  596. package/templates/common/Harness/specs/runtime/dispatch.md +9 -1
  597. package/templates/common/Harness/specs/runtime/subagents.md +20 -5
  598. package/templates/common/Harness/specs/workflows/WF-AUTO-SPARK.md +19 -0
  599. package/templates/common/Harness/specs/workflows/WF-AUTO.md +21 -0
  600. package/templates/common/Harness/specs/workflows/WF-KERNEL.md +4 -2
  601. package/templates/common/Harness/specs/workflows/WF-MAX.md +39 -12
  602. package/templates/common/Harness/specs/workflows/WF-STATE.md +62 -14
  603. package/templates/common/Harness/specs/workflows/WF.md +32 -0
  604. package/templates/common/Harness/tasks/INDEX.json +7 -0
  605. package/templates/common/Harness/tasks/INDEX.md +12 -0
  606. package/templates/common/Harness/tasks/_template/PLAN.md +6 -0
  607. package/templates/common/Harness/tasks/_template/PROGRESS.md +5 -0
  608. package/templates/common/Harness/tasks/_template/STATE.json +22 -0
  609. package/templates/common/Harness/templates/TEST_PLAN.template.md +5 -4
  610. package/templates/common/Harness/templates/UI_CONTRACT.template.md +7 -5
  611. package/templates/common/Harness/wf-browser/README.md +69 -0
  612. package/templates/common/README.md +17 -0
  613. package/src/ui/dist/assets/AgentsRoute-CuSKYmFu.js +0 -17
  614. package/src/ui/dist/assets/AgentsRoute-CuSKYmFu.js.map +0 -1
  615. package/src/ui/dist/assets/RolesRoute-DOzTYVRm.js +0 -7
  616. package/src/ui/dist/assets/RolesRoute-DOzTYVRm.js.map +0 -1
  617. package/src/ui/dist/assets/SettingsRoute-DPU7jSQm.js +0 -12
  618. package/src/ui/dist/assets/SettingsRoute-DPU7jSQm.js.map +0 -1
  619. package/src/ui/dist/assets/TaskList-BN4r8s1i.js +0 -50
  620. package/src/ui/dist/assets/TaskList-BN4r8s1i.js.map +0 -1
  621. package/src/ui/dist/assets/TerminalDrawer-Cej4PxsH.js +0 -74
  622. package/src/ui/dist/assets/TerminalDrawer-Cej4PxsH.js.map +0 -1
  623. package/src/ui/dist/assets/WorkflowRoute-BnuhLJ6X.css +0 -1
  624. package/src/ui/dist/assets/WorkflowRoute-C-clKe-j.js +0 -39
  625. package/src/ui/dist/assets/WorkflowRoute-C-clKe-j.js.map +0 -1
  626. package/src/ui/dist/assets/index-BOVYWntB.js +0 -117
  627. package/src/ui/dist/assets/index-BOVYWntB.js.map +0 -1
  628. package/src/ui/dist/assets/index-DaUObq0H.css +0 -1
  629. package/src/ui/dist/assets/maximize-2-LNrr_rKr.js +0 -7
  630. package/src/ui/dist/assets/maximize-2-LNrr_rKr.js.map +0 -1
  631. package/src/ui/dist/assets/plus-QuTJyoT3.js +0 -7
  632. package/src/ui/dist/assets/plus-QuTJyoT3.js.map +0 -1
  633. package/src/ui/dist/assets/proxy-D0vUbds5.js.map +0 -1
  634. package/src/ui/dist/assets/refresh-cw-JNmExijd.js.map +0 -1
  635. package/src/ui/dist/assets/terminal-BBQvnOAK.js.map +0 -1
  636. package/src/ui/dist/assets/useReducedMotion-BqmH0Tf7.js +0 -7
  637. package/src/ui/dist/assets/useReducedMotion-BqmH0Tf7.js.map +0 -1
  638. package/src/ui/dist/assets/x-DoIOGAJz.js.map +0 -1
  639. package/src/ui/pnpm-lock.yaml +0 -1582
  640. package/src/ui/src/App.tsx +0 -86
  641. package/src/ui/src/api.ts +0 -93
  642. package/src/ui/src/components/AgentsRoute.tsx +0 -503
  643. package/src/ui/src/components/Footer.tsx +0 -69
  644. package/src/ui/src/components/Header.tsx +0 -175
  645. package/src/ui/src/components/LoadingView.tsx +0 -22
  646. package/src/ui/src/components/RolesRoute.tsx +0 -169
  647. package/src/ui/src/components/SettingsRoute.tsx +0 -166
  648. package/src/ui/src/components/TaskList.tsx +0 -388
  649. package/src/ui/src/components/TerminalDrawer.tsx +0 -611
  650. package/src/ui/src/components/WorkflowRoute.tsx +0 -670
  651. package/src/ui/src/hooks/useReducedMotion.ts +0 -17
  652. package/src/ui/src/hooks/useServerConnection.ts +0 -114
  653. package/src/ui/src/index.css +0 -281
  654. package/src/ui/src/main.tsx +0 -11
  655. package/src/ui/src/types.ts +0 -108
  656. /package/src/ui/dist/assets/{TerminalDrawer-6GBZ9nXN.css → terminalControl-6GBZ9nXN.css} +0 -0
@@ -0,0 +1,209 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { makeHarnessTempRoot } from '../../../tests/support/temp-root.js';
6
+ import {
7
+ encodeClaudeProjectDir,
8
+ extractConversationTurns,
9
+ buildClaudeTranscript,
10
+ materializeClaudeTranscript,
11
+ } from '../claude-transcript-materializer.mjs';
12
+
13
+ // Fixtures mirror the real terminal.jsonl shapes captured from a live claude
14
+ // harness session (RESUME-E2E-EVIDENCE.md PASS 3, session dae0424d): char-by-char
15
+ // stdin, "❯ " prompt echo, spinner/progress stdout, "●answer✻Verb for Xs❯ " reply.
16
+
17
+ let seq = 0;
18
+ function entry(stream, data) {
19
+ return { seq: ++seq, ts: new Date().toISOString(), stream, data };
20
+ }
21
+ function typePrompt(text) {
22
+ const entries = [];
23
+ for (const ch of text) entries.push(entry('stdin', ch));
24
+ entries.push(entry('stdin', '\r'));
25
+ return entries;
26
+ }
27
+ function ansi(text) {
28
+ return `\x1b[38;2;87;105;247m${text}\x1b[39m`;
29
+ }
30
+
31
+ const PROMPT_A = 'Reply with exactly one word: plum';
32
+ const REPLY_A = ansi('✢thinking with max effort Thought for 9s ●plum✻Baked for 9s❯ ');
33
+ const PROMPT_B = 'What was the one word I asked you to reply?';
34
+ const ECHO_B = `❯ ${PROMPT_B}`;
35
+ const REPLY_B = ansi('Thought for 5s ●plum✻Worked for 5s❯ ');
36
+
37
+ function singleTurnEntries() {
38
+ return [...typePrompt(PROMPT_A), entry('stdout', REPLY_A)];
39
+ }
40
+
41
+ test('U1 single turn: prompt from stdin chars, answer from ● bullet', () => {
42
+ const turns = extractConversationTurns(singleTurnEntries());
43
+ assert.equal(turns.length, 1);
44
+ assert.deepEqual(turns[0], { user: PROMPT_A, assistant: 'plum' });
45
+ });
46
+
47
+ test('U2 multi-turn: next prompt echo does not leak into previous answer', () => {
48
+ const entries = [
49
+ ...typePrompt(PROMPT_A),
50
+ entry('stdout', REPLY_A),
51
+ entry('stdout', ECHO_B), // echo of turn 2 leaks into turn 1 stdout segment
52
+ ...typePrompt(PROMPT_B),
53
+ entry('stdout', REPLY_B),
54
+ ];
55
+ const turns = extractConversationTurns(entries);
56
+ assert.equal(turns.length, 2);
57
+ assert.equal(turns[0].assistant, 'plum');
58
+ assert.deepEqual(turns[1], { user: PROMPT_B, assistant: 'plum' });
59
+ });
60
+
61
+ test('U3 slash commands are control input, not conversation turns', () => {
62
+ const entries = [
63
+ ...typePrompt('/model'),
64
+ entry('stdout', 'model picker'),
65
+ ...singleTurnEntries(),
66
+ ];
67
+ const turns = extractConversationTurns(entries);
68
+ assert.equal(turns.length, 1);
69
+ assert.equal(turns[0].user, PROMPT_A);
70
+ });
71
+
72
+ test('U4 boot-only session (no submitted prompt) yields no turns', () => {
73
+ const turns = extractConversationTurns([
74
+ entry('stdin', 'R'),
75
+ entry('stdout', 'Claude Code v2.1.215'),
76
+ entry('stdin', 'e'),
77
+ ]);
78
+ assert.deepEqual(turns, []);
79
+ });
80
+
81
+ test('U10 promptSubmit shape: one full-prompt stdin entry, no CR in the ring', () => {
82
+ // The promptSubmit path types char-by-char at the PTY level and sends the enter
83
+ // as a raw write, so the ring holds ONE stdin entry with the whole prompt and
84
+ // the turn bracket is the only delimiter (real E2E shape, session d9245593).
85
+ const entries = [
86
+ entry('stdin', PROMPT_A),
87
+ entry('stdout', ansi(`❯ ${PROMPT_A}`)), // composer echo
88
+ entry('stdout', ansi('✢thinking with max effort')),
89
+ entry('stdout', ansi('●mango✻Crunched for 5s❯ ')),
90
+ ];
91
+ const turns = extractConversationTurns(entries);
92
+ assert.equal(turns.length, 1);
93
+ assert.deepEqual(turns[0], { user: PROMPT_A, assistant: 'mango' });
94
+ });
95
+
96
+ test('U8 answer cleanup: verb tail, spinner glyphs, thinking preview, multi-bullet', () => {
97
+ const entries = [
98
+ ...typePrompt(PROMPT_A),
99
+ entry('stdout', ansi('Thought for 3s\n⎿ thinking preview line\n● item one\n● item two✻Baked for 3s❯ ')),
100
+ ];
101
+ const turns = extractConversationTurns(entries);
102
+ assert.equal(turns.length, 1);
103
+ // the second ● is a list marker inside the answer — kept as rendered
104
+ assert.equal(turns[0].assistant, 'item one\n● item two');
105
+ });
106
+
107
+ test('U5 buildClaudeTranscript: every line valid JSON, schema-faithful type sequence', () => {
108
+ const sessionId = '11111111-2222-3333-4444-555555555555';
109
+ const content = buildClaudeTranscript({
110
+ sessionId,
111
+ cwd: 'D:\\MyFile\\sample',
112
+ turns: [{ user: PROMPT_A, assistant: 'plum' }],
113
+ });
114
+ const lines = content.trim().split('\n').map((line) => JSON.parse(line));
115
+ assert.deepEqual(
116
+ lines.map((line) => line.type),
117
+ ['last-prompt', 'mode', 'permission-mode', 'user', 'assistant', 'last-prompt', 'mode', 'permission-mode', 'last-prompt'],
118
+ );
119
+ for (const line of lines) {
120
+ if (line.sessionId !== undefined) assert.equal(line.sessionId, sessionId);
121
+ if (line.session_id !== undefined) assert.equal(line.session_id, sessionId);
122
+ assert.notEqual(JSON.stringify(line).includes('undefined'), true);
123
+ }
124
+ const userLine = lines.find((line) => line.type === 'user');
125
+ const assistantLine = lines.find((line) => line.type === 'assistant');
126
+ assert.equal(userLine.message.content, PROMPT_A);
127
+ assert.equal(assistantLine.message.content[0].text, 'plum');
128
+ const finalLine = lines[lines.length - 1];
129
+ assert.equal(finalLine.lastPrompt, PROMPT_A);
130
+ });
131
+
132
+ test('U6 materializeClaudeTranscript writes into the encoded project dir', () => {
133
+ const home = makeHarnessTempRoot('claude-mat-');
134
+ const sessionId = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';
135
+ try {
136
+ const result = materializeClaudeTranscript({
137
+ home,
138
+ cwd: 'D:\\MyFile\\sample',
139
+ sessionId,
140
+ entries: singleTurnEntries(),
141
+ });
142
+ assert.ok(result);
143
+ assert.equal(result.turns, 1);
144
+ const expectedPath = path.join(home, '.claude', 'projects', 'D--MyFile-sample', `${sessionId}.jsonl`);
145
+ assert.equal(result.path, expectedPath);
146
+ assert.equal(result.bytes, fs.statSync(expectedPath).size);
147
+ // uuids/timestamps are per-build, so compare structure + content, not bytes
148
+ const onDisk = fs.readFileSync(expectedPath, 'utf8').trim().split('\n').map((line) => JSON.parse(line));
149
+ assert.deepEqual(
150
+ onDisk.map((line) => line.type),
151
+ ['last-prompt', 'mode', 'permission-mode', 'user', 'assistant', 'last-prompt', 'mode', 'permission-mode', 'last-prompt'],
152
+ );
153
+ for (const line of onDisk) {
154
+ if (line.sessionId !== undefined) assert.equal(line.sessionId, sessionId);
155
+ if (line.session_id !== undefined) assert.equal(line.session_id, sessionId);
156
+ }
157
+ assert.equal(onDisk.find((line) => line.type === 'user').message.content, PROMPT_A);
158
+ assert.equal(onDisk.find((line) => line.type === 'assistant').message.content[0].text, 'plum');
159
+ assert.equal(onDisk[onDisk.length - 1].lastPrompt, PROMPT_A);
160
+ } finally {
161
+ fs.rmSync(home, { recursive: true, force: true });
162
+ }
163
+ });
164
+
165
+ test('U7 no turns: materialize returns null and writes nothing', () => {
166
+ const home = makeHarnessTempRoot('claude-mat-');
167
+ try {
168
+ const result = materializeClaudeTranscript({
169
+ home,
170
+ cwd: 'D:\\MyFile\\sample',
171
+ sessionId: 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
172
+ entries: [entry('stdin', 'R'), entry('stdout', 'boot banner')],
173
+ });
174
+ assert.equal(result, null);
175
+ assert.equal(fs.existsSync(path.join(home, '.claude')), false);
176
+ } finally {
177
+ fs.rmSync(home, { recursive: true, force: true });
178
+ }
179
+ });
180
+
181
+ test('U12 a "❯" inside the answer (quoted shell prompt) is preserved, not a turn-over', () => {
182
+ const entries = [
183
+ ...typePrompt(PROMPT_A),
184
+ entry('stdout', ansi('●Try: ❯ npm run dev, or check the docs✻Baked for 4s❯ ')),
185
+ ];
186
+ const turns = extractConversationTurns(entries);
187
+ assert.equal(turns.length, 1);
188
+ assert.equal(turns[0].assistant, 'Try: ❯ npm run dev, or check the docs');
189
+ });
190
+
191
+ test('U13 ready marker without verb tail: next prompt input closes the turn', () => {
192
+ const entries = [
193
+ ...typePrompt(PROMPT_A),
194
+ entry('stdout', ansi('●done❯ ')), // ready "❯" but no "✻Verb for Xs" tail
195
+ ...typePrompt(PROMPT_B),
196
+ entry('stdout', REPLY_B),
197
+ ];
198
+ const turns = extractConversationTurns(entries);
199
+ assert.equal(turns.length, 2);
200
+ assert.deepEqual(turns[0], { user: PROMPT_A, assistant: 'done' });
201
+ assert.deepEqual(turns[1], { user: PROMPT_B, assistant: 'plum' });
202
+ });
203
+
204
+ test('U9 encodeClaudeProjectDir matches the real claude encoding', () => {
205
+ assert.equal(
206
+ encodeClaudeProjectDir('D:\\MyFile\\sample\\synchronous-github\\zingspark\\create-harness-vibe-coding'),
207
+ 'D--MyFile-sample-synchronous-github-zingspark-create-harness-vibe-coding',
208
+ );
209
+ });
@@ -0,0 +1,173 @@
1
+ // CLI shared-action-registry + manuals tests (wf-ui-control.mjs).
2
+ //
3
+ // Proves two CLI surface additions:
4
+ // 1. `help --json` merges the shared action registry
5
+ // (Harness/a2a/action-registry.json) into its machine-readable output as
6
+ // an `actions` array, and sets `actionsFallback: true` (no `actions` key)
7
+ // when the registry file is absent from the project.
8
+ // 2. `manuals <nodeType>` prints the node manual JSON plus generated
9
+ // `id — summary` command lines derived from the registry, and
10
+ // `manuals --list` enumerates the valid manual types.
11
+ // T6 asserts the template mirror of the CLI stays byte-identical.
12
+ import { describe, it, before, after } from 'node:test';
13
+ import assert from 'node:assert/strict';
14
+ import fs from 'node:fs';
15
+ import path from 'node:path';
16
+ import { spawn } from 'node:child_process';
17
+ import { makeHarnessTempRoot } from '../../../tests/support/temp-root.js';
18
+
19
+ const REPO_ROOT = process.cwd();
20
+
21
+ // Spawn a real `node Harness/scripts/wf-ui-control.mjs <command>` process.
22
+ // Resolves with { status, stdout, stderr }; stdout is the parsed JSON object
23
+ // when the CLI printed JSON, otherwise the raw string.
24
+ function runWfUi(args, { cwd, env = {}, timeout = 15000 } = {}) {
25
+ return new Promise((resolve, reject) => {
26
+ const script = path.join(cwd, 'Harness', 'scripts', 'wf-ui-control.mjs');
27
+ const child = spawn(process.execPath, [script, ...args], {
28
+ cwd,
29
+ env: { ...process.env, ...env },
30
+ windowsHide: true,
31
+ stdio: ['ignore', 'pipe', 'pipe'],
32
+ });
33
+ let stdout = '';
34
+ let stderr = '';
35
+ const timer = setTimeout(() => {
36
+ child.kill();
37
+ reject(new Error(`wf-ui-control timeout: ${args.join(' ')}`));
38
+ }, timeout);
39
+ child.stdout.on('data', (chunk) => { stdout += chunk; });
40
+ child.stderr.on('data', (chunk) => { stderr += chunk; });
41
+ child.on('error', reject);
42
+ child.on('close', (status) => {
43
+ clearTimeout(timer);
44
+ let parsed = stdout.trim();
45
+ try {
46
+ parsed = JSON.parse(parsed);
47
+ } catch {
48
+ // Non-JSON output (e.g. help text) is left as the raw string.
49
+ }
50
+ resolve({ status, stdout: parsed, stderr });
51
+ });
52
+ });
53
+ }
54
+
55
+ // ── Fixtures ────────────────────────────────────────────────────────────────
56
+
57
+ let tempRoot;
58
+
59
+ // Temp project without a Harness/a2a/action-registry.json (used by T2 to
60
+ // prove the actionsFallback marker).
61
+ before(() => {
62
+ tempRoot = makeHarnessTempRoot('wf-cli-registry-manuals-');
63
+ });
64
+
65
+ after(() => {
66
+ if (!tempRoot) return;
67
+ const resolved = path.resolve(tempRoot);
68
+ const tempRootDir = path.resolve('Harness', '.temp') + path.sep;
69
+ assert.ok(resolved.startsWith(tempRootDir), `refusing to remove non-temp root: ${resolved}`);
70
+ try {
71
+ fs.rmSync(resolved, { recursive: true, force: true, maxRetries: 25, retryDelay: 200 });
72
+ } catch (e) {
73
+ // Windows may briefly hold session files after server close; tolerate.
74
+ if (process.platform === 'win32' && ['EPERM', 'EBUSY', 'ENOTEMPTY'].includes(e?.code)) return;
75
+ throw e;
76
+ }
77
+ });
78
+
79
+ // ── T1: help --json merges the shared action registry ───────────────────────
80
+
81
+ describe('help --json merges the shared action registry', () => {
82
+ it('T1: includes the actions array with agent.sendMessage mapped to its CLI command', async () => {
83
+ const result = await runWfUi(['help', '--json'], { cwd: REPO_ROOT });
84
+ assert.equal(result.status, 0, `help --json failed: ${result.stderr}`);
85
+ assert.ok(result.stdout && typeof result.stdout === 'object', `non-JSON stdout: ${result.stdout}`);
86
+ assert.ok(Array.isArray(result.stdout.commands), 'must return a commands array');
87
+ assert.ok(Array.isArray(result.stdout.actions), 'must return an actions array from the shared registry');
88
+ assert.ok(!('actionsFallback' in result.stdout), 'must not set actionsFallback when the registry is present');
89
+
90
+ const sendMessage = result.stdout.actions.find(action => action.id === 'agent.sendMessage');
91
+ assert.ok(sendMessage, `actions must include agent.sendMessage: ${result.stdout.actions.map(a => a.id).join(', ')}`);
92
+ assert.equal(sendMessage.command, 'send-agent-message');
93
+ assert.ok(typeof sendMessage.summary === 'string' && sendMessage.summary.length > 0, 'entry must carry a summary');
94
+ assert.ok(Array.isArray(sendMessage.flags), 'entry must carry a flags array');
95
+ });
96
+ });
97
+
98
+ // ── T2: help --json without a registry file ─────────────────────────────────
99
+
100
+ describe('help --json without a registry file', () => {
101
+ it('T2: marks actionsFallback and omits the actions key', async () => {
102
+ const result = await runWfUi(['help', '--json', '--project', tempRoot], { cwd: REPO_ROOT });
103
+ assert.equal(result.status, 0, `help --json --project failed: ${result.stderr}`);
104
+ assert.equal(result.stdout.actionsFallback, true, 'must set actionsFallback when the registry is missing');
105
+ assert.ok(!('actions' in result.stdout), 'must omit the actions key when the registry is missing');
106
+ assert.ok(Array.isArray(result.stdout.commands), 'commands must still be present');
107
+ });
108
+ });
109
+
110
+ // ── T3/T4/T5: manuals command ───────────────────────────────────────────────
111
+
112
+ describe('manuals command', () => {
113
+ it('T3: prints the timer manual and generated command lines', async () => {
114
+ const result = await runWfUi(['manuals', 'timer'], { cwd: REPO_ROOT });
115
+ assert.equal(result.status, 0, `manuals timer failed: ${result.stderr}`);
116
+ assert.ok(result.stdout && typeof result.stdout === 'object', `non-JSON stdout: ${result.stdout}`);
117
+ assert.equal(result.stdout.type, 'timer');
118
+ assert.ok(result.stdout.manual && typeof result.stdout.manual === 'object', 'must carry the full manual');
119
+ assert.match(String(result.stdout.manual.description || ''), /Timer nodes/i, 'must carry the timer manual description');
120
+ assert.ok(Array.isArray(result.stdout.commands), 'must carry a generated commands array');
121
+ assert.ok(
122
+ result.stdout.commands.some(line => line.startsWith('timer.read —')),
123
+ 'commands must include a timer.read line',
124
+ );
125
+ assert.ok(
126
+ result.stdout.commands.some(line => line.startsWith('timer.configure —')),
127
+ 'commands must include a timer.configure line',
128
+ );
129
+ });
130
+
131
+ it('T3b: excalidraw resolves to the diagram manual with excalidraw action lines', async () => {
132
+ const result = await runWfUi(['manuals', 'excalidraw'], { cwd: REPO_ROOT });
133
+ assert.equal(result.status, 0, `manuals excalidraw failed: ${result.stderr}`);
134
+ assert.equal(result.stdout.type, 'diagram', 'excalidraw must resolve to the diagram manual type');
135
+ assert.match(String(result.stdout.manual.description || ''), /Diagram nodes/i, 'must carry the diagram manual description');
136
+ assert.ok(
137
+ result.stdout.commands.some(line => line.startsWith('excalidraw.readScene —')),
138
+ 'commands must include excalidraw action lines for the alias',
139
+ );
140
+ });
141
+
142
+ it('T4: --list enumerates all manual types including the diagram alias', async () => {
143
+ const result = await runWfUi(['manuals', '--list'], { cwd: REPO_ROOT });
144
+ assert.equal(result.status, 0, `manuals --list failed: ${result.stderr}`);
145
+ assert.ok(Array.isArray(result.stdout.types), 'must return a types array');
146
+ for (const type of ['agent', 'markdown', 'excalidraw', 'file', 'timer', 'goal', 'skill-group', 'mcp-connector', 'github-trigger', 'diagram']) {
147
+ assert.ok(result.stdout.types.includes(type), `types must include ${type}`);
148
+ }
149
+ assert.deepEqual(result.stdout.alias, { excalidraw: 'diagram' });
150
+ });
151
+
152
+ it('T5: unknown type fails with a valid-types list and non-zero exit', async () => {
153
+ const result = await runWfUi(['manuals', 'unknown-type'], { cwd: REPO_ROOT });
154
+ assert.notEqual(result.status, 0, 'must exit non-zero for an unknown type');
155
+ assert.match(
156
+ result.stderr,
157
+ /Valid types: agent\|markdown\|excalidraw\|file\|display\|timer\|goal\|skill-group\|mcp-connector\|github-trigger\|diagram/,
158
+ );
159
+ });
160
+ });
161
+
162
+ // ── T6: template mirror parity ──────────────────────────────────────────────
163
+
164
+ describe('template mirror parity', () => {
165
+ it('T6: the CLI file and its template mirror are byte-identical', () => {
166
+ const cli = fs.readFileSync(path.join(REPO_ROOT, 'Harness', 'scripts', 'wf-ui-control.mjs'));
167
+ const mirror = fs.readFileSync(path.join(REPO_ROOT, 'templates', 'common', 'Harness', 'scripts', 'wf-ui-control.mjs'));
168
+ assert.ok(
169
+ cli.equals(mirror),
170
+ 'Harness/scripts/wf-ui-control.mjs and templates/common/Harness/scripts/wf-ui-control.mjs must be byte-identical',
171
+ );
172
+ });
173
+ });
@@ -0,0 +1,176 @@
1
+ // Workflow CLI surface tests (wf-ui-control.mjs).
2
+ //
3
+ // Proves the machine-readable command registry (`help --json`) and the
4
+ // send-key keystroke primitive. Each test spawns a genuine
5
+ // `node Harness/scripts/wf-ui-control.mjs <command>` subprocess against a
6
+ // copied CLI script, so it exercises exactly what an Agent node would run.
7
+ // Help/registry tests need no backend; send-key posts to a local recording
8
+ // HTTP server that captures the request bodies.
9
+ import { describe, it, before, after } from 'node:test';
10
+ import assert from 'node:assert/strict';
11
+ import fs from 'node:fs';
12
+ import http from 'node:http';
13
+ import path from 'node:path';
14
+ import { spawn } from 'node:child_process';
15
+ import { makeHarnessTempRoot } from '../../../tests/support/temp-root.js';
16
+
17
+ // ── CLI runner ──────────────────────────────────────────────────────────────
18
+
19
+ // Spawn a real `node Harness/scripts/wf-ui-control.mjs <command>` process.
20
+ // Resolves with { status, stdout, stderr }; stdout is the parsed JSON object
21
+ // when the CLI printed JSON, otherwise the raw string (e.g. help text).
22
+ function runWfUi(args, { cwd, env = {}, timeout = 15000 } = {}) {
23
+ return new Promise((resolve, reject) => {
24
+ const script = path.join(cwd, 'Harness', 'scripts', 'wf-ui-control.mjs');
25
+ const child = spawn(process.execPath, [script, ...args], {
26
+ cwd,
27
+ env: { ...process.env, ...env },
28
+ windowsHide: true,
29
+ stdio: ['ignore', 'pipe', 'pipe'],
30
+ });
31
+ let stdout = '';
32
+ let stderr = '';
33
+ const timer = setTimeout(() => {
34
+ child.kill();
35
+ reject(new Error(`wf-ui-control timeout: ${args.join(' ')}`));
36
+ }, timeout);
37
+ child.stdout.on('data', (chunk) => { stdout += chunk; });
38
+ child.stderr.on('data', (chunk) => { stderr += chunk; });
39
+ child.on('error', reject);
40
+ child.on('close', (status) => {
41
+ clearTimeout(timer);
42
+ let parsed = stdout.trim();
43
+ try {
44
+ parsed = JSON.parse(parsed);
45
+ } catch {
46
+ // Non-JSON output (e.g. help text) is left as the raw string.
47
+ }
48
+ resolve({ status, stdout: parsed, stderr });
49
+ });
50
+ });
51
+ }
52
+
53
+ // ── Fixtures ────────────────────────────────────────────────────────────────
54
+
55
+ let tempRoot;
56
+
57
+ // Identity environment every spawned Agent CLI runs with: the actor is a
58
+ // Main Agent node, so the CLI main-agent gates (assertMainAgent) pass.
59
+ const AGENT_ENV = { HARNESS_AGENT_KIND: 'main' };
60
+
61
+ before(() => {
62
+ tempRoot = makeHarnessTempRoot('wf-cli-surface-');
63
+ const dest = path.join(tempRoot, 'Harness', 'scripts', 'wf-ui-control.mjs');
64
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
65
+ fs.copyFileSync(path.join(process.cwd(), 'Harness', 'scripts', 'wf-ui-control.mjs'), dest);
66
+ });
67
+
68
+ after(() => {
69
+ if (!tempRoot) return;
70
+ const resolved = path.resolve(tempRoot);
71
+ const tempRootDir = path.resolve('Harness', '.temp') + path.sep;
72
+ assert.ok(resolved.startsWith(tempRootDir), `refusing to remove non-temp root: ${resolved}`);
73
+ try {
74
+ fs.rmSync(resolved, { recursive: true, force: true, maxRetries: 25, retryDelay: 200 });
75
+ } catch (e) {
76
+ // Windows may briefly hold session files after server close; tolerate.
77
+ if (process.platform === 'win32' && ['EPERM', 'EBUSY', 'ENOTEMPTY'].includes(e?.code)) return;
78
+ throw e;
79
+ }
80
+ });
81
+
82
+ // ── T1: help --json dumps the full machine-readable registry ───────────────
83
+
84
+ describe('help --json registry', () => {
85
+ it('prints a valid JSON registry with the core commands and their flags', async () => {
86
+ const result = await runWfUi(['help', '--json'], { cwd: tempRoot });
87
+ assert.equal(result.status, 0, `help --json failed: ${result.stderr}`);
88
+ assert.ok(result.stdout && typeof result.stdout === 'object', `non-JSON stdout: ${result.stdout}`);
89
+ assert.ok(Array.isArray(result.stdout.commands), 'must return a commands array');
90
+
91
+ const byName = new Map(result.stdout.commands.map(entry => [entry.name, entry]));
92
+ for (const required of ['create-agent', 'send-input', 'send-agent-message', 'send-key']) {
93
+ const entry = byName.get(required);
94
+ assert.ok(entry, `commands must include ${required}: ${result.stdout.commands.map(c => c.name).join(', ')}`);
95
+ assert.ok(typeof entry.summary === 'string' && entry.summary.length > 0, `${required} must carry a summary`);
96
+ assert.ok(Array.isArray(entry.aliases), `${required} must carry an aliases array`);
97
+ assert.ok(Array.isArray(entry.flags), `${required} must carry a flags array`);
98
+ }
99
+
100
+ const createAgent = byName.get('create-agent');
101
+ assert.ok(
102
+ createAgent.flags.some(flag => flag.flag === 'initial-prompt'),
103
+ 'create-agent must list the initial-prompt flag',
104
+ );
105
+ });
106
+ });
107
+
108
+ // ── T2: help <command> --json prints one command entry ─────────────────────
109
+
110
+ describe('help <command> --json', () => {
111
+ it('prints a single command entry with flags', async () => {
112
+ const result = await runWfUi(['help', 'send-input', '--json'], { cwd: tempRoot });
113
+ assert.equal(result.status, 0, `help send-input --json failed: ${result.stderr}`);
114
+ assert.equal(result.stdout.name, 'send-input');
115
+ assert.ok(typeof result.stdout.summary === 'string' && result.stdout.summary.length > 0, 'entry must carry a summary');
116
+ assert.ok(Array.isArray(result.stdout.flags), 'entry must carry flags');
117
+ assert.ok(result.stdout.flags.some(flag => flag.flag === 'session'), 'send-input must list the session flag');
118
+ assert.ok(result.stdout.flags.some(flag => flag.flag === 'text'), 'send-input must list the text flag');
119
+ });
120
+ });
121
+
122
+ // ── T3: plain-text help parity (no regression) ──────────────────────────────
123
+
124
+ describe('plain help parity', () => {
125
+ it('create-agent --help still lists --initial-prompt', async () => {
126
+ const result = await runWfUi(['create-agent', '--help'], { cwd: tempRoot });
127
+ assert.equal(result.status, 0, `create-agent --help failed: ${result.stderr}`);
128
+ const text = String(result.stdout);
129
+ assert.match(text, /Usage: wf-ui-control\.mjs create-agent \[flags\]/);
130
+ assert.match(text, /--initial-prompt/, 'create-agent help must still show --initial-prompt');
131
+ });
132
+ });
133
+
134
+ // ── T4: send-key keystroke primitive ───────────────────────────────────────
135
+
136
+ describe('send-key keystroke primitive', () => {
137
+ it('maps named keys to raw bytes posted to the session input endpoint', async () => {
138
+ const requests = [];
139
+ const server = http.createServer((req, res) => {
140
+ let raw = '';
141
+ req.on('data', (chunk) => { raw += chunk; });
142
+ req.on('end', () => {
143
+ let body = null;
144
+ try { body = raw ? JSON.parse(raw) : null; } catch { /* record raw */ }
145
+ requests.push({ method: req.method, url: req.url, body });
146
+ res.writeHead(200, { 'Content-Type': 'application/json' });
147
+ res.end('{"ok":true}');
148
+ });
149
+ });
150
+ await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve));
151
+ const baseUrl = `http://127.0.0.1:${server.address().port}`;
152
+ const expectMap = {
153
+ up: '\x1b[A',
154
+ down: '\x1b[B',
155
+ enter: '\r',
156
+ esc: '\x1b',
157
+ backspace: '\x7f',
158
+ };
159
+ try {
160
+ for (const [key, expected] of Object.entries(expectMap)) {
161
+ const result = await runWfUi(
162
+ ['send-key', key, '--session', 'sess-live-1', '--url', baseUrl],
163
+ { cwd: tempRoot, env: AGENT_ENV },
164
+ );
165
+ assert.equal(result.status, 0, `send-key ${key} failed: ${result.stderr}`);
166
+ const last = requests[requests.length - 1];
167
+ assert.equal(last.method, 'POST', `${key}: must POST to the input endpoint`);
168
+ assert.equal(last.url, '/api/sessions/sess-live-1/input', `${key}: must target the session input endpoint`);
169
+ assert.equal(last.body.data, expected, `${key}: raw data bytes must match the terminal mapping`);
170
+ assert.equal(last.body.raw, true, `${key}: raw flag must be true`);
171
+ }
172
+ } finally {
173
+ await new Promise((resolve) => server.close(resolve));
174
+ }
175
+ });
176
+ });