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.
- package/CHANGELOG.md +49 -0
- package/README-CN.md +4 -2
- package/README.md +23 -4
- package/package.json +17 -2
- package/src/generator.js +19 -6
- package/src/index.js +531 -38
- package/src/prompts.js +4 -4
- package/src/ui/dist/assets/AgentsRoute-BGGs90wH.js +7 -0
- package/src/ui/dist/assets/Assistant-Bold-gm-uSS1B.woff2 +0 -0
- package/src/ui/dist/assets/Assistant-Medium-DrcxCXg3.woff2 +0 -0
- package/src/ui/dist/assets/Assistant-Regular-DVxZuzxb.woff2 +0 -0
- package/src/ui/dist/assets/Assistant-SemiBold-SCI4bEL9.woff2 +0 -0
- package/src/ui/dist/assets/Combination-DhBLEmof.js +42 -0
- package/src/ui/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/src/ui/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/src/ui/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/src/ui/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/src/ui/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/src/ui/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/src/ui/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/src/ui/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/src/ui/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/src/ui/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/src/ui/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/src/ui/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/src/ui/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/src/ui/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/src/ui/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/src/ui/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/src/ui/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/src/ui/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/src/ui/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/src/ui/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/src/ui/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/src/ui/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/src/ui/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/src/ui/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/src/ui/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/src/ui/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/src/ui/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/src/ui/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/src/ui/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/src/ui/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/src/ui/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/src/ui/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/src/ui/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/src/ui/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/src/ui/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/src/ui/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/src/ui/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/src/ui/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/src/ui/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/src/ui/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/src/ui/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/src/ui/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/src/ui/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/src/ui/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/src/ui/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/src/ui/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/src/ui/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/src/ui/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/src/ui/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/src/ui/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/src/ui/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/src/ui/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/src/ui/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/src/ui/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/src/ui/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/src/ui/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/src/ui/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/src/ui/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/src/ui/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/src/ui/dist/assets/RolesRoute-DnodCSz0.js +2 -0
- package/src/ui/dist/assets/RuntimePicker-CucD8TGn.js +7 -0
- package/src/ui/dist/assets/SettingsRoute-DquMWjac.js +2 -0
- package/src/ui/dist/assets/TaskList-Bxc0Uktx.js +7 -0
- package/src/ui/dist/assets/TerminalDrawer-CDusYltc.js +36 -0
- package/src/ui/dist/assets/WorkflowRoute-BN8yHmUs.css +1 -0
- package/src/ui/dist/assets/WorkflowRoute-D-0wVDpY.js +334 -0
- package/src/ui/dist/assets/abnfDiagram-VRR7QNED-zkRKkaxO.js +2 -0
- package/src/ui/dist/assets/apl-B4CMkyY2.js +2 -0
- package/src/ui/dist/assets/ar-SA-G6X2FPQ2-BiHaArx5.js +11 -0
- package/src/ui/dist/assets/arc-CBnLtOFO.js +2 -0
- package/src/ui/dist/assets/architectureDiagram-ZJ3FMSHR-DWXRXsh1.js +37 -0
- package/src/ui/dist/assets/asciiarmor-Df11BRmG.js +2 -0
- package/src/ui/dist/assets/asn1-EdZsLKOL.js +2 -0
- package/src/ui/dist/assets/asterisk-B-8jnY81.js +2 -0
- package/src/ui/dist/assets/az-AZ-76LH7QW2-CiT05voO.js +2 -0
- package/src/ui/dist/assets/bg-BG-XCXSNQG7-L-UM9tNf.js +6 -0
- package/src/ui/dist/assets/blockDiagram-677ZJIJ3-BIyh3Bry.js +133 -0
- package/src/ui/dist/assets/bn-BD-2XOGV67Q-NdgbA0bC.js +6 -0
- package/src/ui/dist/assets/brainfuck-C4LP7Hcl.js +2 -0
- package/src/ui/dist/assets/c4Diagram-LMCZKHZV-CA54vWWM.js +11 -0
- package/src/ui/dist/assets/ca-ES-6MX7JW3Y-BKZZsQ5J.js +9 -0
- package/src/ui/dist/assets/channel-Da_-zcAu.js +2 -0
- package/src/ui/dist/assets/chunk-2Q5K7J3B-DE4cxr1v.js +2 -0
- package/src/ui/dist/assets/chunk-32BRIVSS-i7FwbEU9.js +2 -0
- package/src/ui/dist/assets/chunk-5VM5RSS4-BhIcOYSu.js +16 -0
- package/src/ui/dist/assets/chunk-EX3LRPZG-Ci9zZRIs.js +232 -0
- package/src/ui/dist/assets/chunk-JWPE2WC7-BFdkcz-G.js +2 -0
- package/src/ui/dist/assets/chunk-MOJQB5TN-Dzmapl_S.js +89 -0
- package/src/ui/dist/assets/chunk-RYQCIY6F-RTmp7FOy.js +2 -0
- package/src/ui/dist/assets/chunk-V7JOEXUC-DInU3v3D.js +207 -0
- package/src/ui/dist/assets/chunk-VR4S4FIN-BHoyGBQO.js +2 -0
- package/src/ui/dist/assets/chunk-XXDRQBXY-DfeLZNZx.js +2 -0
- package/src/ui/dist/assets/classDiagram-OUVF2IWQ-FKbUS0bu.js +2 -0
- package/src/ui/dist/assets/classDiagram-v2-EOCWNBFH-FKbUS0bu.js +2 -0
- package/src/ui/dist/assets/clike-B9uivgTg.js +2 -0
- package/src/ui/dist/assets/clojure-BMjYHr_A.js +2 -0
- package/src/ui/dist/assets/cmake-BQqOBYOt.js +2 -0
- package/src/ui/dist/assets/cobol-CWcv1MsR.js +2 -0
- package/src/ui/dist/assets/coffeescript-S37ZYGWr.js +2 -0
- package/src/ui/dist/assets/commonlisp-DBKNyK5s.js +2 -0
- package/src/ui/dist/assets/cose-bilkent-JH36ORCC-_5PUJ615.js +2 -0
- package/src/ui/dist/assets/crystal-SjHAIU92.js +2 -0
- package/src/ui/dist/assets/cs-CZ-2BRQDIVT-DnkfnhDU.js +12 -0
- package/src/ui/dist/assets/css-BnMrqG3P.js +2 -0
- package/src/ui/dist/assets/cynefin-VYW2F7L2-CmkcFv-b.js +179 -0
- package/src/ui/dist/assets/cynefinDiagram-TSTJHNR4-D72VZn8H.js +63 -0
- package/src/ui/dist/assets/cypher-C_CwsFkJ.js +2 -0
- package/src/ui/dist/assets/cytoscape.esm-DTSO7Bv0.js +332 -0
- package/src/ui/dist/assets/d-pRatUO7H.js +2 -0
- package/src/ui/dist/assets/da-DK-5WZEPLOC-C54tQUgd.js +6 -0
- package/src/ui/dist/assets/dagre-VKFMJZFB-0BsAkrmo.js +5 -0
- package/src/ui/dist/assets/de-DE-XR44H4JA-DGfZlR10.js +9 -0
- package/src/ui/dist/assets/defaultLocale-DX6XiGOO.js +2 -0
- package/src/ui/dist/assets/diagram-FQU43EPY-C1ZJDOca.js +4 -0
- package/src/ui/dist/assets/diagram-G47NLZAW-D3pr3FSP.js +25 -0
- package/src/ui/dist/assets/diagram-NH7WQ7WH-Bwry0NV-.js +25 -0
- package/src/ui/dist/assets/diagram-OA4YK3LP-L6g09cmV.js +31 -0
- package/src/ui/dist/assets/diagram-WEI45ONY-Bh1puYVX.js +42 -0
- package/src/ui/dist/assets/diff-DbItnlRl.js +2 -0
- package/src/ui/dist/assets/directory-open-01563666-DWU9wJ6I.js +2 -0
- package/src/ui/dist/assets/directory-open-4ed118d0-CunoC1EB.js +2 -0
- package/src/ui/dist/assets/dockerfile-BKs6k2Af.js +2 -0
- package/src/ui/dist/assets/dtd-DF_7sFjM.js +2 -0
- package/src/ui/dist/assets/dylan-DwRh75JA.js +2 -0
- package/src/ui/dist/assets/ebnf-CDyGwa7X.js +2 -0
- package/src/ui/dist/assets/ebnfDiagram-CCIWWBDH-BC_mBRR5.js +2 -0
- package/src/ui/dist/assets/ecl-Cabwm37j.js +2 -0
- package/src/ui/dist/assets/eiffel-CnydiIhH.js +2 -0
- package/src/ui/dist/assets/el-GR-BZB4AONW-DsnwWweL.js +11 -0
- package/src/ui/dist/assets/elm-vLlmbW-K.js +2 -0
- package/src/ui/dist/assets/erDiagram-Q63AITRT-Bkxam36l.js +86 -0
- package/src/ui/dist/assets/erlang-BNw1qcRV.js +2 -0
- package/src/ui/dist/assets/es-ES-U4NZUMDT-CRxBcQgC.js +10 -0
- package/src/ui/dist/assets/eu-ES-A7QVB2H4-CTd_E7YR.js +12 -0
- package/src/ui/dist/assets/excalidraw-default-bMWIgNCy.svg +1 -0
- package/src/ui/dist/assets/fa-IR-HGAKTJCU-DO56k7eG.js +9 -0
- package/src/ui/dist/assets/factor-kuTfRLto.js +2 -0
- package/src/ui/dist/assets/fcl-Kvtd6kyn.js +2 -0
- package/src/ui/dist/assets/fi-FI-Z5N7JZ37-DEDCF9WB.js +7 -0
- package/src/ui/dist/assets/file-open-002ab408-DIuFHtCF.js +2 -0
- package/src/ui/dist/assets/file-open-7c801643-684qeFg4.js +2 -0
- package/src/ui/dist/assets/file-save-3189631c-C1wFhQhH.js +2 -0
- package/src/ui/dist/assets/file-save-745eba88-Bb9F9Kg7.js +2 -0
- package/src/ui/dist/assets/flowDiagram-23GEKE2U-C3SAEao7.js +157 -0
- package/src/ui/dist/assets/forth-Ffai-XNe.js +2 -0
- package/src/ui/dist/assets/fortran-DYz_wnZ1.js +2 -0
- package/src/ui/dist/assets/fr-FR-RHASNOE6-DE2nPyDt.js +10 -0
- package/src/ui/dist/assets/ganttDiagram-NO4QXBWP-U-J_Xi-_.js +293 -0
- package/src/ui/dist/assets/gas-Bneqetm1.js +2 -0
- package/src/ui/dist/assets/gherkin-heZmZLOM.js +2 -0
- package/src/ui/dist/assets/gitGraphDiagram-IHSO6WYX-BADVbD-a.js +107 -0
- package/src/ui/dist/assets/gl-ES-HMX3MZ6V-mCqVgQHC.js +11 -0
- package/src/ui/dist/assets/graph-C9eacEi8.js +2 -0
- package/src/ui/dist/assets/groovy-D9Dt4D0W.js +2 -0
- package/src/ui/dist/assets/haskell-Cw1EW3IL.js +2 -0
- package/src/ui/dist/assets/haxe-H-WmDvRZ.js +2 -0
- package/src/ui/dist/assets/he-IL-6SHJWFNN-KnaLrCzw.js +11 -0
- package/src/ui/dist/assets/hi-IN-IWLTKZ5I-wuqiaaWt.js +5 -0
- package/src/ui/dist/assets/http-DBlCnlav.js +2 -0
- package/src/ui/dist/assets/hu-HU-A5ZG7DT2-DLg_zm22.js +8 -0
- package/src/ui/dist/assets/id-ID-SAP4L64H-MB2mXqcR.js +11 -0
- package/src/ui/dist/assets/idl-BEugSyMb.js +2 -0
- package/src/ui/dist/assets/image-blob-reduce.esm-HwCm7IZ0.js +8 -0
- package/src/ui/dist/assets/index-39SJtrt0.js +2 -0
- package/src/ui/dist/assets/index-BQ0LIrW-.js +2 -0
- package/src/ui/dist/assets/index-BcAUh2Nm.css +1 -0
- package/src/ui/dist/assets/index-BcThOK-i.js +331 -0
- package/src/ui/dist/assets/index-BnxV3k_S.js +3 -0
- package/src/ui/dist/assets/index-C7MZBHbT.js +117 -0
- package/src/ui/dist/assets/index-CCvKI2rM.js +2 -0
- package/src/ui/dist/assets/index-CZvmcCab.js +8 -0
- package/src/ui/dist/assets/index-Cp3hLKNl.js +2 -0
- package/src/ui/dist/assets/index-D7ayFxcx.js +2 -0
- package/src/ui/dist/assets/index-DAYxSQGU.js +2 -0
- package/src/ui/dist/assets/index-DD-HeMV0.css +1 -0
- package/src/ui/dist/assets/index-DPMxd3Qn.js +2 -0
- package/src/ui/dist/assets/index-DSe2jx3k.js +4 -0
- package/src/ui/dist/assets/index-DUirCkgW.js +2 -0
- package/src/ui/dist/assets/index-DaKPQ2hN.js +159 -0
- package/src/ui/dist/assets/index-DzpuR0Jg.js +2 -0
- package/src/ui/dist/assets/index-POndwsCI.js +2 -0
- package/src/ui/dist/assets/index-R8NM9I_9.js +2 -0
- package/src/ui/dist/assets/index-TCDuDhBj.js +2 -0
- package/src/ui/dist/assets/index-TckzASdM.js +2 -0
- package/src/ui/dist/assets/index-Yi5ytFFr.js +2 -0
- package/src/ui/dist/assets/infoDiagram-FWYZ7A6U-CiGBlFqH.js +3 -0
- package/src/ui/dist/assets/init-Gi6I4Gst.js +2 -0
- package/src/ui/dist/assets/ishikawaDiagram-FXEZZL3T-B1aheRbz.js +71 -0
- package/src/ui/dist/assets/it-IT-JPQ66NNP-DT3HSU7X.js +12 -0
- package/src/ui/dist/assets/ja-JP-DBVTYXUO-CsfJjjWt.js +9 -0
- package/src/ui/dist/assets/javascript-iXu5QeM3.js +2 -0
- package/src/ui/dist/assets/journeyDiagram-5HDEW3XC-DtnJPxub.js +140 -0
- package/src/ui/dist/assets/julia-DuME0IfC.js +2 -0
- package/src/ui/dist/assets/kaa-6HZHGXH3-DQz-1-Gn.js +2 -0
- package/src/ui/dist/assets/kab-KAB-ZGHBKWFO-CaH-LSoK.js +9 -0
- package/src/ui/dist/assets/kanban-definition-HUTT4EX6-CZatSm3e.js +90 -0
- package/src/ui/dist/assets/katex-C5jXJg4s.js +258 -0
- package/src/ui/dist/assets/kk-KZ-P5N5QNE5-BMXmcm55.js +2 -0
- package/src/ui/dist/assets/km-KH-HSX4SM5Z-ZeoJNBpN.js +12 -0
- package/src/ui/dist/assets/ko-KR-MTYHY66A-BeaLRKph.js +10 -0
- package/src/ui/dist/assets/ku-TR-6OUDTVRD-B_28KrkR.js +10 -0
- package/src/ui/dist/assets/layout-DEXfKzaS.js +2 -0
- package/src/ui/dist/assets/linear-CpEDnQRC.js +2 -0
- package/src/ui/dist/assets/livescript-BwQOo05w.js +2 -0
- package/src/ui/dist/assets/lt-LT-XHIRWOB4-BxDcnUhp.js +4 -0
- package/src/ui/dist/assets/lua-VAEuO923.js +2 -0
- package/src/ui/dist/assets/lv-LV-5QDEKY6T-DpKDl1_y.js +8 -0
- package/src/ui/dist/assets/map-Czzmt4hB.js +2 -0
- package/src/ui/dist/assets/mathematica-DTrFuWx2.js +2 -0
- package/src/ui/dist/assets/mbox-CNhZ1qSd.js +2 -0
- package/src/ui/dist/assets/mermaidLoader-CBO31t0J.js +305 -0
- package/src/ui/dist/assets/mermaidLoader-CEK31ho9.css +1 -0
- package/src/ui/dist/assets/mindmap-definition-LN4V7U3C-CQ0TccEr.js +97 -0
- package/src/ui/dist/assets/mirc-CjQqDB4T.js +2 -0
- package/src/ui/dist/assets/mllike-CXdrOF99.js +2 -0
- package/src/ui/dist/assets/modelica-Dc1JOy9r.js +2 -0
- package/src/ui/dist/assets/mr-IN-CRQNXWMA-BKCZT58p.js +14 -0
- package/src/ui/dist/assets/mscgen-BA5vi2Kp.js +2 -0
- package/src/ui/dist/assets/mumps-BT43cFF4.js +2 -0
- package/src/ui/dist/assets/my-MM-5M5IBNSE-D34k0G9T.js +2 -0
- package/src/ui/dist/assets/nb-NO-T6EIAALU-DXr_KW8J.js +11 -0
- package/src/ui/dist/assets/nginx-DdIZxoE0.js +2 -0
- package/src/ui/dist/assets/nl-NL-IS3SIHDZ-C1L0aVDR.js +9 -0
- package/src/ui/dist/assets/nn-NO-6E72VCQL-CLWVSxbZ.js +9 -0
- package/src/ui/dist/assets/nsis-LdVXkNf5.js +2 -0
- package/src/ui/dist/assets/ntriples-BfvgReVJ.js +2 -0
- package/src/ui/dist/assets/oc-FR-POXYY2M6-nf8_J3eR.js +9 -0
- package/src/ui/dist/assets/octave-Ck1zUtKM.js +2 -0
- package/src/ui/dist/assets/ordinal-Cboi1Yqb.js +2 -0
- package/src/ui/dist/assets/oz-BzwKVEFT.js +2 -0
- package/src/ui/dist/assets/pa-IN-N4M65BXN-CAMJ-xd6.js +5 -0
- package/src/ui/dist/assets/pascal--L3eBynH.js +2 -0
- package/src/ui/dist/assets/pegDiagram-2B236MQR-Bj2RcmRd.js +2 -0
- package/src/ui/dist/assets/percentages-BXMCSKIN-s9yWFdr6.js +160 -0
- package/src/ui/dist/assets/perl-CdXCOZ3F.js +2 -0
- package/src/ui/dist/assets/pica-BGv_AhAB.js +8 -0
- package/src/ui/dist/assets/pieDiagram-ENE6RG2P-obpzz8dC.js +40 -0
- package/src/ui/dist/assets/pig-CevX1Tat.js +2 -0
- package/src/ui/dist/assets/pl-PL-T2D74RX3-DKJ5H85v.js +10 -0
- package/src/ui/dist/assets/powershell-CFHJl5sT.js +2 -0
- package/src/ui/dist/assets/properties-C78fOPTZ.js +2 -0
- package/src/ui/dist/assets/protobuf-ChK-085T.js +2 -0
- package/src/ui/dist/assets/{proxy-D0vUbds5.js → proxy-BSmwef4H.js} +2 -2
- package/src/ui/dist/assets/pt-BR-5N22H2LF-B5kow-kN.js +10 -0
- package/src/ui/dist/assets/pt-PT-UZXXM6DQ-B2G34fso.js +10 -0
- package/src/ui/dist/assets/pug-DeIclll2.js +2 -0
- package/src/ui/dist/assets/puppet-DMA9R1ak.js +2 -0
- package/src/ui/dist/assets/python-BuPzkPfP.js +2 -0
- package/src/ui/dist/assets/q-pXgVlZs6.js +2 -0
- package/src/ui/dist/assets/quadrantDiagram-ABIIQ3AL-Cl-T7NkJ.js +8 -0
- package/src/ui/dist/assets/r-B6wPVr8A.js +2 -0
- package/src/ui/dist/assets/railroadDiagram-RFXS5EU6-DMq82RHg.js +2 -0
- package/src/ui/dist/assets/{refresh-cw-JNmExijd.js → refresh-cw-CbFd7guV.js} +2 -2
- package/src/ui/dist/assets/requirementDiagram-TGXJPOKE-tGInMDgU.js +85 -0
- package/src/ui/dist/assets/ro-RO-JPDTUUEW-BwLdZW91.js +12 -0
- package/src/ui/dist/assets/roundRect-0PYZxl1G.js +2 -0
- package/src/ui/dist/assets/rpm-CTu-6PCP.js +2 -0
- package/src/ui/dist/assets/ru-RU-B4JR7IUQ-DpdAgIJc.js +10 -0
- package/src/ui/dist/assets/ruby-B2Rjki9n.js +2 -0
- package/src/ui/dist/assets/runtimeBrand-BoKPimsz.js +2 -0
- package/src/ui/dist/assets/sankeyDiagram-HTMAVEWB-C7X-ET4m.js +41 -0
- package/src/ui/dist/assets/sas-B4kiWyti.js +2 -0
- package/src/ui/dist/assets/save-D1CXHwBw.js +12 -0
- package/src/ui/dist/assets/scheme-C41bIUwD.js +2 -0
- package/src/ui/dist/assets/sequenceDiagram-DBY2YBRQ-Bn24i_nY.js +163 -0
- package/src/ui/dist/assets/settings-2-DtSNAAcU.js +22 -0
- package/src/ui/dist/assets/shell-CjFT_Tl9.js +2 -0
- package/src/ui/dist/assets/shield-check-BVbJ8T_N.js +7 -0
- package/src/ui/dist/assets/si-LK-N5RQ5JYF-naJaUy5u.js +2 -0
- package/src/ui/dist/assets/sieve-C3Gn_uJK.js +2 -0
- package/src/ui/dist/assets/simple-mode-GW_nhZxv.js +2 -0
- package/src/ui/dist/assets/sizeCapture-X5ZJPWSS-DAQHfm82.js +2 -0
- package/src/ui/dist/assets/sk-SK-C5VTKIMK-1NPz1J_d.js +7 -0
- package/src/ui/dist/assets/sl-SI-NN7IZMDC-D8RfmNQw.js +7 -0
- package/src/ui/dist/assets/smalltalk-CnHTOXQT.js +2 -0
- package/src/ui/dist/assets/solr-DehyRSwq.js +2 -0
- package/src/ui/dist/assets/sparql-DkYu6x3z.js +2 -0
- package/src/ui/dist/assets/spreadsheet-BCZA_wO0.js +2 -0
- package/src/ui/dist/assets/sql-D0XecflT.js +2 -0
- package/src/ui/dist/assets/stateDiagram-2N3HPSRC-Ck48D1ck.js +2 -0
- package/src/ui/dist/assets/stateDiagram-v2-6OUMAXLB-CdfRCJAJ.js +2 -0
- package/src/ui/dist/assets/stex-C3f8Ysf7.js +2 -0
- package/src/ui/dist/assets/style-C3QI7VPf.css +1 -0
- package/src/ui/dist/assets/stylus-B533Al4x.js +2 -0
- package/src/ui/dist/assets/subset-shared.chunk-eAtLHmbi.js +85 -0
- package/src/ui/dist/assets/subset-worker.chunk-DeHCTnTk.js +2 -0
- package/src/ui/dist/assets/sv-SE-XGPEYMSR-BeOYCU-8.js +11 -0
- package/src/ui/dist/assets/swift-BzpIVaGY.js +2 -0
- package/src/ui/dist/assets/swimlanes-5IMT3BWC-DOy22UjP.js +3 -0
- package/src/ui/dist/assets/swimlanesDiagram-G3AALYLV-sicPbVOg.js +9 -0
- package/src/ui/dist/assets/ta-IN-2NMHFXQM-CtS68WDd.js +10 -0
- package/src/ui/dist/assets/tcl-DVfN8rqt.js +2 -0
- package/src/ui/dist/assets/{terminal-BBQvnOAK.js → terminal-DEby5Y_P.js} +2 -2
- package/src/ui/dist/assets/terminalControl-BkFeDVXo.js +134 -0
- package/src/ui/dist/assets/textile-CnDTJFAw.js +2 -0
- package/src/ui/dist/assets/th-TH-HPSO5L25-DCHY9-Co.js +3 -0
- package/src/ui/dist/assets/tiddlywiki-DO-Gjzrf.js +2 -0
- package/src/ui/dist/assets/tiki-DGYXhP31.js +2 -0
- package/src/ui/dist/assets/timeline-definition-FHXFAJF6-DVkG72qO.js +121 -0
- package/src/ui/dist/assets/toml-Bm5Em-hy.js +2 -0
- package/src/ui/dist/assets/tr-TR-DEFEU3FU-y5-vjTv8.js +8 -0
- package/src/ui/dist/assets/troff-wAsdV37c.js +2 -0
- package/src/ui/dist/assets/ttcn-CfJYG6tj.js +2 -0
- package/src/ui/dist/assets/ttcn-cfg-B9xdYoR4.js +2 -0
- package/src/ui/dist/assets/turtle-B1tBg_DP.js +2 -0
- package/src/ui/dist/assets/uk-UA-QMV73CPH-BRbR5It6.js +7 -0
- package/src/ui/dist/assets/useReducedMotion-D07XP52Q.js +12 -0
- package/src/ui/dist/assets/vb-CmGdzxic.js +2 -0
- package/src/ui/dist/assets/vbscript-BuJXcnF6.js +2 -0
- package/src/ui/dist/assets/velocity-D8B20fx6.js +2 -0
- package/src/ui/dist/assets/vennDiagram-L72KCM5P-DwMwBlf-.js +35 -0
- package/src/ui/dist/assets/verilog-C6RDOZhf.js +2 -0
- package/src/ui/dist/assets/vhdl-lSbBsy5d.js +2 -0
- package/src/ui/dist/assets/vi-VN-M7AON7JQ-s6wSBv2s.js +6 -0
- package/src/ui/dist/assets/wardleyDiagram-EHGQE667-CNuuvzEg.js +79 -0
- package/src/ui/dist/assets/webidl-ZXfAyPTL.js +2 -0
- package/src/ui/dist/assets/{x-DoIOGAJz.js → x-B84wq78k.js} +2 -2
- package/src/ui/dist/assets/xquery-DzFWVndE.js +2 -0
- package/src/ui/dist/assets/xychartDiagram-FW5EYKEG-dUpZxmn6.js +8 -0
- package/src/ui/dist/assets/yacas-BJ4BC0dw.js +2 -0
- package/src/ui/dist/assets/z80-Hz9HOZM7.js +2 -0
- package/src/ui/dist/assets/zh-CN-LNUGB5OW-Cu_-POQN.js +11 -0
- package/src/ui/dist/assets/zh-HK-E62DVLB3-BCx4W4qZ.js +2 -0
- package/src/ui/dist/assets/zh-TW-RAJ6MFWO-02wx_Mrj.js +10 -0
- package/src/ui/dist/icons/excalidraw.svg +1 -0
- package/src/ui/dist/icons/markdown.svg +1 -0
- package/src/ui/dist/index.html +2 -2
- package/src/ui/package.json +10 -0
- package/src/ui/playwright.config.ts +36 -0
- package/src/ui/pnpm-workspace.yaml +2 -0
- package/src/ui/public/icons/excalidraw.svg +1 -0
- package/src/ui/public/icons/markdown.svg +1 -0
- package/src/ui/tsconfig.json +2 -1
- package/src/ui/vite.config.ts +1 -0
- package/src/wf-ui-server/__tests__/a2a-store.test.mjs +432 -15
- package/src/wf-ui-server/__tests__/action-registry-loader.test.mjs +156 -0
- package/src/wf-ui-server/__tests__/claude-stream-json.test.mjs +397 -0
- package/src/wf-ui-server/__tests__/codex-appserver.test.mjs +392 -0
- package/src/wf-ui-server/__tests__/component-node-api.test.mjs +881 -0
- package/src/wf-ui-server/__tests__/component-node-store.test.mjs +401 -0
- package/src/wf-ui-server/__tests__/control-plane-acceptance.test.mjs +2027 -0
- package/src/wf-ui-server/__tests__/control-plane-cli-smoke.test.mjs +1014 -0
- package/src/wf-ui-server/__tests__/dispatch-lifecycle.test.mjs +330 -0
- package/src/wf-ui-server/__tests__/effort-compatibility-red-092.test.mjs +151 -0
- package/src/wf-ui-server/__tests__/graph-layout-agent-tree.test.mjs +254 -0
- package/src/wf-ui-server/__tests__/graph-layout-tidy.test.mjs +260 -0
- package/src/wf-ui-server/__tests__/graph-layout.test.mjs +84 -0
- package/src/wf-ui-server/__tests__/node-config-api.test.mjs +384 -0
- package/src/wf-ui-server/__tests__/opencode-server.test.mjs +526 -0
- package/src/wf-ui-server/__tests__/peer-capsule.test.mjs +2 -2
- package/src/wf-ui-server/__tests__/pty-adapter.test.mjs +71 -1
- package/src/wf-ui-server/__tests__/runtime-config.test.mjs +3 -3
- package/src/wf-ui-server/__tests__/runtime-detector.test.mjs +21 -0
- package/src/wf-ui-server/__tests__/runtime-review.test.mjs +828 -0
- package/src/wf-ui-server/__tests__/server.integration.test.mjs +1463 -11
- package/src/wf-ui-server/__tests__/session-cleanup.test.mjs +159 -0
- package/src/wf-ui-server/__tests__/session-registry.test.mjs +52 -3
- package/src/wf-ui-server/__tests__/settings.test.mjs +12 -2
- package/src/wf-ui-server/__tests__/spawn-gate.test.mjs +78 -0
- package/src/wf-ui-server/__tests__/task-group-parser.test.mjs +120 -0
- package/src/wf-ui-server/__tests__/task-group-tag.test.mjs +264 -0
- package/src/wf-ui-server/__tests__/task-parser.test.mjs +49 -3
- package/src/wf-ui-server/__tests__/terminal-context-hardening.test.mjs +122 -0
- package/src/wf-ui-server/__tests__/terminal-context.test.mjs +164 -0
- package/src/wf-ui-server/__tests__/terminal-store.test.mjs +4 -4
- package/src/wf-ui-server/__tests__/wf-browser-api.test.mjs +599 -0
- package/src/wf-ui-server/__tests__/wf-browser-store.test.mjs +184 -0
- package/src/wf-ui-server/__tests__/workflow-action-registry.test.mjs +282 -0
- package/src/wf-ui-server/__tests__/workflow-agent-communication.test.mjs +411 -0
- package/src/wf-ui-server/__tests__/workflow-agent-context.test.mjs +323 -0
- package/src/wf-ui-server/__tests__/workflow-agent-cooperation-permissions.test.mjs +318 -0
- package/src/wf-ui-server/__tests__/workflow-agent-messages-structured.test.mjs +458 -0
- package/src/wf-ui-server/__tests__/workflow-agent-routing.test.mjs +434 -0
- package/src/wf-ui-server/__tests__/workflow-agent-runtime.test.mjs +324 -0
- package/src/wf-ui-server/__tests__/workflow-api-integration.test.mjs +263 -0
- package/src/wf-ui-server/__tests__/workflow-api-phase3.test.mjs +1213 -0
- package/src/wf-ui-server/__tests__/workflow-claude-materialize.test.mjs +209 -0
- package/src/wf-ui-server/__tests__/workflow-cli-registry-manuals.test.mjs +173 -0
- package/src/wf-ui-server/__tests__/workflow-cli-surface.test.mjs +176 -0
- package/src/wf-ui-server/__tests__/workflow-codex-resume-id.test.mjs +556 -0
- package/src/wf-ui-server/__tests__/workflow-cooperation-enforcement.test.mjs +553 -0
- package/src/wf-ui-server/__tests__/workflow-depth-resume-dock.test.mjs +846 -0
- package/src/wf-ui-server/__tests__/workflow-display-node.test.mjs +150 -0
- package/src/wf-ui-server/__tests__/workflow-edge-update.test.mjs +296 -0
- package/src/wf-ui-server/__tests__/workflow-file-cache-lock-watch.test.mjs +380 -0
- package/src/wf-ui-server/__tests__/workflow-file-formats.test.mjs +994 -0
- package/src/wf-ui-server/__tests__/workflow-file-node-actions.test.mjs +294 -0
- package/src/wf-ui-server/__tests__/workflow-goal-actions.test.mjs +357 -0
- package/src/wf-ui-server/__tests__/workflow-goal-task-autoclose.test.mjs +256 -0
- package/src/wf-ui-server/__tests__/workflow-graceful-stop.test.mjs +108 -0
- package/src/wf-ui-server/__tests__/workflow-graph-undo.test.mjs +524 -0
- package/src/wf-ui-server/__tests__/workflow-layout.test.mjs +732 -0
- package/src/wf-ui-server/__tests__/workflow-magnetic-topology.test.mjs +222 -0
- package/src/wf-ui-server/__tests__/workflow-markdown-lock.test.mjs +359 -0
- package/src/wf-ui-server/__tests__/workflow-mcp-hub.test.mjs +174 -0
- package/src/wf-ui-server/__tests__/workflow-node-manual-schema.test.mjs +241 -0
- package/src/wf-ui-server/__tests__/workflow-node-runtime.test.mjs +1991 -0
- package/src/wf-ui-server/__tests__/workflow-node-store-utils.test.mjs +125 -0
- package/src/wf-ui-server/__tests__/workflow-registry-drift.test.mjs +296 -0
- package/src/wf-ui-server/__tests__/workflow-resource-handle-four-side.test.mjs +217 -0
- package/src/wf-ui-server/__tests__/workflow-role-profile.test.mjs +234 -0
- package/src/wf-ui-server/__tests__/workflow-set-model.test.mjs +261 -0
- package/src/wf-ui-server/__tests__/workflow-skill-group-context-enabled.test.mjs +131 -0
- package/src/wf-ui-server/__tests__/workflow-skill-group-enable-disable.test.mjs +186 -0
- package/src/wf-ui-server/__tests__/workflow-skills-hub.test.mjs +125 -0
- package/src/wf-ui-server/__tests__/workflow-state-reconcile.test.mjs +139 -0
- package/src/wf-ui-server/__tests__/workflow-subagent-strategy-matrix.test.mjs +529 -0
- package/src/wf-ui-server/__tests__/workflow-team-flow.test.mjs +278 -0
- package/src/wf-ui-server/__tests__/workflow-terminal-control-live.test.mjs +294 -0
- package/src/wf-ui-server/__tests__/workflow-terminal-control.test.mjs +631 -0
- package/src/wf-ui-server/__tests__/workflow-timer-wakeup.test.mjs +318 -0
- package/src/wf-ui-server/__tests__/workflow-unified-resume.test.mjs +537 -0
- package/src/wf-ui-server/__tests__/workspace-api-hardening.test.mjs +187 -0
- package/src/wf-ui-server/__tests__/workspace-api.test.mjs +382 -0
- package/src/wf-ui-server/__tests__/workspace-reveal.test.mjs +138 -0
- package/src/wf-ui-server/__tests__/workspace-store-hardening.test.mjs +255 -0
- package/src/wf-ui-server/__tests__/workspace-store.test.mjs +208 -0
- package/src/wf-ui-server/__tests__/ws-events.integration.test.mjs +52 -25
- package/src/wf-ui-server/__tests__/ws-terminal.integration.test.mjs +12 -6
- package/src/wf-ui-server/__tests__/ws-wf-browser.integration.test.mjs +488 -0
- package/src/wf-ui-server/a2a-store.mjs +3007 -89
- package/src/wf-ui-server/action-registry.mjs +277 -0
- package/src/wf-ui-server/bridge-store.mjs +276 -0
- package/src/wf-ui-server/chat-driver.mjs +220 -0
- package/src/wf-ui-server/chat-store.mjs +109 -0
- package/src/wf-ui-server/claude-transcript-materializer.mjs +235 -0
- package/src/wf-ui-server/codex-update-prompt.mjs +53 -0
- package/src/wf-ui-server/component-node-store.mjs +689 -0
- package/src/wf-ui-server/composition-api.mjs +436 -0
- package/src/wf-ui-server/control-plane-token.mjs +17 -0
- package/src/wf-ui-server/dispatch-contract.mjs +150 -0
- package/src/wf-ui-server/drivers/claude-stream-json.mjs +371 -0
- package/src/wf-ui-server/drivers/codex-appserver.mjs +513 -0
- package/src/wf-ui-server/drivers/opencode-server.mjs +486 -0
- package/src/wf-ui-server/excalidraw-svg.mjs +141 -0
- package/src/wf-ui-server/file-format-adapters.mjs +511 -0
- package/src/wf-ui-server/file-watcher.mjs +215 -0
- package/src/wf-ui-server/graph-layout.mjs +778 -0
- package/src/wf-ui-server/harness-env.mjs +46 -0
- package/src/wf-ui-server/json-store-utils.mjs +48 -0
- package/src/wf-ui-server/model-capability.mjs +773 -0
- package/src/wf-ui-server/node-config-store.mjs +233 -0
- package/src/wf-ui-server/node-store-utils.mjs +88 -0
- package/src/wf-ui-server/peer-capsule.mjs +56 -1
- package/src/wf-ui-server/pty-adapter.mjs +513 -11
- package/src/wf-ui-server/reveal-foreground.mjs +69 -0
- package/src/wf-ui-server/runtime-detector.mjs +52 -6
- package/src/wf-ui-server/server.mjs +5613 -403
- package/src/wf-ui-server/session-cleanup.mjs +363 -0
- package/src/wf-ui-server/session-registry.mjs +179 -3
- package/src/wf-ui-server/settings.mjs +25 -0
- package/src/wf-ui-server/spawn-gate.mjs +46 -0
- package/src/wf-ui-server/task-parser.mjs +88 -3
- package/src/wf-ui-server/terminal-store.mjs +225 -11
- package/src/wf-ui-server/timer-wakeup-scheduler.mjs +226 -0
- package/src/wf-ui-server/wf-browser-store.mjs +733 -0
- package/src/wf-ui-server/workflow-agent-context.mjs +1731 -0
- package/src/wf-ui-server/workflow-capability-node-store.mjs +676 -0
- package/src/wf-ui-server/workflow-event-node-store.mjs +623 -0
- package/src/wf-ui-server/workflow-goal-node-store.mjs +328 -0
- package/src/wf-ui-server/workflow-graph-store.mjs +623 -0
- package/src/wf-ui-server/workflow-mcp-hub.mjs +286 -0
- package/src/wf-ui-server/workflow-node-runtime.mjs +1767 -0
- package/src/wf-ui-server/workflow-node-settings-store.mjs +339 -0
- package/src/wf-ui-server/workflow-node-types/agent-node.mjs +920 -0
- package/src/wf-ui-server/workflow-node-types/display-node.mjs +151 -0
- package/src/wf-ui-server/workflow-node-types/excalidraw-node.mjs +145 -0
- package/src/wf-ui-server/workflow-node-types/file-node.mjs +484 -0
- package/src/wf-ui-server/workflow-node-types/github-trigger-node.mjs +207 -0
- package/src/wf-ui-server/workflow-node-types/goal-node.mjs +491 -0
- package/src/wf-ui-server/workflow-node-types/markdown-node.mjs +225 -0
- package/src/wf-ui-server/workflow-node-types/mcp-connector-node.mjs +71 -0
- package/src/wf-ui-server/workflow-node-types/role-profile-store.mjs +191 -0
- package/src/wf-ui-server/workflow-node-types/skill-group-node.mjs +98 -0
- package/src/wf-ui-server/workflow-node-types/timer-node.mjs +607 -0
- package/src/wf-ui-server/workflow-ontology.mjs +681 -0
- package/src/wf-ui-server/workflow-operation-store.mjs +115 -0
- package/src/wf-ui-server/workflow-skills-hub.mjs +366 -0
- package/src/wf-ui-server/workflow-skills-market.mjs +723 -0
- package/src/wf-ui-server/workspace-store.mjs +951 -0
- package/src/wf-ui-server/ws-chat.mjs +299 -0
- package/src/wf-ui-server/ws-events.mjs +45 -20
- package/src/wf-ui-server/ws-terminal.mjs +165 -22
- package/src/wf-ui-server/ws-wf-browser.mjs +419 -0
- package/templates/common/.claude/agents/review-manager.md +33 -29
- package/templates/common/.claude/commands/wf-browser.md +1 -1
- package/templates/common/.claude/commands/wf-help.md +5 -3
- package/templates/common/.claude/commands/wf-init.md +44 -0
- package/templates/common/.claude/commands/wf-learn.md +34 -8
- package/templates/common/.claude/commands/wf-max.md +19 -9
- package/templates/common/.claude/commands/wf-review.md +3 -3
- package/templates/common/.claude/commands/wf-search.md +55 -0
- package/templates/common/.claude/commands/wf-task-archive.md +5 -4
- package/templates/common/.claude/commands/wf-task-list.md +6 -3
- package/templates/common/.claude/commands/wf-task-record.md +10 -2
- package/templates/common/.claude/commands/wf-ui.md +12 -5
- package/templates/common/.claude/commands/wf-update.md +4 -0
- package/templates/common/.claude/commands/wf.md +12 -1
- package/templates/common/.claude/rules/ecc/common.md +10 -1
- package/templates/common/.claude/skills/wf/SKILL.md +36 -0
- package/templates/common/.claude/skills/wf-browser/SKILL.md +427 -122
- package/templates/common/.claude/skills/wf-browser/references/BROWSER_CONTROL_PATTERNS.md +43 -0
- package/templates/common/.claude/skills/wf-init/SKILL.md +33 -0
- package/templates/common/.claude/skills/wf-learn/SKILL.md +106 -26
- package/templates/common/.claude/skills/wf-max/SKILL.md +45 -11
- package/templates/common/.claude/skills/wf-review/SKILL.md +26 -54
- package/templates/common/.claude/skills/wf-search/SKILL.md +122 -0
- package/templates/common/.claude/skills/wf-search/references/evidence-contract.md +77 -0
- package/templates/common/.claude/skills/wf-search/references/policies/compare.md +38 -0
- package/templates/common/.claude/skills/wf-search/references/policies/fact.md +39 -0
- package/templates/common/.claude/skills/wf-search/references/policies/troubleshoot.md +39 -0
- package/templates/common/.claude/skills/wf-search/references/policies/verify.md +44 -0
- package/templates/common/.claude/skills/wf-search/references/source-routing.md +40 -0
- package/templates/common/.claude/skills/wf-search/references/tool-adapters.md +38 -0
- package/templates/common/.claude/skills/wf-ui/SKILL.md +146 -12
- package/templates/common/.claude/skills/wf-update/SKILL.md +5 -1
- package/templates/common/.harness-version +188 -85
- package/templates/common/.opencode/agents/review-manager.md +31 -27
- package/templates/common/.opencode/commands/wf-browser.md +1 -1
- package/templates/common/.opencode/commands/wf-help.md +5 -3
- package/templates/common/.opencode/commands/wf-init.md +44 -0
- package/templates/common/.opencode/commands/wf-learn.md +34 -8
- package/templates/common/.opencode/commands/wf-max.md +19 -9
- package/templates/common/.opencode/commands/wf-review.md +3 -3
- package/templates/common/.opencode/commands/wf-search.md +55 -0
- package/templates/common/.opencode/commands/wf-task-archive.md +5 -7
- package/templates/common/.opencode/commands/wf-task-list.md +6 -6
- package/templates/common/.opencode/commands/wf-task-record.md +10 -5
- package/templates/common/.opencode/commands/wf-ui.md +12 -5
- package/templates/common/.opencode/commands/wf-update.md +4 -0
- package/templates/common/.opencode/commands/wf.md +12 -1
- package/templates/common/CLAUDE.md +61 -3
- package/templates/common/Harness/MEMORY.md +8 -5
- package/templates/common/Harness/README.md +14 -10
- package/templates/common/Harness/a2a/action-registry.json +4397 -0
- package/templates/common/Harness/a2a/role-graph.json +16 -3
- package/templates/common/Harness/a2a/skills/terminal-control.json +45 -1
- package/templates/common/Harness/a2a/skills/wf-ui-map.json +50 -0
- package/templates/common/Harness/a2a/skills/workflow-agent-node.json +143 -0
- package/templates/common/Harness/a2a/skills/workflow-context.json +95 -0
- package/templates/common/Harness/a2a/skills/workflow-diagram-node.json +60 -0
- package/templates/common/Harness/a2a/skills/workflow-display-node.json +69 -0
- package/templates/common/Harness/a2a/skills/workflow-file-node.json +92 -0
- package/templates/common/Harness/a2a/skills/workflow-goal-node.json +76 -0
- package/templates/common/Harness/a2a/skills/workflow-markdown-node.json +79 -0
- package/templates/common/Harness/a2a/skills/workflow-mcp-connector-node.json +59 -0
- package/templates/common/Harness/a2a/skills/workflow-node-actions.json +105 -0
- package/templates/common/Harness/a2a/skills/workflow-node-map.json +71 -0
- package/templates/common/Harness/a2a/skills/workflow-ontology.json +54 -0
- package/templates/common/Harness/a2a/skills/workflow-resource-node.json +68 -0
- package/templates/common/Harness/a2a/skills/workflow-skill-group-node.json +56 -0
- package/templates/common/Harness/a2a/skills/workflow-timer-node.json +81 -0
- package/templates/common/Harness/a2a/workflows.json +33 -0
- package/templates/common/Harness/ownership.manifest.json +263 -2
- package/templates/common/Harness/project/architecture.md +499 -0
- package/templates/common/Harness/research/README.md +20 -0
- package/templates/common/Harness/scripts/README.md +70 -6
- package/templates/common/Harness/scripts/a2a-terminal.mjs +12 -4
- package/templates/common/Harness/scripts/context-budget.mjs +7 -3
- package/templates/common/Harness/scripts/lib/memory-context.mjs +400 -0
- package/templates/common/Harness/scripts/lib/path-scope.mjs +77 -0
- package/templates/common/Harness/scripts/lib/research-policy.mjs +99 -0
- package/templates/common/Harness/scripts/lib/wf-search.mjs +189 -0
- package/templates/common/Harness/scripts/memory-context.mjs +63 -0
- package/templates/common/Harness/scripts/research-policy.mjs +27 -0
- package/templates/common/Harness/scripts/task-context.mjs +547 -0
- package/templates/common/Harness/scripts/task-group-index.mjs +242 -0
- package/templates/common/Harness/scripts/task-state.mjs +659 -95
- package/templates/common/Harness/scripts/validate-harness.mjs +70 -28
- package/templates/common/Harness/scripts/wf-auto-update-prompt.mjs +24 -0
- package/templates/common/Harness/scripts/wf-remove.mjs +10 -0
- package/templates/common/Harness/scripts/wf-search.mjs +10 -0
- package/templates/common/Harness/scripts/wf-ui-control.mjs +3144 -0
- package/templates/common/Harness/scripts/wf-update-check.mjs +274 -51
- package/templates/common/Harness/scripts/wf-update-runner.mjs +53 -16
- package/templates/common/Harness/settings.json +10 -0
- package/templates/common/Harness/specs/guides/SETUP.md +4 -3
- package/templates/common/Harness/specs/protocols/HARNESS_BRIDGE.md +429 -48
- package/templates/common/Harness/specs/protocols/MEMORY_PROTOCOL.md +24 -0
- package/templates/common/Harness/specs/protocols/TASK_ARCHIVE.md +14 -11
- package/templates/common/Harness/specs/runtime/command-surface.json +28 -0
- package/templates/common/Harness/specs/runtime/context-loading.md +6 -0
- package/templates/common/Harness/specs/runtime/dispatch.md +9 -1
- package/templates/common/Harness/specs/runtime/subagents.md +20 -5
- package/templates/common/Harness/specs/workflows/WF-AUTO-SPARK.md +19 -0
- package/templates/common/Harness/specs/workflows/WF-AUTO.md +21 -0
- package/templates/common/Harness/specs/workflows/WF-KERNEL.md +4 -2
- package/templates/common/Harness/specs/workflows/WF-MAX.md +39 -12
- package/templates/common/Harness/specs/workflows/WF-STATE.md +62 -14
- package/templates/common/Harness/specs/workflows/WF.md +32 -0
- package/templates/common/Harness/tasks/INDEX.json +7 -0
- package/templates/common/Harness/tasks/INDEX.md +12 -0
- package/templates/common/Harness/tasks/_template/PLAN.md +6 -0
- package/templates/common/Harness/tasks/_template/PROGRESS.md +5 -0
- package/templates/common/Harness/tasks/_template/STATE.json +22 -0
- package/templates/common/Harness/templates/TEST_PLAN.template.md +5 -4
- package/templates/common/Harness/templates/UI_CONTRACT.template.md +7 -5
- package/templates/common/Harness/wf-browser/README.md +69 -0
- package/templates/common/README.md +17 -0
- package/src/ui/dist/assets/AgentsRoute-CuSKYmFu.js +0 -17
- package/src/ui/dist/assets/AgentsRoute-CuSKYmFu.js.map +0 -1
- package/src/ui/dist/assets/RolesRoute-DOzTYVRm.js +0 -7
- package/src/ui/dist/assets/RolesRoute-DOzTYVRm.js.map +0 -1
- package/src/ui/dist/assets/SettingsRoute-DPU7jSQm.js +0 -12
- package/src/ui/dist/assets/SettingsRoute-DPU7jSQm.js.map +0 -1
- package/src/ui/dist/assets/TaskList-BN4r8s1i.js +0 -50
- package/src/ui/dist/assets/TaskList-BN4r8s1i.js.map +0 -1
- package/src/ui/dist/assets/TerminalDrawer-Cej4PxsH.js +0 -74
- package/src/ui/dist/assets/TerminalDrawer-Cej4PxsH.js.map +0 -1
- package/src/ui/dist/assets/WorkflowRoute-BnuhLJ6X.css +0 -1
- package/src/ui/dist/assets/WorkflowRoute-C-clKe-j.js +0 -39
- package/src/ui/dist/assets/WorkflowRoute-C-clKe-j.js.map +0 -1
- package/src/ui/dist/assets/index-BOVYWntB.js +0 -117
- package/src/ui/dist/assets/index-BOVYWntB.js.map +0 -1
- package/src/ui/dist/assets/index-DaUObq0H.css +0 -1
- package/src/ui/dist/assets/maximize-2-LNrr_rKr.js +0 -7
- package/src/ui/dist/assets/maximize-2-LNrr_rKr.js.map +0 -1
- package/src/ui/dist/assets/plus-QuTJyoT3.js +0 -7
- package/src/ui/dist/assets/plus-QuTJyoT3.js.map +0 -1
- package/src/ui/dist/assets/proxy-D0vUbds5.js.map +0 -1
- package/src/ui/dist/assets/refresh-cw-JNmExijd.js.map +0 -1
- package/src/ui/dist/assets/terminal-BBQvnOAK.js.map +0 -1
- package/src/ui/dist/assets/useReducedMotion-BqmH0Tf7.js +0 -7
- package/src/ui/dist/assets/useReducedMotion-BqmH0Tf7.js.map +0 -1
- package/src/ui/dist/assets/x-DoIOGAJz.js.map +0 -1
- package/src/ui/pnpm-lock.yaml +0 -1582
- package/src/ui/src/App.tsx +0 -86
- package/src/ui/src/api.ts +0 -93
- package/src/ui/src/components/AgentsRoute.tsx +0 -503
- package/src/ui/src/components/Footer.tsx +0 -69
- package/src/ui/src/components/Header.tsx +0 -175
- package/src/ui/src/components/LoadingView.tsx +0 -22
- package/src/ui/src/components/RolesRoute.tsx +0 -169
- package/src/ui/src/components/SettingsRoute.tsx +0 -166
- package/src/ui/src/components/TaskList.tsx +0 -388
- package/src/ui/src/components/TerminalDrawer.tsx +0 -611
- package/src/ui/src/components/WorkflowRoute.tsx +0 -670
- package/src/ui/src/hooks/useReducedMotion.ts +0 -17
- package/src/ui/src/hooks/useServerConnection.ts +0 -114
- package/src/ui/src/index.css +0 -281
- package/src/ui/src/main.tsx +0 -11
- package/src/ui/src/types.ts +0 -108
- /package/src/ui/dist/assets/{TerminalDrawer-6GBZ9nXN.css → terminalControl-6GBZ9nXN.css} +0 -0
package/src/index.js
CHANGED
|
@@ -7,9 +7,12 @@ import pc from 'picocolors';
|
|
|
7
7
|
import { askConflictPolicy, askInstallScope, askOptionalSelections, askProjectName, askTargetDir } from './prompts.js';
|
|
8
8
|
import { generate, getOptionalCatalog } from './generator.js';
|
|
9
9
|
|
|
10
|
-
const UPDATE_SUCCESS_STATUSES = new Set(['up-to-date', 'update-available', 'partial-update']);
|
|
11
|
-
const UPDATE_FAILURE_STATUSES = new Set(['error', 'offline', 'template-remote', 'downgrade-refused']);
|
|
10
|
+
const UPDATE_SUCCESS_STATUSES = new Set(['up-to-date', 'update-available', 'partial-update', 'ok']);
|
|
11
|
+
const UPDATE_FAILURE_STATUSES = new Set(['error', 'offline', 'template-remote', 'downgrade-refused', 'timeout', 'locked', 'failed']);
|
|
12
12
|
const CANONICAL_UPDATE_SOURCE_BASE = 'https://raw.githubusercontent.com/LiWeny16/create-harness-vibe-coding/main/templates/common/';
|
|
13
|
+
const DEFAULT_WF_UI_PORT = 56670;
|
|
14
|
+
const DEFAULT_UPDATE_TIMEOUT_MS = 120000;
|
|
15
|
+
const UPDATE_TIMEOUT_EXIT = 3;
|
|
13
16
|
|
|
14
17
|
// ── CLI flags ──────────────────────────────────────────────
|
|
15
18
|
const raw = process.argv.slice(2);
|
|
@@ -28,6 +31,16 @@ function hasFlag(args, flag) {
|
|
|
28
31
|
// never fall through to the scaffold installer.
|
|
29
32
|
if (raw[0] === 'wf-ui') {
|
|
30
33
|
await runWfUi(raw.slice(1));
|
|
34
|
+
await flushStdout();
|
|
35
|
+
process.exit(0);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// init subcommand: bind an existing project to the global Harness runtime.
|
|
39
|
+
// The global runtime (installed once via npm i -g) is the single version
|
|
40
|
+
// source of truth; the project keeps only bridge docs plus its own state.
|
|
41
|
+
if (raw[0] === 'init') {
|
|
42
|
+
runInit(raw.slice(1));
|
|
43
|
+
await flushStdout();
|
|
31
44
|
process.exit(0);
|
|
32
45
|
}
|
|
33
46
|
|
|
@@ -49,10 +62,13 @@ if (showHelp) {
|
|
|
49
62
|
console.log('');
|
|
50
63
|
console.log(' Usage:');
|
|
51
64
|
console.log(' npx create-harness-vibe-coding@latest [project-name] [target-dir] [flags]');
|
|
65
|
+
console.log(' create-harness-vibe-coding init [target-dir] [flags]');
|
|
66
|
+
console.log(' create-harness-vibe-coding wf-ui --project . [flags]');
|
|
52
67
|
console.log('');
|
|
53
68
|
console.log(' Arguments:');
|
|
54
69
|
console.log(' project-name Name for the new project (default: my-vibe-project)');
|
|
55
70
|
console.log(' target-dir Directory to create the project in (default: ./<project-name>)');
|
|
71
|
+
console.log(' init Bind an existing project to the global Harness runtime (thin bridge; global runtime is the single version source of truth)');
|
|
56
72
|
console.log('');
|
|
57
73
|
console.log(' Flags:');
|
|
58
74
|
console.log(' -y, --yes Skip all prompts, use defaults or provided args');
|
|
@@ -63,7 +79,7 @@ if (showHelp) {
|
|
|
63
79
|
console.log(' --without <id,id> Remove optional workflow skills selected by --preset or --with');
|
|
64
80
|
console.log(' --recommend <id,id> Record recommendation-only external capabilities');
|
|
65
81
|
console.log(' --preset <name> Add a built-in optional workflow preset');
|
|
66
|
-
console.log(' --install-scope <scope> project or global (default: project)');
|
|
82
|
+
console.log(' --install-scope <scope> project or global (new project default: global; existing target keeps project compatibility)');
|
|
67
83
|
console.log(' --global-dir <dir> Global Harness runtime directory for --install-scope global');
|
|
68
84
|
console.log(' --host-global-dir <dir> Base directory for Claude/Codex/OpenCode global copies');
|
|
69
85
|
console.log(' --list-options Print optional workflow skills and presets');
|
|
@@ -82,6 +98,8 @@ if (showHelp) {
|
|
|
82
98
|
console.log(' npx create-harness-vibe-coding@latest web ./web -y --preset web-app');
|
|
83
99
|
console.log(' npx create-harness-vibe-coding@latest api ./api -y --preset fullstack --without github-pr-review');
|
|
84
100
|
console.log(' npx create-harness-vibe-coding@latest app ./app -y --install-scope global');
|
|
101
|
+
console.log(' create-harness-vibe-coding init . # Per-project init against the global runtime');
|
|
102
|
+
console.log(' create-harness-vibe-coding init . --dry-run');
|
|
85
103
|
console.log('');
|
|
86
104
|
process.exit(0);
|
|
87
105
|
}
|
|
@@ -102,7 +120,10 @@ const generationOptions = {
|
|
|
102
120
|
withoutOptions: parsed.flags.without || [],
|
|
103
121
|
externalOptions: parsed.flags.recommend || [],
|
|
104
122
|
preset: parsed.flags.preset,
|
|
105
|
-
|
|
123
|
+
// New repositories use the global runtime standard. Existing non-empty
|
|
124
|
+
// targets are switched back to project scope below unless the user chose a
|
|
125
|
+
// scope explicitly, preserving the historical installer behavior.
|
|
126
|
+
installScope: parsed.flags.installScope || 'global',
|
|
106
127
|
globalDir: parsed.flags.globalDir,
|
|
107
128
|
hostGlobalDir: parsed.flags.hostGlobalDir,
|
|
108
129
|
json: Boolean(parsed.flags.json),
|
|
@@ -115,6 +136,9 @@ if (generationOptions.json) {
|
|
|
115
136
|
const projectName = argName || DEFAULT_NAME;
|
|
116
137
|
const targetDir = argDir || `./${projectName}`;
|
|
117
138
|
const scan = scanTarget(targetDir);
|
|
139
|
+
if (parsed.flags.installScope === undefined) {
|
|
140
|
+
generationOptions.installScope = defaultInstallScope(scan);
|
|
141
|
+
}
|
|
118
142
|
if (needsScaffoldRecovery(scan)) {
|
|
119
143
|
const recovery = createScaffoldRecoveryResult({ projectName, targetDir, options: generationOptions, scan });
|
|
120
144
|
printJsonResult(recovery);
|
|
@@ -122,8 +146,9 @@ if (generationOptions.json) {
|
|
|
122
146
|
}
|
|
123
147
|
|
|
124
148
|
if (scan.hasHarness) {
|
|
125
|
-
|
|
126
|
-
|
|
149
|
+
const updateResult = createUpdateSwitchResult(scan, { json: true });
|
|
150
|
+
printJsonResult(updateResult, { exitOnFailure: false });
|
|
151
|
+
process.exit(updateResult.success ? 0 : (updateResult.exitCode || 1));
|
|
127
152
|
}
|
|
128
153
|
const result = generate({ projectName, targetDir, ...generationOptions });
|
|
129
154
|
result.scan = createJsonScan(scan);
|
|
@@ -154,6 +179,9 @@ if (argName || skipPrompts) {
|
|
|
154
179
|
projectName = argName || DEFAULT_NAME;
|
|
155
180
|
targetDir = argDir || `./${projectName}`;
|
|
156
181
|
const scan = scanTarget(targetDir);
|
|
182
|
+
if (parsed.flags.installScope === undefined) {
|
|
183
|
+
generationOptions.installScope = defaultInstallScope(scan);
|
|
184
|
+
}
|
|
157
185
|
|
|
158
186
|
if (needsScaffoldRecovery(scan)) {
|
|
159
187
|
process.exit(runScaffoldRecovery({ projectName, targetDir, options: generationOptions, scan }));
|
|
@@ -217,14 +245,15 @@ if (argName || skipPrompts) {
|
|
|
217
245
|
console.log(pc.dim(` Directory: ${targetDir} (default)`));
|
|
218
246
|
}
|
|
219
247
|
|
|
248
|
+
const targetScan = scanTarget(targetDir);
|
|
220
249
|
try {
|
|
221
|
-
generationOptions.installScope = await askInstallScope();
|
|
250
|
+
generationOptions.installScope = await askInstallScope(defaultInstallScope(targetScan));
|
|
222
251
|
} catch {
|
|
223
|
-
generationOptions.installScope =
|
|
224
|
-
console.log(pc.dim(
|
|
252
|
+
generationOptions.installScope = defaultInstallScope(targetScan);
|
|
253
|
+
console.log(pc.dim(` Scope: ${generationOptions.installScope} (default)`));
|
|
225
254
|
}
|
|
226
255
|
|
|
227
|
-
const scan =
|
|
256
|
+
const scan = targetScan;
|
|
228
257
|
printScan(scan);
|
|
229
258
|
|
|
230
259
|
if (needsScaffoldRecovery(scan)) {
|
|
@@ -389,9 +418,11 @@ function printResult(result, targetDir) {
|
|
|
389
418
|
async function runWfUi(args) {
|
|
390
419
|
const projectRoot = extractFlag(args, '--project') || process.cwd();
|
|
391
420
|
const host = extractFlag(args, '--host') || '127.0.0.1';
|
|
392
|
-
const rawPort = extractFlag(args, '--port') ||
|
|
421
|
+
const rawPort = extractFlag(args, '--port') || String(DEFAULT_WF_UI_PORT);
|
|
393
422
|
const port = Number.parseInt(rawPort, 10);
|
|
394
423
|
const openBrowser = !hasFlag(args, '--no-open');
|
|
424
|
+
const detach = hasFlag(args, '--detach');
|
|
425
|
+
const detachedChild = hasFlag(args, '--detached-child');
|
|
395
426
|
|
|
396
427
|
if (host !== '127.0.0.1') {
|
|
397
428
|
console.error('[wf-ui] host must be 127.0.0.1');
|
|
@@ -402,24 +433,36 @@ async function runWfUi(args) {
|
|
|
402
433
|
process.exit(1);
|
|
403
434
|
}
|
|
404
435
|
|
|
436
|
+
if (detach && !detachedChild) {
|
|
437
|
+
try {
|
|
438
|
+
await runDetachedWfUi(args);
|
|
439
|
+
} catch (err) {
|
|
440
|
+
console.error(`[wf-ui] ${err.message}`);
|
|
441
|
+
process.exit(1);
|
|
442
|
+
}
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
|
|
405
446
|
try {
|
|
406
447
|
const serverModule = await import('./wf-ui-server/server.mjs');
|
|
407
448
|
const { SessionRegistry } = await import('./wf-ui-server/session-registry.mjs');
|
|
408
|
-
const { attachEventsWs } = await import('./wf-ui-server/ws-events.mjs');
|
|
409
449
|
const { attachTerminalWs } = await import('./wf-ui-server/ws-terminal.mjs');
|
|
450
|
+
const { attachWfBrowserWs } = await import('./wf-ui-server/ws-wf-browser.mjs');
|
|
410
451
|
const { warmRuntimeCache } = await import('./wf-ui-server/runtime-detector.mjs');
|
|
411
452
|
const { appendSessionEvent, appendTerminalData, persistSession, recordInputRequest } =
|
|
412
453
|
await import('./wf-ui-server/terminal-store.mjs');
|
|
413
454
|
const registry = new SessionRegistry();
|
|
414
455
|
const terminalHub = {};
|
|
415
|
-
const
|
|
456
|
+
const wfBrowserHub = {};
|
|
457
|
+
const started = await startWfUiServerWithPortFallback(serverModule, {
|
|
416
458
|
projectRoot,
|
|
417
459
|
host,
|
|
418
460
|
port,
|
|
419
461
|
sessionRegistry: registry,
|
|
420
462
|
terminalHub,
|
|
463
|
+
wfBrowserHub,
|
|
421
464
|
});
|
|
422
|
-
|
|
465
|
+
Object.assign(wfBrowserHub, attachWfBrowserWs(started.server, started.token, projectRoot));
|
|
423
466
|
Object.assign(terminalHub, attachTerminalWs(started.server, started.token, registry, {
|
|
424
467
|
onTerminalInput(session, data) {
|
|
425
468
|
try {
|
|
@@ -439,15 +482,241 @@ async function runWfUi(args) {
|
|
|
439
482
|
},
|
|
440
483
|
}));
|
|
441
484
|
warmRuntimeCache();
|
|
442
|
-
|
|
485
|
+
await writeStdoutLine(`[wf-ui] ${started.url}`);
|
|
486
|
+
writeWfUiReadyFile(started.url, projectRoot);
|
|
443
487
|
if (openBrowser) openLocalUrl(started.url);
|
|
444
|
-
|
|
488
|
+
try {
|
|
489
|
+
await waitForWfUiShutdown(started.server);
|
|
490
|
+
} finally {
|
|
491
|
+
cleanupWfUiLaunchDirFromReadyFile();
|
|
492
|
+
}
|
|
445
493
|
} catch (err) {
|
|
446
494
|
console.error(`[wf-ui] ${err.message}`);
|
|
447
495
|
process.exit(1);
|
|
448
496
|
}
|
|
449
497
|
}
|
|
450
498
|
|
|
499
|
+
async function startWfUiServerWithPortFallback(serverModule, options) {
|
|
500
|
+
const requestedPort = options.port;
|
|
501
|
+
let candidatePort = requestedPort;
|
|
502
|
+
|
|
503
|
+
while (true) {
|
|
504
|
+
try {
|
|
505
|
+
return await serverModule.startServer({ ...options, port: candidatePort });
|
|
506
|
+
} catch (err) {
|
|
507
|
+
if (requestedPort === 0 || err?.code !== 'EADDRINUSE') throw err;
|
|
508
|
+
if (candidatePort >= 65535) {
|
|
509
|
+
throw new Error(`ports ${requestedPort}-65535 are occupied`);
|
|
510
|
+
}
|
|
511
|
+
candidatePort += 1;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
async function runDetachedWfUi(args) {
|
|
517
|
+
const projectRoot = extractFlag(args, '--project') || process.cwd();
|
|
518
|
+
const readyDir = process.env.HARNESS_WF_UI_READY_FILE
|
|
519
|
+
? null
|
|
520
|
+
: makeProjectLocalWfUiLaunchDir(projectRoot);
|
|
521
|
+
const readyFile = process.env.HARNESS_WF_UI_READY_FILE || path.join(readyDir, 'ready.json');
|
|
522
|
+
const logFile = path.join(path.dirname(readyFile), 'wf-ui.log');
|
|
523
|
+
fs.mkdirSync(path.dirname(readyFile), { recursive: true });
|
|
524
|
+
try { fs.rmSync(readyFile, { force: true }); } catch {}
|
|
525
|
+
|
|
526
|
+
const childArgs = args.filter(arg => arg !== '--detach');
|
|
527
|
+
childArgs.push('--detached-child');
|
|
528
|
+
const child = spawnDetachedWfUiChild(childArgs, readyFile, logFile);
|
|
529
|
+
|
|
530
|
+
let childExit = null;
|
|
531
|
+
child.once('exit', (code, signal) => {
|
|
532
|
+
childExit = { code, signal };
|
|
533
|
+
});
|
|
534
|
+
child.unref();
|
|
535
|
+
|
|
536
|
+
const started = await waitForWfUiReadyFile(readyFile, () => {
|
|
537
|
+
if (process.platform === 'win32' && childExit?.code === 0) return null;
|
|
538
|
+
return childExit;
|
|
539
|
+
}, logFile);
|
|
540
|
+
spawnWfUiLaunchCleanupWatcher(started.pid, path.dirname(readyFile));
|
|
541
|
+
await writeStdoutLine(`[wf-ui] ${started.url}`);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
function makeProjectLocalWfUiLaunchDir(projectRoot) {
|
|
545
|
+
const launchRoot = path.join(path.resolve(projectRoot || process.cwd()), 'Harness', '.temp', 'wf-ui-launch');
|
|
546
|
+
fs.mkdirSync(launchRoot, { recursive: true });
|
|
547
|
+
return fs.mkdtempSync(path.join(launchRoot, 'harness-wf-ui-'));
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
function spawnDetachedWfUiChild(childArgs, readyFile, logFile) {
|
|
551
|
+
if (process.platform === 'win32') {
|
|
552
|
+
const launcherScript = `
|
|
553
|
+
const { spawn } = require('child_process');
|
|
554
|
+
const fs = require('fs');
|
|
555
|
+
const spec = JSON.parse(process.argv[1]);
|
|
556
|
+
const logFd = fs.openSync(spec.logFile, 'a');
|
|
557
|
+
const child = spawn(spec.execPath, spec.argv, {
|
|
558
|
+
cwd: spec.cwd,
|
|
559
|
+
detached: true,
|
|
560
|
+
env: { ...process.env, HARNESS_WF_UI_READY_FILE: spec.readyFile },
|
|
561
|
+
stdio: ['ignore', logFd, logFd],
|
|
562
|
+
windowsHide: true,
|
|
563
|
+
});
|
|
564
|
+
fs.closeSync(logFd);
|
|
565
|
+
child.unref();
|
|
566
|
+
`;
|
|
567
|
+
return spawn(process.execPath, ['-e', launcherScript, JSON.stringify({
|
|
568
|
+
execPath: process.execPath,
|
|
569
|
+
argv: [process.argv[1], 'wf-ui', ...childArgs],
|
|
570
|
+
cwd: process.cwd(),
|
|
571
|
+
readyFile,
|
|
572
|
+
logFile,
|
|
573
|
+
})], {
|
|
574
|
+
cwd: process.cwd(),
|
|
575
|
+
env: process.env,
|
|
576
|
+
stdio: 'ignore',
|
|
577
|
+
windowsHide: true,
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
const logFd = fs.openSync(logFile, 'a');
|
|
582
|
+
const child = spawn(process.execPath, [process.argv[1], 'wf-ui', ...childArgs], {
|
|
583
|
+
cwd: process.cwd(),
|
|
584
|
+
detached: true,
|
|
585
|
+
env: {
|
|
586
|
+
...process.env,
|
|
587
|
+
HARNESS_WF_UI_READY_FILE: readyFile,
|
|
588
|
+
},
|
|
589
|
+
stdio: ['ignore', logFd, logFd],
|
|
590
|
+
});
|
|
591
|
+
fs.closeSync(logFd);
|
|
592
|
+
return child;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
function writeWfUiReadyFile(url, projectRoot) {
|
|
596
|
+
const readyFile = process.env.HARNESS_WF_UI_READY_FILE;
|
|
597
|
+
if (!readyFile) return;
|
|
598
|
+
try {
|
|
599
|
+
fs.mkdirSync(path.dirname(readyFile), { recursive: true });
|
|
600
|
+
fs.writeFileSync(readyFile, `${JSON.stringify({
|
|
601
|
+
url,
|
|
602
|
+
pid: process.pid,
|
|
603
|
+
projectRoot: path.resolve(projectRoot),
|
|
604
|
+
startedAt: new Date().toISOString(),
|
|
605
|
+
})}\n`, 'utf8');
|
|
606
|
+
} catch (err) {
|
|
607
|
+
console.error(`[wf-ui] could not write ready file: ${err.message}`);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
function isProjectLocalWfUiLaunchDir(dir) {
|
|
612
|
+
const resolved = path.resolve(dir);
|
|
613
|
+
const launchRoot = path.dirname(resolved);
|
|
614
|
+
return path.basename(resolved).startsWith('harness-wf-ui-')
|
|
615
|
+
&& path.basename(launchRoot) === 'wf-ui-launch'
|
|
616
|
+
&& path.basename(path.dirname(launchRoot)) === '.temp'
|
|
617
|
+
&& path.basename(path.dirname(path.dirname(launchRoot))) === 'Harness';
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
function removeWfUiLaunchDir(dir) {
|
|
621
|
+
if (!isProjectLocalWfUiLaunchDir(dir)) return;
|
|
622
|
+
const resolved = path.resolve(dir);
|
|
623
|
+
const launchRoot = path.dirname(resolved);
|
|
624
|
+
try {
|
|
625
|
+
fs.rmSync(resolved, { recursive: true, force: true });
|
|
626
|
+
} catch {
|
|
627
|
+
// Best-effort cleanup; the detached cleanup watcher also retries after process exit.
|
|
628
|
+
}
|
|
629
|
+
try {
|
|
630
|
+
if (fs.existsSync(launchRoot) && fs.readdirSync(launchRoot).length === 0) {
|
|
631
|
+
fs.rmdirSync(launchRoot);
|
|
632
|
+
}
|
|
633
|
+
} catch {
|
|
634
|
+
// no-op
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
function cleanupWfUiLaunchDirFromReadyFile() {
|
|
639
|
+
const readyFile = process.env.HARNESS_WF_UI_READY_FILE;
|
|
640
|
+
if (!readyFile) return;
|
|
641
|
+
removeWfUiLaunchDir(path.dirname(readyFile));
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
function spawnWfUiLaunchCleanupWatcher(pid, launchDir) {
|
|
645
|
+
if (!pid || !isProjectLocalWfUiLaunchDir(launchDir)) return;
|
|
646
|
+
const watcherScript = `
|
|
647
|
+
const fs = require('fs');
|
|
648
|
+
const path = require('path');
|
|
649
|
+
const pid = Number(process.argv[1]);
|
|
650
|
+
const dir = process.argv[2];
|
|
651
|
+
const launchRoot = path.dirname(dir);
|
|
652
|
+
function alive() {
|
|
653
|
+
try {
|
|
654
|
+
process.kill(pid, 0);
|
|
655
|
+
return true;
|
|
656
|
+
} catch {
|
|
657
|
+
return false;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
function cleanup() {
|
|
661
|
+
try { fs.rmSync(dir, { recursive: true, force: true }); } catch {}
|
|
662
|
+
try {
|
|
663
|
+
if (fs.existsSync(launchRoot) && fs.readdirSync(launchRoot).length === 0) {
|
|
664
|
+
fs.rmdirSync(launchRoot);
|
|
665
|
+
}
|
|
666
|
+
} catch {}
|
|
667
|
+
}
|
|
668
|
+
(function wait() {
|
|
669
|
+
if (!alive()) {
|
|
670
|
+
cleanup();
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
setTimeout(wait, 1000);
|
|
674
|
+
})();
|
|
675
|
+
`;
|
|
676
|
+
try {
|
|
677
|
+
const watcher = spawn(process.execPath, ['-e', watcherScript, String(pid), path.resolve(launchDir)], {
|
|
678
|
+
cwd: process.cwd(),
|
|
679
|
+
detached: true,
|
|
680
|
+
stdio: 'ignore',
|
|
681
|
+
windowsHide: true,
|
|
682
|
+
});
|
|
683
|
+
watcher.unref();
|
|
684
|
+
} catch {
|
|
685
|
+
// no-op
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
function waitForWfUiReadyFile(readyFile, getChildExit, logFile) {
|
|
690
|
+
const deadline = Date.now() + 15000;
|
|
691
|
+
return new Promise((resolve, reject) => {
|
|
692
|
+
const poll = () => {
|
|
693
|
+
try {
|
|
694
|
+
if (fs.existsSync(readyFile)) {
|
|
695
|
+
const payload = JSON.parse(fs.readFileSync(readyFile, 'utf8'));
|
|
696
|
+
if (payload?.url) {
|
|
697
|
+
resolve(payload);
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
} catch {
|
|
702
|
+
// The child may still be writing the handoff file.
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
const childExit = getChildExit();
|
|
706
|
+
if (childExit) {
|
|
707
|
+
reject(new Error(`detached server exited before startup (${childExit.signal || childExit.code}); log: ${logFile}`));
|
|
708
|
+
return;
|
|
709
|
+
}
|
|
710
|
+
if (Date.now() >= deadline) {
|
|
711
|
+
reject(new Error(`detached server did not report a URL within 15s; log: ${logFile}`));
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
setTimeout(poll, 80);
|
|
715
|
+
};
|
|
716
|
+
poll();
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
|
|
451
720
|
function waitForWfUiShutdown(server) {
|
|
452
721
|
return new Promise((resolve) => {
|
|
453
722
|
let closing = false;
|
|
@@ -481,6 +750,135 @@ function openLocalUrl(url) {
|
|
|
481
750
|
}
|
|
482
751
|
}
|
|
483
752
|
|
|
753
|
+
function flushStdout() {
|
|
754
|
+
return new Promise((resolve) => {
|
|
755
|
+
if (!process.stdout.writable || process.stdout.writableEnded) {
|
|
756
|
+
resolve();
|
|
757
|
+
return;
|
|
758
|
+
}
|
|
759
|
+
process.stdout.write('', resolve);
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
// init: bind an existing project to a Harness runtime (non-interactive).
|
|
764
|
+
// Default scope `global`: the project gets thin bridge docs plus its own
|
|
765
|
+
// state, while framework files/commands/skills/scripts live once in the
|
|
766
|
+
// machine-level global runtime — the single version source of truth.
|
|
767
|
+
// Scope `project` keeps the classic full project-level install: the whole
|
|
768
|
+
// framework is copied into the project so it stays self-contained.
|
|
769
|
+
// Safe to re-run: user-authored files are preserved under the default `skip`
|
|
770
|
+
// conflict policy.
|
|
771
|
+
function runInit(args) {
|
|
772
|
+
const valueFlags = new Set(['--global-dir', '--host-global-dir', '--on-conflict', '--scope']);
|
|
773
|
+
const scopeRaw = (extractFlag(args, '--scope') || 'global').trim().toLowerCase();
|
|
774
|
+
const installScope = scopeRaw === 'project' || scopeRaw === 'global' ? scopeRaw : null;
|
|
775
|
+
if (!installScope) {
|
|
776
|
+
console.error(pc.red(`[init] unknown --scope "${scopeRaw}". Use project or global.`));
|
|
777
|
+
process.exit(1);
|
|
778
|
+
}
|
|
779
|
+
const positional = args.find((arg, idx) => !arg.startsWith('-') && !valueFlags.has(args[idx - 1]));
|
|
780
|
+
const targetDir = positional || '.';
|
|
781
|
+
const scan = scanTarget(targetDir);
|
|
782
|
+
|
|
783
|
+
if (scan.hasHarness) {
|
|
784
|
+
if (hasFlag(args, '--json')) process.exit(runUpdateSwitch(scan, { json: true }));
|
|
785
|
+
console.log(pc.yellow(`\nHarness already detected in ${targetDir}. Nothing to init.`));
|
|
786
|
+
process.exit(runUpdateSwitch(scan, { json: false }));
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
const result = generate({
|
|
790
|
+
projectName: path.basename(path.resolve(process.cwd(), targetDir)),
|
|
791
|
+
targetDir,
|
|
792
|
+
dryRun: hasFlag(args, '--dry-run'),
|
|
793
|
+
onConflict: extractFlag(args, '--on-conflict') || 'skip',
|
|
794
|
+
withOptions: [],
|
|
795
|
+
withoutOptions: [],
|
|
796
|
+
externalOptions: [],
|
|
797
|
+
preset: undefined,
|
|
798
|
+
installScope,
|
|
799
|
+
globalDir: installScope === 'global' ? extractFlag(args, '--global-dir') : undefined,
|
|
800
|
+
hostGlobalDir: installScope === 'global' ? extractFlag(args, '--host-global-dir') : undefined,
|
|
801
|
+
json: hasFlag(args, '--json'),
|
|
802
|
+
});
|
|
803
|
+
|
|
804
|
+
if (hasFlag(args, '--json')) {
|
|
805
|
+
console.log(JSON.stringify({
|
|
806
|
+
success: result.success,
|
|
807
|
+
installScope: result.installScope,
|
|
808
|
+
globalDir: result.globalDir || null,
|
|
809
|
+
createdCount: result.created.length,
|
|
810
|
+
project: result.summary || null,
|
|
811
|
+
globalRuntime: result.globalSummary || null,
|
|
812
|
+
hosts: result.hostSummary || [],
|
|
813
|
+
errors: result.errors,
|
|
814
|
+
warnings: result.warnings,
|
|
815
|
+
}, null, 2));
|
|
816
|
+
if (!result.success) process.exit(1);
|
|
817
|
+
return;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
if (!result.success) {
|
|
821
|
+
console.log(pc.red('\nInit failed:'));
|
|
822
|
+
for (const err of result.errors) {
|
|
823
|
+
console.log(pc.red(` - ${err}`));
|
|
824
|
+
}
|
|
825
|
+
process.exit(1);
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
if (result.dryRun) {
|
|
829
|
+
console.log(pc.yellow('\nDry run: no files or directories were written.'));
|
|
830
|
+
} else {
|
|
831
|
+
console.log(pc.green(`\nInit complete (${installScope} scope).\n`));
|
|
832
|
+
}
|
|
833
|
+
console.log(pc.bold('Project install:'));
|
|
834
|
+
printInitSummary(result.summary);
|
|
835
|
+
if (result.globalSummary) {
|
|
836
|
+
console.log(pc.bold('\nGlobal runtime (single version source of truth):'));
|
|
837
|
+
console.log(` Directory ${pc.cyan(result.globalDir)}`);
|
|
838
|
+
printInitSummary(result.globalSummary);
|
|
839
|
+
}
|
|
840
|
+
for (const host of result.hostSummary || []) {
|
|
841
|
+
console.log(pc.bold(`\nHost copy (${host.host}):`));
|
|
842
|
+
console.log(` Directory ${pc.cyan(host.root)}`);
|
|
843
|
+
printInitSummary(host.summary);
|
|
844
|
+
}
|
|
845
|
+
printInitWarnings(result);
|
|
846
|
+
|
|
847
|
+
console.log(pc.bold('\nNext steps:'));
|
|
848
|
+
console.log(` ${pc.cyan('/wf-ui')} # Open the control panel${installScope === 'global' ? '; the global runtime serves this project' : ''}`);
|
|
849
|
+
console.log(` ${pc.cyan('/wf <task>')} # Start a workflow task in this project`);
|
|
850
|
+
if (installScope === 'global') {
|
|
851
|
+
console.log(pc.dim('\n Project state (Harness/tasks, memory, PROGRESS.md) stays local to this project.'));
|
|
852
|
+
console.log(pc.dim(' Update the global runtime with /wf-update or `npm i -g create-harness-vibe-coding@latest`; every project picks it up.'));
|
|
853
|
+
} else {
|
|
854
|
+
console.log(pc.dim('\n The full Harness framework lives in this project; update it per project with /wf-update.'));
|
|
855
|
+
}
|
|
856
|
+
console.log('');
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
function printInitSummary(summary) {
|
|
860
|
+
if (!summary) return;
|
|
861
|
+
console.log(` Created ${summary.created}, skipped ${summary.skipped}, overwritten ${summary.overwritten}, backed up ${summary.backedUp}, conflicts ${summary.conflicts}`);
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
function printInitWarnings(result) {
|
|
865
|
+
if (!result.warnings || result.warnings.length === 0) return;
|
|
866
|
+
console.log(pc.yellow('\nWarning(s):'));
|
|
867
|
+
for (const warning of result.warnings) {
|
|
868
|
+
console.log(pc.yellow(` - ${warning}`));
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
function writeStdoutLine(line) {
|
|
873
|
+
return new Promise((resolve) => {
|
|
874
|
+
if (!process.stdout.writable || process.stdout.writableEnded) {
|
|
875
|
+
resolve();
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
process.stdout.write(`${line}\n`, resolve);
|
|
879
|
+
});
|
|
880
|
+
}
|
|
881
|
+
|
|
484
882
|
function parseArgs(args) {
|
|
485
883
|
const flags = {
|
|
486
884
|
with: [],
|
|
@@ -657,11 +1055,11 @@ function printWarnings(result) {
|
|
|
657
1055
|
}
|
|
658
1056
|
}
|
|
659
1057
|
|
|
660
|
-
function printJsonResult(result) {
|
|
1058
|
+
function printJsonResult(result, { exitOnFailure = true } = {}) {
|
|
661
1059
|
// Remove `created` array from output — it is already in the plan, avoid duplication
|
|
662
1060
|
const { created, globalCreated, hostCreated, ...rest } = result;
|
|
663
1061
|
console.log(JSON.stringify(rest, null, 2));
|
|
664
|
-
if (!result.success) {
|
|
1062
|
+
if (exitOnFailure && !result.success) {
|
|
665
1063
|
process.exit(1);
|
|
666
1064
|
}
|
|
667
1065
|
}
|
|
@@ -670,6 +1068,59 @@ function updateScriptPath(scan) {
|
|
|
670
1068
|
return path.join(scan.resolvedDir, 'Harness', 'scripts', 'wf-update-check.mjs');
|
|
671
1069
|
}
|
|
672
1070
|
|
|
1071
|
+
function updateTimeoutMs() {
|
|
1072
|
+
const raw = process.env.WF_UPDATE_TIMEOUT_MS;
|
|
1073
|
+
const parsed = raw ? Number.parseInt(raw, 10) : DEFAULT_UPDATE_TIMEOUT_MS;
|
|
1074
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_UPDATE_TIMEOUT_MS;
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
function readInstallMetadata(scan) {
|
|
1078
|
+
const file = path.join(scan.resolvedDir, 'Harness', '.harness-version');
|
|
1079
|
+
try {
|
|
1080
|
+
return fs.existsSync(file) ? JSON.parse(fs.readFileSync(file, 'utf8')) : null;
|
|
1081
|
+
} catch {
|
|
1082
|
+
return null;
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
function sameResolvedPath(left, right) {
|
|
1087
|
+
if (!left || !right) return false;
|
|
1088
|
+
const a = path.resolve(left);
|
|
1089
|
+
const b = path.resolve(right);
|
|
1090
|
+
return process.platform === 'win32' ? a.toLowerCase() === b.toLowerCase() : a === b;
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
function globalBridgeMetadata(scan) {
|
|
1094
|
+
const metadata = readInstallMetadata(scan);
|
|
1095
|
+
if (metadata?.installScope !== 'global' || !metadata.globalDir) return null;
|
|
1096
|
+
const globalDir = path.resolve(metadata.globalDir);
|
|
1097
|
+
if (sameResolvedPath(globalDir, scan.resolvedDir)) return null;
|
|
1098
|
+
return { metadata, globalDir };
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
function globalBridgeUpdateTarget(scan) {
|
|
1102
|
+
const bridge = globalBridgeMetadata(scan);
|
|
1103
|
+
if (!bridge) return null;
|
|
1104
|
+
const globalVersion = path.join(bridge.globalDir, 'Harness', '.harness-version');
|
|
1105
|
+
const globalChecker = path.join(bridge.globalDir, 'Harness', 'scripts', 'wf-update-check.mjs');
|
|
1106
|
+
const globalRunner = path.join(bridge.globalDir, 'Harness', 'scripts', 'wf-update-runner.mjs');
|
|
1107
|
+
if (!fs.existsSync(globalVersion) || !fs.existsSync(globalChecker)) return null;
|
|
1108
|
+
return {
|
|
1109
|
+
root: bridge.globalDir,
|
|
1110
|
+
scriptPath: fs.existsSync(globalRunner) ? globalRunner : globalChecker,
|
|
1111
|
+
runner: fs.existsSync(globalRunner),
|
|
1112
|
+
bridge: true,
|
|
1113
|
+
};
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
function isGlobalBridge(scan) {
|
|
1117
|
+
return Boolean(globalBridgeMetadata(scan));
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
function defaultInstallScope(scan) {
|
|
1121
|
+
return scan.needsConflictPolicy && !isGlobalBridge(scan) ? 'project' : 'global';
|
|
1122
|
+
}
|
|
1123
|
+
|
|
673
1124
|
function missingRecoveryReasons(scan) {
|
|
674
1125
|
const reasons = [];
|
|
675
1126
|
if (!fs.existsSync(updateScriptPath(scan))) reasons.push('Harness/scripts/wf-update-check.mjs');
|
|
@@ -677,7 +1128,9 @@ function missingRecoveryReasons(scan) {
|
|
|
677
1128
|
}
|
|
678
1129
|
|
|
679
1130
|
function needsScaffoldRecovery(scan) {
|
|
680
|
-
|
|
1131
|
+
// A global bridge intentionally omits local updater scripts. Do not turn it
|
|
1132
|
+
// into a full project install just because its shared runtime is elsewhere.
|
|
1133
|
+
return scan.hasHarness && !isGlobalBridge(scan) && missingRecoveryReasons(scan).length > 0;
|
|
681
1134
|
}
|
|
682
1135
|
|
|
683
1136
|
function recoveryOptions(options) {
|
|
@@ -712,20 +1165,20 @@ function runScaffoldRecovery({ projectName, targetDir, options, scan }) {
|
|
|
712
1165
|
function runUpdateSwitch(scan, { json }) {
|
|
713
1166
|
const updateResult = createUpdateSwitchResult(scan, { json });
|
|
714
1167
|
if (json) {
|
|
715
|
-
printJsonResult(updateResult);
|
|
716
|
-
return updateResult.success ? 0 : 1;
|
|
1168
|
+
printJsonResult(updateResult, { exitOnFailure: false });
|
|
1169
|
+
return updateResult.success ? 0 : (updateResult.exitCode || 1);
|
|
717
1170
|
}
|
|
718
1171
|
|
|
719
1172
|
console.log('');
|
|
720
1173
|
console.log(pc.yellow('Existing Harness detected. Switching to wf-update check.'));
|
|
721
1174
|
console.log(pc.dim(`Directory ${scan.resolvedDir}`));
|
|
722
|
-
console.log(pc.dim(
|
|
1175
|
+
console.log(pc.dim(`Command ${updateResult.command || 'node Harness/scripts/wf-update-check.mjs'}`));
|
|
723
1176
|
console.log(pc.dim(`Source ${CANONICAL_UPDATE_SOURCE_BASE}`));
|
|
724
1177
|
console.log('');
|
|
725
1178
|
|
|
726
1179
|
if (!updateResult.success && updateResult.error) {
|
|
727
1180
|
console.error(pc.red(updateResult.error));
|
|
728
|
-
return 1;
|
|
1181
|
+
return updateResult.exitCode ?? 1;
|
|
729
1182
|
}
|
|
730
1183
|
|
|
731
1184
|
if (updateResult.stdout) process.stdout.write(updateResult.stdout);
|
|
@@ -747,35 +1200,64 @@ function getUpdateStatusError(update) {
|
|
|
747
1200
|
}
|
|
748
1201
|
|
|
749
1202
|
function createUpdateSwitchResult(scan, { json }) {
|
|
750
|
-
const
|
|
1203
|
+
const bridge = globalBridgeMetadata(scan);
|
|
1204
|
+
const bridgeTarget = globalBridgeUpdateTarget(scan);
|
|
1205
|
+
const target = bridgeTarget || (bridge ? {
|
|
1206
|
+
root: bridge.globalDir,
|
|
1207
|
+
scriptPath: path.join(bridge.globalDir, 'Harness', 'scripts', 'wf-update-check.mjs'),
|
|
1208
|
+
runner: false,
|
|
1209
|
+
bridge: true,
|
|
1210
|
+
} : {
|
|
1211
|
+
root: scan.resolvedDir,
|
|
1212
|
+
scriptPath: updateScriptPath(scan),
|
|
1213
|
+
runner: false,
|
|
1214
|
+
bridge: false,
|
|
1215
|
+
});
|
|
1216
|
+
const args = target.runner
|
|
1217
|
+
? [target.scriptPath, '--project', scan.resolvedDir]
|
|
1218
|
+
: [target.scriptPath];
|
|
751
1219
|
if (json) args.push('--json');
|
|
752
|
-
|
|
753
|
-
const scriptPath = path.join(scan.resolvedDir, 'Harness', 'scripts', 'wf-update-check.mjs');
|
|
754
|
-
const command = `node ${args.join(' ')}`;
|
|
1220
|
+
const command = `node ${args.map(value => (/\s/.test(value) ? JSON.stringify(value) : value)).join(' ')}`;
|
|
755
1221
|
const base = {
|
|
756
1222
|
success: false,
|
|
757
1223
|
mode: 'update',
|
|
758
1224
|
scan: createJsonScan(scan),
|
|
759
1225
|
agent: {
|
|
760
1226
|
sourceOfTruth: 'Existing Harness detected; install automatically switched to the target update checker. Do not continue install writes.',
|
|
761
|
-
updateCommand:
|
|
762
|
-
? 'node Harness/scripts/wf-update-check.mjs --json'
|
|
763
|
-
: 'node Harness/scripts/wf-update-check.mjs',
|
|
1227
|
+
updateCommand: command,
|
|
764
1228
|
updateSourceBase: CANONICAL_UPDATE_SOURCE_BASE,
|
|
765
1229
|
next: [
|
|
766
1230
|
{
|
|
767
1231
|
action: 'update',
|
|
768
|
-
command
|
|
769
|
-
? 'node Harness/scripts/wf-update-check.mjs --json'
|
|
770
|
-
: 'node Harness/scripts/wf-update-check.mjs',
|
|
1232
|
+
command,
|
|
771
1233
|
env: { WF_SOURCE_BASE: CANONICAL_UPDATE_SOURCE_BASE },
|
|
772
|
-
reason:
|
|
1234
|
+
reason: target.bridge
|
|
1235
|
+
? 'This project is a thin global bridge; the shared runtime is the single update source of truth.'
|
|
1236
|
+
: 'Harness already exists, so updates must use the installed Harness update flow.',
|
|
773
1237
|
},
|
|
774
1238
|
],
|
|
775
1239
|
},
|
|
776
1240
|
};
|
|
777
1241
|
|
|
778
|
-
if (!fs.existsSync(scriptPath)) {
|
|
1242
|
+
if (!fs.existsSync(target.scriptPath)) {
|
|
1243
|
+
if (target.bridge) {
|
|
1244
|
+
return {
|
|
1245
|
+
...base,
|
|
1246
|
+
success: false,
|
|
1247
|
+
exitCode: 1,
|
|
1248
|
+
error: 'This project is a global Harness bridge, but its shared global runtime was not found. No project files were written. Reinstall or update the global create-harness-vibe-coding runtime, then retry.',
|
|
1249
|
+
errors: ['global Harness runtime not found'],
|
|
1250
|
+
agent: {
|
|
1251
|
+
...base.agent,
|
|
1252
|
+
next: [{
|
|
1253
|
+
action: 'global-runtime-recovery',
|
|
1254
|
+
reason: 'The bridge must not be expanded into a project install when the shared runtime is unavailable.',
|
|
1255
|
+
command: 'npm install --global create-harness-vibe-coding@latest',
|
|
1256
|
+
note: 'The project bridge remains untouched; reinstalling the one global runtime restores the shared update source.',
|
|
1257
|
+
}],
|
|
1258
|
+
},
|
|
1259
|
+
};
|
|
1260
|
+
}
|
|
779
1261
|
return {
|
|
780
1262
|
...base,
|
|
781
1263
|
success: false,
|
|
@@ -795,8 +1277,10 @@ function createUpdateSwitchResult(scan, { json }) {
|
|
|
795
1277
|
}
|
|
796
1278
|
|
|
797
1279
|
const result = spawnSync(process.execPath, args, {
|
|
798
|
-
cwd:
|
|
1280
|
+
cwd: target.root,
|
|
799
1281
|
encoding: 'utf8',
|
|
1282
|
+
timeout: updateTimeoutMs(),
|
|
1283
|
+
killSignal: 'SIGTERM',
|
|
800
1284
|
env: {
|
|
801
1285
|
...process.env,
|
|
802
1286
|
WF_SOURCE_BASE: CANONICAL_UPDATE_SOURCE_BASE,
|
|
@@ -804,7 +1288,8 @@ function createUpdateSwitchResult(scan, { json }) {
|
|
|
804
1288
|
});
|
|
805
1289
|
const stdout = result.stdout || '';
|
|
806
1290
|
const stderr = result.stderr || '';
|
|
807
|
-
const
|
|
1291
|
+
const timedOut = result.error?.code === 'ETIMEDOUT';
|
|
1292
|
+
const status = timedOut ? UPDATE_TIMEOUT_EXIT : (result.status ?? 1);
|
|
808
1293
|
|
|
809
1294
|
let update = undefined;
|
|
810
1295
|
if (json && stdout.trim()) {
|
|
@@ -814,9 +1299,16 @@ function createUpdateSwitchResult(scan, { json }) {
|
|
|
814
1299
|
update = { rawOutput: stdout };
|
|
815
1300
|
}
|
|
816
1301
|
}
|
|
1302
|
+
if (timedOut && !update) {
|
|
1303
|
+
update = {
|
|
1304
|
+
status: 'timeout',
|
|
1305
|
+
code: 'UPDATE_TIMEOUT',
|
|
1306
|
+
message: `Update command exceeded the ${updateTimeoutMs()}ms deadline.`,
|
|
1307
|
+
};
|
|
1308
|
+
}
|
|
817
1309
|
|
|
818
1310
|
const errors = [];
|
|
819
|
-
if (status !== 0) errors.push(`Update checker exited with status ${status}`);
|
|
1311
|
+
if (status !== 0) errors.push(timedOut ? `Update checker exceeded the ${updateTimeoutMs()}ms deadline` : `Update checker exited with status ${status}`);
|
|
820
1312
|
if (json) {
|
|
821
1313
|
const statusError = getUpdateStatusError(update);
|
|
822
1314
|
if (statusError) errors.push(statusError);
|
|
@@ -829,6 +1321,7 @@ function createUpdateSwitchResult(scan, { json }) {
|
|
|
829
1321
|
command,
|
|
830
1322
|
stdout,
|
|
831
1323
|
stderr,
|
|
1324
|
+
...(timedOut ? { timedOut: true, errorCode: 'UPDATE_TIMEOUT' } : {}),
|
|
832
1325
|
...(json ? { update } : {}),
|
|
833
1326
|
...(errors.length === 0 ? {} : { error: errors[0], errors }),
|
|
834
1327
|
};
|