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,556 @@
1
+ // workflow-codex-resume-id.test.mjs
2
+ //
3
+ // Codex resume fix: codex keys its saved sessions by an internal rollout UUID
4
+ // (e.g. `Session 019ffa1b-...`), not by the harness session id — `codex resume
5
+ // <harnessSessionId>` exits 1. The codex TUI never prints the UUID to the PTY
6
+ // (verified against real sessions), so the primary capture source is codex's
7
+ // sessions dir with the REAL nested per-day layout:
8
+ // `~/.codex/sessions/<YYYY>/<MM>/<DD>/rollout-<timestamp>-<uuid>.jsonl`
9
+ // (a flat readdir would never see these files). These tests cover:
10
+ //
11
+ // T1 — FS capture: a NEW rollout-*.jsonl file appearing after spawn in the
12
+ // nested layout yields the rollout id from its filename; pre-spawn
13
+ // (baseline) files are ignored and the capture fires only once.
14
+ // T2 — FS capture: rollout files that existed before spawn never fire, and
15
+ // the capture expires after the window.
16
+ // T3 — FS capture: no new file within the (env-overridable) window → no
17
+ // event; filename parsing unit checks.
18
+ // T3d — Recursive walk: the baseline snapshot sees nested rollout files and
19
+ // the fs existence check only confirms real rollout uuids.
20
+ // T4 — resolveRuntimeResumeArgs unit: codex with agentSessionId absent and a
21
+ // captured codexRolloutId resumes that rollout id (codexRolloutId wins over
22
+ // the harness-tracked id).
23
+ // T5 — Server integration: the capture event persists codexRolloutId on the
24
+ // session record (registry + STATE.json + event), and a subsequent
25
+ // agent.start on the bound node resumes the captured rollout id instead of
26
+ // the harness session id.
27
+ // T6 — PTY scanner anti-false-positive: a uuid on a resume error line
28
+ // (`No saved session found with ID <harness-uuid>`) with NO matching
29
+ // rollout file never fires; once a matching nested rollout file exists,
30
+ // the same scanner does fire with the confirmed uuid.
31
+ //
32
+ // Pattern: in-process node:test + HTTP server on port 0, temp roots, a fake
33
+ // PTY via a pty-adapter.mjs fixture (registerHooks, same as
34
+ // workflow-depth-resume-dock.test.mjs) that emits the codex:rollout-id control
35
+ // request the real capture would emit, and a stub `codex` executable on PATH
36
+ // so POST /api/sessions reaches the spawn branch.
37
+ import { describe, it, beforeEach, afterEach, before, after } from 'node:test';
38
+ import assert from 'node:assert/strict';
39
+ import fs from 'node:fs';
40
+ import os from 'node:os';
41
+ import path from 'node:path';
42
+ import http from 'node:http';
43
+ import { registerHooks } from 'node:module';
44
+ import { pathToFileURL } from 'node:url';
45
+ import { makeHarnessTempRoot } from '../../../tests/support/temp-root.js';
46
+ import { SessionRegistry } from '../session-registry.mjs';
47
+ import { persistSession, listTerminalSessions } from '../terminal-store.mjs';
48
+ import { loadWorkflowGraphMap, writeWorkflowGraphMap } from '../a2a-store.mjs';
49
+ import {
50
+ createCodexRolloutFsCapture,
51
+ createCodexRolloutIdDetector,
52
+ CODEX_ROLLOUT_FS_CAPTURE_WINDOW_MS,
53
+ codexSessionsDir,
54
+ extractRolloutIdFromFilename,
55
+ rolloutIdExistsInSessionsDir,
56
+ snapshotRolloutFilenames,
57
+ } from '../pty-adapter.mjs';
58
+ import { resolveRuntimeResumeArgs } from '../runtime-detector.mjs';
59
+
60
+ // ── pty-adapter fixture ─────────────────────────────────────────────────────
61
+ // Replaces pty-adapter.mjs for server.mjs: spawnPty records the spawn opts and
62
+ // emits the codex:rollout-id control request the real capture would emit for a
63
+ // codex session whose rollout file appeared in the sessions dir.
64
+ const FAKE_ROLLOUT_ID = '019ffa1b-1234-5678-9abc-def012345678';
65
+ const FIXTURE_SOURCE = [
66
+ '// Test fixture replacing pty-adapter.mjs (workflow-codex-resume-id.test.mjs).',
67
+ 'const recorder = {',
68
+ ' spawnOpts: [],',
69
+ ' reset() { this.spawnOpts.length = 0; },',
70
+ '};',
71
+ 'export async function spawnPty(opts) {',
72
+ ' recorder.spawnOpts.push(opts);',
73
+ ` if (opts.runtime === "codex" && typeof opts.onControlRequest === "function") {`,
74
+ ' opts.onControlRequest({',
75
+ ' reason: "codex-rollout-id-detected",',
76
+ ' type: "codex:rollout-id",',
77
+ ` payload: { rolloutId: "${FAKE_ROLLOUT_ID}" },`,
78
+ ' });',
79
+ ' }',
80
+ ' const ptyProcess = {',
81
+ ' pid: 43200 + recorder.spawnOpts.length,',
82
+ ' write() {},',
83
+ ' kill() {},',
84
+ ' onData() {},',
85
+ ' onExit() {},',
86
+ ' };',
87
+ ' return { sessionId: opts.sessionId, pid: ptyProcess.pid, ptyProcess, ptyProvider: "test-fixture" };',
88
+ '}',
89
+ 'export { recorder };',
90
+ ].join('\n');
91
+
92
+ const fixtureDir = makeHarnessTempRoot('wf-codex-resume-id-fixture-');
93
+ const fixturePath = path.join(fixtureDir, 'pty-adapter.mjs');
94
+ fs.writeFileSync(fixturePath, FIXTURE_SOURCE, 'utf8');
95
+ const fixtureUrl = pathToFileURL(fixturePath).href;
96
+
97
+ registerHooks({
98
+ resolve(specifier, context, nextResolve) {
99
+ if (specifier === './pty-adapter.mjs' && String(context.parentURL || '').endsWith('/src/wf-ui-server/server.mjs')) {
100
+ return { url: fixtureUrl, shortCircuit: true };
101
+ }
102
+ return nextResolve(specifier, context);
103
+ },
104
+ });
105
+
106
+ const { startServer, stopServer } = await import('../server.mjs');
107
+ const { recorder } = await import(fixtureUrl);
108
+
109
+ // ── runtime stub ────────────────────────────────────────────────────────────
110
+ // A stub `codex` on PATH makes createRuntimeSession take the spawn branch so
111
+ // spawnPty (the fixture) runs for real in-process.
112
+ const ORIGINAL_PATH = process.env.PATH || '';
113
+ let runtimeStubDir = '';
114
+
115
+ before(() => {
116
+ runtimeStubDir = makeHarnessTempRoot('wf-codex-resume-id-runtime-');
117
+ if (process.platform === 'win32') {
118
+ fs.writeFileSync(path.join(runtimeStubDir, 'codex.cmd'), '@echo off\r\nrem wf-ui codex resume id test stub\r\n');
119
+ } else {
120
+ const stub = path.join(runtimeStubDir, 'codex');
121
+ fs.writeFileSync(stub, '#!/bin/sh\n');
122
+ fs.chmodSync(stub, 0o755);
123
+ }
124
+ process.env.PATH = `${runtimeStubDir}${path.delimiter}${ORIGINAL_PATH}`;
125
+ });
126
+
127
+ after(() => {
128
+ process.env.PATH = ORIGINAL_PATH;
129
+ for (const dir of [runtimeStubDir, fixtureDir]) {
130
+ try { fs.rmSync(dir, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 }); } catch { /* best effort */ }
131
+ }
132
+ });
133
+
134
+ // ── HTTP helper ──
135
+ function jsonRequest(baseUrl, route, { method = 'GET', body } = {}) {
136
+ return new Promise((resolve, reject) => {
137
+ const url = new URL(route, baseUrl);
138
+ const payload = body ? JSON.stringify(body) : null;
139
+ const req = http.request({
140
+ hostname: url.hostname,
141
+ port: url.port,
142
+ path: `${url.pathname}${url.search}`,
143
+ method,
144
+ headers: payload ? { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) } : {},
145
+ }, (res) => {
146
+ let data = '';
147
+ res.on('data', chunk => { data += chunk; });
148
+ res.on('end', () => {
149
+ try { resolve({ status: res.statusCode, body: JSON.parse(data) }); }
150
+ catch { resolve({ status: res.statusCode, body: data }); }
151
+ });
152
+ });
153
+ req.on('error', reject);
154
+ if (payload) req.write(payload);
155
+ req.end();
156
+ });
157
+ }
158
+
159
+ function seedRoot(prefix) {
160
+ const root = makeHarnessTempRoot(prefix);
161
+ fs.mkdirSync(path.join(root, 'Harness', 'tasks'), { recursive: true });
162
+ fs.mkdirSync(path.join(root, 'Harness', 'a2a'), { recursive: true });
163
+ return root;
164
+ }
165
+
166
+ function seedAgent(root, { nodeId, sessionId, agentKind = 'subagent', role = 'Agent', runtime = 'claude', status = 'running' }) {
167
+ const graph = loadWorkflowGraphMap(root);
168
+ const nodes = [
169
+ ...(graph.nodes || []).filter(node => (node.nodeId || node.id) !== nodeId),
170
+ {
171
+ nodeId,
172
+ sessionId,
173
+ kind: 'terminal-session',
174
+ runtime,
175
+ agentKind,
176
+ role,
177
+ label: role,
178
+ status,
179
+ },
180
+ ];
181
+ writeWorkflowGraphMap(root, {
182
+ schemaVersion: 1,
183
+ version: 1,
184
+ nodes,
185
+ edges: [],
186
+ capsuleDockLinks: [],
187
+ positions: Object.fromEntries(nodes.map(node => [node.nodeId, { x: 0, y: 0 }])),
188
+ });
189
+ persistSession(root, {
190
+ sessionId,
191
+ graphNodeId: nodeId,
192
+ runtime,
193
+ agentKind,
194
+ role,
195
+ status,
196
+ attachMode: true,
197
+ taskId: null,
198
+ });
199
+ }
200
+
201
+ function readSessionEvents(root, sessionId) {
202
+ const dirs = ['Harness', 'a2a', 'sessions', sessionId];
203
+ const eventsPath = path.join(root, ...dirs, 'events.jsonl');
204
+ if (!fs.existsSync(eventsPath)) return [];
205
+ return fs.readFileSync(eventsPath, 'utf8')
206
+ .split(/\r?\n/)
207
+ .filter(Boolean)
208
+ .map(line => JSON.parse(line));
209
+ }
210
+
211
+ // ── fs-capture helpers ──
212
+ // Real codex filename shape: rollout-<dash-separated timestamp>-<uuid>.jsonl
213
+ function rolloutFilename(uuid, stamp = '2026-08-13T16-21-24') {
214
+ return `rollout-${stamp}-${uuid}.jsonl`;
215
+ }
216
+
217
+ // Real codex layout: sessions/<YYYY>/<MM>/<DD>/rollout-<ts>-<uuid>.jsonl —
218
+ // the timestamp in the name also selects the per-day directory.
219
+ function rolloutDir(sessionsDir, stamp) {
220
+ const [date] = String(stamp).split('T');
221
+ const [y, m, d] = date.split('-');
222
+ return path.join(sessionsDir, y, m, d);
223
+ }
224
+
225
+ function writeRolloutFile(sessionsDir, uuid, stamp = '2026-08-13T16-21-24') {
226
+ const dir = rolloutDir(sessionsDir, stamp);
227
+ fs.mkdirSync(dir, { recursive: true });
228
+ fs.writeFileSync(path.join(dir, rolloutFilename(uuid, stamp)), '');
229
+ }
230
+
231
+ function waitForEvent(capture, events, timeoutMs = 5000) {
232
+ const deadline = Date.now() + timeoutMs;
233
+ return (async () => {
234
+ while (events.length === 0 && Date.now() < deadline) {
235
+ await new Promise(resolve => setTimeout(resolve, 25));
236
+ }
237
+ })();
238
+ }
239
+
240
+ describe('codex resume id (rollout UUID capture + mapping)', () => {
241
+ let root;
242
+ let registry;
243
+ let server;
244
+ let baseUrl;
245
+
246
+ beforeEach(async () => {
247
+ recorder.reset();
248
+ root = seedRoot('wf-cri-');
249
+ registry = new SessionRegistry();
250
+ const started = await startServer({
251
+ projectRoot: root,
252
+ host: '127.0.0.1',
253
+ port: 0,
254
+ sessionRegistry: registry,
255
+ eventsWs: false,
256
+ });
257
+ server = started.server;
258
+ baseUrl = `http://127.0.0.1:${started.port}`;
259
+ });
260
+
261
+ afterEach(async () => {
262
+ if (server) {
263
+ await stopServer(server);
264
+ server = null;
265
+ }
266
+ if (root) {
267
+ fs.rmSync(root, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 });
268
+ root = null;
269
+ }
270
+ });
271
+
272
+ // ══════════════════════════════════════════════════════════════════
273
+ // T1 — fs capture: new rollout file after spawn fires its UUID once
274
+ // ══════════════════════════════════════════════════════════════════
275
+ it('T1 - fires with the UUID of a NEW rollout file (nested layout); baseline files ignored; fires once', async () => {
276
+ const sessionsDir = makeHarnessTempRoot('wf-cri-fs-');
277
+ try {
278
+ // Pre-existing rollout file in its per-day dir (written before spawn) → baseline.
279
+ writeRolloutFile(sessionsDir, '11111111-2222-3333-4444-555555555555', '2026-07-01T08-00-00');
280
+ const events = [];
281
+ const capture = createCodexRolloutFsCapture({
282
+ sessionsDir,
283
+ baselineFiles: snapshotRolloutFilenames(sessionsDir),
284
+ spawnTime: Date.now(),
285
+ windowMs: 5000,
286
+ pollMs: 25,
287
+ onControlRequest: event => events.push(event),
288
+ });
289
+ capture.start();
290
+ assert.equal(capture.active, true, 'capture must be active before a new file appears');
291
+
292
+ // codex writes its new rollout file shortly after spawn, nested under
293
+ // today's YYYY/MM/DD dir — a flat readdir would never see it.
294
+ writeRolloutFile(sessionsDir, FAKE_ROLLOUT_ID);
295
+ await waitForEvent(capture, events);
296
+
297
+ assert.equal(events.length, 1, `fs capture must fire exactly once, got: ${JSON.stringify(events)}`);
298
+ assert.equal(events[0].type, 'codex:rollout-id');
299
+ assert.equal(events[0].reason, 'codex-rollout-id-detected');
300
+ assert.deepEqual(events[0].payload, { rolloutId: FAKE_ROLLOUT_ID },
301
+ 'must carry the NEW file uuid, not the pre-spawn baseline uuid');
302
+ assert.equal(capture.rolloutId, FAKE_ROLLOUT_ID);
303
+ assert.equal(capture.active, false, 'capture must stop after firing');
304
+
305
+ // A second new file must not refire.
306
+ writeRolloutFile(sessionsDir, '66666666-7777-8888-9999-000000000000', '2026-08-13T17-00-00');
307
+ await new Promise(resolve => setTimeout(resolve, 100));
308
+ assert.equal(events.length, 1, 'must fire only once');
309
+ } finally {
310
+ fs.rmSync(sessionsDir, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 });
311
+ }
312
+ });
313
+
314
+ // ══════════════════════════════════════════════════════════════════
315
+ // T2 — fs capture: pre-spawn files never fire; capture expires
316
+ // ══════════════════════════════════════════════════════════════════
317
+ it('T2 - rollout files present pre-spawn (nested layout) are ignored and the capture expires', async () => {
318
+ const sessionsDir = makeHarnessTempRoot('wf-cri-fs-');
319
+ try {
320
+ // Files that exist before spawn (baseline) and a name without a UUID
321
+ // must never trigger the capture — including nested ones.
322
+ writeRolloutFile(sessionsDir, FAKE_ROLLOUT_ID, '2026-07-01T08-00-00');
323
+ writeRolloutFile(sessionsDir, 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee', '2026-08-12T09-30-00');
324
+ fs.mkdirSync(rolloutDir(sessionsDir, '2026-08-13T00-00-00'), { recursive: true });
325
+ fs.writeFileSync(path.join(rolloutDir(sessionsDir, '2026-08-13T00-00-00'), 'rollout-not-a-uuid.jsonl'), '');
326
+ const events = [];
327
+ const capture = createCodexRolloutFsCapture({
328
+ sessionsDir,
329
+ baselineFiles: snapshotRolloutFilenames(sessionsDir),
330
+ spawnTime: Date.now(),
331
+ windowMs: 250,
332
+ pollMs: 25,
333
+ onControlRequest: event => events.push(event),
334
+ });
335
+ capture.start();
336
+ await new Promise(resolve => setTimeout(resolve, 400));
337
+
338
+ assert.deepEqual(events, [], 'pre-spawn rollout files must never fire');
339
+ assert.equal(capture.rolloutId, null);
340
+ assert.equal(capture.active, false, 'capture must expire after the window');
341
+ } finally {
342
+ fs.rmSync(sessionsDir, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 });
343
+ }
344
+ });
345
+
346
+ // ══════════════════════════════════════════════════════════════════
347
+ // T3 — fs capture: no new file within the window → no event; env override
348
+ // ══════════════════════════════════════════════════════════════════
349
+ it('T3 - no new rollout file within the window → no event (env-overridable window)', async () => {
350
+ const sessionsDir = makeHarnessTempRoot('wf-cri-fs-');
351
+ const prevWindow = process.env.CODEX_ROLLOUT_FS_CAPTURE_WINDOW_MS;
352
+ process.env.CODEX_ROLLOUT_FS_CAPTURE_WINDOW_MS = '200';
353
+ try {
354
+ const events = [];
355
+ const capture = createCodexRolloutFsCapture({
356
+ sessionsDir,
357
+ baselineFiles: snapshotRolloutFilenames(sessionsDir),
358
+ spawnTime: Date.now(),
359
+ pollMs: 25,
360
+ onControlRequest: event => events.push(event),
361
+ });
362
+ capture.start();
363
+ await new Promise(resolve => setTimeout(resolve, 350));
364
+
365
+ assert.deepEqual(events, [], 'no new rollout file → no event');
366
+ assert.equal(capture.rolloutId, null);
367
+ assert.equal(capture.active, false, 'capture must expire after the window');
368
+ } finally {
369
+ if (prevWindow === undefined) {
370
+ delete process.env.CODEX_ROLLOUT_FS_CAPTURE_WINDOW_MS;
371
+ } else {
372
+ process.env.CODEX_ROLLOUT_FS_CAPTURE_WINDOW_MS = prevWindow;
373
+ }
374
+ fs.rmSync(sessionsDir, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 });
375
+ }
376
+ });
377
+
378
+ // ══════════════════════════════════════════════════════════════════
379
+ // T3b — filename parsing + sessions dir resolution + default window
380
+ // ══════════════════════════════════════════════════════════════════
381
+ it('T3b - parses the uuid segment from real codex rollout filenames', () => {
382
+ assert.equal(
383
+ extractRolloutIdFromFilename('rollout-2026-08-13T16-21-24-019ffa36-34a1-7923-ab6b-c66732a1e06e.jsonl'),
384
+ '019ffa36-34a1-7923-ab6b-c66732a1e06e',
385
+ 'real codex rollout filename must yield its uuid',
386
+ );
387
+ assert.equal(extractRolloutIdFromFilename(rolloutFilename(FAKE_ROLLOUT_ID)), FAKE_ROLLOUT_ID);
388
+ assert.equal(extractRolloutIdFromFilename('rollout-2026-08-13T16-21-24.jsonl'), null, 'missing uuid segment');
389
+ assert.equal(extractRolloutIdFromFilename('rollout-not-a-uuid.jsonl'), null);
390
+ assert.equal(extractRolloutIdFromFilename('session_meta.jsonl'), null);
391
+ assert.equal(extractRolloutIdFromFilename(''), null);
392
+ });
393
+
394
+ it('T3c - codex sessions dir resolves CODEX_HOME or ~/.codex; default window is positive', () => {
395
+ const prevHome = process.env.CODEX_HOME;
396
+ process.env.CODEX_HOME = path.join('C:', 'fake-codex-home');
397
+ try {
398
+ assert.equal(codexSessionsDir(), path.join('C:', 'fake-codex-home', 'sessions'));
399
+ } finally {
400
+ if (prevHome === undefined) {
401
+ delete process.env.CODEX_HOME;
402
+ } else {
403
+ process.env.CODEX_HOME = prevHome;
404
+ }
405
+ }
406
+ assert.equal(codexSessionsDir(), path.join(os.homedir(), '.codex', 'sessions'));
407
+ assert.ok(CODEX_ROLLOUT_FS_CAPTURE_WINDOW_MS > 0, 'default capture window must be positive');
408
+ });
409
+
410
+ // ══════════════════════════════════════════════════════════════════
411
+ // T3d — recursive walk: nested rollout files are visible to the baseline
412
+ // snapshot and the fs existence check
413
+ // ══════════════════════════════════════════════════════════════════
414
+ it('T3d - baseline snapshot and existence check see nested rollout files only', () => {
415
+ const sessionsDir = makeHarnessTempRoot('wf-cri-snap-');
416
+ try {
417
+ writeRolloutFile(sessionsDir, FAKE_ROLLOUT_ID, '2026-08-13T16-21-24');
418
+ // Non-rollout files (nested and flat) must never appear in the snapshot.
419
+ fs.writeFileSync(path.join(rolloutDir(sessionsDir, '2026-08-13T16-21-24'), 'session_meta.jsonl'), '');
420
+ fs.writeFileSync(path.join(sessionsDir, 'other.jsonl'), '');
421
+
422
+ const snapshot = snapshotRolloutFilenames(sessionsDir);
423
+ assert.equal(snapshot.size, 1, 'only rollout-*.jsonl files count, nested or not');
424
+ assert.deepEqual([...snapshot], [
425
+ '2026/08/13/rollout-2026-08-13T16-21-24-019ffa1b-1234-5678-9abc-def012345678.jsonl',
426
+ ], 'relative posix path into the YYYY/MM/DD layout');
427
+
428
+ assert.equal(rolloutIdExistsInSessionsDir(sessionsDir, FAKE_ROLLOUT_ID), true,
429
+ 'a uuid with a nested rollout file must be confirmed');
430
+ assert.equal(rolloutIdExistsInSessionsDir(sessionsDir, '00000000-0000-0000-0000-000000000000'), false,
431
+ 'a uuid with no rollout file anywhere must not be confirmed');
432
+ assert.equal(rolloutIdExistsInSessionsDir(sessionsDir, ''), false);
433
+ assert.equal(rolloutIdExistsInSessionsDir(sessionsDir, null), false);
434
+ } finally {
435
+ fs.rmSync(sessionsDir, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 });
436
+ }
437
+ });
438
+
439
+ // ══════════════════════════════════════════════════════════════════
440
+ // T4 — resume arg resolution prefers the codex rollout id
441
+ // ══════════════════════════════════════════════════════════════════
442
+ it('T4 - codex resume args use the captured rollout id over the harness session id', () => {
443
+ assert.deepEqual(
444
+ resolveRuntimeResumeArgs('codex', { agentSessionId: null, codexRolloutId: FAKE_ROLLOUT_ID }),
445
+ ['resume', FAKE_ROLLOUT_ID],
446
+ 'codex with agentSessionId absent must resume the captured rollout id',
447
+ );
448
+ assert.deepEqual(
449
+ resolveRuntimeResumeArgs('codex', { agentSessionId: 'harness-session-1', codexRolloutId: FAKE_ROLLOUT_ID }),
450
+ ['resume', FAKE_ROLLOUT_ID],
451
+ 'codexRolloutId must win over the harness-tracked agentSessionId',
452
+ );
453
+ assert.deepEqual(
454
+ resolveRuntimeResumeArgs('codex', { agentSessionId: 'harness-session-1' }),
455
+ ['resume', 'harness-session-1'],
456
+ 'without a rollout id the harness id is used unchanged',
457
+ );
458
+ assert.deepEqual(resolveRuntimeResumeArgs('codex', {}), ['resume', '--last']);
459
+ // Other runtimes are unaffected by the new option.
460
+ assert.deepEqual(
461
+ resolveRuntimeResumeArgs('claude', { agentSessionId: 's1', codexRolloutId: FAKE_ROLLOUT_ID }),
462
+ ['--resume', 's1'],
463
+ );
464
+ assert.deepEqual(
465
+ resolveRuntimeResumeArgs('opencode', { agentSessionId: 's1', codexRolloutId: FAKE_ROLLOUT_ID }),
466
+ ['--session', 's1'],
467
+ );
468
+ });
469
+
470
+ // ══════════════════════════════════════════════════════════════════
471
+ // T5 — server integration: capture persists on the session record and
472
+ // drives the resume mapping
473
+ // ══════════════════════════════════════════════════════════════════
474
+ it('T5 - capture event persists codexRolloutId; agent.start resumes it', async () => {
475
+ const created = await jsonRequest(baseUrl, '/api/sessions', {
476
+ method: 'POST',
477
+ body: { runtime: 'codex', agentKind: 'subagent', attachGraphNode: false },
478
+ });
479
+ assert.equal(created.status, 201, JSON.stringify(created.body));
480
+ const sessionId = created.body.sessionId;
481
+ assert.ok(sessionId, 'session must be created');
482
+ assert.equal(created.body.codexRolloutId, FAKE_ROLLOUT_ID, 'response session must carry the captured rollout id');
483
+
484
+ // Registry record.
485
+ const live = registry.get(sessionId);
486
+ assert.ok(live, 'session must be in the registry');
487
+ assert.equal(live.codexRolloutId, FAKE_ROLLOUT_ID);
488
+ assert.equal(live.agentSessionId, FAKE_ROLLOUT_ID, 'agentSessionId must mirror the rollout id for resume metadata');
489
+
490
+ // Persisted STATE.json record.
491
+ const persisted = listTerminalSessions(root).find(session => session.sessionId === sessionId);
492
+ assert.ok(persisted, 'session must be persisted');
493
+ assert.equal(persisted.codexRolloutId, FAKE_ROLLOUT_ID, 'STATE.json must persist codexRolloutId');
494
+ assert.equal(persisted.agentSessionId, FAKE_ROLLOUT_ID);
495
+
496
+ // Session event.
497
+ const events = readSessionEvents(root, sessionId);
498
+ assert.ok(events.some(event => event.type === 'codex.rollout-id.captured' && event.codexRolloutId === FAKE_ROLLOUT_ID),
499
+ `expected codex.rollout-id.captured event, got: ${JSON.stringify(events)}`);
500
+
501
+ // Now bind the captured session to a graph node as a previous (exited)
502
+ // session and start the node: resume must target the rollout id, not the
503
+ // harness session id.
504
+ registry.remove(sessionId);
505
+ seedAgent(root, {
506
+ nodeId: 't5-main',
507
+ sessionId,
508
+ runtime: 'codex',
509
+ agentKind: 'main',
510
+ role: 'Main Agent',
511
+ status: 'exited',
512
+ });
513
+ const resumed = await jsonRequest(baseUrl, `/api/workflow/nodes/${encodeURIComponent('t5-main')}/actions/agent.start`, {
514
+ method: 'POST',
515
+ body: { deferPtySpawn: true },
516
+ });
517
+ assert.equal(resumed.status, 200, JSON.stringify(resumed.body));
518
+ assert.equal(resumed.body.result.resumeUsed, true);
519
+ assert.deepEqual(resumed.body.result.resumeArgs, ['resume', FAKE_ROLLOUT_ID],
520
+ `codex resume must target the captured rollout id, got: ${JSON.stringify(resumed.body.result.resumeArgs)}`);
521
+ assert.notEqual(resumed.body.result.resumeArgs[1], sessionId, 'harness session id must not be used for codex resume');
522
+ });
523
+
524
+ // ══════════════════════════════════════════════════════════════════
525
+ // T6 — PTY scanner anti-false-positive: a uuid on a resume error line
526
+ // never fires without a matching rollout file in the sessions dir;
527
+ // once the fs confirms the uuid, the same scanner does fire
528
+ // ══════════════════════════════════════════════════════════════════
529
+ it('T6 - PTY scanner ignores a uuid with no matching rollout file; fires only on fs confirmation', () => {
530
+ const sessionsDir = makeHarnessTempRoot('wf-cri-pty-');
531
+ try {
532
+ const detector = createCodexRolloutIdDetector({ sessionsDir });
533
+
534
+ // `codex resume <harnessSessionId>` fails with this line — the uuid is
535
+ // the HARNESS session id, which never matches a real rollout file, so
536
+ // it must not fire (and must not poison the persisted rollout id).
537
+ const errorLine = `codex: error: No saved session found with ID ${FAKE_ROLLOUT_ID}`;
538
+ assert.equal(detector.observe(errorLine), null, 'error-line harness uuid must never fire without an fs match');
539
+ assert.equal(detector.rolloutId, null, 'detector must stay uncaptured');
540
+ assert.equal(detector.active, true, 'detector must keep scanning after an unmatched uuid');
541
+
542
+ // A real rollout file (nested layout) confirms a REAL uuid, so the same
543
+ // scanner now fires for it.
544
+ const realId = '019ffa36-34a1-7923-ab6b-c66732a1e06e';
545
+ writeRolloutFile(sessionsDir, realId, '2026-08-13T16-21-24');
546
+ const request = detector.observe(`Session ${realId} resumed`);
547
+ assert.ok(request, 'a PTY uuid with a matching nested rollout file must fire');
548
+ assert.equal(request.type, 'codex:rollout-id');
549
+ assert.equal(request.reason, 'codex-rollout-id-detected');
550
+ assert.deepEqual(request.payload, { rolloutId: realId });
551
+ assert.equal(detector.rolloutId, realId);
552
+ } finally {
553
+ fs.rmSync(sessionsDir, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 });
554
+ }
555
+ });
556
+ });