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,323 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { makeHarnessTempRoot } from '../../../tests/support/temp-root.js';
6
+ import {
7
+ buildAgentContext,
8
+ buildAgentSnapshot,
9
+ buildConnections,
10
+ buildConnectedAgentRefs,
11
+ buildConnectedCapabilityRefs,
12
+ buildConnectedEventRefs,
13
+ buildConnectedGoalRefs,
14
+ buildConnectedResourceRefs,
15
+ effectiveSkillGroupsFor,
16
+ findAgentGraphNode,
17
+ outputRoutingFor,
18
+ skillTriggersFor,
19
+ } from '../workflow-agent-context.mjs';
20
+ import { buildWorkflowSnapshot, loadWorkflowGraphMap, writeWorkflowGraphMap } from '../a2a-store.mjs';
21
+ import { SessionRegistry } from '../session-registry.mjs';
22
+ import * as runtime from '../workflow-node-runtime.mjs';
23
+
24
+ // W40-C1-CONTEXT-UNIFY golden test: the API path (/api/workflow/context/:id via
25
+ // buildAgentContext) and the snapshot path (/api/a2a/snapshot per-node context
26
+ // via buildWorkflowSnapshot -> buildSessionGraph) MUST produce the same Agent
27
+ // context shape and values. The snapshot path may only add the session-
28
+ // enumeration extras (agentKind, parentAgentId, connectedPeerIds,
29
+ // outboundPeerIds, inboundPeerIds).
30
+ const SNAPSHOT_ONLY_KEYS = ['agentKind', 'connectedPeerIds', 'inboundPeerIds', 'outboundPeerIds', 'parentAgentId'];
31
+
32
+ const DRIFT_FIELDS = [
33
+ 'defaultSkills',
34
+ 'defaultCapabilityRefs',
35
+ 'ontology',
36
+ 'affordances',
37
+ 'availableActions',
38
+ 'magneticTopology',
39
+ 'outputRouting',
40
+ 'directMagneticNeighbors',
41
+ 'magneticReachableNodes',
42
+ 'magneticGroupId',
43
+ 'identity',
44
+ 'workspace',
45
+ 'connectedPeers',
46
+ 'connectedAgentRefs',
47
+ 'skillTriggers',
48
+ 'availableOnDemandCapabilityRefs',
49
+ 'graphVersion',
50
+ ];
51
+
52
+ function makeProject() {
53
+ const projectRoot = makeHarnessTempRoot('wf-agent-context-');
54
+ const taskRoot = path.join(projectRoot, 'Harness', 'tasks', 'task-context-unify');
55
+ fs.mkdirSync(taskRoot, { recursive: true });
56
+ fs.writeFileSync(path.join(projectRoot, 'Harness', 'PROGRESS.md'), '## Active Task\n\n- task-context-unify\n');
57
+ fs.writeFileSync(path.join(taskRoot, 'STATE.json'), JSON.stringify({
58
+ schemaVersion: 1,
59
+ taskId: 'task-context-unify',
60
+ status: 'active',
61
+ mode: 'wf',
62
+ phase: 'implementation',
63
+ gate: 'AC-GATE',
64
+ links: { dependsOn: [], blocks: [] },
65
+ acceptance: [{ id: 'AC-CONTEXT', text: 'unified context', status: 'pending' }],
66
+ }, null, 2));
67
+ fs.writeFileSync(path.join(taskRoot, 'PLAN.md'), '# Plan\n');
68
+ fs.writeFileSync(path.join(taskRoot, 'PROGRESS.md'), '# Progress\n');
69
+ return projectRoot;
70
+ }
71
+
72
+ async function seedGraphFixture(root) {
73
+ // One agent, one timer (event + control edges), one markdown resource,
74
+ // one goal, one capability (skill-group), one capsule dock (magnetic group).
75
+ const agentNodeId = 'session-context-unify';
76
+ const registry = new SessionRegistry();
77
+ const session = registry.create({
78
+ runtime: 'codex',
79
+ agentKind: 'main',
80
+ role: 'Main Agent',
81
+ graphNodeId: agentNodeId,
82
+ });
83
+ const sessionId = session.sessionId;
84
+ registry.update(sessionId, { status: 'running' });
85
+ const subagent = registry.create({
86
+ runtime: 'claude',
87
+ agentKind: 'subagent',
88
+ role: 'Subagent',
89
+ parentAgentId: sessionId,
90
+ graphNodeId: 'session-context-sub',
91
+ });
92
+ const subSessionId = subagent.sessionId;
93
+ registry.update(subSessionId, { status: 'running' });
94
+
95
+ const markdown = await runtime.createNode(root, { type: 'markdown', title: 'Agent Notes', markdown: '# Notes' });
96
+ const timer = await runtime.createNode(root, {
97
+ type: 'timer',
98
+ title: 'Heartbeat Timer',
99
+ schedule: { mode: 'loop', intervalSeconds: 30 },
100
+ });
101
+ const pack = await runtime.createNode(root, {
102
+ type: 'skill-group',
103
+ title: 'Agent Skill Pack',
104
+ sourceGroup: { id: 'source:workflow', label: 'Workflow', kind: 'source' },
105
+ skills: [
106
+ { id: 'skill:wf-ui', name: 'wf-ui', title: 'WF-UI Adapter', source: 'project' },
107
+ { id: 'skill:browser-lab', name: 'browser-lab', title: 'Browser Lab', source: 'project' },
108
+ ],
109
+ });
110
+ const goalNodeId = 'goal-task-context-unify';
111
+
112
+ writeWorkflowGraphMap(root, {
113
+ schemaVersion: 1,
114
+ version: 7,
115
+ nodes: [{
116
+ nodeId: agentNodeId,
117
+ sessionId,
118
+ kind: 'terminal-session',
119
+ agentKind: 'main',
120
+ runtime: 'codex',
121
+ status: 'running',
122
+ role: 'Main Agent',
123
+ label: 'Main Agent',
124
+ cwd: root,
125
+ taskId: null,
126
+ }],
127
+ edges: [
128
+ { id: 'edge-agent-timer', from: agentNodeId, to: timer.node.nodeId, relation: 'event', direction: 'source-to-target', sourceHandle: 'context', targetHandle: 'event' },
129
+ { id: 'edge-agent-timer-control', from: agentNodeId, to: timer.node.nodeId, relation: 'control', direction: 'source-to-target', sourceHandle: 'context', targetHandle: 'config' },
130
+ { id: 'edge-agent-markdown', from: agentNodeId, to: markdown.node.nodeId, relation: 'default-output', direction: 'bidirectional', sourceHandle: 'output', targetHandle: 'markdown' },
131
+ { id: 'edge-agent-goal', from: agentNodeId, to: goalNodeId, relation: 'goal', direction: 'bidirectional', sourceHandle: 'context', targetHandle: 'goal' },
132
+ { id: 'edge-agent-pack', from: agentNodeId, to: pack.node.nodeId, relation: 'capability', direction: 'bidirectional', sourceHandle: 'right', targetHandle: 'capability:left' },
133
+ ],
134
+ capsuleDockLinks: [{
135
+ id: 'dock-context',
136
+ nodeIds: [agentNodeId, markdown.node.nodeId],
137
+ anchorId: agentNodeId,
138
+ draggedId: markdown.node.nodeId,
139
+ connections: [
140
+ { id: 'dock-context-1', from: agentNodeId, to: markdown.node.nodeId, relation: 'wf-bridge', direction: 'bidirectional' },
141
+ ],
142
+ }],
143
+ positions: {
144
+ [agentNodeId]: { x: 100, y: 100 },
145
+ },
146
+ });
147
+ return { registry, sessionId, subSessionId, agentNodeId, markdown: markdown.node.nodeId, timer: timer.node.nodeId, pack: pack.node.nodeId, goalNodeId };
148
+ }
149
+
150
+ function assertRefsCarryW38e(refs, label) {
151
+ assert.ok(Array.isArray(refs), `${label} must be an array`);
152
+ for (const ref of refs) {
153
+ assert.equal(typeof ref.nodeId, 'string', `${label} ref nodeId`);
154
+ assert.equal(typeof ref.title, 'string', `${label} ref title (${ref.nodeId})`);
155
+ assert.equal(typeof ref.shortId, 'string', `${label} ref shortId (${ref.nodeId})`);
156
+ assert.ok(ref.shortId.length > 0, `${label} ref shortId non-empty (${ref.nodeId})`);
157
+ assert.equal(typeof ref.displayName, 'string', `${label} ref displayName (${ref.nodeId})`);
158
+ assert.ok(ref.displayName.length > 0, `${label} ref displayName non-empty (${ref.nodeId})`);
159
+ }
160
+ }
161
+
162
+ test('API path and snapshot path produce identical Agent context fields and values', async () => {
163
+ const root = makeProject();
164
+ try {
165
+ const fixture = await seedGraphFixture(root);
166
+ const graph = loadWorkflowGraphMap(root);
167
+ const graphNode = findAgentGraphNode(graph, fixture.agentNodeId);
168
+ assert.ok(graphNode, 'agent node must be present in the workflow graph');
169
+
170
+ const api = buildAgentContext(root, graphNode, graph);
171
+ assert.equal(api.ok, true);
172
+ assert.equal(api.node.kind, 'agent');
173
+ const apiContext = api.context;
174
+
175
+ const workflow = buildWorkflowSnapshot(root, fixture.registry);
176
+ const snapContext = workflow.graphContextBySessionId[fixture.sessionId];
177
+ assert.ok(snapContext, 'snapshot must expose per-session graph context');
178
+
179
+ // 1. Field parity: every API field exists in the snapshot path...
180
+ const apiKeys = Object.keys(apiContext);
181
+ const snapKeys = Object.keys(snapContext);
182
+ for (const key of apiKeys) {
183
+ assert.ok(Object.hasOwn(snapContext, key), `snapshot context is missing API field: ${key}`);
184
+ }
185
+ // ...and the snapshot path only adds its session-enumeration extras.
186
+ const extras = snapKeys.filter(key => !apiKeys.includes(key)).sort();
187
+ assert.deepEqual(extras, SNAPSHOT_ONLY_KEYS, `snapshot extras leaked: ${extras.join(',')}`);
188
+
189
+ // 2. Value parity: every shared field has identical values.
190
+ for (const key of apiKeys) {
191
+ assert.deepEqual(apiContext[key], snapContext[key], `value drift on context field: ${key}`);
192
+ }
193
+
194
+ // 3. The W39 drift fields are present in BOTH paths.
195
+ for (const key of DRIFT_FIELDS) {
196
+ assert.ok(Object.hasOwn(apiContext, key), `API context missing drift field: ${key}`);
197
+ assert.ok(Object.hasOwn(snapContext, key), `snapshot context missing drift field: ${key}`);
198
+ }
199
+
200
+ // 4. The snapshot extras keep their contract values (session enumeration;
201
+ // edges to non-session nodes contribute null session ids, as before W40-C1).
202
+ assert.equal(snapContext.agentKind, 'main');
203
+ assert.equal(snapContext.parentAgentId, null);
204
+ assert.ok(snapContext.connectedPeerIds.includes(fixture.subSessionId), 'connectedPeerIds must include the subagent session');
205
+ assert.ok(snapContext.outboundPeerIds.includes(fixture.subSessionId), 'outboundPeerIds must include the subagent session');
206
+ assert.ok(!snapContext.inboundPeerIds.includes(fixture.subSessionId), 'main agent has no inbound session edges');
207
+ const subContext = workflow.graphContextBySessionId[fixture.subSessionId];
208
+ assert.ok(subContext, 'snapshot must expose subagent context');
209
+ assert.equal(subContext.parentAgentId, fixture.sessionId, 'subagent parentAgentId must resolve to the main session');
210
+ assert.ok(subContext.connectedPeerIds.includes(fixture.sessionId), 'subagent connectedPeerIds must include the main session');
211
+
212
+ // 5. Specific drift-field content (both paths).
213
+ for (const context of [apiContext, snapContext]) {
214
+ assert.ok(context.defaultSkills.includes('workflow-ontology'), 'defaultSkills must include workflow-ontology');
215
+ assert.equal(context.ontology.ontologyId, 'harness.workflow.ontology');
216
+ assert.ok(Array.isArray(context.affordances), 'affordances must be an array');
217
+ assert.ok(context.affordances.length > 0, 'affordances must be non-empty');
218
+ assert.ok(context.availableActions.includes('agent.sendInput'), 'availableActions must include agent.sendInput');
219
+ assert.ok(context.availableActions.includes('agent.createNode'), 'availableActions must include agent graph capabilities');
220
+ assert.ok(context.skillTriggers['workflow-node-actions'].includes('draw flowchart'), 'skillTriggers must carry canonical triggers');
221
+ assert.equal(context.skillPolicy, 'auto', 'skillPolicy must come from normalized node config');
222
+ assert.deepEqual(context.outputRouting.markdownDefault, {
223
+ enabled: false,
224
+ explicitTargetNodeId: '',
225
+ resolvedTargetNodeId: '',
226
+ resolution: 'disabled',
227
+ });
228
+ assert.ok(context.magneticTopology.groupCount >= 1, 'magnetic topology must have a group');
229
+ assert.equal(context.magneticTopology.dockLinkCount, 1);
230
+ assert.equal(typeof context.magneticGroupId, 'string');
231
+ assert.ok(context.magneticGroupId.length > 0, 'agent must belong to a magnetic group');
232
+ assert.ok(context.directMagneticNeighbors.includes(fixture.markdown), 'markdown must be a direct magnetic neighbor');
233
+ assert.ok(context.magneticReachableNodes.includes(fixture.markdown), 'markdown must be magnetically reachable');
234
+ assert.equal(context.identity.isMainAgent, true);
235
+ assert.equal(context.workspace.kind, 'agent-node-home');
236
+ assert.equal(context.graphVersion, 7);
237
+ }
238
+
239
+ // 6. Connected refs carry shortId + displayName + title (W38e) in both paths.
240
+ for (const context of [apiContext, snapContext]) {
241
+ assertRefsCarryW38e(context.connectedResourceRefs, 'connectedResourceRefs');
242
+ assertRefsCarryW38e(context.connectedEventRefs, 'connectedEventRefs');
243
+ assertRefsCarryW38e(context.connectedCapabilityRefs, 'connectedCapabilityRefs');
244
+ assertRefsCarryW38e(context.connectedGoalRefs, 'connectedGoalRefs');
245
+ assertRefsCarryW38e(context.connectedCapabilityNodeRefs, 'connectedCapabilityNodeRefs');
246
+ }
247
+
248
+ // 7. Timer control affordance resolves through the control edge (both paths).
249
+ for (const context of [apiContext, snapContext]) {
250
+ const timerRef = context.connectedEventRefs.find(ref => ref.type === 'timer');
251
+ assert.ok(timerRef, 'timer event ref must be connected');
252
+ assert.equal(timerRef.canControl, true, 'control edge must grant timer control');
253
+ assert.ok(timerRef.allowedActions.includes('timer.configure'), 'timer control actions must be allowed');
254
+ assert.equal(timerRef.connection.relation, 'event');
255
+ }
256
+
257
+ // 8. Goal and capability refs resolve (both paths).
258
+ for (const context of [apiContext, snapContext]) {
259
+ assert.ok(context.connectedGoalRefs.some(ref => ref.nodeId === fixture.goalNodeId && ref.type === 'goal'), 'goal ref must resolve');
260
+ assert.ok(context.connectedCapabilityNodeRefs.some(ref => ref.nodeId === fixture.pack && ref.capabilityKind === 'skill-group'), 'skill-group ref must resolve');
261
+ }
262
+
263
+ // 9. effectiveSkillGroups carry skillRefs with enabled (W38-BE-FOLLOWUP, both paths).
264
+ for (const context of [apiContext, snapContext]) {
265
+ assert.equal(context.effectiveSkillGroups.length, 1);
266
+ const group = context.effectiveSkillGroups[0];
267
+ assert.equal(group.nodeId, fixture.pack);
268
+ assert.equal(group.label, 'Workflow');
269
+ assert.deepEqual(group.skillNames, ['wf-ui', 'browser-lab']);
270
+ for (const skillRef of group.skillRefs) {
271
+ assert.equal(skillRef.enabled, true, `skill ${skillRef.name} must default to enabled:true`);
272
+ assert.deepEqual(Object.keys(skillRef).sort(), ['enabled', 'id', 'name', 'source', 'state', 'title']);
273
+ }
274
+ assert.ok(context.effectiveSkills.includes('wf-ui'), 'connected skill names must feed effectiveSkills');
275
+ assert.ok(context.effectiveSkills.includes('browser-lab'), 'connected skill names must feed effectiveSkills');
276
+ }
277
+
278
+ // 10. connectedPeers enumerates every non-agent peer in both paths
279
+ // (timer appears once per event/control edge; the capsule dock duplicates
280
+ // the markdown edge — dedupe by node id for the peer-set assertion).
281
+ for (const context of [apiContext, snapContext]) {
282
+ const peerIds = [...new Set(context.connectedPeers.map(peer => peer.nodeId))].sort();
283
+ assert.deepEqual(peerIds, [fixture.goalNodeId, fixture.markdown, fixture.pack, fixture.timer].sort());
284
+ const goalPeer = context.connectedPeers.find(peer => peer.nodeId === fixture.goalNodeId);
285
+ assert.equal(goalPeer.type, 'goal');
286
+ assert.equal(typeof goalPeer.shortId, 'string');
287
+ assert.equal(typeof goalPeer.displayName, 'string');
288
+ }
289
+ } finally {
290
+ fs.rmSync(root, { recursive: true, force: true });
291
+ }
292
+ });
293
+
294
+ test('sub-builders are independently importable and produce the canonical shapes', async () => {
295
+ const root = makeProject();
296
+ try {
297
+ const fixture = await seedGraphFixture(root);
298
+ const graph = loadWorkflowGraphMap(root);
299
+ const graphNode = findAgentGraphNode(graph, fixture.agentNodeId);
300
+ const nodeId = fixture.agentNodeId;
301
+
302
+ const resourceRefs = buildConnectedResourceRefs(root, nodeId, graph);
303
+ assert.ok(resourceRefs.some(ref => ref.nodeId === fixture.markdown));
304
+ const eventRefs = buildConnectedEventRefs(root, nodeId, graph);
305
+ assert.ok(eventRefs.some(ref => ref.nodeId === fixture.timer));
306
+ const capabilityRefs = buildConnectedCapabilityRefs(root, nodeId, graph);
307
+ assert.ok(capabilityRefs.some(ref => ref.nodeId === fixture.pack));
308
+ const goalRefs = buildConnectedGoalRefs(root, nodeId, graph);
309
+ assert.ok(goalRefs.some(ref => ref.nodeId === fixture.goalNodeId));
310
+ const agentRefs = buildConnectedAgentRefs(root, nodeId, graph, { isMainAgent: true });
311
+ assert.deepEqual(agentRefs, []);
312
+ const connections = buildConnections(nodeId, graph);
313
+ assert.equal(connections.length, 6); // 5 edges + 1 capsule-dock connection
314
+ assert.ok(effectiveSkillGroupsFor(capabilityRefs).length >= 1);
315
+ assert.ok(Object.keys(skillTriggersFor(['workflow-ontology'])).includes('workflow-ontology'));
316
+ assert.deepEqual(outputRoutingFor({ values: {} }, resourceRefs).markdownDefault.resolution, 'disabled');
317
+ const snapshot = buildAgentSnapshot(root, graphNode, graph);
318
+ assert.equal(snapshot.kind, 'agent');
319
+ assert.equal(snapshot.sessionId, fixture.sessionId);
320
+ } finally {
321
+ fs.rmSync(root, { recursive: true, force: true });
322
+ }
323
+ });
@@ -0,0 +1,318 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import http from 'node:http';
6
+ import { makeHarnessTempRoot } from '../../../tests/support/temp-root.js';
7
+ import { loadWorkflowGraphMap, writeWorkflowGraphMap, loadA2aSkills } from '../a2a-store.mjs';
8
+ import { workflowOntology } from '../workflow-ontology.mjs';
9
+ import { createNode } from '../workflow-node-runtime.mjs';
10
+ import { startServer, stopServer } from '../server.mjs';
11
+ import { SessionRegistry } from '../session-registry.mjs';
12
+
13
+ // ── Helpers ──
14
+ function seedRoot() {
15
+ const root = makeHarnessTempRoot('wf-agent-coop-permissions-');
16
+ fs.mkdirSync(path.join(root, 'Harness', 'tasks'), { recursive: true });
17
+ fs.mkdirSync(path.join(root, 'Harness', 'a2a'), { recursive: true });
18
+ return root;
19
+ }
20
+
21
+ function seedActiveTask(root, taskId = 'task-coop-permissions') {
22
+ fs.mkdirSync(path.join(root, 'Harness', 'tasks', taskId), { recursive: true });
23
+ fs.writeFileSync(path.join(root, 'Harness', 'PROGRESS.md'), `# PROGRESS.md\n\n## Active Task\n\n- ${taskId}\n`, 'utf8');
24
+ fs.writeFileSync(path.join(root, 'Harness', 'tasks', taskId, 'STATE.json'), JSON.stringify({
25
+ schemaVersion: 1,
26
+ taskId,
27
+ status: 'active',
28
+ nextAction: 'Close cooperation permission gates',
29
+ acceptance: [],
30
+ planItems: [],
31
+ phase: 'implement',
32
+ }));
33
+ return `goal-${taskId}`;
34
+ }
35
+
36
+ async function seedGoalItems(base, goalNodeId, agentNodeId, count) {
37
+ const added = await jsonRequest(base, `/api/workflow/nodes/${goalNodeId}/actions/goal.add`, {
38
+ method: 'POST',
39
+ body: { actorNodeId: agentNodeId, planItems: Array.from({ length: count }, (_, index) => ({ text: `Open item ${index + 1}` })) },
40
+ });
41
+ assert.equal(added.status, 200, JSON.stringify(added.body));
42
+ return added;
43
+ }
44
+
45
+ function seedAgentGraphNode(root, nodeId, sessionId = `${nodeId}-pty`) {
46
+ writeWorkflowGraphMap(root, {
47
+ ...loadWorkflowGraphMap(root),
48
+ version: loadWorkflowGraphMap(root).version + 1,
49
+ nodes: [
50
+ ...(loadWorkflowGraphMap(root).nodes || []),
51
+ { nodeId, sessionId, kind: 'terminal-session', runtime: 'claude', agentKind: 'subagent', role: 'Agent', label: 'Agent', status: 'stopped' },
52
+ ],
53
+ });
54
+ return nodeId;
55
+ }
56
+
57
+ function connectGoal(root, goalNodeId, agentNodeId) {
58
+ writeWorkflowGraphMap(root, {
59
+ ...loadWorkflowGraphMap(root),
60
+ version: loadWorkflowGraphMap(root).version + 1,
61
+ edges: [
62
+ ...(loadWorkflowGraphMap(root).edges || []),
63
+ { id: `edge-${goalNodeId}-${agentNodeId}`, from: goalNodeId, to: agentNodeId, relation: 'goal', direction: 'bidirectional' },
64
+ ],
65
+ });
66
+ }
67
+
68
+ function dockLink(a, b) {
69
+ const pair = [a, b].sort();
70
+ return {
71
+ id: `dock:${pair[0]}::${pair[1]}`,
72
+ nodeIds: pair,
73
+ anchorId: pair[0],
74
+ draggedId: pair[1],
75
+ side: 'top',
76
+ edges: [],
77
+ connections: [
78
+ {
79
+ source: a,
80
+ target: b,
81
+ relation: 'wf-bridge',
82
+ direction: 'source-to-target',
83
+ sourceHandle: 'dock',
84
+ targetHandle: 'dock',
85
+ },
86
+ ],
87
+ };
88
+ }
89
+
90
+ function jsonRequest(baseUrl, route, { method = 'GET', body } = {}) {
91
+ return new Promise((resolve, reject) => {
92
+ const url = new URL(route, baseUrl);
93
+ const payload = body === undefined ? null : JSON.stringify(body);
94
+ const req = http.request(url, {
95
+ method,
96
+ headers: payload ? { 'content-type': 'application/json' } : {},
97
+ });
98
+ req.on('response', (res) => {
99
+ let data = '';
100
+ res.on('data', chunk => { data += chunk; });
101
+ res.on('end', () => {
102
+ try { resolve({ status: res.statusCode, body: JSON.parse(data) }); }
103
+ catch { resolve({ status: res.statusCode, body: data }); }
104
+ });
105
+ });
106
+ req.on('error', reject);
107
+ if (payload) req.write(payload);
108
+ req.end();
109
+ });
110
+ }
111
+
112
+ async function startTestServer(root) {
113
+ const registry = new SessionRegistry();
114
+ const started = await startServer({ projectRoot: root, host: '127.0.0.1', port: 0, sessionRegistry: registry });
115
+ return { base: `http://127.0.0.1:${started.port}`, stop: () => stopServer(started.server) };
116
+ }
117
+
118
+ // ── Agent-visible allowed action set (spec §7/§8: agents tick goals and use the
119
+ // markdown blackboard with locks; timer.dispatchWakeup stays denied) ──
120
+ test('AC-013/AC-016/AC-017 (a): agent allowed set includes goal item + markdown lock actions; dispatchWakeup denied', () => {
121
+ const root = seedRoot();
122
+ try {
123
+ // Backend skill manuals carry the agent-visible allowed lists (a2a-store defaults)
124
+ const skills = loadA2aSkills(root);
125
+ const goalSkill = skills.find(s => s.skillId === 'workflow-goal-node');
126
+ assert.ok(goalSkill, 'workflow-goal-node skill must be present');
127
+ for (const action of ['goal.add', 'goal.delete', 'goal.replace', 'goal.check', 'goal.uncheck', 'goal.complete', 'goal.reopen']) {
128
+ assert.ok(goalSkill.policy.allowed.includes(action), `goal skill allowed set must include ${action}`);
129
+ }
130
+ const markdownSkill = skills.find(s => s.skillId === 'workflow-markdown-node');
131
+ assert.ok(markdownSkill, 'workflow-markdown-node skill must be present');
132
+ for (const action of ['markdown.find', 'markdown.acquireLock', 'markdown.releaseLock']) {
133
+ assert.ok(markdownSkill.policy.allowed.includes(action), `markdown skill allowed set must include ${action}`);
134
+ }
135
+ const resourceSkill = skills.find(s => s.skillId === 'workflow-resource-node');
136
+ assert.ok(resourceSkill, 'workflow-resource-node skill must be present');
137
+ for (const action of ['markdown.find', 'markdown.acquireLock', 'markdown.releaseLock']) {
138
+ assert.ok(resourceSkill.policy.allowed.includes(action), `resource skill allowed set must include ${action}`);
139
+ }
140
+
141
+ // timer.dispatchWakeup stays denied to agents everywhere in the skill layer
142
+ for (const skill of skills) {
143
+ for (const list of [skill.policy?.allowed, skill.policy?.subagent, skill.policy?.mainAgent]) {
144
+ if (Array.isArray(list)) {
145
+ assert.ok(!list.includes('timer.dispatchWakeup'), `timer.dispatchWakeup must not appear in ${skill.skillId} allowed lists`);
146
+ }
147
+ }
148
+ }
149
+
150
+ // Ontology affordances: goal/markdown schema expose the new actions to agents
151
+ const ontology = workflowOntology();
152
+ const goalSchema = ontology.nodeTypes.goal;
153
+ for (const action of ['goal.add', 'goal.delete', 'goal.replace', 'goal.check', 'goal.uncheck', 'goal.complete', 'goal.reopen']) {
154
+ assert.ok(goalSchema.writableActions.includes(action), `goal ontology writableActions must include ${action}`);
155
+ }
156
+ const markdownSchema = ontology.nodeTypes.markdown;
157
+ assert.ok(markdownSchema.readableActions.includes('markdown.find'), 'markdown ontology must expose markdown.find as a read action');
158
+ assert.ok(markdownSchema.writableActions.includes('markdown.acquireLock'), 'markdown ontology writableActions must include markdown.acquireLock');
159
+ assert.ok(markdownSchema.writableActions.includes('markdown.releaseLock'), 'markdown ontology writableActions must include markdown.releaseLock');
160
+
161
+ // timer.dispatchWakeup remains a runtime action, denied to agents
162
+ assert.ok(ontology.nodeTypes.timer.runtimeActions.includes('timer.dispatchWakeup'), 'timer.dispatchWakeup must stay a runtime action');
163
+ } finally {
164
+ fs.rmSync(root, { recursive: true, force: true });
165
+ }
166
+ });
167
+
168
+ // ── Live HTTP dispatch: an agent CAN invoke goal.check and markdown.acquireLock ──
169
+ test('AC-013/AC-017 (a): agent invokes goal.check and markdown.acquireLock through the node-action route', async () => {
170
+ const root = seedRoot();
171
+ const goalNodeId = seedActiveTask(root);
172
+ const agentNodeId = seedAgentGraphNode(root, 'agent-coop-1');
173
+ connectGoal(root, goalNodeId, agentNodeId);
174
+ const markdown = await createNode(root, { type: 'markdown', title: 'Team Blackboard' });
175
+ const markdownNodeId = markdown.node.nodeId;
176
+ const server = await startTestServer(root);
177
+ try {
178
+ await seedGoalItems(server.base, goalNodeId, agentNodeId, 1);
179
+ const goalCheck = await jsonRequest(server.base, `/api/workflow/nodes/${goalNodeId}/actions/goal.check`, {
180
+ method: 'POST',
181
+ body: { planItemIds: ['P-001'], actorNodeId: agentNodeId },
182
+ });
183
+ assert.equal(goalCheck.status, 200, JSON.stringify(goalCheck.body));
184
+ assert.equal(goalCheck.body.ok, true);
185
+ assert.equal(goalCheck.body.action, 'goal.check');
186
+ assert.equal(goalCheck.body.result.state.planItems[0].status, 'done', 'goal.check must tick the item');
187
+
188
+ const acquire = await jsonRequest(server.base, `/api/workflow/nodes/${markdownNodeId}/actions/markdown.acquireLock`, {
189
+ method: 'POST',
190
+ body: { lockOwner: agentNodeId, ttlSeconds: 30 },
191
+ });
192
+ assert.equal(acquire.status, 200, JSON.stringify(acquire.body));
193
+ assert.ok(acquire.body.result.lockId, 'acquireLock must return a lockId');
194
+ assert.equal(acquire.body.result.owner, agentNodeId);
195
+ } finally {
196
+ await server.stop();
197
+ fs.rmSync(root, { recursive: true, force: true });
198
+ }
199
+ });
200
+
201
+ // ── HTTP error body detail fields (spec §7 goal_items_pending) ──
202
+ test('AC-014 (c): HTTP goal.complete rejection carries remaining ids in the body', async () => {
203
+ const root = seedRoot();
204
+ const goalNodeId = seedActiveTask(root);
205
+ const agentNodeId = seedAgentGraphNode(root, 'agent-coop-2');
206
+ connectGoal(root, goalNodeId, agentNodeId);
207
+ const server = await startTestServer(root);
208
+ try {
209
+ await seedGoalItems(server.base, goalNodeId, agentNodeId, 2);
210
+ const complete = await jsonRequest(server.base, `/api/workflow/nodes/${goalNodeId}/actions/goal.complete`, {
211
+ method: 'POST',
212
+ body: { evidenceRefs: [], actorNodeId: agentNodeId },
213
+ });
214
+ assert.equal(complete.status, 409, JSON.stringify(complete.body));
215
+ assert.equal(complete.body.error.code, 'goal_items_pending');
216
+ assert.equal(complete.body.error.message, 'Complete all plan items before completing the Goal.');
217
+ assert.deepEqual(complete.body.remaining, ['P-001', 'P-002'], 'HTTP body must carry the typed remaining field');
218
+ } finally {
219
+ await server.stop();
220
+ fs.rmSync(root, { recursive: true, force: true });
221
+ }
222
+ });
223
+
224
+ // ── HTTP error body detail fields (spec §8.3 markdown_conflict) ──
225
+ test('AC-018 (d): HTTP markdown_conflict carries currentRevision + expectedRevision', async () => {
226
+ const root = seedRoot();
227
+ const markdown = await createNode(root, { type: 'markdown', title: 'Blackboard' });
228
+ const markdownNodeId = markdown.node.nodeId;
229
+ const server = await startTestServer(root);
230
+ try {
231
+ const v1 = await jsonRequest(server.base, `/api/workflow/nodes/${markdownNodeId}/actions/markdown.append`, {
232
+ method: 'POST',
233
+ body: { markdown: '# v1' },
234
+ });
235
+ assert.equal(v1.status, 200, JSON.stringify(v1.body));
236
+ const v2 = await jsonRequest(server.base, `/api/workflow/nodes/${markdownNodeId}/actions/markdown.append`, {
237
+ method: 'POST',
238
+ body: { markdown: '# v2' },
239
+ });
240
+ assert.equal(v2.status, 200, JSON.stringify(v2.body));
241
+ const currentRevision = v2.body.result.revision;
242
+
243
+ const stale = await jsonRequest(server.base, `/api/workflow/nodes/${markdownNodeId}/actions/markdown.append`, {
244
+ method: 'POST',
245
+ body: { markdown: '# stale', expectedRevision: 1 },
246
+ });
247
+ assert.equal(stale.status, 409, JSON.stringify(stale.body));
248
+ assert.equal(stale.body.error.code, 'markdown_conflict');
249
+ assert.equal(stale.body.currentRevision, currentRevision, 'HTTP body must carry currentRevision');
250
+ assert.equal(stale.body.expectedRevision, 1, 'HTTP body must carry expectedRevision');
251
+
252
+ // Lock conflict (spec §8.2/8.3, F18/D15): write by a non-holder is refused
253
+ // with markdown_locked — mandatory exclusion while the lock is held, even
254
+ // without expectedRevision — carrying the holder and lease expiry so the
255
+ // UI can surface them.
256
+ const lock = await jsonRequest(server.base, `/api/workflow/nodes/${markdownNodeId}/actions/markdown.acquireLock`, {
257
+ method: 'POST',
258
+ body: { lockOwner: 'agent-a', ttlSeconds: 30 },
259
+ });
260
+ assert.equal(lock.status, 200, JSON.stringify(lock.body));
261
+ const locked = await jsonRequest(server.base, `/api/workflow/nodes/${markdownNodeId}/actions/markdown.append`, {
262
+ method: 'POST',
263
+ body: { markdown: '# blocked', lockOwner: 'agent-b' },
264
+ });
265
+ assert.equal(locked.status, 409, JSON.stringify(locked.body));
266
+ assert.equal(locked.body.error.code, 'markdown_locked');
267
+ assert.equal(locked.body.holder, 'agent-a', 'HTTP body must carry the lock holder');
268
+ assert.ok(locked.body.expiresAt > Date.now(), 'HTTP body must carry the lock expiresAt');
269
+ } finally {
270
+ await server.stop();
271
+ fs.rmSync(root, { recursive: true, force: true });
272
+ }
273
+ });
274
+
275
+ // ── HTTP error body detail fields (spec §6.2 goal_already_bound, AC-015/T12) ──
276
+ test('AC-015 (e): HTTP goal_already_bound carries existingGoalNodeId + timerNodeId (409)', async () => {
277
+ const root = seedRoot();
278
+ const goalNodeId = seedActiveTask(root);
279
+ const timer = await createNode(root, { type: 'timer', title: 'Coop Timer' });
280
+ const timerNodeId = timer.node.nodeId;
281
+ const agentNodeId = seedAgentGraphNode(root, 'agent-coop-3');
282
+ writeWorkflowGraphMap(root, {
283
+ ...loadWorkflowGraphMap(root),
284
+ version: loadWorkflowGraphMap(root).version + 1,
285
+ capsuleDockLinks: [
286
+ dockLink(goalNodeId, timerNodeId),
287
+ dockLink(timerNodeId, agentNodeId),
288
+ ],
289
+ });
290
+ const server = await startTestServer(root);
291
+ try {
292
+ const first = await jsonRequest(server.base, '/api/workflow/nodes', { method: 'POST', body: { type: 'goal' } });
293
+ assert.equal(first.status, 201, JSON.stringify(first.body));
294
+
295
+ // Inject a second goal into the same magnetic group
296
+ writeWorkflowGraphMap(root, {
297
+ ...loadWorkflowGraphMap(root),
298
+ version: loadWorkflowGraphMap(root).version + 1,
299
+ nodes: [
300
+ ...(loadWorkflowGraphMap(root).nodes || []),
301
+ { nodeId: 'goal-second', label: 'Second Goal' },
302
+ ],
303
+ capsuleDockLinks: [
304
+ ...(loadWorkflowGraphMap(root).capsuleDockLinks || []),
305
+ dockLink(agentNodeId, 'goal-second'),
306
+ ],
307
+ });
308
+
309
+ const second = await jsonRequest(server.base, '/api/workflow/nodes', { method: 'POST', body: { type: 'goal' } });
310
+ assert.equal(second.status, 409, JSON.stringify(second.body));
311
+ assert.equal(second.body.error, 'goal_already_bound');
312
+ assert.equal(second.body.existingGoalNodeId, 'goal-second');
313
+ assert.equal(second.body.timerNodeId, timerNodeId);
314
+ } finally {
315
+ await server.stop();
316
+ fs.rmSync(root, { recursive: true, force: true });
317
+ }
318
+ });