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
package/src/index.js CHANGED
@@ -7,9 +7,12 @@ import pc from 'picocolors';
7
7
  import { askConflictPolicy, askInstallScope, askOptionalSelections, askProjectName, askTargetDir } from './prompts.js';
8
8
  import { generate, getOptionalCatalog } from './generator.js';
9
9
 
10
- const UPDATE_SUCCESS_STATUSES = new Set(['up-to-date', 'update-available', 'partial-update']);
11
- const UPDATE_FAILURE_STATUSES = new Set(['error', 'offline', 'template-remote', 'downgrade-refused']);
10
+ const UPDATE_SUCCESS_STATUSES = new Set(['up-to-date', 'update-available', 'partial-update', 'ok']);
11
+ const UPDATE_FAILURE_STATUSES = new Set(['error', 'offline', 'template-remote', 'downgrade-refused', 'timeout', 'locked', 'failed']);
12
12
  const CANONICAL_UPDATE_SOURCE_BASE = 'https://raw.githubusercontent.com/LiWeny16/create-harness-vibe-coding/main/templates/common/';
13
+ const DEFAULT_WF_UI_PORT = 56670;
14
+ const DEFAULT_UPDATE_TIMEOUT_MS = 120000;
15
+ const UPDATE_TIMEOUT_EXIT = 3;
13
16
 
14
17
  // ── CLI flags ──────────────────────────────────────────────
15
18
  const raw = process.argv.slice(2);
@@ -28,6 +31,16 @@ function hasFlag(args, flag) {
28
31
  // never fall through to the scaffold installer.
29
32
  if (raw[0] === 'wf-ui') {
30
33
  await runWfUi(raw.slice(1));
34
+ await flushStdout();
35
+ process.exit(0);
36
+ }
37
+
38
+ // init subcommand: bind an existing project to the global Harness runtime.
39
+ // The global runtime (installed once via npm i -g) is the single version
40
+ // source of truth; the project keeps only bridge docs plus its own state.
41
+ if (raw[0] === 'init') {
42
+ runInit(raw.slice(1));
43
+ await flushStdout();
31
44
  process.exit(0);
32
45
  }
33
46
 
@@ -49,10 +62,13 @@ if (showHelp) {
49
62
  console.log('');
50
63
  console.log(' Usage:');
51
64
  console.log(' npx create-harness-vibe-coding@latest [project-name] [target-dir] [flags]');
65
+ console.log(' create-harness-vibe-coding init [target-dir] [flags]');
66
+ console.log(' create-harness-vibe-coding wf-ui --project . [flags]');
52
67
  console.log('');
53
68
  console.log(' Arguments:');
54
69
  console.log(' project-name Name for the new project (default: my-vibe-project)');
55
70
  console.log(' target-dir Directory to create the project in (default: ./<project-name>)');
71
+ console.log(' init Bind an existing project to the global Harness runtime (thin bridge; global runtime is the single version source of truth)');
56
72
  console.log('');
57
73
  console.log(' Flags:');
58
74
  console.log(' -y, --yes Skip all prompts, use defaults or provided args');
@@ -63,7 +79,7 @@ if (showHelp) {
63
79
  console.log(' --without <id,id> Remove optional workflow skills selected by --preset or --with');
64
80
  console.log(' --recommend <id,id> Record recommendation-only external capabilities');
65
81
  console.log(' --preset <name> Add a built-in optional workflow preset');
66
- console.log(' --install-scope <scope> project or global (default: project)');
82
+ console.log(' --install-scope <scope> project or global (new project default: global; existing target keeps project compatibility)');
67
83
  console.log(' --global-dir <dir> Global Harness runtime directory for --install-scope global');
68
84
  console.log(' --host-global-dir <dir> Base directory for Claude/Codex/OpenCode global copies');
69
85
  console.log(' --list-options Print optional workflow skills and presets');
@@ -82,6 +98,8 @@ if (showHelp) {
82
98
  console.log(' npx create-harness-vibe-coding@latest web ./web -y --preset web-app');
83
99
  console.log(' npx create-harness-vibe-coding@latest api ./api -y --preset fullstack --without github-pr-review');
84
100
  console.log(' npx create-harness-vibe-coding@latest app ./app -y --install-scope global');
101
+ console.log(' create-harness-vibe-coding init . # Per-project init against the global runtime');
102
+ console.log(' create-harness-vibe-coding init . --dry-run');
85
103
  console.log('');
86
104
  process.exit(0);
87
105
  }
@@ -102,7 +120,10 @@ const generationOptions = {
102
120
  withoutOptions: parsed.flags.without || [],
103
121
  externalOptions: parsed.flags.recommend || [],
104
122
  preset: parsed.flags.preset,
105
- installScope: parsed.flags.installScope || 'project',
123
+ // New repositories use the global runtime standard. Existing non-empty
124
+ // targets are switched back to project scope below unless the user chose a
125
+ // scope explicitly, preserving the historical installer behavior.
126
+ installScope: parsed.flags.installScope || 'global',
106
127
  globalDir: parsed.flags.globalDir,
107
128
  hostGlobalDir: parsed.flags.hostGlobalDir,
108
129
  json: Boolean(parsed.flags.json),
@@ -115,6 +136,9 @@ if (generationOptions.json) {
115
136
  const projectName = argName || DEFAULT_NAME;
116
137
  const targetDir = argDir || `./${projectName}`;
117
138
  const scan = scanTarget(targetDir);
139
+ if (parsed.flags.installScope === undefined) {
140
+ generationOptions.installScope = defaultInstallScope(scan);
141
+ }
118
142
  if (needsScaffoldRecovery(scan)) {
119
143
  const recovery = createScaffoldRecoveryResult({ projectName, targetDir, options: generationOptions, scan });
120
144
  printJsonResult(recovery);
@@ -122,8 +146,9 @@ if (generationOptions.json) {
122
146
  }
123
147
 
124
148
  if (scan.hasHarness) {
125
- printJsonResult(createUpdateSwitchResult(scan, { json: true }));
126
- process.exit(0);
149
+ const updateResult = createUpdateSwitchResult(scan, { json: true });
150
+ printJsonResult(updateResult, { exitOnFailure: false });
151
+ process.exit(updateResult.success ? 0 : (updateResult.exitCode || 1));
127
152
  }
128
153
  const result = generate({ projectName, targetDir, ...generationOptions });
129
154
  result.scan = createJsonScan(scan);
@@ -154,6 +179,9 @@ if (argName || skipPrompts) {
154
179
  projectName = argName || DEFAULT_NAME;
155
180
  targetDir = argDir || `./${projectName}`;
156
181
  const scan = scanTarget(targetDir);
182
+ if (parsed.flags.installScope === undefined) {
183
+ generationOptions.installScope = defaultInstallScope(scan);
184
+ }
157
185
 
158
186
  if (needsScaffoldRecovery(scan)) {
159
187
  process.exit(runScaffoldRecovery({ projectName, targetDir, options: generationOptions, scan }));
@@ -217,14 +245,15 @@ if (argName || skipPrompts) {
217
245
  console.log(pc.dim(` Directory: ${targetDir} (default)`));
218
246
  }
219
247
 
248
+ const targetScan = scanTarget(targetDir);
220
249
  try {
221
- generationOptions.installScope = await askInstallScope();
250
+ generationOptions.installScope = await askInstallScope(defaultInstallScope(targetScan));
222
251
  } catch {
223
- generationOptions.installScope = 'project';
224
- console.log(pc.dim(' Scope: project (default)'));
252
+ generationOptions.installScope = defaultInstallScope(targetScan);
253
+ console.log(pc.dim(` Scope: ${generationOptions.installScope} (default)`));
225
254
  }
226
255
 
227
- const scan = scanTarget(targetDir);
256
+ const scan = targetScan;
228
257
  printScan(scan);
229
258
 
230
259
  if (needsScaffoldRecovery(scan)) {
@@ -389,9 +418,11 @@ function printResult(result, targetDir) {
389
418
  async function runWfUi(args) {
390
419
  const projectRoot = extractFlag(args, '--project') || process.cwd();
391
420
  const host = extractFlag(args, '--host') || '127.0.0.1';
392
- const rawPort = extractFlag(args, '--port') || '0';
421
+ const rawPort = extractFlag(args, '--port') || String(DEFAULT_WF_UI_PORT);
393
422
  const port = Number.parseInt(rawPort, 10);
394
423
  const openBrowser = !hasFlag(args, '--no-open');
424
+ const detach = hasFlag(args, '--detach');
425
+ const detachedChild = hasFlag(args, '--detached-child');
395
426
 
396
427
  if (host !== '127.0.0.1') {
397
428
  console.error('[wf-ui] host must be 127.0.0.1');
@@ -402,24 +433,36 @@ async function runWfUi(args) {
402
433
  process.exit(1);
403
434
  }
404
435
 
436
+ if (detach && !detachedChild) {
437
+ try {
438
+ await runDetachedWfUi(args);
439
+ } catch (err) {
440
+ console.error(`[wf-ui] ${err.message}`);
441
+ process.exit(1);
442
+ }
443
+ return;
444
+ }
445
+
405
446
  try {
406
447
  const serverModule = await import('./wf-ui-server/server.mjs');
407
448
  const { SessionRegistry } = await import('./wf-ui-server/session-registry.mjs');
408
- const { attachEventsWs } = await import('./wf-ui-server/ws-events.mjs');
409
449
  const { attachTerminalWs } = await import('./wf-ui-server/ws-terminal.mjs');
450
+ const { attachWfBrowserWs } = await import('./wf-ui-server/ws-wf-browser.mjs');
410
451
  const { warmRuntimeCache } = await import('./wf-ui-server/runtime-detector.mjs');
411
452
  const { appendSessionEvent, appendTerminalData, persistSession, recordInputRequest } =
412
453
  await import('./wf-ui-server/terminal-store.mjs');
413
454
  const registry = new SessionRegistry();
414
455
  const terminalHub = {};
415
- const started = await serverModule.startServer({
456
+ const wfBrowserHub = {};
457
+ const started = await startWfUiServerWithPortFallback(serverModule, {
416
458
  projectRoot,
417
459
  host,
418
460
  port,
419
461
  sessionRegistry: registry,
420
462
  terminalHub,
463
+ wfBrowserHub,
421
464
  });
422
- attachEventsWs(started.server, started.token, projectRoot);
465
+ Object.assign(wfBrowserHub, attachWfBrowserWs(started.server, started.token, projectRoot));
423
466
  Object.assign(terminalHub, attachTerminalWs(started.server, started.token, registry, {
424
467
  onTerminalInput(session, data) {
425
468
  try {
@@ -439,15 +482,241 @@ async function runWfUi(args) {
439
482
  },
440
483
  }));
441
484
  warmRuntimeCache();
442
- console.log(`[wf-ui] ${started.url}`);
485
+ await writeStdoutLine(`[wf-ui] ${started.url}`);
486
+ writeWfUiReadyFile(started.url, projectRoot);
443
487
  if (openBrowser) openLocalUrl(started.url);
444
- await waitForWfUiShutdown(started.server);
488
+ try {
489
+ await waitForWfUiShutdown(started.server);
490
+ } finally {
491
+ cleanupWfUiLaunchDirFromReadyFile();
492
+ }
445
493
  } catch (err) {
446
494
  console.error(`[wf-ui] ${err.message}`);
447
495
  process.exit(1);
448
496
  }
449
497
  }
450
498
 
499
+ async function startWfUiServerWithPortFallback(serverModule, options) {
500
+ const requestedPort = options.port;
501
+ let candidatePort = requestedPort;
502
+
503
+ while (true) {
504
+ try {
505
+ return await serverModule.startServer({ ...options, port: candidatePort });
506
+ } catch (err) {
507
+ if (requestedPort === 0 || err?.code !== 'EADDRINUSE') throw err;
508
+ if (candidatePort >= 65535) {
509
+ throw new Error(`ports ${requestedPort}-65535 are occupied`);
510
+ }
511
+ candidatePort += 1;
512
+ }
513
+ }
514
+ }
515
+
516
+ async function runDetachedWfUi(args) {
517
+ const projectRoot = extractFlag(args, '--project') || process.cwd();
518
+ const readyDir = process.env.HARNESS_WF_UI_READY_FILE
519
+ ? null
520
+ : makeProjectLocalWfUiLaunchDir(projectRoot);
521
+ const readyFile = process.env.HARNESS_WF_UI_READY_FILE || path.join(readyDir, 'ready.json');
522
+ const logFile = path.join(path.dirname(readyFile), 'wf-ui.log');
523
+ fs.mkdirSync(path.dirname(readyFile), { recursive: true });
524
+ try { fs.rmSync(readyFile, { force: true }); } catch {}
525
+
526
+ const childArgs = args.filter(arg => arg !== '--detach');
527
+ childArgs.push('--detached-child');
528
+ const child = spawnDetachedWfUiChild(childArgs, readyFile, logFile);
529
+
530
+ let childExit = null;
531
+ child.once('exit', (code, signal) => {
532
+ childExit = { code, signal };
533
+ });
534
+ child.unref();
535
+
536
+ const started = await waitForWfUiReadyFile(readyFile, () => {
537
+ if (process.platform === 'win32' && childExit?.code === 0) return null;
538
+ return childExit;
539
+ }, logFile);
540
+ spawnWfUiLaunchCleanupWatcher(started.pid, path.dirname(readyFile));
541
+ await writeStdoutLine(`[wf-ui] ${started.url}`);
542
+ }
543
+
544
+ function makeProjectLocalWfUiLaunchDir(projectRoot) {
545
+ const launchRoot = path.join(path.resolve(projectRoot || process.cwd()), 'Harness', '.temp', 'wf-ui-launch');
546
+ fs.mkdirSync(launchRoot, { recursive: true });
547
+ return fs.mkdtempSync(path.join(launchRoot, 'harness-wf-ui-'));
548
+ }
549
+
550
+ function spawnDetachedWfUiChild(childArgs, readyFile, logFile) {
551
+ if (process.platform === 'win32') {
552
+ const launcherScript = `
553
+ const { spawn } = require('child_process');
554
+ const fs = require('fs');
555
+ const spec = JSON.parse(process.argv[1]);
556
+ const logFd = fs.openSync(spec.logFile, 'a');
557
+ const child = spawn(spec.execPath, spec.argv, {
558
+ cwd: spec.cwd,
559
+ detached: true,
560
+ env: { ...process.env, HARNESS_WF_UI_READY_FILE: spec.readyFile },
561
+ stdio: ['ignore', logFd, logFd],
562
+ windowsHide: true,
563
+ });
564
+ fs.closeSync(logFd);
565
+ child.unref();
566
+ `;
567
+ return spawn(process.execPath, ['-e', launcherScript, JSON.stringify({
568
+ execPath: process.execPath,
569
+ argv: [process.argv[1], 'wf-ui', ...childArgs],
570
+ cwd: process.cwd(),
571
+ readyFile,
572
+ logFile,
573
+ })], {
574
+ cwd: process.cwd(),
575
+ env: process.env,
576
+ stdio: 'ignore',
577
+ windowsHide: true,
578
+ });
579
+ }
580
+
581
+ const logFd = fs.openSync(logFile, 'a');
582
+ const child = spawn(process.execPath, [process.argv[1], 'wf-ui', ...childArgs], {
583
+ cwd: process.cwd(),
584
+ detached: true,
585
+ env: {
586
+ ...process.env,
587
+ HARNESS_WF_UI_READY_FILE: readyFile,
588
+ },
589
+ stdio: ['ignore', logFd, logFd],
590
+ });
591
+ fs.closeSync(logFd);
592
+ return child;
593
+ }
594
+
595
+ function writeWfUiReadyFile(url, projectRoot) {
596
+ const readyFile = process.env.HARNESS_WF_UI_READY_FILE;
597
+ if (!readyFile) return;
598
+ try {
599
+ fs.mkdirSync(path.dirname(readyFile), { recursive: true });
600
+ fs.writeFileSync(readyFile, `${JSON.stringify({
601
+ url,
602
+ pid: process.pid,
603
+ projectRoot: path.resolve(projectRoot),
604
+ startedAt: new Date().toISOString(),
605
+ })}\n`, 'utf8');
606
+ } catch (err) {
607
+ console.error(`[wf-ui] could not write ready file: ${err.message}`);
608
+ }
609
+ }
610
+
611
+ function isProjectLocalWfUiLaunchDir(dir) {
612
+ const resolved = path.resolve(dir);
613
+ const launchRoot = path.dirname(resolved);
614
+ return path.basename(resolved).startsWith('harness-wf-ui-')
615
+ && path.basename(launchRoot) === 'wf-ui-launch'
616
+ && path.basename(path.dirname(launchRoot)) === '.temp'
617
+ && path.basename(path.dirname(path.dirname(launchRoot))) === 'Harness';
618
+ }
619
+
620
+ function removeWfUiLaunchDir(dir) {
621
+ if (!isProjectLocalWfUiLaunchDir(dir)) return;
622
+ const resolved = path.resolve(dir);
623
+ const launchRoot = path.dirname(resolved);
624
+ try {
625
+ fs.rmSync(resolved, { recursive: true, force: true });
626
+ } catch {
627
+ // Best-effort cleanup; the detached cleanup watcher also retries after process exit.
628
+ }
629
+ try {
630
+ if (fs.existsSync(launchRoot) && fs.readdirSync(launchRoot).length === 0) {
631
+ fs.rmdirSync(launchRoot);
632
+ }
633
+ } catch {
634
+ // no-op
635
+ }
636
+ }
637
+
638
+ function cleanupWfUiLaunchDirFromReadyFile() {
639
+ const readyFile = process.env.HARNESS_WF_UI_READY_FILE;
640
+ if (!readyFile) return;
641
+ removeWfUiLaunchDir(path.dirname(readyFile));
642
+ }
643
+
644
+ function spawnWfUiLaunchCleanupWatcher(pid, launchDir) {
645
+ if (!pid || !isProjectLocalWfUiLaunchDir(launchDir)) return;
646
+ const watcherScript = `
647
+ const fs = require('fs');
648
+ const path = require('path');
649
+ const pid = Number(process.argv[1]);
650
+ const dir = process.argv[2];
651
+ const launchRoot = path.dirname(dir);
652
+ function alive() {
653
+ try {
654
+ process.kill(pid, 0);
655
+ return true;
656
+ } catch {
657
+ return false;
658
+ }
659
+ }
660
+ function cleanup() {
661
+ try { fs.rmSync(dir, { recursive: true, force: true }); } catch {}
662
+ try {
663
+ if (fs.existsSync(launchRoot) && fs.readdirSync(launchRoot).length === 0) {
664
+ fs.rmdirSync(launchRoot);
665
+ }
666
+ } catch {}
667
+ }
668
+ (function wait() {
669
+ if (!alive()) {
670
+ cleanup();
671
+ return;
672
+ }
673
+ setTimeout(wait, 1000);
674
+ })();
675
+ `;
676
+ try {
677
+ const watcher = spawn(process.execPath, ['-e', watcherScript, String(pid), path.resolve(launchDir)], {
678
+ cwd: process.cwd(),
679
+ detached: true,
680
+ stdio: 'ignore',
681
+ windowsHide: true,
682
+ });
683
+ watcher.unref();
684
+ } catch {
685
+ // no-op
686
+ }
687
+ }
688
+
689
+ function waitForWfUiReadyFile(readyFile, getChildExit, logFile) {
690
+ const deadline = Date.now() + 15000;
691
+ return new Promise((resolve, reject) => {
692
+ const poll = () => {
693
+ try {
694
+ if (fs.existsSync(readyFile)) {
695
+ const payload = JSON.parse(fs.readFileSync(readyFile, 'utf8'));
696
+ if (payload?.url) {
697
+ resolve(payload);
698
+ return;
699
+ }
700
+ }
701
+ } catch {
702
+ // The child may still be writing the handoff file.
703
+ }
704
+
705
+ const childExit = getChildExit();
706
+ if (childExit) {
707
+ reject(new Error(`detached server exited before startup (${childExit.signal || childExit.code}); log: ${logFile}`));
708
+ return;
709
+ }
710
+ if (Date.now() >= deadline) {
711
+ reject(new Error(`detached server did not report a URL within 15s; log: ${logFile}`));
712
+ return;
713
+ }
714
+ setTimeout(poll, 80);
715
+ };
716
+ poll();
717
+ });
718
+ }
719
+
451
720
  function waitForWfUiShutdown(server) {
452
721
  return new Promise((resolve) => {
453
722
  let closing = false;
@@ -481,6 +750,135 @@ function openLocalUrl(url) {
481
750
  }
482
751
  }
483
752
 
753
+ function flushStdout() {
754
+ return new Promise((resolve) => {
755
+ if (!process.stdout.writable || process.stdout.writableEnded) {
756
+ resolve();
757
+ return;
758
+ }
759
+ process.stdout.write('', resolve);
760
+ });
761
+ }
762
+
763
+ // init: bind an existing project to a Harness runtime (non-interactive).
764
+ // Default scope `global`: the project gets thin bridge docs plus its own
765
+ // state, while framework files/commands/skills/scripts live once in the
766
+ // machine-level global runtime — the single version source of truth.
767
+ // Scope `project` keeps the classic full project-level install: the whole
768
+ // framework is copied into the project so it stays self-contained.
769
+ // Safe to re-run: user-authored files are preserved under the default `skip`
770
+ // conflict policy.
771
+ function runInit(args) {
772
+ const valueFlags = new Set(['--global-dir', '--host-global-dir', '--on-conflict', '--scope']);
773
+ const scopeRaw = (extractFlag(args, '--scope') || 'global').trim().toLowerCase();
774
+ const installScope = scopeRaw === 'project' || scopeRaw === 'global' ? scopeRaw : null;
775
+ if (!installScope) {
776
+ console.error(pc.red(`[init] unknown --scope "${scopeRaw}". Use project or global.`));
777
+ process.exit(1);
778
+ }
779
+ const positional = args.find((arg, idx) => !arg.startsWith('-') && !valueFlags.has(args[idx - 1]));
780
+ const targetDir = positional || '.';
781
+ const scan = scanTarget(targetDir);
782
+
783
+ if (scan.hasHarness) {
784
+ if (hasFlag(args, '--json')) process.exit(runUpdateSwitch(scan, { json: true }));
785
+ console.log(pc.yellow(`\nHarness already detected in ${targetDir}. Nothing to init.`));
786
+ process.exit(runUpdateSwitch(scan, { json: false }));
787
+ }
788
+
789
+ const result = generate({
790
+ projectName: path.basename(path.resolve(process.cwd(), targetDir)),
791
+ targetDir,
792
+ dryRun: hasFlag(args, '--dry-run'),
793
+ onConflict: extractFlag(args, '--on-conflict') || 'skip',
794
+ withOptions: [],
795
+ withoutOptions: [],
796
+ externalOptions: [],
797
+ preset: undefined,
798
+ installScope,
799
+ globalDir: installScope === 'global' ? extractFlag(args, '--global-dir') : undefined,
800
+ hostGlobalDir: installScope === 'global' ? extractFlag(args, '--host-global-dir') : undefined,
801
+ json: hasFlag(args, '--json'),
802
+ });
803
+
804
+ if (hasFlag(args, '--json')) {
805
+ console.log(JSON.stringify({
806
+ success: result.success,
807
+ installScope: result.installScope,
808
+ globalDir: result.globalDir || null,
809
+ createdCount: result.created.length,
810
+ project: result.summary || null,
811
+ globalRuntime: result.globalSummary || null,
812
+ hosts: result.hostSummary || [],
813
+ errors: result.errors,
814
+ warnings: result.warnings,
815
+ }, null, 2));
816
+ if (!result.success) process.exit(1);
817
+ return;
818
+ }
819
+
820
+ if (!result.success) {
821
+ console.log(pc.red('\nInit failed:'));
822
+ for (const err of result.errors) {
823
+ console.log(pc.red(` - ${err}`));
824
+ }
825
+ process.exit(1);
826
+ }
827
+
828
+ if (result.dryRun) {
829
+ console.log(pc.yellow('\nDry run: no files or directories were written.'));
830
+ } else {
831
+ console.log(pc.green(`\nInit complete (${installScope} scope).\n`));
832
+ }
833
+ console.log(pc.bold('Project install:'));
834
+ printInitSummary(result.summary);
835
+ if (result.globalSummary) {
836
+ console.log(pc.bold('\nGlobal runtime (single version source of truth):'));
837
+ console.log(` Directory ${pc.cyan(result.globalDir)}`);
838
+ printInitSummary(result.globalSummary);
839
+ }
840
+ for (const host of result.hostSummary || []) {
841
+ console.log(pc.bold(`\nHost copy (${host.host}):`));
842
+ console.log(` Directory ${pc.cyan(host.root)}`);
843
+ printInitSummary(host.summary);
844
+ }
845
+ printInitWarnings(result);
846
+
847
+ console.log(pc.bold('\nNext steps:'));
848
+ console.log(` ${pc.cyan('/wf-ui')} # Open the control panel${installScope === 'global' ? '; the global runtime serves this project' : ''}`);
849
+ console.log(` ${pc.cyan('/wf <task>')} # Start a workflow task in this project`);
850
+ if (installScope === 'global') {
851
+ console.log(pc.dim('\n Project state (Harness/tasks, memory, PROGRESS.md) stays local to this project.'));
852
+ console.log(pc.dim(' Update the global runtime with /wf-update or `npm i -g create-harness-vibe-coding@latest`; every project picks it up.'));
853
+ } else {
854
+ console.log(pc.dim('\n The full Harness framework lives in this project; update it per project with /wf-update.'));
855
+ }
856
+ console.log('');
857
+ }
858
+
859
+ function printInitSummary(summary) {
860
+ if (!summary) return;
861
+ console.log(` Created ${summary.created}, skipped ${summary.skipped}, overwritten ${summary.overwritten}, backed up ${summary.backedUp}, conflicts ${summary.conflicts}`);
862
+ }
863
+
864
+ function printInitWarnings(result) {
865
+ if (!result.warnings || result.warnings.length === 0) return;
866
+ console.log(pc.yellow('\nWarning(s):'));
867
+ for (const warning of result.warnings) {
868
+ console.log(pc.yellow(` - ${warning}`));
869
+ }
870
+ }
871
+
872
+ function writeStdoutLine(line) {
873
+ return new Promise((resolve) => {
874
+ if (!process.stdout.writable || process.stdout.writableEnded) {
875
+ resolve();
876
+ return;
877
+ }
878
+ process.stdout.write(`${line}\n`, resolve);
879
+ });
880
+ }
881
+
484
882
  function parseArgs(args) {
485
883
  const flags = {
486
884
  with: [],
@@ -657,11 +1055,11 @@ function printWarnings(result) {
657
1055
  }
658
1056
  }
659
1057
 
660
- function printJsonResult(result) {
1058
+ function printJsonResult(result, { exitOnFailure = true } = {}) {
661
1059
  // Remove `created` array from output — it is already in the plan, avoid duplication
662
1060
  const { created, globalCreated, hostCreated, ...rest } = result;
663
1061
  console.log(JSON.stringify(rest, null, 2));
664
- if (!result.success) {
1062
+ if (exitOnFailure && !result.success) {
665
1063
  process.exit(1);
666
1064
  }
667
1065
  }
@@ -670,6 +1068,59 @@ function updateScriptPath(scan) {
670
1068
  return path.join(scan.resolvedDir, 'Harness', 'scripts', 'wf-update-check.mjs');
671
1069
  }
672
1070
 
1071
+ function updateTimeoutMs() {
1072
+ const raw = process.env.WF_UPDATE_TIMEOUT_MS;
1073
+ const parsed = raw ? Number.parseInt(raw, 10) : DEFAULT_UPDATE_TIMEOUT_MS;
1074
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_UPDATE_TIMEOUT_MS;
1075
+ }
1076
+
1077
+ function readInstallMetadata(scan) {
1078
+ const file = path.join(scan.resolvedDir, 'Harness', '.harness-version');
1079
+ try {
1080
+ return fs.existsSync(file) ? JSON.parse(fs.readFileSync(file, 'utf8')) : null;
1081
+ } catch {
1082
+ return null;
1083
+ }
1084
+ }
1085
+
1086
+ function sameResolvedPath(left, right) {
1087
+ if (!left || !right) return false;
1088
+ const a = path.resolve(left);
1089
+ const b = path.resolve(right);
1090
+ return process.platform === 'win32' ? a.toLowerCase() === b.toLowerCase() : a === b;
1091
+ }
1092
+
1093
+ function globalBridgeMetadata(scan) {
1094
+ const metadata = readInstallMetadata(scan);
1095
+ if (metadata?.installScope !== 'global' || !metadata.globalDir) return null;
1096
+ const globalDir = path.resolve(metadata.globalDir);
1097
+ if (sameResolvedPath(globalDir, scan.resolvedDir)) return null;
1098
+ return { metadata, globalDir };
1099
+ }
1100
+
1101
+ function globalBridgeUpdateTarget(scan) {
1102
+ const bridge = globalBridgeMetadata(scan);
1103
+ if (!bridge) return null;
1104
+ const globalVersion = path.join(bridge.globalDir, 'Harness', '.harness-version');
1105
+ const globalChecker = path.join(bridge.globalDir, 'Harness', 'scripts', 'wf-update-check.mjs');
1106
+ const globalRunner = path.join(bridge.globalDir, 'Harness', 'scripts', 'wf-update-runner.mjs');
1107
+ if (!fs.existsSync(globalVersion) || !fs.existsSync(globalChecker)) return null;
1108
+ return {
1109
+ root: bridge.globalDir,
1110
+ scriptPath: fs.existsSync(globalRunner) ? globalRunner : globalChecker,
1111
+ runner: fs.existsSync(globalRunner),
1112
+ bridge: true,
1113
+ };
1114
+ }
1115
+
1116
+ function isGlobalBridge(scan) {
1117
+ return Boolean(globalBridgeMetadata(scan));
1118
+ }
1119
+
1120
+ function defaultInstallScope(scan) {
1121
+ return scan.needsConflictPolicy && !isGlobalBridge(scan) ? 'project' : 'global';
1122
+ }
1123
+
673
1124
  function missingRecoveryReasons(scan) {
674
1125
  const reasons = [];
675
1126
  if (!fs.existsSync(updateScriptPath(scan))) reasons.push('Harness/scripts/wf-update-check.mjs');
@@ -677,7 +1128,9 @@ function missingRecoveryReasons(scan) {
677
1128
  }
678
1129
 
679
1130
  function needsScaffoldRecovery(scan) {
680
- return scan.hasHarness && missingRecoveryReasons(scan).length > 0;
1131
+ // A global bridge intentionally omits local updater scripts. Do not turn it
1132
+ // into a full project install just because its shared runtime is elsewhere.
1133
+ return scan.hasHarness && !isGlobalBridge(scan) && missingRecoveryReasons(scan).length > 0;
681
1134
  }
682
1135
 
683
1136
  function recoveryOptions(options) {
@@ -712,20 +1165,20 @@ function runScaffoldRecovery({ projectName, targetDir, options, scan }) {
712
1165
  function runUpdateSwitch(scan, { json }) {
713
1166
  const updateResult = createUpdateSwitchResult(scan, { json });
714
1167
  if (json) {
715
- printJsonResult(updateResult);
716
- return updateResult.success ? 0 : 1;
1168
+ printJsonResult(updateResult, { exitOnFailure: false });
1169
+ return updateResult.success ? 0 : (updateResult.exitCode || 1);
717
1170
  }
718
1171
 
719
1172
  console.log('');
720
1173
  console.log(pc.yellow('Existing Harness detected. Switching to wf-update check.'));
721
1174
  console.log(pc.dim(`Directory ${scan.resolvedDir}`));
722
- console.log(pc.dim('Command node Harness/scripts/wf-update-check.mjs'));
1175
+ console.log(pc.dim(`Command ${updateResult.command || 'node Harness/scripts/wf-update-check.mjs'}`));
723
1176
  console.log(pc.dim(`Source ${CANONICAL_UPDATE_SOURCE_BASE}`));
724
1177
  console.log('');
725
1178
 
726
1179
  if (!updateResult.success && updateResult.error) {
727
1180
  console.error(pc.red(updateResult.error));
728
- return 1;
1181
+ return updateResult.exitCode ?? 1;
729
1182
  }
730
1183
 
731
1184
  if (updateResult.stdout) process.stdout.write(updateResult.stdout);
@@ -747,35 +1200,64 @@ function getUpdateStatusError(update) {
747
1200
  }
748
1201
 
749
1202
  function createUpdateSwitchResult(scan, { json }) {
750
- const args = ['Harness/scripts/wf-update-check.mjs'];
1203
+ const bridge = globalBridgeMetadata(scan);
1204
+ const bridgeTarget = globalBridgeUpdateTarget(scan);
1205
+ const target = bridgeTarget || (bridge ? {
1206
+ root: bridge.globalDir,
1207
+ scriptPath: path.join(bridge.globalDir, 'Harness', 'scripts', 'wf-update-check.mjs'),
1208
+ runner: false,
1209
+ bridge: true,
1210
+ } : {
1211
+ root: scan.resolvedDir,
1212
+ scriptPath: updateScriptPath(scan),
1213
+ runner: false,
1214
+ bridge: false,
1215
+ });
1216
+ const args = target.runner
1217
+ ? [target.scriptPath, '--project', scan.resolvedDir]
1218
+ : [target.scriptPath];
751
1219
  if (json) args.push('--json');
752
-
753
- const scriptPath = path.join(scan.resolvedDir, 'Harness', 'scripts', 'wf-update-check.mjs');
754
- const command = `node ${args.join(' ')}`;
1220
+ const command = `node ${args.map(value => (/\s/.test(value) ? JSON.stringify(value) : value)).join(' ')}`;
755
1221
  const base = {
756
1222
  success: false,
757
1223
  mode: 'update',
758
1224
  scan: createJsonScan(scan),
759
1225
  agent: {
760
1226
  sourceOfTruth: 'Existing Harness detected; install automatically switched to the target update checker. Do not continue install writes.',
761
- updateCommand: json
762
- ? 'node Harness/scripts/wf-update-check.mjs --json'
763
- : 'node Harness/scripts/wf-update-check.mjs',
1227
+ updateCommand: command,
764
1228
  updateSourceBase: CANONICAL_UPDATE_SOURCE_BASE,
765
1229
  next: [
766
1230
  {
767
1231
  action: 'update',
768
- command: json
769
- ? 'node Harness/scripts/wf-update-check.mjs --json'
770
- : 'node Harness/scripts/wf-update-check.mjs',
1232
+ command,
771
1233
  env: { WF_SOURCE_BASE: CANONICAL_UPDATE_SOURCE_BASE },
772
- reason: 'Harness already exists, so updates must use the installed Harness update flow.',
1234
+ reason: target.bridge
1235
+ ? 'This project is a thin global bridge; the shared runtime is the single update source of truth.'
1236
+ : 'Harness already exists, so updates must use the installed Harness update flow.',
773
1237
  },
774
1238
  ],
775
1239
  },
776
1240
  };
777
1241
 
778
- if (!fs.existsSync(scriptPath)) {
1242
+ if (!fs.existsSync(target.scriptPath)) {
1243
+ if (target.bridge) {
1244
+ return {
1245
+ ...base,
1246
+ success: false,
1247
+ exitCode: 1,
1248
+ error: 'This project is a global Harness bridge, but its shared global runtime was not found. No project files were written. Reinstall or update the global create-harness-vibe-coding runtime, then retry.',
1249
+ errors: ['global Harness runtime not found'],
1250
+ agent: {
1251
+ ...base.agent,
1252
+ next: [{
1253
+ action: 'global-runtime-recovery',
1254
+ reason: 'The bridge must not be expanded into a project install when the shared runtime is unavailable.',
1255
+ command: 'npm install --global create-harness-vibe-coding@latest',
1256
+ note: 'The project bridge remains untouched; reinstalling the one global runtime restores the shared update source.',
1257
+ }],
1258
+ },
1259
+ };
1260
+ }
779
1261
  return {
780
1262
  ...base,
781
1263
  success: false,
@@ -795,8 +1277,10 @@ function createUpdateSwitchResult(scan, { json }) {
795
1277
  }
796
1278
 
797
1279
  const result = spawnSync(process.execPath, args, {
798
- cwd: scan.resolvedDir,
1280
+ cwd: target.root,
799
1281
  encoding: 'utf8',
1282
+ timeout: updateTimeoutMs(),
1283
+ killSignal: 'SIGTERM',
800
1284
  env: {
801
1285
  ...process.env,
802
1286
  WF_SOURCE_BASE: CANONICAL_UPDATE_SOURCE_BASE,
@@ -804,7 +1288,8 @@ function createUpdateSwitchResult(scan, { json }) {
804
1288
  });
805
1289
  const stdout = result.stdout || '';
806
1290
  const stderr = result.stderr || '';
807
- const status = result.status ?? 1;
1291
+ const timedOut = result.error?.code === 'ETIMEDOUT';
1292
+ const status = timedOut ? UPDATE_TIMEOUT_EXIT : (result.status ?? 1);
808
1293
 
809
1294
  let update = undefined;
810
1295
  if (json && stdout.trim()) {
@@ -814,9 +1299,16 @@ function createUpdateSwitchResult(scan, { json }) {
814
1299
  update = { rawOutput: stdout };
815
1300
  }
816
1301
  }
1302
+ if (timedOut && !update) {
1303
+ update = {
1304
+ status: 'timeout',
1305
+ code: 'UPDATE_TIMEOUT',
1306
+ message: `Update command exceeded the ${updateTimeoutMs()}ms deadline.`,
1307
+ };
1308
+ }
817
1309
 
818
1310
  const errors = [];
819
- if (status !== 0) errors.push(`Update checker exited with status ${status}`);
1311
+ if (status !== 0) errors.push(timedOut ? `Update checker exceeded the ${updateTimeoutMs()}ms deadline` : `Update checker exited with status ${status}`);
820
1312
  if (json) {
821
1313
  const statusError = getUpdateStatusError(update);
822
1314
  if (statusError) errors.push(statusError);
@@ -829,6 +1321,7 @@ function createUpdateSwitchResult(scan, { json }) {
829
1321
  command,
830
1322
  stdout,
831
1323
  stderr,
1324
+ ...(timedOut ? { timedOut: true, errorCode: 'UPDATE_TIMEOUT' } : {}),
832
1325
  ...(json ? { update } : {}),
833
1326
  ...(errors.length === 0 ? {} : { error: errors[0], errors }),
834
1327
  };