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