@forgeax/view 0.2.1-beta-20260924075842
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 +11 -0
- package/README.md +742 -0
- package/dist/modules/backend.mjs +54 -0
- package/dist/modules/backend.mjs.map +7 -0
- package/dist/modules/browser.mjs +180 -0
- package/dist/modules/browser.mjs.map +7 -0
- package/dist/modules/carrier-contract.mjs +38 -0
- package/dist/modules/carrier-contract.mjs.map +7 -0
- package/dist/modules/carrier.mjs +13 -0
- package/dist/modules/carrier.mjs.map +7 -0
- package/dist/modules/chunks/chunk-2ASWB6IX.mjs +225 -0
- package/dist/modules/chunks/chunk-2ASWB6IX.mjs.map +7 -0
- package/dist/modules/chunks/chunk-2IJKOG2F.mjs +801 -0
- package/dist/modules/chunks/chunk-2IJKOG2F.mjs.map +7 -0
- package/dist/modules/chunks/chunk-2K3BBJ5S.mjs +9 -0
- package/dist/modules/chunks/chunk-2K3BBJ5S.mjs.map +7 -0
- package/dist/modules/chunks/chunk-32GD5LL6.mjs +482 -0
- package/dist/modules/chunks/chunk-32GD5LL6.mjs.map +7 -0
- package/dist/modules/chunks/chunk-3B4KFAEC.mjs +10 -0
- package/dist/modules/chunks/chunk-3B4KFAEC.mjs.map +7 -0
- package/dist/modules/chunks/chunk-46O5WX43.mjs +25 -0
- package/dist/modules/chunks/chunk-46O5WX43.mjs.map +7 -0
- package/dist/modules/chunks/chunk-47J5JXAB.mjs +237 -0
- package/dist/modules/chunks/chunk-47J5JXAB.mjs.map +7 -0
- package/dist/modules/chunks/chunk-4BXQOUDQ.mjs +17 -0
- package/dist/modules/chunks/chunk-4BXQOUDQ.mjs.map +7 -0
- package/dist/modules/chunks/chunk-4GQWYU2V.mjs +126 -0
- package/dist/modules/chunks/chunk-4GQWYU2V.mjs.map +7 -0
- package/dist/modules/chunks/chunk-4N5X2PRQ.mjs +48 -0
- package/dist/modules/chunks/chunk-4N5X2PRQ.mjs.map +7 -0
- package/dist/modules/chunks/chunk-4WXD2KYX.mjs +56 -0
- package/dist/modules/chunks/chunk-4WXD2KYX.mjs.map +7 -0
- package/dist/modules/chunks/chunk-6ZWWVAZK.mjs +468 -0
- package/dist/modules/chunks/chunk-6ZWWVAZK.mjs.map +7 -0
- package/dist/modules/chunks/chunk-73UZNRHN.mjs +296 -0
- package/dist/modules/chunks/chunk-73UZNRHN.mjs.map +7 -0
- package/dist/modules/chunks/chunk-7ITLCRND.mjs +10 -0
- package/dist/modules/chunks/chunk-7ITLCRND.mjs.map +7 -0
- package/dist/modules/chunks/chunk-7TGVWKH7.mjs +59 -0
- package/dist/modules/chunks/chunk-7TGVWKH7.mjs.map +7 -0
- package/dist/modules/chunks/chunk-7URFF53W.mjs +42 -0
- package/dist/modules/chunks/chunk-7URFF53W.mjs.map +7 -0
- package/dist/modules/chunks/chunk-7YSDRIFN.mjs +14 -0
- package/dist/modules/chunks/chunk-7YSDRIFN.mjs.map +7 -0
- package/dist/modules/chunks/chunk-AAFVCQPK.mjs +52 -0
- package/dist/modules/chunks/chunk-AAFVCQPK.mjs.map +7 -0
- package/dist/modules/chunks/chunk-AEK7ZESQ.mjs +18 -0
- package/dist/modules/chunks/chunk-AEK7ZESQ.mjs.map +7 -0
- package/dist/modules/chunks/chunk-AL6ZWIEU.mjs +42 -0
- package/dist/modules/chunks/chunk-AL6ZWIEU.mjs.map +7 -0
- package/dist/modules/chunks/chunk-ALT7XVMQ.mjs +73 -0
- package/dist/modules/chunks/chunk-ALT7XVMQ.mjs.map +7 -0
- package/dist/modules/chunks/chunk-ASI2HBE6.mjs +116 -0
- package/dist/modules/chunks/chunk-ASI2HBE6.mjs.map +7 -0
- package/dist/modules/chunks/chunk-ATWGCH7I.mjs +174 -0
- package/dist/modules/chunks/chunk-ATWGCH7I.mjs.map +7 -0
- package/dist/modules/chunks/chunk-C45U6IIY.mjs +692 -0
- package/dist/modules/chunks/chunk-C45U6IIY.mjs.map +7 -0
- package/dist/modules/chunks/chunk-C7R3YRA7.mjs +98 -0
- package/dist/modules/chunks/chunk-C7R3YRA7.mjs.map +7 -0
- package/dist/modules/chunks/chunk-CRMICXKN.mjs +87 -0
- package/dist/modules/chunks/chunk-CRMICXKN.mjs.map +7 -0
- package/dist/modules/chunks/chunk-CUH2G6UF.mjs +81 -0
- package/dist/modules/chunks/chunk-CUH2G6UF.mjs.map +7 -0
- package/dist/modules/chunks/chunk-D7GWRZLL.mjs +77 -0
- package/dist/modules/chunks/chunk-D7GWRZLL.mjs.map +7 -0
- package/dist/modules/chunks/chunk-DBWUIBE3.mjs +10 -0
- package/dist/modules/chunks/chunk-DBWUIBE3.mjs.map +7 -0
- package/dist/modules/chunks/chunk-DQWVWWUU.mjs +77 -0
- package/dist/modules/chunks/chunk-DQWVWWUU.mjs.map +7 -0
- package/dist/modules/chunks/chunk-DZZ2WFEU.mjs +122 -0
- package/dist/modules/chunks/chunk-DZZ2WFEU.mjs.map +7 -0
- package/dist/modules/chunks/chunk-E4UIAN26.mjs +58 -0
- package/dist/modules/chunks/chunk-E4UIAN26.mjs.map +7 -0
- package/dist/modules/chunks/chunk-EJGBVKFE.mjs +77 -0
- package/dist/modules/chunks/chunk-EJGBVKFE.mjs.map +7 -0
- package/dist/modules/chunks/chunk-EPSTTHWV.mjs +173 -0
- package/dist/modules/chunks/chunk-EPSTTHWV.mjs.map +7 -0
- package/dist/modules/chunks/chunk-ER7T6QJ3.mjs +64 -0
- package/dist/modules/chunks/chunk-ER7T6QJ3.mjs.map +7 -0
- package/dist/modules/chunks/chunk-FD4BAJ6K.mjs +389 -0
- package/dist/modules/chunks/chunk-FD4BAJ6K.mjs.map +7 -0
- package/dist/modules/chunks/chunk-FJM6WWIY.mjs +80 -0
- package/dist/modules/chunks/chunk-FJM6WWIY.mjs.map +7 -0
- package/dist/modules/chunks/chunk-FKCQYDLX.mjs +162 -0
- package/dist/modules/chunks/chunk-FKCQYDLX.mjs.map +7 -0
- package/dist/modules/chunks/chunk-FLGC65SR.mjs +10 -0
- package/dist/modules/chunks/chunk-FLGC65SR.mjs.map +7 -0
- package/dist/modules/chunks/chunk-FMCACPX5.mjs +289 -0
- package/dist/modules/chunks/chunk-FMCACPX5.mjs.map +7 -0
- package/dist/modules/chunks/chunk-FOBRLUQV.mjs +51 -0
- package/dist/modules/chunks/chunk-FOBRLUQV.mjs.map +7 -0
- package/dist/modules/chunks/chunk-FV3DSKZB.mjs +33 -0
- package/dist/modules/chunks/chunk-FV3DSKZB.mjs.map +7 -0
- package/dist/modules/chunks/chunk-G7BAFAGO.mjs +98 -0
- package/dist/modules/chunks/chunk-G7BAFAGO.mjs.map +7 -0
- package/dist/modules/chunks/chunk-GQBZMCTK.mjs +145 -0
- package/dist/modules/chunks/chunk-GQBZMCTK.mjs.map +7 -0
- package/dist/modules/chunks/chunk-GYWIY7AL.mjs +131 -0
- package/dist/modules/chunks/chunk-GYWIY7AL.mjs.map +7 -0
- package/dist/modules/chunks/chunk-H3KNBALD.mjs +256 -0
- package/dist/modules/chunks/chunk-H3KNBALD.mjs.map +7 -0
- package/dist/modules/chunks/chunk-H3M22JDL.mjs +144 -0
- package/dist/modules/chunks/chunk-H3M22JDL.mjs.map +7 -0
- package/dist/modules/chunks/chunk-HES3DNTM.mjs +40 -0
- package/dist/modules/chunks/chunk-HES3DNTM.mjs.map +7 -0
- package/dist/modules/chunks/chunk-I5BFP7SS.mjs +2392 -0
- package/dist/modules/chunks/chunk-I5BFP7SS.mjs.map +7 -0
- package/dist/modules/chunks/chunk-IGRMZYRD.mjs +15 -0
- package/dist/modules/chunks/chunk-IGRMZYRD.mjs.map +7 -0
- package/dist/modules/chunks/chunk-IKNGC766.mjs +321 -0
- package/dist/modules/chunks/chunk-IKNGC766.mjs.map +7 -0
- package/dist/modules/chunks/chunk-IVHNYKZB.mjs +35 -0
- package/dist/modules/chunks/chunk-IVHNYKZB.mjs.map +7 -0
- package/dist/modules/chunks/chunk-JHOURMYW.mjs +101 -0
- package/dist/modules/chunks/chunk-JHOURMYW.mjs.map +7 -0
- package/dist/modules/chunks/chunk-JURXMRFA.mjs +282 -0
- package/dist/modules/chunks/chunk-JURXMRFA.mjs.map +7 -0
- package/dist/modules/chunks/chunk-JWZIREC3.mjs +18 -0
- package/dist/modules/chunks/chunk-JWZIREC3.mjs.map +7 -0
- package/dist/modules/chunks/chunk-KHRTIZ56.mjs +1400 -0
- package/dist/modules/chunks/chunk-KHRTIZ56.mjs.map +7 -0
- package/dist/modules/chunks/chunk-KLJZZ23J.mjs +102 -0
- package/dist/modules/chunks/chunk-KLJZZ23J.mjs.map +7 -0
- package/dist/modules/chunks/chunk-KNBAYU5I.mjs +49 -0
- package/dist/modules/chunks/chunk-KNBAYU5I.mjs.map +7 -0
- package/dist/modules/chunks/chunk-KSZNCFU4.mjs +125 -0
- package/dist/modules/chunks/chunk-KSZNCFU4.mjs.map +7 -0
- package/dist/modules/chunks/chunk-L45W6KM6.mjs +158 -0
- package/dist/modules/chunks/chunk-L45W6KM6.mjs.map +7 -0
- package/dist/modules/chunks/chunk-LERMYZRC.mjs +239 -0
- package/dist/modules/chunks/chunk-LERMYZRC.mjs.map +7 -0
- package/dist/modules/chunks/chunk-LKJCXYSJ.mjs +91 -0
- package/dist/modules/chunks/chunk-LKJCXYSJ.mjs.map +7 -0
- package/dist/modules/chunks/chunk-MBS3EICT.mjs +25 -0
- package/dist/modules/chunks/chunk-MBS3EICT.mjs.map +7 -0
- package/dist/modules/chunks/chunk-MUOQZPVH.mjs +609 -0
- package/dist/modules/chunks/chunk-MUOQZPVH.mjs.map +7 -0
- package/dist/modules/chunks/chunk-MVEPGFSB.mjs +1 -0
- package/dist/modules/chunks/chunk-MVEPGFSB.mjs.map +7 -0
- package/dist/modules/chunks/chunk-NBJKLWJ5.mjs +42 -0
- package/dist/modules/chunks/chunk-NBJKLWJ5.mjs.map +7 -0
- package/dist/modules/chunks/chunk-NBLGKTEM.mjs +86 -0
- package/dist/modules/chunks/chunk-NBLGKTEM.mjs.map +7 -0
- package/dist/modules/chunks/chunk-NI7CS3I2.mjs +110 -0
- package/dist/modules/chunks/chunk-NI7CS3I2.mjs.map +7 -0
- package/dist/modules/chunks/chunk-NJH2OJFC.mjs +2113 -0
- package/dist/modules/chunks/chunk-NJH2OJFC.mjs.map +7 -0
- package/dist/modules/chunks/chunk-OBK4LIJB.mjs +20 -0
- package/dist/modules/chunks/chunk-OBK4LIJB.mjs.map +7 -0
- package/dist/modules/chunks/chunk-PEUT3FW7.mjs +1 -0
- package/dist/modules/chunks/chunk-PEUT3FW7.mjs.map +7 -0
- package/dist/modules/chunks/chunk-PRZOWPDN.mjs +66 -0
- package/dist/modules/chunks/chunk-PRZOWPDN.mjs.map +7 -0
- package/dist/modules/chunks/chunk-Q4RXBGQS.mjs +55 -0
- package/dist/modules/chunks/chunk-Q4RXBGQS.mjs.map +7 -0
- package/dist/modules/chunks/chunk-QBHBKOIL.mjs +55 -0
- package/dist/modules/chunks/chunk-QBHBKOIL.mjs.map +7 -0
- package/dist/modules/chunks/chunk-QD6CCRMG.mjs +20 -0
- package/dist/modules/chunks/chunk-QD6CCRMG.mjs.map +7 -0
- package/dist/modules/chunks/chunk-QF4V23GW.mjs +39 -0
- package/dist/modules/chunks/chunk-QF4V23GW.mjs.map +7 -0
- package/dist/modules/chunks/chunk-QK6W7MJO.mjs +42 -0
- package/dist/modules/chunks/chunk-QK6W7MJO.mjs.map +7 -0
- package/dist/modules/chunks/chunk-QL7V6DK7.mjs +34 -0
- package/dist/modules/chunks/chunk-QL7V6DK7.mjs.map +7 -0
- package/dist/modules/chunks/chunk-QLBQQKRI.mjs +25 -0
- package/dist/modules/chunks/chunk-QLBQQKRI.mjs.map +7 -0
- package/dist/modules/chunks/chunk-QLZQGZDC.mjs +418 -0
- package/dist/modules/chunks/chunk-QLZQGZDC.mjs.map +7 -0
- package/dist/modules/chunks/chunk-QSKQZGK7.mjs +1625 -0
- package/dist/modules/chunks/chunk-QSKQZGK7.mjs.map +7 -0
- package/dist/modules/chunks/chunk-QURKBAG4.mjs +25 -0
- package/dist/modules/chunks/chunk-QURKBAG4.mjs.map +7 -0
- package/dist/modules/chunks/chunk-R274XBEH.mjs +53 -0
- package/dist/modules/chunks/chunk-R274XBEH.mjs.map +7 -0
- package/dist/modules/chunks/chunk-R4I4JEY5.mjs +77 -0
- package/dist/modules/chunks/chunk-R4I4JEY5.mjs.map +7 -0
- package/dist/modules/chunks/chunk-RR6L6VVR.mjs +9 -0
- package/dist/modules/chunks/chunk-RR6L6VVR.mjs.map +7 -0
- package/dist/modules/chunks/chunk-RXF7SBBZ.mjs +125 -0
- package/dist/modules/chunks/chunk-RXF7SBBZ.mjs.map +7 -0
- package/dist/modules/chunks/chunk-SR66S6EJ.mjs +138 -0
- package/dist/modules/chunks/chunk-SR66S6EJ.mjs.map +7 -0
- package/dist/modules/chunks/chunk-SSQMQJ52.mjs +27 -0
- package/dist/modules/chunks/chunk-SSQMQJ52.mjs.map +7 -0
- package/dist/modules/chunks/chunk-TP26TASL.mjs +20 -0
- package/dist/modules/chunks/chunk-TP26TASL.mjs.map +7 -0
- package/dist/modules/chunks/chunk-TSAEK5P3.mjs +50 -0
- package/dist/modules/chunks/chunk-TSAEK5P3.mjs.map +7 -0
- package/dist/modules/chunks/chunk-UAY27HT3.mjs +68 -0
- package/dist/modules/chunks/chunk-UAY27HT3.mjs.map +7 -0
- package/dist/modules/chunks/chunk-UDLIWGWS.mjs +103 -0
- package/dist/modules/chunks/chunk-UDLIWGWS.mjs.map +7 -0
- package/dist/modules/chunks/chunk-UDVQHPWV.mjs +89 -0
- package/dist/modules/chunks/chunk-UDVQHPWV.mjs.map +7 -0
- package/dist/modules/chunks/chunk-UM23W3G7.mjs +237 -0
- package/dist/modules/chunks/chunk-UM23W3G7.mjs.map +7 -0
- package/dist/modules/chunks/chunk-VDZJWEAA.mjs +214 -0
- package/dist/modules/chunks/chunk-VDZJWEAA.mjs.map +7 -0
- package/dist/modules/chunks/chunk-VIGOJWSO.mjs +42 -0
- package/dist/modules/chunks/chunk-VIGOJWSO.mjs.map +7 -0
- package/dist/modules/chunks/chunk-VY3S5BWI.mjs +284 -0
- package/dist/modules/chunks/chunk-VY3S5BWI.mjs.map +7 -0
- package/dist/modules/chunks/chunk-VZXGRZYU.mjs +47 -0
- package/dist/modules/chunks/chunk-VZXGRZYU.mjs.map +7 -0
- package/dist/modules/chunks/chunk-W5DMQZB5.mjs +42 -0
- package/dist/modules/chunks/chunk-W5DMQZB5.mjs.map +7 -0
- package/dist/modules/chunks/chunk-WOMHSTVZ.mjs +918 -0
- package/dist/modules/chunks/chunk-WOMHSTVZ.mjs.map +7 -0
- package/dist/modules/chunks/chunk-XFQT7XCG.mjs +42 -0
- package/dist/modules/chunks/chunk-XFQT7XCG.mjs.map +7 -0
- package/dist/modules/chunks/chunk-XJZEVRYX.mjs +98 -0
- package/dist/modules/chunks/chunk-XJZEVRYX.mjs.map +7 -0
- package/dist/modules/chunks/chunk-XUYFV23R.mjs +317 -0
- package/dist/modules/chunks/chunk-XUYFV23R.mjs.map +7 -0
- package/dist/modules/chunks/chunk-Y5HXCPPQ.mjs +58 -0
- package/dist/modules/chunks/chunk-Y5HXCPPQ.mjs.map +7 -0
- package/dist/modules/chunks/chunk-YTHGRKGI.mjs +147 -0
- package/dist/modules/chunks/chunk-YTHGRKGI.mjs.map +7 -0
- package/dist/modules/chunks/chunk-YVQSDKAO.mjs +341 -0
- package/dist/modules/chunks/chunk-YVQSDKAO.mjs.map +7 -0
- package/dist/modules/chunks/chunk-YYXQDUVT.mjs +123 -0
- package/dist/modules/chunks/chunk-YYXQDUVT.mjs.map +7 -0
- package/dist/modules/chunks/chunk-ZFXZ2NUI.mjs +142 -0
- package/dist/modules/chunks/chunk-ZFXZ2NUI.mjs.map +7 -0
- package/dist/modules/chunks/chunk-ZLNWF4ET.mjs +9 -0
- package/dist/modules/chunks/chunk-ZLNWF4ET.mjs.map +7 -0
- package/dist/modules/chunks/chunk-ZLU5QW2O.mjs +9 -0
- package/dist/modules/chunks/chunk-ZLU5QW2O.mjs.map +7 -0
- package/dist/modules/chunks/chunk-ZNZPYE2V.mjs +28 -0
- package/dist/modules/chunks/chunk-ZNZPYE2V.mjs.map +7 -0
- package/dist/modules/chunks/core-564N45MO.mjs +7480 -0
- package/dist/modules/chunks/core-564N45MO.mjs.map +7 -0
- package/dist/modules/chunks/css-BKH4SVJG.mjs +8 -0
- package/dist/modules/chunks/css-BKH4SVJG.mjs.map +7 -0
- package/dist/modules/chunks/engine-javascript-PDVIGNGR.mjs +3241 -0
- package/dist/modules/chunks/engine-javascript-PDVIGNGR.mjs.map +7 -0
- package/dist/modules/chunks/github-dark-default-6HVTHEWF.mjs +8 -0
- package/dist/modules/chunks/github-dark-default-6HVTHEWF.mjs.map +7 -0
- package/dist/modules/chunks/github-light-default-LAXRA6XL.mjs +8 -0
- package/dist/modules/chunks/github-light-default-LAXRA6XL.mjs.map +7 -0
- package/dist/modules/chunks/glsl-UC3YWUD2.mjs +18 -0
- package/dist/modules/chunks/glsl-UC3YWUD2.mjs.map +7 -0
- package/dist/modules/chunks/html-FRVIUV63.mjs +19 -0
- package/dist/modules/chunks/html-FRVIUV63.mjs.map +7 -0
- package/dist/modules/chunks/javascript-LN3OC7S2.mjs +8 -0
- package/dist/modules/chunks/javascript-LN3OC7S2.mjs.map +7 -0
- package/dist/modules/chunks/json-5CUGWTOP.mjs +11 -0
- package/dist/modules/chunks/json-5CUGWTOP.mjs.map +7 -0
- package/dist/modules/chunks/json5-YZQI5VNO.mjs +11 -0
- package/dist/modules/chunks/json5-YZQI5VNO.mjs.map +7 -0
- package/dist/modules/chunks/jsonc-SWID6VOZ.mjs +11 -0
- package/dist/modules/chunks/jsonc-SWID6VOZ.mjs.map +7 -0
- package/dist/modules/chunks/jsx-A7RDCLJO.mjs +11 -0
- package/dist/modules/chunks/jsx-A7RDCLJO.mjs.map +7 -0
- package/dist/modules/chunks/markdown-QTCU5KP5.mjs +11 -0
- package/dist/modules/chunks/markdown-QTCU5KP5.mjs.map +7 -0
- package/dist/modules/chunks/python-LAZONBIB.mjs +11 -0
- package/dist/modules/chunks/python-LAZONBIB.mjs.map +7 -0
- package/dist/modules/chunks/rust-XWTPJFJO.mjs +11 -0
- package/dist/modules/chunks/rust-XWTPJFJO.mjs.map +7 -0
- package/dist/modules/chunks/scss-CFXRHUUW.mjs +15 -0
- package/dist/modules/chunks/scss-CFXRHUUW.mjs.map +7 -0
- package/dist/modules/chunks/shellscript-OHO3LCVU.mjs +11 -0
- package/dist/modules/chunks/shellscript-OHO3LCVU.mjs.map +7 -0
- package/dist/modules/chunks/toml-IOHFZJ5B.mjs +11 -0
- package/dist/modules/chunks/toml-IOHFZJ5B.mjs.map +7 -0
- package/dist/modules/chunks/tsx-2E6WNX2E.mjs +11 -0
- package/dist/modules/chunks/tsx-2E6WNX2E.mjs.map +7 -0
- package/dist/modules/chunks/typescript-PBKAS54P.mjs +11 -0
- package/dist/modules/chunks/typescript-PBKAS54P.mjs.map +7 -0
- package/dist/modules/chunks/wgsl-PS6QPRLZ.mjs +11 -0
- package/dist/modules/chunks/wgsl-PS6QPRLZ.mjs.map +7 -0
- package/dist/modules/chunks/xml-JECR2ACB.mjs +18 -0
- package/dist/modules/chunks/xml-JECR2ACB.mjs.map +7 -0
- package/dist/modules/chunks/yaml-P2SV4LOE.mjs +11 -0
- package/dist/modules/chunks/yaml-P2SV4LOE.mjs.map +7 -0
- package/dist/modules/cli-contributions.mjs +32 -0
- package/dist/modules/cli-contributions.mjs.map +7 -0
- package/dist/modules/cli.mjs +14 -0
- package/dist/modules/cli.mjs.map +7 -0
- package/dist/modules/command-executor.mjs +65 -0
- package/dist/modules/command-executor.mjs.map +7 -0
- package/dist/modules/commands.mjs +10 -0
- package/dist/modules/commands.mjs.map +7 -0
- package/dist/modules/embedded.mjs +18608 -0
- package/dist/modules/embedded.mjs.map +7 -0
- package/dist/modules/extension-bridge.mjs +18 -0
- package/dist/modules/extension-bridge.mjs.map +7 -0
- package/dist/modules/frontend-root.mjs +61 -0
- package/dist/modules/frontend-root.mjs.map +7 -0
- package/dist/modules/index.mjs +784 -0
- package/dist/modules/index.mjs.map +7 -0
- package/dist/modules/page.mjs +45 -0
- package/dist/modules/page.mjs.map +7 -0
- package/dist/modules/pages/scene.mjs +18 -0
- package/dist/modules/pages/scene.mjs.map +7 -0
- package/dist/modules/plugin.mjs +56 -0
- package/dist/modules/plugin.mjs.map +7 -0
- package/dist/modules/plugins/asset/frontend.mjs +23 -0
- package/dist/modules/plugins/asset/frontend.mjs.map +7 -0
- package/dist/modules/plugins/asset/i18n.mjs +15 -0
- package/dist/modules/plugins/asset/i18n.mjs.map +7 -0
- package/dist/modules/plugins/asset/identity.mjs +42 -0
- package/dist/modules/plugins/asset/identity.mjs.map +7 -0
- package/dist/modules/plugins/asset/schema.mjs +10 -0
- package/dist/modules/plugins/asset/schema.mjs.map +7 -0
- package/dist/modules/plugins/asset/ui.mjs +16 -0
- package/dist/modules/plugins/asset/ui.mjs.map +7 -0
- package/dist/modules/plugins/content-browser/frontend.mjs +17 -0
- package/dist/modules/plugins/content-browser/frontend.mjs.map +7 -0
- package/dist/modules/plugins/content-browser/i18n.mjs +15 -0
- package/dist/modules/plugins/content-browser/i18n.mjs.map +7 -0
- package/dist/modules/plugins/content-browser/identity.mjs +22 -0
- package/dist/modules/plugins/content-browser/identity.mjs.map +7 -0
- package/dist/modules/plugins/content-browser/schema.mjs +12 -0
- package/dist/modules/plugins/content-browser/schema.mjs.map +7 -0
- package/dist/modules/plugins/content-browser/ui.mjs +15 -0
- package/dist/modules/plugins/content-browser/ui.mjs.map +7 -0
- package/dist/modules/plugins/display/api.mjs +10 -0
- package/dist/modules/plugins/display/api.mjs.map +7 -0
- package/dist/modules/plugins/display/backend.mjs +16 -0
- package/dist/modules/plugins/display/backend.mjs.map +7 -0
- package/dist/modules/plugins/display/carrier-contract.mjs +38 -0
- package/dist/modules/plugins/display/carrier-contract.mjs.map +7 -0
- package/dist/modules/plugins/display/carrier.mjs +13 -0
- package/dist/modules/plugins/display/carrier.mjs.map +7 -0
- package/dist/modules/plugins/display/effects.mjs +8 -0
- package/dist/modules/plugins/display/effects.mjs.map +7 -0
- package/dist/modules/plugins/display/frontend.mjs +14 -0
- package/dist/modules/plugins/display/frontend.mjs.map +7 -0
- package/dist/modules/plugins/display/i18n.mjs +58 -0
- package/dist/modules/plugins/display/i18n.mjs.map +7 -0
- package/dist/modules/plugins/display/identity.mjs +30 -0
- package/dist/modules/plugins/display/identity.mjs.map +7 -0
- package/dist/modules/plugins/display/page-broker.mjs +12 -0
- package/dist/modules/plugins/display/page-broker.mjs.map +7 -0
- package/dist/modules/plugins/display/schema.mjs +40 -0
- package/dist/modules/plugins/display/schema.mjs.map +7 -0
- package/dist/modules/plugins/display/ui.mjs +9 -0
- package/dist/modules/plugins/display/ui.mjs.map +7 -0
- package/dist/modules/plugins/inspector/frontend.mjs +17 -0
- package/dist/modules/plugins/inspector/frontend.mjs.map +7 -0
- package/dist/modules/plugins/inspector/i18n.mjs +15 -0
- package/dist/modules/plugins/inspector/i18n.mjs.map +7 -0
- package/dist/modules/plugins/inspector/identity.mjs +22 -0
- package/dist/modules/plugins/inspector/identity.mjs.map +7 -0
- package/dist/modules/plugins/inspector/schema.mjs +12 -0
- package/dist/modules/plugins/inspector/schema.mjs.map +7 -0
- package/dist/modules/plugins/inspector/ui.mjs +16 -0
- package/dist/modules/plugins/inspector/ui.mjs.map +7 -0
- package/dist/modules/plugins/material/frontend.mjs +25 -0
- package/dist/modules/plugins/material/frontend.mjs.map +7 -0
- package/dist/modules/plugins/material/i18n.mjs +15 -0
- package/dist/modules/plugins/material/i18n.mjs.map +7 -0
- package/dist/modules/plugins/material/identity.mjs +60 -0
- package/dist/modules/plugins/material/identity.mjs.map +7 -0
- package/dist/modules/plugins/material/schema.mjs +47 -0
- package/dist/modules/plugins/material/schema.mjs.map +7 -0
- package/dist/modules/plugins/material/ui.mjs +28 -0
- package/dist/modules/plugins/material/ui.mjs.map +7 -0
- package/dist/modules/plugins/mesh/frontend.mjs +23 -0
- package/dist/modules/plugins/mesh/frontend.mjs.map +7 -0
- package/dist/modules/plugins/mesh/i18n.mjs +15 -0
- package/dist/modules/plugins/mesh/i18n.mjs.map +7 -0
- package/dist/modules/plugins/mesh/identity.mjs +54 -0
- package/dist/modules/plugins/mesh/identity.mjs.map +7 -0
- package/dist/modules/plugins/mesh/schema.mjs +10 -0
- package/dist/modules/plugins/mesh/schema.mjs.map +7 -0
- package/dist/modules/plugins/mesh/ui.mjs +26 -0
- package/dist/modules/plugins/mesh/ui.mjs.map +7 -0
- package/dist/modules/plugins/plugins/api.mjs +11 -0
- package/dist/modules/plugins/plugins/api.mjs.map +7 -0
- package/dist/modules/plugins/plugins/backend.mjs +21 -0
- package/dist/modules/plugins/plugins/backend.mjs.map +7 -0
- package/dist/modules/plugins/plugins/cli.mjs +12 -0
- package/dist/modules/plugins/plugins/cli.mjs.map +7 -0
- package/dist/modules/plugins/plugins/frontend.mjs +17 -0
- package/dist/modules/plugins/plugins/frontend.mjs.map +7 -0
- package/dist/modules/plugins/plugins/i18n.mjs +15 -0
- package/dist/modules/plugins/plugins/i18n.mjs.map +7 -0
- package/dist/modules/plugins/plugins/identity.mjs +26 -0
- package/dist/modules/plugins/plugins/identity.mjs.map +7 -0
- package/dist/modules/plugins/plugins/runtime.mjs +50 -0
- package/dist/modules/plugins/plugins/runtime.mjs.map +7 -0
- package/dist/modules/plugins/plugins/schema.mjs +12 -0
- package/dist/modules/plugins/plugins/schema.mjs.map +7 -0
- package/dist/modules/plugins/plugins/ui/panel.mjs +14 -0
- package/dist/modules/plugins/plugins/ui/panel.mjs.map +7 -0
- package/dist/modules/plugins/plugins/ui.mjs +15 -0
- package/dist/modules/plugins/plugins/ui.mjs.map +7 -0
- package/dist/modules/plugins/scene/frontend.mjs +18 -0
- package/dist/modules/plugins/scene/frontend.mjs.map +7 -0
- package/dist/modules/plugins/scene/identity.mjs +14 -0
- package/dist/modules/plugins/scene/identity.mjs.map +7 -0
- package/dist/modules/plugins/scene-tree/frontend.mjs +17 -0
- package/dist/modules/plugins/scene-tree/frontend.mjs.map +7 -0
- package/dist/modules/plugins/scene-tree/i18n.mjs +15 -0
- package/dist/modules/plugins/scene-tree/i18n.mjs.map +7 -0
- package/dist/modules/plugins/scene-tree/identity.mjs +22 -0
- package/dist/modules/plugins/scene-tree/identity.mjs.map +7 -0
- package/dist/modules/plugins/scene-tree/schema.mjs +12 -0
- package/dist/modules/plugins/scene-tree/schema.mjs.map +7 -0
- package/dist/modules/plugins/scene-tree/ui.mjs +16 -0
- package/dist/modules/plugins/scene-tree/ui.mjs.map +7 -0
- package/dist/modules/plugins/texture/frontend.mjs +23 -0
- package/dist/modules/plugins/texture/frontend.mjs.map +7 -0
- package/dist/modules/plugins/texture/i18n.mjs +15 -0
- package/dist/modules/plugins/texture/i18n.mjs.map +7 -0
- package/dist/modules/plugins/texture/identity.mjs +54 -0
- package/dist/modules/plugins/texture/identity.mjs.map +7 -0
- package/dist/modules/plugins/texture/schema.mjs +10 -0
- package/dist/modules/plugins/texture/schema.mjs.map +7 -0
- package/dist/modules/plugins/texture/ui.mjs +26 -0
- package/dist/modules/plugins/texture/ui.mjs.map +7 -0
- package/dist/modules/plugins/viewport/frontend.mjs +27 -0
- package/dist/modules/plugins/viewport/frontend.mjs.map +7 -0
- package/dist/modules/plugins/viewport/identity.mjs +28 -0
- package/dist/modules/plugins/viewport/identity.mjs.map +7 -0
- package/dist/modules/plugins/viewport/presentation-identity.mjs +10 -0
- package/dist/modules/plugins/viewport/presentation-identity.mjs.map +7 -0
- package/dist/modules/plugins/viewport/presentation.mjs +18 -0
- package/dist/modules/plugins/viewport/presentation.mjs.map +7 -0
- package/dist/modules/plugins/viewport/schema.mjs +18 -0
- package/dist/modules/plugins/viewport/schema.mjs.map +7 -0
- package/dist/modules/plugins/viewport/workspace-shell.mjs +29 -0
- package/dist/modules/plugins/viewport/workspace-shell.mjs.map +7 -0
- package/dist/modules/shell/contract.mjs +10 -0
- package/dist/modules/shell/contract.mjs.map +7 -0
- package/dist/modules/shell/frontend.mjs +14 -0
- package/dist/modules/shell/frontend.mjs.map +7 -0
- package/dist/modules/shell/layout-zones.mjs +20 -0
- package/dist/modules/shell/layout-zones.mjs.map +7 -0
- package/dist/modules/start-cli.mjs +57 -0
- package/dist/modules/start-cli.mjs.map +7 -0
- package/dist/modules/start.mjs +18 -0
- package/dist/modules/start.mjs.map +7 -0
- package/dist/modules/viewer/catalog/backend.mjs +47 -0
- package/dist/modules/viewer/catalog/backend.mjs.map +7 -0
- package/dist/modules/viewer/catalog/frontend.mjs +55 -0
- package/dist/modules/viewer/catalog/frontend.mjs.map +7 -0
- package/dist/modules/viewer/catalog/shared.mjs +43 -0
- package/dist/modules/viewer/catalog/shared.mjs.map +7 -0
- package/dist/modules/viewer/catalog.mjs +85 -0
- package/dist/modules/viewer/catalog.mjs.map +7 -0
- package/dist/modules/viewer/cli.mjs +23 -0
- package/dist/modules/viewer/cli.mjs.map +7 -0
- package/dist/modules/viewer-host/frontend.mjs +65 -0
- package/dist/modules/viewer-host/frontend.mjs.map +7 -0
- package/dist/modules/viewer-host/page-registry.mjs +27 -0
- package/dist/modules/viewer-host/page-registry.mjs.map +7 -0
- package/dist/modules/viewer-host/slot-registry.mjs +8 -0
- package/dist/modules/viewer-host/slot-registry.mjs.map +7 -0
- package/dist/modules/viewer-host.mjs +43 -0
- package/dist/modules/viewer-host.mjs.map +7 -0
- package/dist/modules/viewer.mjs +85 -0
- package/dist/modules/viewer.mjs.map +7 -0
- package/dist/modules/workspace/adopt-surface.mjs +16 -0
- package/dist/modules/workspace/adopt-surface.mjs.map +7 -0
- package/dist/modules/workspace/api.mjs +8 -0
- package/dist/modules/workspace/api.mjs.map +7 -0
- package/dist/modules/workspace/backend.mjs +23 -0
- package/dist/modules/workspace/backend.mjs.map +7 -0
- package/dist/modules/workspace/broker.mjs +16 -0
- package/dist/modules/workspace/broker.mjs.map +7 -0
- package/dist/modules/workspace/cli.mjs +9 -0
- package/dist/modules/workspace/cli.mjs.map +7 -0
- package/dist/modules/workspace/client.mjs +15 -0
- package/dist/modules/workspace/client.mjs.map +7 -0
- package/dist/modules/workspace/command-error.mjs +16 -0
- package/dist/modules/workspace/command-error.mjs.map +7 -0
- package/dist/modules/workspace/contract.mjs +71 -0
- package/dist/modules/workspace/contract.mjs.map +7 -0
- package/dist/modules/workspace/demo-client.mjs +127 -0
- package/dist/modules/workspace/demo-client.mjs.map +7 -0
- package/dist/modules/workspace/engine-adapter.mjs +16 -0
- package/dist/modules/workspace/engine-adapter.mjs.map +7 -0
- package/dist/modules/workspace/engine-presentation.mjs +10 -0
- package/dist/modules/workspace/engine-presentation.mjs.map +7 -0
- package/dist/modules/workspace/extension-bridge.mjs +18 -0
- package/dist/modules/workspace/extension-bridge.mjs.map +7 -0
- package/dist/modules/workspace/frontend-plugin.mjs +18 -0
- package/dist/modules/workspace/frontend-plugin.mjs.map +7 -0
- package/dist/modules/workspace/frontend.mjs +29 -0
- package/dist/modules/workspace/frontend.mjs.map +7 -0
- package/dist/modules/workspace/id.mjs +8 -0
- package/dist/modules/workspace/id.mjs.map +7 -0
- package/dist/modules/workspace/inspection-presentation.mjs +12 -0
- package/dist/modules/workspace/inspection-presentation.mjs.map +7 -0
- package/dist/modules/workspace/locale-bridge.mjs +14 -0
- package/dist/modules/workspace/locale-bridge.mjs.map +7 -0
- package/dist/modules/workspace/page-title.mjs +13 -0
- package/dist/modules/workspace/page-title.mjs.map +7 -0
- package/dist/modules/workspace/presentation.mjs +18 -0
- package/dist/modules/workspace/presentation.mjs.map +7 -0
- package/dist/modules/workspace/preview-surface.mjs +17 -0
- package/dist/modules/workspace/preview-surface.mjs.map +7 -0
- package/dist/modules/workspace/project-session.mjs +18 -0
- package/dist/modules/workspace/project-session.mjs.map +7 -0
- package/dist/modules/workspace/render-resize-sync.mjs +12 -0
- package/dist/modules/workspace/render-resize-sync.mjs.map +7 -0
- package/dist/modules/workspace/resident.mjs +16 -0
- package/dist/modules/workspace/resident.mjs.map +7 -0
- package/dist/modules/workspace/resource-open.mjs +34 -0
- package/dist/modules/workspace/resource-open.mjs.map +7 -0
- package/dist/modules/workspace/resource-page.mjs +27 -0
- package/dist/modules/workspace/resource-page.mjs.map +7 -0
- package/dist/modules/workspace/tool-runtime.mjs +14 -0
- package/dist/modules/workspace/tool-runtime.mjs.map +7 -0
- package/dist/modules/workspace/view-trace.mjs +60 -0
- package/dist/modules/workspace/view-trace.mjs.map +7 -0
- package/dist/modules/workspace/workspace-client-connection.mjs +22 -0
- package/dist/modules/workspace/workspace-client-connection.mjs.map +7 -0
- package/dist/modules/workspace/workspace-recovery.mjs +35 -0
- package/dist/modules/workspace/workspace-recovery.mjs.map +7 -0
- package/dist/modules/workspace/workspace-state.mjs +12 -0
- package/dist/modules/workspace/workspace-state.mjs.map +7 -0
- package/dist/modules/workspace-frontend.mjs +17 -0
- package/dist/modules/workspace-frontend.mjs.map +7 -0
- package/dist/viewer/assets/chunk-CilyBKbf.js +1 -0
- package/dist/viewer/assets/core-DSQma37-.js +13 -0
- package/dist/viewer/assets/core-DSQma37-.js.map +1 -0
- package/dist/viewer/assets/css-Bq1BXecw.js +2 -0
- package/dist/viewer/assets/css-Bq1BXecw.js.map +1 -0
- package/dist/viewer/assets/css-CWQWazmX.js +1 -0
- package/dist/viewer/assets/embedded-D4ZDx--W.js +2 -0
- package/dist/viewer/assets/embedded-D4ZDx--W.js.map +1 -0
- package/dist/viewer/assets/engine-javascript-BvokIV9O.js +142 -0
- package/dist/viewer/assets/engine-javascript-BvokIV9O.js.map +1 -0
- package/dist/viewer/assets/github-dark-default-DaDlj-WZ.js +2 -0
- package/dist/viewer/assets/github-dark-default-DaDlj-WZ.js.map +1 -0
- package/dist/viewer/assets/github-light-default-BqhWxAZd.js +2 -0
- package/dist/viewer/assets/github-light-default-BqhWxAZd.js.map +1 -0
- package/dist/viewer/assets/glsl-BJgVnv11.js +2 -0
- package/dist/viewer/assets/glsl-BJgVnv11.js.map +1 -0
- package/dist/viewer/assets/html-AaaHGGyt.js +2 -0
- package/dist/viewer/assets/html-AaaHGGyt.js.map +1 -0
- package/dist/viewer/assets/javascript-BX9W64FE.js +1 -0
- package/dist/viewer/assets/javascript-DQODvD07.js +2 -0
- package/dist/viewer/assets/javascript-DQODvD07.js.map +1 -0
- package/dist/viewer/assets/json-CpcIDpT7.js +2 -0
- package/dist/viewer/assets/json-CpcIDpT7.js.map +1 -0
- package/dist/viewer/assets/json5-Czq4A7dk.js +2 -0
- package/dist/viewer/assets/json5-Czq4A7dk.js.map +1 -0
- package/dist/viewer/assets/jsonc-BXDfCMmu.js +2 -0
- package/dist/viewer/assets/jsonc-BXDfCMmu.js.map +1 -0
- package/dist/viewer/assets/jsx-DAWscEnf.js +2 -0
- package/dist/viewer/assets/jsx-DAWscEnf.js.map +1 -0
- package/dist/viewer/assets/main-C-2CHTN_.js +15 -0
- package/dist/viewer/assets/main-C-2CHTN_.js.map +1 -0
- package/dist/viewer/assets/markdown-Cx1FMNw-.js +2 -0
- package/dist/viewer/assets/markdown-Cx1FMNw-.js.map +1 -0
- package/dist/viewer/assets/panels-entry-Ddhfjgf0.js +46 -0
- package/dist/viewer/assets/panels-entry-Ddhfjgf0.js.map +1 -0
- package/dist/viewer/assets/python-CYPKjWV9.js +2 -0
- package/dist/viewer/assets/python-CYPKjWV9.js.map +1 -0
- package/dist/viewer/assets/rust-0e5cNx_V.js +2 -0
- package/dist/viewer/assets/rust-0e5cNx_V.js.map +1 -0
- package/dist/viewer/assets/scss-B-aKzLbT.js +2 -0
- package/dist/viewer/assets/scss-B-aKzLbT.js.map +1 -0
- package/dist/viewer/assets/shellscript-CpXD-pSm.js +2 -0
- package/dist/viewer/assets/shellscript-CpXD-pSm.js.map +1 -0
- package/dist/viewer/assets/style-ClttNKZk.css +2 -0
- package/dist/viewer/assets/styles-BXozhwiU.js +11 -0
- package/dist/viewer/assets/styles-BXozhwiU.js.map +1 -0
- package/dist/viewer/assets/toml-GmchYTXa.js +2 -0
- package/dist/viewer/assets/toml-GmchYTXa.js.map +1 -0
- package/dist/viewer/assets/tsx-Crj1Bi53.js +2 -0
- package/dist/viewer/assets/tsx-Crj1Bi53.js.map +1 -0
- package/dist/viewer/assets/typescript-xi0cSHCO.js +2 -0
- package/dist/viewer/assets/typescript-xi0cSHCO.js.map +1 -0
- package/dist/viewer/assets/wgsl-BoEPRo9U.js +2 -0
- package/dist/viewer/assets/wgsl-BoEPRo9U.js.map +1 -0
- package/dist/viewer/assets/xml-B8JqQrMD.js +2 -0
- package/dist/viewer/assets/xml-B8JqQrMD.js.map +1 -0
- package/dist/viewer/assets/yaml-DsIB85X9.js +2 -0
- package/dist/viewer/assets/yaml-DsIB85X9.js.map +1 -0
- package/dist/viewer/index.html +15 -0
- package/dist/viewer/panels.js +1 -0
- package/host.pack.json +13 -0
- package/package.json +174 -0
- package/skills/forgeax-view-cli/SKILL.md +74 -0
- package/skills/forgeax-view-start/SKILL.md +202 -0
- package/skills/forgeax-view-start/scripts/start-view.mjs +202 -0
package/README.md
ADDED
|
@@ -0,0 +1,742 @@
|
|
|
1
|
+
# ForgeaX View
|
|
2
|
+
|
|
3
|
+
View is an optional project workspace and read-only observer of Engine AI runs.
|
|
4
|
+
The CLI and frontend are clients of Engine APIs. The Engine service owns runs,
|
|
5
|
+
project facts, assets, scenes, observation, capture, and termination; View owns
|
|
6
|
+
window resources, tab bindings, and presentation.
|
|
7
|
+
|
|
8
|
+
## Start here
|
|
9
|
+
|
|
10
|
+
Agent guidance: [forgeax-view-start](skills/forgeax-view-start/SKILL.md).
|
|
11
|
+
|
|
12
|
+
For a known game project using a local Engine checkout, one script prepares
|
|
13
|
+
the builds and services and returns the project URL as JSON:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
node skills/forgeax-view-start/scripts/start-view.mjs \
|
|
17
|
+
--project /absolute/path/to/game \
|
|
18
|
+
--engine /absolute/path/to/forgeax-engine
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Open its `url` in a browser to load the Editor project. The script leaves the
|
|
22
|
+
browser, Play, and independent AI runs to their separate operations. See the
|
|
23
|
+
[skill](skills/forgeax-view-start/SKILL.md#open-a-project-with-one-script) for
|
|
24
|
+
reuse, restart, and failure behavior.
|
|
25
|
+
|
|
26
|
+
> [!IMPORTANT]
|
|
27
|
+
> This workflow requires an Engine build with `backend start --host-pack`,
|
|
28
|
+
> a built View package, and an Engine workspace root. A running backend must
|
|
29
|
+
> be restarted to change its selected host Pack.
|
|
30
|
+
|
|
31
|
+
Select View's installed host Pack when starting Engine. The game project does
|
|
32
|
+
not need a View asset or a `forge.json.roots.host` change:
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
forgeax backend start --root /path/to/workspace \
|
|
36
|
+
--host-pack /path/to/forgeax-view/host.pack.json --json
|
|
37
|
+
forgeax view start --root /path/to/workspace --project /path/to/game --json
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The packaged `host.pack.json` identifies View's native plugin and its CLI
|
|
41
|
+
declarations. The Engine backend loads that Pack from the View package; the
|
|
42
|
+
game remains an ordinary project opened through the Engine workspace API.
|
|
43
|
+
Use a separate workspace root when the game already declares its own host root.
|
|
44
|
+
The selected host Pack is visible in `backend status`.
|
|
45
|
+
|
|
46
|
+
Start the backend, then enable View:
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
forgeax backend status --root /path/to/workspace --json
|
|
50
|
+
forgeax view start --root /path/to/workspace --json
|
|
51
|
+
# Override the project when it differs from the backend workspace.
|
|
52
|
+
forgeax view start --root /path/to/workspace --project /path/to/game --json
|
|
53
|
+
# Optional explicit allocation on an already-running View.
|
|
54
|
+
forgeax view project open --root /path/to/workspace --project /path/to/game --json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Open the `url` returned by `view start` in your browser. Explicit `--project`
|
|
58
|
+
wins; otherwise a backend root containing `forge.json` is included automatically.
|
|
59
|
+
The browser connects and opens that project without asking you to type its path.
|
|
60
|
+
`view project open`
|
|
61
|
+
allocates the project and returns its headed document as `projectTarget.url`;
|
|
62
|
+
open that URL, or leave an already-open empty shell to navigate there.
|
|
63
|
+
Only an unknown project requires the **Open project** dialog. Open a project before using
|
|
64
|
+
any View page, including Runtime capture. `backend start` and `view start` do
|
|
65
|
+
not open an Editor project or run a game. These
|
|
66
|
+
commands do not launch Playwright or install Chromium. Repeat `view start` to
|
|
67
|
+
retrieve the URL of the existing interface.
|
|
68
|
+
|
|
69
|
+
| Step | What success means |
|
|
70
|
+
|:--|:--|
|
|
71
|
+
| `backend start` | Engine API and declared host plugins are available; no browser or renderer is required |
|
|
72
|
+
| `view start` | View is serving its interface on the existing Engine Host |
|
|
73
|
+
| Open the returned URL | The browser has loaded the Shell and connected its frontend plugins |
|
|
74
|
+
| Open an Editor project | Engine has opened the chosen project; its rendering target has its own readiness and errors |
|
|
75
|
+
| Play or start an AI run | An explicit Engine execution target has started |
|
|
76
|
+
|
|
77
|
+
When the request includes a project path, opening the Shell is only an
|
|
78
|
+
intermediate state. Return the URL with that project intent, or run
|
|
79
|
+
`view project open` and open its headed URL; wait for
|
|
80
|
+
the project name, its directories, and an Engine target to appear. A final
|
|
81
|
+
screenshot that still shows `No project`, an empty path, or a disabled
|
|
82
|
+
**Open project** button does not prove that the project opened. A JSON result
|
|
83
|
+
that only contains `projectTarget.url` does not prove the headed page has
|
|
84
|
+
loaded. Scene preview
|
|
85
|
+
and Play are later, separate gates: open a scene asset to verify the hierarchy,
|
|
86
|
+
and select **Play** to verify the game target and rendered pixels.
|
|
87
|
+
|
|
88
|
+
### Use a local Engine checkout
|
|
89
|
+
|
|
90
|
+
Build the local repository explicitly, then bind the game to those outputs:
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
pnpm --dir /path/to/forgeax-engine build:engine
|
|
94
|
+
node /path/to/forgeax-engine/scripts/forgeax/prepare-shader-release-inputs.mjs --build --profile base-ssao
|
|
95
|
+
test -s /path/to/forgeax-engine/packages/vite-plugin-shader/dist/engine-inputs/base-ssao/manifest.json
|
|
96
|
+
test -s /path/to/forgeax-engine/packages/vite-plugin-shader/dist/engine-inputs/base-ssao/imports.json
|
|
97
|
+
cd /path/to/game
|
|
98
|
+
pnpm link /path/to/forgeax-engine/packages/engine
|
|
99
|
+
pnpm exec forgeax project engine use-local /path/to/forgeax-engine --json
|
|
100
|
+
pnpm exec forgeax project engine check --json
|
|
101
|
+
pnpm exec forgeax backend start --host-pack /path/to/forgeax-view/host.pack.json --json
|
|
102
|
+
pnpm exec forgeax view start --json
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The explicit build and shader preparation happen before startup; the local
|
|
106
|
+
browser proof uses those prepared outputs. Prepare the matching `point-ssao`
|
|
107
|
+
profile instead when point shadows are enabled. Recheck the profile files after
|
|
108
|
+
rebuilding the shader package: without them, every new Backend falls back to
|
|
109
|
+
source compilation, which can take minutes. The package link selects the local
|
|
110
|
+
CLI and Node-side Pack dependencies; the
|
|
111
|
+
existing project binding selects local workspace exports for Engine's browser
|
|
112
|
+
host. The binding is stored in `.forgeax/engine-binding.json`. It must report
|
|
113
|
+
`mode: "local"`, the selected checkout, and a healthy build. No SDK archive or
|
|
114
|
+
candidate packing is required for this path. Rebuild affected Engine packages
|
|
115
|
+
after source changes; binding does not implicitly build Engine or rewrite its
|
|
116
|
+
exports to TypeScript source. Resolve `node_modules/@forgeax/engine` and confirm
|
|
117
|
+
that it belongs to the same checkout recorded by the binding. A healthy browser
|
|
118
|
+
binding cannot prevent Node-side Pack imports from using a different checkout;
|
|
119
|
+
that mismatch can add stale component defaults and make scene cooking fail.
|
|
120
|
+
Open the returned View URL, then choose the game
|
|
121
|
+
project explicitly. A running backend keeps its original Engine; apply a
|
|
122
|
+
binding change with explicit `backend stop` / `backend start`. Independent runs
|
|
123
|
+
retain their own input version and lifecycle.
|
|
124
|
+
|
|
125
|
+
A Pack initialization timeout occurs while loading its module and dependencies,
|
|
126
|
+
before asset generation. The loader transpiles reachable TypeScript helpers;
|
|
127
|
+
built Engine package exports remain JavaScript imports. The timeout alone does
|
|
128
|
+
not establish that the entire Engine was compiled. Preserve the original Pack
|
|
129
|
+
filename and diagnostic when investigating a different local binding.
|
|
130
|
+
Engine may load a PluginAsset through a compiled chunk. View resolves its static
|
|
131
|
+
UI from the selected View package's `@forgeax/view/plugin` entry instead of
|
|
132
|
+
using that chunk's URL. Game plugins execute in Engine's Worker; browser UI
|
|
133
|
+
belongs to frontend plugins.
|
|
134
|
+
|
|
135
|
+
### Observe an AI run
|
|
136
|
+
|
|
137
|
+
```sh
|
|
138
|
+
forgeax engine run start --root /path/to/game --json
|
|
139
|
+
forgeax engine run status --root /path/to/game --json
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
In View, select **Runtime capture** (AI Display), enter the game project path and the exact
|
|
143
|
+
`runId` from Engine, then select **Observe run**. First complete the required
|
|
144
|
+
project dialog; the observed run can belong to a different project.
|
|
145
|
+
View receives cached status, logs and timestamped screenshots from that run.
|
|
146
|
+
A different run at the same path requires an explicit new binding; opening or
|
|
147
|
+
closing an Editor project does not change the observed run. **Disconnect**
|
|
148
|
+
removes the observation binding and does not stop the game.
|
|
149
|
+
|
|
150
|
+
### Open an Editor project
|
|
151
|
+
|
|
152
|
+
With View already started, allocate the project from the command line:
|
|
153
|
+
|
|
154
|
+
```sh
|
|
155
|
+
forgeax view project open --root /path/to/workspace --project /path/to/game --json
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Then open the returned `projectTarget.url`. An empty shell that is already
|
|
159
|
+
connected navigates there when the snapshot gains that target. The required
|
|
160
|
+
dialog remains available: enter the **Project path** and select **Open project**. The
|
|
161
|
+
browser opens the Engine-generated workspace document. Editor and asset
|
|
162
|
+
previews use inline Engine surfaces; **Play** explicitly creates the isolated
|
|
163
|
+
game iframe. Hierarchy and Inspector operate on the selected Engine target.
|
|
164
|
+
Opening a project does not start an independent AI run.
|
|
165
|
+
In Content Browser, select a folder or asset and choose **Open**, double-click
|
|
166
|
+
it, or press **Enter**. A single click selects it for inspection. **Preparing
|
|
167
|
+
Play** means Engine is freezing the game's inputs; **Stop** can cancel this
|
|
168
|
+
preparation before a game target appears, or stop the target after it appears.
|
|
169
|
+
If project scanning fails, View remains available. Inspect the Engine source
|
|
170
|
+
diagnostic, repair that project, then select **Open project** again.
|
|
171
|
+
|
|
172
|
+
### Check status and stop
|
|
173
|
+
|
|
174
|
+
```sh
|
|
175
|
+
forgeax view status --root /path/to/workspace --json
|
|
176
|
+
forgeax backend status --root /path/to/workspace --json
|
|
177
|
+
forgeax view stop --root /path/to/workspace --json
|
|
178
|
+
forgeax backend stop --root /path/to/workspace --json
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
`view stop` disconnects the interface and releases View plugins; it preserves
|
|
182
|
+
the Engine backend and does not close your browser window. Closing a page loses
|
|
183
|
+
its actual Editor rendering targets, but not the backend or independent AI run.
|
|
184
|
+
`backend stop` releases the Engine workspace and its Host. Stop an independent
|
|
185
|
+
run separately with `forgeax engine run stop --root /path/to/game --json`.
|
|
186
|
+
|
|
187
|
+
The API/CLI operations can be composed by a caller. No startup operation
|
|
188
|
+
implicitly runs the following steps on its behalf.
|
|
189
|
+
|
|
190
|
+
## Publishing
|
|
191
|
+
|
|
192
|
+
`@forgeax/view` is the only npm package. Record user-facing work with
|
|
193
|
+
`pnpm changeset`. Pushing that changeset to `main` lets Release open a Version
|
|
194
|
+
Packages PR; merging it updates `CHANGELOG.md` and publishes `@latest`.
|
|
195
|
+
|
|
196
|
+
Test versions do not move `latest`. Dispatch Release with `dry_run` left enabled
|
|
197
|
+
to pack a `beta` snapshot without publishing. Uncheck it only for a real
|
|
198
|
+
`channel=beta` or `channel=next` snapshot. Install a published snapshot with:
|
|
199
|
+
|
|
200
|
+
```sh
|
|
201
|
+
pnpm add @forgeax/view@beta
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
A longer beta line uses `pnpm changeset pre enter beta` on `main`, then the same
|
|
205
|
+
Version Packages flow. Prerelease publishes stay on the `beta` dist-tag until
|
|
206
|
+
`pnpm changeset pre exit`.
|
|
207
|
+
|
|
208
|
+
## Development and verification
|
|
209
|
+
|
|
210
|
+
CI tests the installed package distribution by preparing its complete candidate
|
|
211
|
+
closure from a built Engine checkout:
|
|
212
|
+
|
|
213
|
+
```sh
|
|
214
|
+
export pnpm_config_verify_deps_before_run=false
|
|
215
|
+
node scripts/engine-candidate.mjs pack /path/to/built/forgeax-engine /tmp/view-engine-candidates
|
|
216
|
+
node scripts/engine-candidate.mjs install /path/to/built/forgeax-engine /tmp/view-engine-candidates
|
|
217
|
+
pnpm build
|
|
218
|
+
node scripts/verify-startup-boundaries.mjs
|
|
219
|
+
xvfb-run -a node scripts/verify-engine-plugin-boundary.mjs
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
CI runs once per PR revision and on pushes to `main`; a newer revision cancels
|
|
223
|
+
the obsolete run. It caches only the complete Engine candidate archives, keyed
|
|
224
|
+
by the exact Engine commit, preparation script, OS/architecture, Node major and
|
|
225
|
+
pnpm version. The cache path is workspace-relative so different runner home
|
|
226
|
+
directories share the same cache version. A cache hit must pass archive digest and dependency-closure checks
|
|
227
|
+
before source preparation is skipped. Missing or invalid candidates rebuild
|
|
228
|
+
from source. View builds, Storybook, package checks and every browser scenario
|
|
229
|
+
always run. Candidate indexes use relative archive names so another runner can
|
|
230
|
+
verify and install the same bytes with the `verify` and `install` commands.
|
|
231
|
+
One build job prepares and checks the candidates, then publishes them as a
|
|
232
|
+
short-lived workflow artifact. Two qualified runners execute the complete
|
|
233
|
+
workspace/10-Play-cycle probe and the startup/game-3d probes concurrently, with
|
|
234
|
+
separate browsers and GPU processes. The existing required `bootstrap` check
|
|
235
|
+
passes only when the build and both browser jobs succeed; failures, skips and
|
|
236
|
+
cancellation cannot turn it green. Cold builds still prepare Engine only once.
|
|
237
|
+
|
|
238
|
+
Candidate preparation includes Engine's packaged shader inputs before any live
|
|
239
|
+
startup deadline begins. A package build alone does not prepare those inputs;
|
|
240
|
+
source shader compilation may take several minutes. The probe keeps the original
|
|
241
|
+
ScriptablePack and Engine's default startup deadlines.
|
|
242
|
+
The environment setting matches CI and prevents pnpm from replacing the temporary
|
|
243
|
+
candidates with the committed SDK dependencies before running a script.
|
|
244
|
+
Linux CI uses Engine's capacity-checked `heavy` runner pool and headed Chrome
|
|
245
|
+
Beta with SwiftShader. Use at least four CPU cores for the complete combined
|
|
246
|
+
suite; two-core runs provide additional stress diagnostics. The paired Engine
|
|
247
|
+
fences IBL prefilter faces and retires closed-server caches. The gate retains
|
|
248
|
+
every target, Play cycle and browser-error assertion, checks that the original
|
|
249
|
+
asset renderers still submit frames after Play, and keeps the GPU watchdog enabled. Install it with `pnpm exec playwright install --with-deps chrome-beta` and
|
|
250
|
+
set `FORGEAX_BROWSER_EXECUTABLE=/opt/google/chrome-beta/chrome` for Engine/probes
|
|
251
|
+
to reproduce that browser locally. Browser setup is a verification prerequisite,
|
|
252
|
+
not a View startup step. CI records the browser version and process diagnostics; GPU
|
|
253
|
+
device loss remains a failure.
|
|
254
|
+
|
|
255
|
+
The combined probe checks shared Host identity, three independent Engine Worlds,
|
|
256
|
+
live asset discovery, hierarchy and Inspector, picking/camera input, ten Editor
|
|
257
|
+
Play cycles, Eject/Possess, plugin removal, poisoned-game recovery, and independent
|
|
258
|
+
AI execution before and after View browser loss. A separate real `game-3d` probe
|
|
259
|
+
checks live hierarchy and player input handoff:
|
|
260
|
+
|
|
261
|
+
```sh
|
|
262
|
+
xvfb-run -a node scripts/verify-game3d-workspace.mjs
|
|
263
|
+
|
|
264
|
+
# Direct local checkout binding, without packing an SDK candidate:
|
|
265
|
+
FORGEAX_ENGINE_CHECKOUT=/path/to/forgeax-engine FORGEAX_LOCAL_ENGINE=1 \
|
|
266
|
+
xvfb-run -a node scripts/verify-game3d-workspace.mjs
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Both preserve the original browser-error assertions. Captured pixels, actual
|
|
270
|
+
capture resize and target/World identities are checked independently. Asset tabs
|
|
271
|
+
host their dedicated Engine preview surfaces in panel-owned DOM containers;
|
|
272
|
+
they never relocate the Editor owner canvas or restore its old preview cards. Screenshots
|
|
273
|
+
include `/tmp/view-inline-previews.png`, `/tmp/view-editor-play.png`, and
|
|
274
|
+
`/tmp/view-game3d-play.png`. The combined Linux/Xvfb probe also requires Python
|
|
275
|
+
and libX11 for its native window check; it does not use CDP.
|
|
276
|
+
|
|
277
|
+
The Content Browser presents the Engine catalog; selection inspects read-only
|
|
278
|
+
asset metadata and double-click opens the exact Engine preview. Assets from
|
|
279
|
+
`.pack.ts` show their Catalog `sourceKey` when present; GUIDs remain their
|
|
280
|
+
operation identity. Hierarchy and Inspector use the optional live target tools
|
|
281
|
+
plugin, reporting capability errors when absent. Sample catalogs and entities
|
|
282
|
+
remain restricted to `dev:ui`.
|
|
283
|
+
Material editing and runtime property writes are not implemented.
|
|
284
|
+
|
|
285
|
+
## Lifecycle and operation ownership
|
|
286
|
+
|
|
287
|
+
The resident Node process contains a BackendHost. It loads the Engine domain
|
|
288
|
+
plugin first, then the optional View PluginAsset and its native backend children.
|
|
289
|
+
The browser FrontendHost activates View's projected frontend root and its
|
|
290
|
+
Shell/panel children. UI-only plugins have no
|
|
291
|
+
backend/API/CLI stubs. The viewport presents the Engine preview; the content
|
|
292
|
+
browser only mounts its resource UI. AI Display presents cached status, logs and
|
|
293
|
+
recent images from an independent Engine run; it contains no execution iframe.
|
|
294
|
+
|
|
295
|
+
| Action | Result |
|
|
296
|
+
|:--|:--|
|
|
297
|
+
| Disable a View panel or dispose its native Fiber | Engine domain tools remain callable; independent AI execution is unchanged |
|
|
298
|
+
| Close the View browser | Its Editor target is lost; the independent AI run continues |
|
|
299
|
+
| Finish a CLI call | The resident backend and Engine live owner remain running |
|
|
300
|
+
| Stop View explicitly | Dispose View plugins and connections; Engine backend, AI runs and caller-owned browsers survive |
|
|
301
|
+
|
|
302
|
+
`view.*` domain operations are thin aliases of Engine ToolApi handlers. UI
|
|
303
|
+
selection never resolves a business target. Pass `targetId` and
|
|
304
|
+
`targetGeneration` (from `preview.target.generation`) for preview/camera calls.
|
|
305
|
+
Engine alone owns camera versions, conflicts, idempotency and disconnect rollback.
|
|
306
|
+
View observation uses only `engine.run.observe`. Frontend callers cannot control
|
|
307
|
+
independent runs; the Engine plugin enforces that permission boundary. Use Engine CLI directly to control independent runs:
|
|
308
|
+
|
|
309
|
+
```sh
|
|
310
|
+
forgeax engine run start --root /path/to/game --json
|
|
311
|
+
forgeax engine run status --root /path/to/game --json
|
|
312
|
+
forgeax engine run capture --root /path/to/game --revision RUN_REVISION --require-ui --json
|
|
313
|
+
forgeax engine run stop --root /path/to/game --json
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Engine snapshots source, assets, configuration and resolved dependencies before
|
|
317
|
+
starting its private browser, headless by default. Editor edits do not update
|
|
318
|
+
that run. Stop/start selects a new input version; reload keeps the current
|
|
319
|
+
snapshot. View tabs, focus, dimensions and lifecycle cannot alter execution.
|
|
320
|
+
Observation displays capture time and stale images explicitly; output is bounded
|
|
321
|
+
and shared per run, with no screenshot loop per viewer.
|
|
322
|
+
After closing a browser, reopen the returned View URL. Its project intent opens
|
|
323
|
+
the same project directly. Refreshing an Editor briefly visits the resident
|
|
324
|
+
View entry, which uses the resident API to replace its exact lost target without
|
|
325
|
+
requiring **Reconnect**.
|
|
326
|
+
During replacement, View shows project restoration status and keeps panels that
|
|
327
|
+
need the old target unmounted. The new target opens automatically when Engine
|
|
328
|
+
reports it ready; a failed replacement remains visible with an explicit retry.
|
|
329
|
+
The new page starts as a freshly opened project: no historical resource tabs,
|
|
330
|
+
selection, camera, dock layout or Play. Saved project files and theme/language
|
|
331
|
+
preferences remain; save authored changes before refreshing. The departing page
|
|
332
|
+
does not initialize another renderer while the View entry opens its replacement.
|
|
333
|
+
`view start` never migrates or replays a target. Conflicts with another active
|
|
334
|
+
page and genuine service failures remain visible with explicit retry; recovery
|
|
335
|
+
never takes over another live target or changes an independent AI run.
|
|
336
|
+
|
|
337
|
+
### Scene navigation
|
|
338
|
+
|
|
339
|
+
| Input | Action |
|
|
340
|
+
|:--|:--|
|
|
341
|
+
| Left click | Select the object in the submitted display frame |
|
|
342
|
+
| Right drag; right + WASD/QE | Look; move along camera axes / world up and down |
|
|
343
|
+
| Right + wheel | Adjust flight speed |
|
|
344
|
+
| Wheel; middle drag | Dolly (orthographic zoom); pan |
|
|
345
|
+
| Alt + left / middle / right drag | Orbit / pan / dolly |
|
|
346
|
+
| F | Focus the selected object's bounds |
|
|
347
|
+
| Escape, focus loss, hidden page | Release input and keep the current camera pose |
|
|
348
|
+
|
|
349
|
+
Pointer lock is optional; pointer capture remains available when the browser
|
|
350
|
+
denies it. Text fields and panel controls do not start viewport navigation.
|
|
351
|
+
View owns these bindings, sensitivity, flight-speed preferences and pitch limits.
|
|
352
|
+
It sends semantic velocity, angle and displacement requests; Engine executes
|
|
353
|
+
them on the actual target and owns camera transactions and the orbit pivot.
|
|
354
|
+
Cancelling a transaction restores the complete camera, including lens and pivot.
|
|
355
|
+
|
|
356
|
+
## Explicit borrowed-carrier library contract
|
|
357
|
+
|
|
358
|
+
This optional library seam is separate from the default independent AI path.
|
|
359
|
+
|
|
360
|
+
| Request | Result |
|
|
361
|
+
|:--|:--|
|
|
362
|
+
| `headless=true` | Existing headless path; do not contact View |
|
|
363
|
+
| Headed, with an injected open, compatible, idle View | Use the same View page for display and capture |
|
|
364
|
+
| Headed, with View unavailable | Existing headed browser path, with the actual carrier and reason reported |
|
|
365
|
+
|
|
366
|
+
View uses an ordinary browser and page. It has no Electron dependency or
|
|
367
|
+
desktop launcher. Selection happens when a run starts. Engine must not start
|
|
368
|
+
another browser/window for the borrowed path or load a second copy of the game.
|
|
369
|
+
Releasing a run must not close the user's browser.
|
|
370
|
+
|
|
371
|
+
Engine's public `BrowserCarrierAdapter` supplies the execution seam: select a
|
|
372
|
+
target, attach its exact owner `Page` plus execution realm, then release the
|
|
373
|
+
run's lease. A View lease uses one child `Frame`; the owner Page remains stable
|
|
374
|
+
and is used only for the exact outer-surface presentation envelope.
|
|
375
|
+
`startView({ platform: createBrowserPagePlatform({ page }) })` is the in-process
|
|
376
|
+
owner path. `page` is the already-open browser Page; Engine receives it through
|
|
377
|
+
`view.carrier`, and releasing a lease only removes View's occupancy. The
|
|
378
|
+
connection does not select CDP, a debugger port, or another transport. When an
|
|
379
|
+
embedding application already owns the compatible Engine hosts, pass them as
|
|
380
|
+
`backendHost` and `frontendHost`; View then borrows those lifecycles and does
|
|
381
|
+
not dispose them.
|
|
382
|
+
|
|
383
|
+
## Current integration
|
|
384
|
+
|
|
385
|
+
The modules in `src/` provide admission, identity, cancellation, a native
|
|
386
|
+
Engine Host plugin, a browser-safe frontend mount, and the browser-neutral
|
|
387
|
+
owner-Page/execution-Frame carrier seam.
|
|
388
|
+
`startView()` starts an observer Host without a display carrier. Supplying
|
|
389
|
+
`platform` explicitly selects the borrowed-carrier library seam. No default
|
|
390
|
+
platform opens a window. In that explicit seam, the Engine carrier owns
|
|
391
|
+
execution and View owns the lease and presentation boundary. The
|
|
392
|
+
authenticated endpoint carries lease metadata only; it never serializes a Page,
|
|
393
|
+
Frame, debugger endpoint, or cleanup callback. A process-local Engine
|
|
394
|
+
attachment must provide the explicit owner Page, execution realm, and close
|
|
395
|
+
handle contract.
|
|
396
|
+
|
|
397
|
+
The backend and frontend are real Engine/Cordis Plugins. The project's host
|
|
398
|
+
PluginAsset mounts the View native plugin; View mounts its backend children
|
|
399
|
+
in the same BackendHost. `HostAssembly` v2 carries one View frontend root,
|
|
400
|
+
and the browser FrontendHost activates that root and its native children.
|
|
401
|
+
Neither path launches a browser or owns
|
|
402
|
+
Engine project state. Only explicit borrowed-carrier consumers pass `view.carrier` to Engine's
|
|
403
|
+
`BrowserCarrierAdapter` seam.
|
|
404
|
+
|
|
405
|
+
For explicit borrowed-carrier consumers, the two target surfaces remain distinct: a workspace target URL
|
|
406
|
+
may be loaded by the one workspace iframe, while a CLI display target is
|
|
407
|
+
presented by the exact iframe allocated by `BrowserPagePlatform`. The browser
|
|
408
|
+
frontend uses `createBrowserPagePresentation()` to find that iframe by its
|
|
409
|
+
lease/generation/surface identity and never reparents or removes it. If the
|
|
410
|
+
exact surface is absent or mismatched, presentation fails closed rather than
|
|
411
|
+
creating a second App/World/renderer.
|
|
412
|
+
|
|
413
|
+
### Source organization
|
|
414
|
+
|
|
415
|
+
| Location | Responsibility |
|
|
416
|
+
|:--|:--|
|
|
417
|
+
| `src/` | Public package entry points, CLI clients, platform adapters and host construction |
|
|
418
|
+
| `src/plugins/` | Native backend/product composition; no page UI |
|
|
419
|
+
| `packages/viewer/src/host/` | Frontend connection, root resolution, page/slot infrastructure and panel bridge |
|
|
420
|
+
| `packages/viewer/src/plugins/` and `packages/viewer/src/shell/` | Shell plugin declaration and its React presentation |
|
|
421
|
+
| `packages/viewer/src/*catalog*.mjs` | Static package composition; shared catalog metadata does not import frontend implementations |
|
|
422
|
+
| `packages/view-plugin-*/src/` | Feature-owned identities and native plugins; only implemented backend/API/CLI endpoints |
|
|
423
|
+
| `packages/view-plugin-*/src/ui/` | That feature's panels, DOM presentation and styles |
|
|
424
|
+
| `packages/view-workspace-core/` | React-free workspace contracts, clients, bindings and shared presentation helpers |
|
|
425
|
+
| `packages/view-components/` | Workspace-independent React primitives, tokens and Storybook |
|
|
426
|
+
|
|
427
|
+
Scene registration lives in `view-plugin-scene`; its viewport and connection-owned
|
|
428
|
+
Play presentation live in `view-plugin-viewport`. Runtime capture's frontend
|
|
429
|
+
lifecycle, status snapshot and DOM view live in `view-plugin-display` as
|
|
430
|
+
`frontend.mjs`, `status.mjs` and `ui/`. Moving source files does not change their
|
|
431
|
+
native plugin names or disposal owners. Existing public entry points,
|
|
432
|
+
including `@forgeax/view/pages/scene` and `@forgeax/view/workspace/presentation`,
|
|
433
|
+
continue to resolve to the same plugins.
|
|
434
|
+
|
|
435
|
+
Feature packages depend on exported workspace-core/components contracts, not
|
|
436
|
+
Viewer internals or sibling feature implementations. The Viewer composes them.
|
|
437
|
+
Keep metadata in `identity.mjs` so backend catalog imports cannot pull in a
|
|
438
|
+
frontend implementation.
|
|
439
|
+
|
|
440
|
+
### Architecture gate
|
|
441
|
+
|
|
442
|
+
Run `pnpm check:architecture` before submitting a change. CI runs this independent
|
|
443
|
+
lane before the Engine build; the final `bootstrap` check requires architecture,
|
|
444
|
+
build and both browser probes to succeed. A failed, skipped or cancelled lane
|
|
445
|
+
cannot produce a successful aggregate. No Engine checkout or browser is needed
|
|
446
|
+
for the static gate itself.
|
|
447
|
+
|
|
448
|
+
| Constraint | Automated evidence |
|
|
449
|
+
|:--|:--|
|
|
450
|
+
| Features use foundations, never sibling features or Viewer; foundations do not depend upwards | Source imports and all dependency sections in each package manifest |
|
|
451
|
+
| Cross-package access uses declared public exports | AST import/re-export/type-import/CommonJS checks; relative-path, alias, symlink and private-subpath rejection |
|
|
452
|
+
| Core uses Engine Host/tool contracts, not domain implementations; components are workspace/Engine-independent | Dependency checks, no React runtime or JSX/TSX/CSS source in core |
|
|
453
|
+
| Host infrastructure does not absorb Shell, panels or Engine domain implementations | Transitive source graph, including self-package and conditional exports |
|
|
454
|
+
| Shared Catalog metadata does not pull in implementations | Transitive identity/contract graph and an actual metadata bundle inspection |
|
|
455
|
+
| Root clients/platform do not implement features | Source graph with explicit public export, catalog and Host composition seams |
|
|
456
|
+
| Plugins remain optional and own cleanup | Existing operation-ownership, page-plugin and real-browser removal/restoration tests in the build/browser lanes |
|
|
457
|
+
|
|
458
|
+
`scripts/check-architecture.mjs` reports the file, rule and offending dependency
|
|
459
|
+
chain. It checks root `src/` and every package's `src/`, including unreferenced
|
|
460
|
+
files. Counterexample tests deliberately introduce violations; CI also exercises
|
|
461
|
+
all 125 success/failure/skipped/cancelled/missing aggregate-result combinations.
|
|
462
|
+
The existing panel bundle loader has one scoped computed-import exception;
|
|
463
|
+
another computed import requires a reviewed resolver policy, not an ignore comment.
|
|
464
|
+
|
|
465
|
+
> [!IMPORTANT]
|
|
466
|
+
> Static checks prove the declared source boundaries, not arbitrary business
|
|
467
|
+
> semantics or complete lifecycle correctness. They do not analyze generated
|
|
468
|
+
> code, arbitrary JavaScript loaders/eval, third-party internals or every possible
|
|
469
|
+
> bundler alias. Changes to resolvers, exports, guardrails or their exceptions
|
|
470
|
+
> require the same architectural review as a boundary change. There is no blanket
|
|
471
|
+
> violation baseline or per-file suppression mechanism.
|
|
472
|
+
|
|
473
|
+
For Host/core/bootstrap changes, the PR must identify the missing public seam,
|
|
474
|
+
why the existing plugin cannot own the change, the minimal domain-neutral
|
|
475
|
+
contract, its consuming plugin, and plugin-absent/removal evidence. Reviewers
|
|
476
|
+
must also inspect contribution ownership and disposal, new business branches,
|
|
477
|
+
and duplicated state. Functional success alone is not acceptance. Update the
|
|
478
|
+
owning Harness design and `AGENTS.md` when the runtime boundary changes; a new
|
|
479
|
+
rule or exemption needs a rejecting counterexample test.
|
|
480
|
+
|
|
481
|
+
Repository administrators must require `bootstrap` on `main` and configure
|
|
482
|
+
review/bypass policy separately. A workflow cannot enforce branch protection
|
|
483
|
+
against itself being changed or a direct push that bypasses checks.
|
|
484
|
+
|
|
485
|
+
### Page plugins and names
|
|
486
|
+
|
|
487
|
+
Every page is an independent native frontend plugin and Cordis Fiber under
|
|
488
|
+
View's frontend root. Closing a tab only changes presentation.
|
|
489
|
+
Use `createViewProductPlan({ disabledPages: ['editor'] })` to omit a page
|
|
490
|
+
and its panels from that root. Page IDs are `editor`,
|
|
491
|
+
`display`, `plugins`, `material`, `mesh`, `texture` and `asset`. Scene panels depend on `viewScenePage`;
|
|
492
|
+
the plan omits the complete contribution when its page is disabled.
|
|
493
|
+
Backend workspace and inspection services remain available.
|
|
494
|
+
The same option is accepted by `startView({ disabledPages: ['editor'] })`.
|
|
495
|
+
The resident `@forgeax/view/plugin` also accepts `config.disabledPages`.
|
|
496
|
+
|
|
497
|
+
| Page | Frontend Plugin name | Owned UI |
|
|
498
|
+
|:--|:--|:--|
|
|
499
|
+
| Scene (Editor tab) | `forgeax.view.page.scene.frontend` | Scene page registration and panel dependency |
|
|
500
|
+
| AI Display (Runtime capture) | `forgeax.view.page.ai-display.frontend` | Exact Engine display surface |
|
|
501
|
+
| Plugin Browser | `forgeax.view.page.plugin-browser.frontend` | Actual Host Fibers and activation states |
|
|
502
|
+
| Material | `forgeax.view.page.material.frontend` | Material preview and properties |
|
|
503
|
+
| Mesh | `forgeax.view.page.mesh.frontend` | Mesh preview and properties |
|
|
504
|
+
| Texture | `forgeax.view.page.texture.frontend` | Texture preview and properties |
|
|
505
|
+
| Asset | `forgeax.view.page.asset.frontend` | Fallback resource properties |
|
|
506
|
+
|
|
507
|
+
Use `forgeax.view.<role>.<feature>.<side>` for native runtime names:
|
|
508
|
+
`page` for pages, `panel` for scene panels, `service` for API clients,
|
|
509
|
+
providers and target presentation, and `shell` for UI hosting. For example,
|
|
510
|
+
`panel.object-inspector.frontend` and `service.plugin-inspection.backend`
|
|
511
|
+
describe different responsibilities. Names are declared beside each plugin
|
|
512
|
+
(product packages use `identity.mjs`). The Scene, Shell and Play presentation
|
|
513
|
+
plugins need no empty backend counterpart. All plugins use the same native Host
|
|
514
|
+
lifecycle.
|
|
515
|
+
|
|
516
|
+
The asset browser owns only its panel. The independent Play presentation
|
|
517
|
+
service owns connection-scoped browser resources; disabling Scene removes its
|
|
518
|
+
viewport placement without terminating Play. The viewport panel presents
|
|
519
|
+
Engine's exact workspace target. Plugin
|
|
520
|
+
Browser reads live Host facts; missing activation evidence stays `unknown`.
|
|
521
|
+
|
|
522
|
+
Plugin Browser groups Fibers by their reported Host source, with backend
|
|
523
|
+
Fibers first. Host selection, text search and tags intersect; multiple tags
|
|
524
|
+
must all match. Counts describe the observed snapshot, not every possible Host.
|
|
525
|
+
|
|
526
|
+
| Filter | Evidence |
|
|
527
|
+
|:--|:--|
|
|
528
|
+
| Backend / Frontend | The reporting Host source kind |
|
|
529
|
+
| Game | A reported game/engine source, or an Engine Fiber declaring `world` / `gameHost` dependencies; the View frontend's Engine realm alone is not enough |
|
|
530
|
+
| API | Tool API operations attributed to the exact provider / Fiber |
|
|
531
|
+
| CLI | A command contract or command paths declared by those Tool API operations; not a running CLI process |
|
|
532
|
+
|
|
533
|
+
The shared workspace client uses `sources()` and `inspectPlugins()`; the
|
|
534
|
+
standalone inspector client's `inspect()` is also supported. Inspection and
|
|
535
|
+
watch `generation` arguments identify the source, not the transport service.
|
|
536
|
+
Remote source failures produce a partial-inventory notice while available
|
|
537
|
+
sources remain visible. Other frontend connections are not hidden when the
|
|
538
|
+
current frontend supplies its local snapshot.
|
|
539
|
+
|
|
540
|
+
> [!NOTE]
|
|
541
|
+
> Inspection covers only reported sources. A zero Game count does not establish
|
|
542
|
+
> that no game is running; independent game/worker Hosts without an inspection
|
|
543
|
+
> report are not fabricated or inferred from names.
|
|
544
|
+
|
|
545
|
+
After `pnpm build` with the matching Engine candidates, run
|
|
546
|
+
`xvfb-run -a node scripts/verify-engine-plugin-boundary.mjs`. Its page-plugin
|
|
547
|
+
probe exercises tab close/reopen, all seven page disable/restore paths,
|
|
548
|
+
service isolation, real backend inventory, Host/tag/search combinations, reset,
|
|
549
|
+
and narrow-screen layout inside the real Engine workspace. Screenshots are saved
|
|
550
|
+
under `artifacts/page-plugins/`.
|
|
551
|
+
For the focused page lifecycle probe without Play stress cycles, run
|
|
552
|
+
`xvfb-run -a node scripts/verify-page-plugin-lifecycle.mjs`.
|
|
553
|
+
|
|
554
|
+
### Workspace CLI
|
|
555
|
+
|
|
556
|
+
Agent guidance: [forgeax-view-cli](skills/forgeax-view-cli/SKILL.md). The
|
|
557
|
+
resident workspace API is authoritative; the browser and CLI are its clients.
|
|
558
|
+
|
|
559
|
+
With a running View owner, Engine CLI can call a workspace operation through
|
|
560
|
+
the native ToolApi provider:
|
|
561
|
+
|
|
562
|
+
```sh
|
|
563
|
+
forgeax view workspace call --root /path/to/backend \
|
|
564
|
+
--operation tabs.get --args '{}' --json
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
This command is declared by the selected View host Pack, so it appears while
|
|
568
|
+
that Pack's backend is running. View must be
|
|
569
|
+
started. The returned operation result comes from the resident View workspace
|
|
570
|
+
owner. The frontend's workspace transport now routes through the same ToolApi
|
|
571
|
+
provider. Browser presentation remains a separate completion check.
|
|
572
|
+
|
|
573
|
+
An independent process can call the same resident `view.*` API through the
|
|
574
|
+
authenticated Engine Host WebSocket. The CLI is deliberately a transport
|
|
575
|
+
client; it does not implement project, asset, scene, camera, or capture logic.
|
|
576
|
+
|
|
577
|
+
```sh
|
|
578
|
+
forgeax-view workspace --operation project.open \
|
|
579
|
+
--endpoint "$FORGEAX_VIEW_WORKSPACE_ENDPOINT" \
|
|
580
|
+
--token "$FORGEAX_VIEW_WORKSPACE_TOKEN" \
|
|
581
|
+
--args '{"root":"/path/to/project","tabId":"forgeax-user-workspace"}'
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
The endpoint and token are explicit capabilities issued by the View owner (or
|
|
585
|
+
can be supplied with `FORGEAX_VIEW_WORKSPACE_ENDPOINT` and
|
|
586
|
+
`FORGEAX_VIEW_WORKSPACE_TOKEN`). The client uses the same operation names and
|
|
587
|
+
JSON argument shape as the browser frontend. This independent CLI path is for
|
|
588
|
+
the workspace API. Independent AI controls use `forgeax engine run`, whose
|
|
589
|
+
private browser does not depend on this connection.
|
|
590
|
+
|
|
591
|
+
Use `--batch '[{"operation":"camera.begin",...},{"operation":"camera.update",...},{"operation":"camera.commit",...}]'`
|
|
592
|
+
when a camera gesture must keep one authenticated client connection. A
|
|
593
|
+
single-operation invocation closes its connection after the Engine API reply.
|
|
594
|
+
|
|
595
|
+
Viewport clicks use View's `scene.pick` selection workflow with physical output
|
|
596
|
+
pixels (`x`, `y`) and the exact `targetId` / `targetGeneration`. It calls Engine's
|
|
597
|
+
existing `target.pick` query; direct `target.pick` calls do not change View
|
|
598
|
+
selection. `scene.select`, `scene.pick` and `scene.clear` share cancellation and
|
|
599
|
+
target guards, so a late result cannot replace a newer selection. Clearing also
|
|
600
|
+
requires the exact target identity. Query or highlight failures preserve the
|
|
601
|
+
last confirmed selection and use the ordinary workspace error channel.
|
|
602
|
+
|
|
603
|
+
## Custom workspace embedding
|
|
604
|
+
|
|
605
|
+
The CLI startup path above already uses Engine's resident workspace provider.
|
|
606
|
+
For a custom embedding application, the library accepts an Engine-owned
|
|
607
|
+
workspace capability through the same Host transport:
|
|
608
|
+
|
|
609
|
+
```js
|
|
610
|
+
const view = await startView({ platform, workspaceEngine });
|
|
611
|
+
const api = await connectViewWorkspace({
|
|
612
|
+
endpoint: view.workspaceEndpoint,
|
|
613
|
+
clientId: 'forgeax-cli',
|
|
614
|
+
token: view.workspaceAccessToken,
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
const tabId = 'forgeax-user-workspace';
|
|
618
|
+
const state = await api.openProject(projectRoot, { tabId });
|
|
619
|
+
const projectId = state.project.id;
|
|
620
|
+
const { assets } = await api.listAssets(projectId, { tabId });
|
|
621
|
+
const scene = assets.find((asset) => asset.kind === 'scene');
|
|
622
|
+
if (scene) {
|
|
623
|
+
await api.inspectAsset(scene.guid, { projectId, tabId });
|
|
624
|
+
await api.openAsset(scene.guid, { projectId, tabId });
|
|
625
|
+
}
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
Authored-asset operations are projections of Engine CLI / ScriptablePack / ToolClient APIs. View does not parse `*.pack.ts`, write DDC, cook, or invent `applyParams`:
|
|
629
|
+
|
|
630
|
+
| View operation | Engine API | View owns |
|
|
631
|
+
|:--|:--|:--|
|
|
632
|
+
| `assets.list` | DevKit `assetList({ root })` / existing `listAssets` → `PackEntry[]` | session catalog snapshot, including optional `sourceKey` |
|
|
633
|
+
| `asset.inspect` | DevKit `assetInspect({ root, subject })` plus ScriptablePack `inspect(sourcePath)` / gateway `inspect-meta` | session inspection of PackEntry + `ScriptablePackMetaJson` |
|
|
634
|
+
| `asset-source.rebuild` | ScriptablePack `rebuild(sourcePath, 'rebuild')` / gateway `rebuild` / ToolClient `asset-source.rebuild` | forwarding + CAS `expectedRevision` |
|
|
635
|
+
| `asset-source.cold-cook` | ScriptablePack `rebuild(sourcePath, 'cold-cook')` / gateway `cold-cook` / ToolClient `asset-source.cold-cook` | forwarding + CAS `expectedRevision` |
|
|
636
|
+
|
|
637
|
+
Codex edits `pack.ts` through the workspace files. The browser shell places the `sourcePath`-grouped Engine catalog and exact viewport on the left, and a **read-only** Engine meta inspector on the right (`packageId`, `importer`, `subAssets`, `cookReceiptUrl`). `Rebuild` / `Cold-cook` only forward Engine cook. Selecting an already-previewed GUID inspects again and does not open a second preview surface. Missing Engine methods fail closed with `view-engine-capability-unavailable`. Engine revision conflicts surface as `pack-source-revision-conflict`.
|
|
638
|
+
|
|
639
|
+
In the already-open browser Page, load the browser entry and mount the View
|
|
640
|
+
frontend once. The returned `api` is the same API used by the independent CLI;
|
|
641
|
+
the returned `shell` owns only DOM presentation and input sampling.
|
|
642
|
+
|
|
643
|
+
```js
|
|
644
|
+
import { mountViewWorkspace } from '@forgeax/view/browser';
|
|
645
|
+
|
|
646
|
+
const mounted = await mountViewWorkspace({
|
|
647
|
+
endpoint: view.workspaceEndpoint,
|
|
648
|
+
token: view.workspaceAccessToken,
|
|
649
|
+
});
|
|
650
|
+
await mounted.api.openProject(projectRoot, { tabId: 'forgeax-user-workspace' });
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
`mountViewWorkspace()` must execute in the browser document that owns the View
|
|
654
|
+
window. It does not navigate the page, start a browser, or create a second
|
|
655
|
+
workspace runtime. For a custom host, `connectViewFrontend()` exposes the
|
|
656
|
+
underlying Engine `FrontendHost` while retaining the same plugin and transport.
|
|
657
|
+
|
|
658
|
+
`workspaceEngine` is the host-supplied Engine capability. View binds Engine's public commands and ports; it does not wrap a second cook implementation. A host should pass the same objects Engine already exposes:
|
|
659
|
+
|
|
660
|
+
```js
|
|
661
|
+
const workspaceEngine = {
|
|
662
|
+
openProject,
|
|
663
|
+
closeProject,
|
|
664
|
+
listAssets: (input) => assetListCommand({ root: input.project.root }),
|
|
665
|
+
assetInspect: (input) => assetInspectCommand({ root: input.root, subject: input.subject }),
|
|
666
|
+
openPreview,
|
|
667
|
+
pack: scriptablePackAuthoringPort, // inspect / preflight / rebuild
|
|
668
|
+
tools: toolClient, // ToolClient.run('asset-source.rebuild' | 'asset-source.cold-cook')
|
|
669
|
+
};
|
|
670
|
+
const view = await startView({ platform, workspaceEngine });
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
Asset listing, SceneAsset preview, Engine-owned camera motion, capture, and close all remain on the headed Engine page. An independent CLI may use the authenticated `workspaceEndpoint` with the out-of-band access token; `connectViewWorkspace()` only creates a client and never starts another Engine target.
|
|
674
|
+
|
|
675
|
+
For another Engine host, `createEngineWorkspaceProvider()` remains the explicit
|
|
676
|
+
adapter boundary: its `openProjectSession` must return an Engine-owned,
|
|
677
|
+
long-lived project session and headed target. View does not invent a project
|
|
678
|
+
loader, copy App/World internals, or provide a mock target. The optional
|
|
679
|
+
`presentation.createSurface` plus `attach`/`detach` callbacks bind the exact
|
|
680
|
+
target surface (the Engine host may return its existing app-shell; View never
|
|
681
|
+
creates a renderer copy). `applyInput` passes semantic motion to the host-owned
|
|
682
|
+
camera executor. Selecting the CLI display tab changes presentation and input focus only;
|
|
683
|
+
it never changes the CLI target or execution. The browser entry installs
|
|
684
|
+
`createBrowserPagePresentation()` by default; a custom adapter is only needed
|
|
685
|
+
when the embedding Engine host supplies a different exact surface.
|
|
686
|
+
|
|
687
|
+
The workspace reports `view-engine-capability-unavailable` until the matching
|
|
688
|
+
Engine plugin is installed. It does not fall back to a mock scene, a second
|
|
689
|
+
game runtime, or an Electron page.
|
|
690
|
+
|
|
691
|
+
For an Engine project capture that owns the browser document Host, keep the
|
|
692
|
+
View frontend out of the bootstrap page and pass the backend binding to the
|
|
693
|
+
Engine capture surface:
|
|
694
|
+
|
|
695
|
+
```js
|
|
696
|
+
const view = await startView({ platform, frontend: false });
|
|
697
|
+
const session = await createBrowserCapture(projectRoot).open({
|
|
698
|
+
headless: false,
|
|
699
|
+
host: view.hostBinding,
|
|
700
|
+
carrier: view.carrier,
|
|
701
|
+
carrierRun: { serviceId: 'forgeax-cli', runId },
|
|
702
|
+
carrierGeneration: 1,
|
|
703
|
+
});
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
The Engine host contribution then activates View's frontend root in the actual
|
|
707
|
+
runtime document. Detached live-dev and external
|
|
708
|
+
`serverUrl` paths remain out of scope until their server owner can carry the
|
|
709
|
+
same binding.
|
|
710
|
+
|
|
711
|
+
## Bootstrap
|
|
712
|
+
|
|
713
|
+
Use Node.js 22+, pnpm, Git, Python 3, and authenticated access to the private
|
|
714
|
+
repositories. Clone `ForgeaXGame/forgeax-harness` alongside this repository,
|
|
715
|
+
or set `FORGEAX_HARNESS_ROOT` to that tooling checkout.
|
|
716
|
+
|
|
717
|
+
```sh
|
|
718
|
+
pnpm harness:init
|
|
719
|
+
pnpm test
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
| Command / setting | Behavior |
|
|
723
|
+
|:--|:--|
|
|
724
|
+
| `pnpm harness:sync` | Clone or fast-forward the independent `.forgeax-harness` repository |
|
|
725
|
+
| `pnpm harness:init` | Install local skills and initialize/verify Harness data |
|
|
726
|
+
| `pnpm install` | Attempt optional Harness synchronization through `postinstall` |
|
|
727
|
+
| `FORGEAX_SKIP_HARNESS_SYNC=1` | Skip optional synchronization |
|
|
728
|
+
| `FORGEAX_HARNESS_STRICT=1` | Make standalone synchronization failures fatal |
|
|
729
|
+
| `FORGEAX_HARNESS_ROOT=/path/to/forgeax-harness` | Select shared tooling |
|
|
730
|
+
|
|
731
|
+
Synchronization preserves dirty, divergent, and differently configured clones.
|
|
732
|
+
Harness data and machine-local installation state are not runtime dependencies.
|
|
733
|
+
|
|
734
|
+
## Design
|
|
735
|
+
|
|
736
|
+
- [Architecture north star](.forgeax-harness/knowledge-base/wiki/architecture-north-star.md)
|
|
737
|
+
- [CLI-authoritative View design](.forgeax-harness/docs/specs/2026-09-12-cli-authoritative-plugin-view-design.md)
|
|
738
|
+
- [Engine Host/Plugin architecture design](.forgeax-harness/docs/specs/2026-09-12-view-engine-host-plugin-architecture-design.md)
|
|
739
|
+
- [Contributor instructions](AGENTS.md)
|
|
740
|
+
|
|
741
|
+
The first two documents belong to the independent
|
|
742
|
+
[forgeax-view-harness](https://github.com/ForgeaXGame/forgeax-view-harness) repository.
|