@holoscript/core 7.0.0 → 8.0.1
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/README.md +4 -4
- package/bin/holoscript.cjs +3 -0
- package/dist/GLTFPipeline-N6B6PJ6G.cjs +38 -0
- package/dist/GLTFPipeline-P3WMNYCN.js +17 -0
- package/dist/HoloScriptPlusParser-7FBIFUFC.js +693 -0
- package/dist/HoloScriptPlusParser-A2W7OCN2.cjs +698 -0
- package/dist/HoloScriptPlusParser-F2Z56FJR.js +10 -0
- package/dist/HoloScriptPlusParser-WKHRIH6T.cjs +27 -0
- package/dist/HoloScriptRuntime-CBYJX3LZ.js +10 -0
- package/dist/HoloScriptRuntime-VJ374RER.cjs +19 -0
- package/dist/USDZExporter-3FWJ25JI.cjs +1037 -0
- package/dist/USDZExporter-D2HQLQYK.js +1035 -0
- package/dist/agents/index.cjs +19 -0
- package/dist/agents/index.d.ts +100 -0
- package/dist/agents/index.js +17 -0
- package/dist/chunk-2BSMSUCE.js +1941 -0
- package/dist/chunk-2IWC4FP7.cjs +1189 -0
- package/dist/chunk-2M2DPHKB.js +762 -0
- package/dist/chunk-2X7NGX3M.js +2426 -0
- package/dist/chunk-2YSNA2F2.cjs +1274 -0
- package/dist/chunk-3FOKASKO.cjs +348 -0
- package/dist/chunk-3WZEJHUQ.cjs +116 -0
- package/dist/chunk-4C57PR42.js +468 -0
- package/dist/chunk-4GU5GCIY.js +1384 -0
- package/dist/chunk-4N4SXXWF.js +769 -0
- package/dist/chunk-4PDEPEQW.cjs +41 -0
- package/dist/chunk-4R6SBXDB.js +45 -0
- package/dist/chunk-4SDKXQ4C.js +811 -0
- package/dist/chunk-4V2E7U7Q.cjs +2015 -0
- package/dist/chunk-5FSKKMR7.cjs +2092 -0
- package/dist/chunk-5GLCTO44.js +161 -0
- package/dist/chunk-5H2G27PK.cjs +627 -0
- package/dist/chunk-5JEU52DW.js +382 -0
- package/dist/chunk-5NWINHR5.cjs +689 -0
- package/dist/chunk-5S7RKFGR.cjs +446 -0
- package/dist/chunk-5WUNN6ZN.cjs +428 -0
- package/dist/chunk-6CTRH7HT.cjs +1985 -0
- package/dist/chunk-6EX3I5P4.cjs +130 -0
- package/dist/chunk-6Q7RC2MK.cjs +1418 -0
- package/dist/chunk-7H33U5SM.cjs +413 -0
- package/dist/chunk-7M3PNU2M.cjs +672 -0
- package/dist/chunk-7T25IEZ2.js +449 -0
- package/dist/chunk-7V4JI5TB.cjs +6947 -0
- package/dist/chunk-A6KINLZJ.js +236 -0
- package/dist/chunk-ADADVMXY.js +404 -0
- package/dist/chunk-AIA52I7T.cjs +543 -0
- package/dist/chunk-ALC6K7GL.cjs +4402 -0
- package/dist/chunk-ANXZFVY2.js +113 -0
- package/dist/chunk-AOVGZ25K.cjs +56583 -0
- package/dist/chunk-AVJHHUC5.cjs +718 -0
- package/dist/chunk-BGY3SDG3.js +4396 -0
- package/dist/chunk-BOVPWH4H.js +3857 -0
- package/dist/chunk-BRQJKJGT.cjs +20 -0
- package/dist/chunk-C37BHB7N.cjs +636 -0
- package/dist/chunk-CBJY23VL.js +126 -0
- package/dist/chunk-CCATWPXM.js +778 -0
- package/dist/chunk-CIWWXYHZ.cjs +50 -0
- package/dist/chunk-CMT5NMMS.js +669 -0
- package/dist/chunk-CR4FMIWL.cjs +1049 -0
- package/dist/chunk-CR7XRXRN.cjs +639 -0
- package/dist/chunk-CSD27UNQ.js +2176 -0
- package/dist/chunk-D3STJ56J.js +714 -0
- package/dist/chunk-DAJXW4KX.js +725 -0
- package/dist/chunk-DHO2YRIM.js +756 -0
- package/dist/chunk-DTGBOSEM.cjs +319 -0
- package/dist/chunk-E6XXE66V.js +2252 -0
- package/dist/chunk-E7JP3BS3.cjs +61 -0
- package/dist/chunk-EKBKLK7P.js +1169 -0
- package/dist/chunk-EKYL4PE3.cjs +404 -0
- package/dist/chunk-EXKSFGSX.cjs +274 -0
- package/dist/chunk-EXUP2BUM.cjs +1173 -0
- package/dist/chunk-FDSGHPAK.js +130 -0
- package/dist/chunk-FEWUHQNM.cjs +144 -0
- package/dist/chunk-FFAOS5HQ.js +70 -0
- package/dist/chunk-FGGJQRLZ.js +270 -0
- package/dist/chunk-FHP6LXJS.js +415 -0
- package/dist/chunk-FJPADH77.cjs +666 -0
- package/dist/chunk-FL33V6U7.js +421 -0
- package/dist/chunk-FYSPZT4V.cjs +169 -0
- package/dist/chunk-GIOYPNTH.js +5575 -0
- package/dist/chunk-GJNCFRJU.cjs +125 -0
- package/dist/chunk-GMP623FG.cjs +1508 -0
- package/dist/chunk-GQHQOPXZ.cjs +5580 -0
- package/dist/chunk-GTU2Z2WW.cjs +262 -0
- package/dist/chunk-GYZE55MO.js +2007 -0
- package/dist/chunk-GZG4KA4E.js +529 -0
- package/dist/chunk-H652NHX5.js +600 -0
- package/dist/chunk-HCCQLAA4.cjs +74 -0
- package/dist/chunk-HKEXJUWS.cjs +4007 -0
- package/dist/chunk-HNDK4IQU.cjs +5737 -0
- package/dist/chunk-HR2OSYVQ.js +56165 -0
- package/dist/chunk-HYNTS5CP.js +422 -0
- package/dist/chunk-I6XZ5DZF.cjs +488 -0
- package/dist/chunk-ILRBGFVD.cjs +72 -0
- package/dist/chunk-IUDGEUDO.cjs +1409 -0
- package/dist/chunk-IUTY5WQ2.cjs +424 -0
- package/dist/chunk-IVY74O6C.js +247 -0
- package/dist/chunk-IWC5DM2M.cjs +611 -0
- package/dist/chunk-J32ZJZJH.js +554 -0
- package/dist/chunk-J52VSAQ7.js +6884 -0
- package/dist/chunk-J6M4FPK5.js +421 -0
- package/dist/chunk-J7XZV333.js +844 -0
- package/dist/chunk-JBNDTXXV.cjs +2433 -0
- package/dist/chunk-JC5YBPSF.cjs +984 -0
- package/dist/chunk-JD7CIZ33.js +1949 -0
- package/dist/chunk-JIBL5LRK.js +4287 -0
- package/dist/chunk-JIYN45TV.cjs +2525 -0
- package/dist/chunk-K574J76X.cjs +457 -0
- package/dist/chunk-KHDZJE5D.cjs +2196 -0
- package/dist/chunk-KKFZ3B6J.cjs +557 -0
- package/dist/chunk-KKP7JKN4.cjs +6002 -0
- package/dist/chunk-KPJL34Y7.cjs +186 -0
- package/dist/chunk-KQCN6AKJ.cjs +3042 -0
- package/dist/chunk-L5LKKENW.cjs +424 -0
- package/dist/chunk-LHAXPADA.js +882 -0
- package/dist/chunk-LM2VU56C.cjs +37 -0
- package/dist/chunk-M56JSP4A.js +400 -0
- package/dist/chunk-MBOOR7X4.js +18 -0
- package/dist/chunk-MQWAT42R.cjs +4310 -0
- package/dist/chunk-MXFUTKCO.js +56 -0
- package/dist/chunk-MYY4PMWX.cjs +264 -0
- package/dist/chunk-N75IH2HY.js +258 -0
- package/dist/chunk-NCWCUZNS.cjs +72 -0
- package/dist/chunk-NG77ATEW.cjs +778 -0
- package/dist/chunk-NW5G5FBQ.js +215 -0
- package/dist/chunk-OBIYPYYS.cjs +1993 -0
- package/dist/chunk-OH2FAIVU.js +608 -0
- package/dist/chunk-OIQYIIO3.cjs +473 -0
- package/dist/chunk-OL46QLBJ.js +61 -0
- package/dist/chunk-OMXII44L.js +5386 -0
- package/dist/chunk-OSYNRVOV.cjs +243 -0
- package/dist/chunk-PGANYCAG.cjs +220 -0
- package/dist/chunk-PHENW4MQ.js +65 -0
- package/dist/chunk-PY37LNDP.js +686 -0
- package/dist/chunk-Q56TT7IL.js +483 -0
- package/dist/chunk-QD32ADK6.js +1046 -0
- package/dist/chunk-QPOQ7VPI.js +1491 -0
- package/dist/chunk-QPSKHBJP.js +5963 -0
- package/dist/chunk-QXH7QDSZ.js +1989 -0
- package/dist/chunk-R24NNAEG.js +1399 -0
- package/dist/chunk-R75BSDH7.cjs +50 -0
- package/dist/chunk-RARB3MBR.js +207 -0
- package/dist/chunk-ROHLEP2W.cjs +847 -0
- package/dist/chunk-S3MDHNKB.cjs +490 -0
- package/dist/chunk-S6YWHCKV.cjs +410 -0
- package/dist/chunk-SIEXCILW.js +229 -0
- package/dist/chunk-SLU6UPJI.cjs +410 -0
- package/dist/chunk-SMIWS6DE.cjs +212 -0
- package/dist/chunk-T5J7ZKP3.cjs +4885 -0
- package/dist/chunk-TDCNJHWO.js +341 -0
- package/dist/chunk-TG7O4WBC.js +406 -0
- package/dist/chunk-THCK6ECW.js +2085 -0
- package/dist/chunk-TJHVSBP2.js +439 -0
- package/dist/chunk-TVHSPJ4N.cjs +606 -0
- package/dist/chunk-TWUXUCEW.cjs +781 -0
- package/dist/chunk-U44IKGG7.cjs +5390 -0
- package/dist/chunk-UFZZ7TSN.cjs +886 -0
- package/dist/chunk-UJXISJBN.js +487 -0
- package/dist/chunk-UOIGFQXC.cjs +9750 -0
- package/dist/chunk-URG2SJLK.js +2521 -0
- package/dist/chunk-UWJHCOH2.js +623 -0
- package/dist/chunk-V6MKC2FZ.js +979 -0
- package/dist/chunk-VJ3L7CHT.cjs +169 -0
- package/dist/chunk-VMLKSV26.js +1216 -0
- package/dist/chunk-VVKVQZI6.js +55 -0
- package/dist/chunk-W6RW64BB.cjs +1219 -0
- package/dist/chunk-WKX5AMOY.js +309 -0
- package/dist/chunk-WNNE3PO3.js +34 -0
- package/dist/chunk-WRKUDAZJ.js +3038 -0
- package/dist/chunk-WRLUBRKS.cjs +1943 -0
- package/dist/chunk-WRNEH5MO.js +3169 -0
- package/dist/chunk-WRWEX5ZF.js +658 -0
- package/dist/chunk-X3GJPRVK.cjs +3246 -0
- package/dist/chunk-X3UVCWNL.cjs +2257 -0
- package/dist/chunk-XB274MW5.cjs +814 -0
- package/dist/chunk-XHIV6326.cjs +793 -0
- package/dist/chunk-XIVIE43A.cjs +729 -0
- package/dist/chunk-XJAN7CZG.cjs +432 -0
- package/dist/chunk-XKTPFXGA.js +164 -0
- package/dist/chunk-XL6INWKT.js +121 -0
- package/dist/chunk-XSFNHP2E.js +632 -0
- package/dist/chunk-XT6JY5W5.js +9684 -0
- package/dist/chunk-XUILI4KB.cjs +430 -0
- package/dist/chunk-YF2I3MV3.js +46 -0
- package/dist/chunk-YIMN575O.js +4847 -0
- package/dist/chunk-YIVFJNYV.js +176 -0
- package/dist/chunk-YKGPCZEE.cjs +237 -0
- package/dist/chunk-YN2YWTXW.js +5731 -0
- package/dist/chunk-YN6V7R3L.cjs +327 -0
- package/dist/chunk-YQELFNJV.js +39 -0
- package/dist/chunk-YVD3CSO3.js +1183 -0
- package/dist/chunk-YVOAF4ML.js +623 -0
- package/dist/chunk-YWOBW2PV.cjs +759 -0
- package/dist/chunk-YYXH45E2.js +426 -0
- package/dist/chunk-ZDSYWBIE.cjs +69 -0
- package/dist/chunk-ZU7NIRT6.js +325 -0
- package/dist/chunk-ZZ7RO2UQ.js +1243 -0
- package/dist/cli/holoscript-runner.cjs +2255 -0
- package/dist/cli/holoscript-runner.js +2230 -0
- package/dist/codebase/index.cjs +336 -0
- package/dist/codebase/index.js +331 -0
- package/dist/compiler/agent-inference.cjs +31 -0
- package/dist/compiler/agent-inference.js +8 -0
- package/dist/compiler/android-xr.cjs +24 -0
- package/dist/compiler/android-xr.js +14 -0
- package/dist/compiler/android.cjs +24 -0
- package/dist/compiler/android.js +14 -0
- package/dist/compiler/ar.cjs +23 -0
- package/dist/compiler/ar.js +11 -0
- package/dist/compiler/babylon.cjs +21 -0
- package/dist/compiler/babylon.js +15 -0
- package/dist/compiler/business-quest.cjs +43 -0
- package/dist/compiler/business-quest.js +4 -0
- package/dist/compiler/coco.cjs +27 -0
- package/dist/compiler/coco.js +4 -0
- package/dist/compiler/context.cjs +25 -0
- package/dist/compiler/context.d.ts +28 -0
- package/dist/compiler/context.js +8 -0
- package/dist/compiler/domain-block-utils.cjs +609 -0
- package/dist/compiler/domain-block-utils.js +11 -0
- package/dist/compiler/dtdl.cjs +27 -0
- package/dist/compiler/dtdl.js +11 -0
- package/dist/compiler/gltf-pipeline.cjs +39 -0
- package/dist/compiler/gltf-pipeline.js +4 -0
- package/dist/compiler/godot.cjs +18 -0
- package/dist/compiler/godot.js +12 -0
- package/dist/compiler/incremental.cjs +34 -0
- package/dist/compiler/incremental.js +9 -0
- package/dist/compiler/index.cjs +5408 -0
- package/dist/compiler/index.d.ts +334 -21
- package/dist/compiler/index.js +5069 -0
- package/dist/compiler/ios.cjs +23 -0
- package/dist/compiler/ios.js +13 -0
- package/dist/compiler/llm-provider-capabilities.cjs +25 -0
- package/dist/compiler/llm-provider-capabilities.d.ts +43 -0
- package/dist/compiler/llm-provider-capabilities.js +8 -0
- package/dist/compiler/multi-layer.cjs +24 -0
- package/dist/compiler/multi-layer.js +15 -0
- package/dist/compiler/nodetoy.cjs +23 -0
- package/dist/compiler/nodetoy.d.ts +69 -0
- package/dist/compiler/nodetoy.js +4 -0
- package/dist/compiler/openxr.cjs +19 -0
- package/dist/compiler/openxr.js +13 -0
- package/dist/compiler/playcanvas.cjs +19 -0
- package/dist/compiler/playcanvas.js +13 -0
- package/dist/compiler/r3f.cjs +39 -0
- package/dist/compiler/r3f.d.ts +22 -0
- package/dist/compiler/r3f.js +17 -0
- package/dist/compiler/remotion.cjs +23 -0
- package/dist/compiler/remotion.js +4 -0
- package/dist/compiler/reproducibility.cjs +39 -0
- package/dist/compiler/reproducibility.js +4 -0
- package/dist/compiler/sdf.cjs +24 -0
- package/dist/compiler/sdf.js +12 -0
- package/dist/compiler/semantic-scene.cjs +31 -0
- package/dist/compiler/semantic-scene.js +4 -0
- package/dist/compiler/state.cjs +21 -0
- package/dist/compiler/state.js +11 -0
- package/dist/compiler/trait-composition.cjs +30 -0
- package/dist/compiler/trait-composition.js +9 -0
- package/dist/compiler/unity.cjs +19 -0
- package/dist/compiler/unity.js +13 -0
- package/dist/compiler/unreal.cjs +23 -0
- package/dist/compiler/unreal.js +13 -0
- package/dist/compiler/urdf.cjs +52 -0
- package/dist/compiler/urdf.js +12 -0
- package/dist/compiler/usd-physics.cjs +26 -0
- package/dist/compiler/usd-physics.js +9 -0
- package/dist/compiler/visionos.cjs +19 -0
- package/dist/compiler/visionos.js +13 -0
- package/dist/compiler/vrchat.cjs +22 -0
- package/dist/compiler/vrchat.js +12 -0
- package/dist/compiler/vrr.cjs +24 -0
- package/dist/compiler/vrr.js +12 -0
- package/dist/compiler/wasm.cjs +36 -0
- package/dist/compiler/wasm.js +12 -0
- package/dist/compiler/webgpu.cjs +18 -0
- package/dist/compiler/webgpu.js +12 -0
- package/dist/coordinators/index.cjs +1266 -0
- package/dist/coordinators/index.d.ts +72 -1
- package/dist/coordinators/index.js +1259 -0
- package/dist/debugger.cjs +24 -0
- package/dist/debugger.js +11 -0
- package/dist/dist-ACXG6IH5.cjs +3113 -0
- package/dist/dist-VD4L6V7Q.js +3076 -0
- package/dist/entries/interop.cjs +64 -0
- package/dist/entries/interop.js +7 -0
- package/dist/entries/scripting.cjs +55 -0
- package/dist/entries/scripting.js +10 -0
- package/dist/hololand/index.cjs +146 -0
- package/dist/hololand/index.d.ts +70 -0
- package/dist/hololand/index.js +5 -0
- package/dist/index.cjs +44660 -0
- package/dist/index.d.ts +978 -21
- package/dist/index.js +41422 -0
- package/dist/math/tropical-spmv.cjs +45 -0
- package/dist/math/tropical-spmv.js +4 -0
- package/dist/math/vec3.cjs +57 -0
- package/dist/math/vec3.js +4 -0
- package/dist/ml-dsa-FSKBTE3W.cjs +1265 -0
- package/dist/ml-dsa-Z7JDKW4L.js +1265 -0
- package/dist/paper-0c-spike/index.cjs +150 -0
- package/dist/paper-0c-spike/index.js +141 -0
- package/dist/parser.cjs +61 -0
- package/dist/parser.d.ts +11 -0
- package/dist/parser.js +12 -0
- package/dist/playwright-3AT3AKTV.cjs +98673 -0
- package/dist/playwright-VZPDVUEQ.js +98660 -0
- package/dist/reconstruction/index.cjs +153 -0
- package/dist/reconstruction/index.d.ts +29 -2
- package/dist/reconstruction/index.js +8 -0
- package/dist/runtime.cjs +316 -0
- package/dist/runtime.d.ts +61 -0
- package/dist/runtime.js +31 -0
- package/dist/self-improvement/index.cjs +563 -0
- package/dist/self-improvement/index.js +545 -0
- package/dist/src-4ROC227P.cjs +2094 -0
- package/dist/src-HCCCSYP7.js +2073 -0
- package/dist/storage/index.cjs +38 -0
- package/dist/storage/index.js +5 -0
- package/dist/testing.cjs +25 -0
- package/dist/testing.d.ts +70 -0
- package/dist/testing.js +4 -0
- package/dist/traitDocs/traitDocs.cjs +33 -0
- package/dist/traitDocs/traitDocs.js +7 -0
- package/dist/traits/botanical-lotus.cjs +177 -0
- package/dist/traits/botanical-lotus.d.ts +502 -0
- package/dist/traits/botanical-lotus.js +7 -0
- package/dist/traits/engines/index.cjs +520 -0
- package/dist/traits/engines/index.js +380 -0
- package/dist/traits/index.cjs +24548 -0
- package/dist/traits/index.d.ts +171 -35
- package/dist/traits/index.js +21638 -0
- package/dist/traits/simulation-solver-factory.cjs +13 -0
- package/dist/traits/simulation-solver-factory.d.ts +23 -0
- package/dist/traits/simulation-solver-factory.js +4 -0
- package/dist/traits/webcam-gaze.cjs +35 -0
- package/dist/traits/webcam-gaze.d.ts +17 -0
- package/dist/traits/webcam-gaze.js +4 -0
- package/dist/type-checker.cjs +19 -0
- package/dist/type-checker.js +6 -0
- package/dist/world/index.cjs +947 -0
- package/dist/world/index.d.ts +147 -0
- package/dist/world/index.js +939 -0
- package/dist/world-model/index.cjs +1446 -0
- package/dist/world-model/index.d.ts +119 -0
- package/dist/world-model/index.js +1414 -0
- package/dist/wot/index.cjs +29 -0
- package/dist/wot/index.js +4 -0
- package/package.json +93 -49
|
@@ -0,0 +1,4310 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkGJNCFRJU_cjs = require('./chunk-GJNCFRJU.cjs');
|
|
4
|
+
var chunkSMIWS6DE_cjs = require('./chunk-SMIWS6DE.cjs');
|
|
5
|
+
var chunkJIYN45TV_cjs = require('./chunk-JIYN45TV.cjs');
|
|
6
|
+
var chunkTVHSPJ4N_cjs = require('./chunk-TVHSPJ4N.cjs');
|
|
7
|
+
var chunkILRBGFVD_cjs = require('./chunk-ILRBGFVD.cjs');
|
|
8
|
+
var chunkE7JP3BS3_cjs = require('./chunk-E7JP3BS3.cjs');
|
|
9
|
+
var ws = require('ws');
|
|
10
|
+
var orbital = require('@holoscript/engine/orbital');
|
|
11
|
+
var mesh = require('@holoscript/mesh');
|
|
12
|
+
var engineRuntime = require('@holoscript/engine/runtime');
|
|
13
|
+
var learning = require('@holoscript/framework/learning');
|
|
14
|
+
|
|
15
|
+
function _interopNamespace(e) {
|
|
16
|
+
if (e && e.__esModule) return e;
|
|
17
|
+
var n = Object.create(null);
|
|
18
|
+
if (e) {
|
|
19
|
+
Object.keys(e).forEach(function (k) {
|
|
20
|
+
if (k !== 'default') {
|
|
21
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
22
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
23
|
+
enumerable: true,
|
|
24
|
+
get: function () { return e[k]; }
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
n.default = e;
|
|
30
|
+
return Object.freeze(n);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
var engineRuntime__namespace = /*#__PURE__*/_interopNamespace(engineRuntime);
|
|
34
|
+
|
|
35
|
+
// src/HoloScriptRuntime.ts
|
|
36
|
+
chunkE7JP3BS3_cjs.init_safeJsonParse();
|
|
37
|
+
|
|
38
|
+
// src/runtime/physics-math.ts
|
|
39
|
+
var GRAVITY = 9.81;
|
|
40
|
+
var ARC_MIN_DISTANCE = 0.1;
|
|
41
|
+
function calculateArc(start, end, speed) {
|
|
42
|
+
const dx = end[0] - start[0];
|
|
43
|
+
const dz = end[2] - start[2];
|
|
44
|
+
const dy = end[1] - start[1];
|
|
45
|
+
const dist = Math.sqrt(dx * dx + dz * dz);
|
|
46
|
+
if (dist < ARC_MIN_DISTANCE) return [0, speed, 0];
|
|
47
|
+
const t = dist / speed;
|
|
48
|
+
const vx = dx / t;
|
|
49
|
+
const vz = dz / t;
|
|
50
|
+
const vy = dy / t + 0.5 * GRAVITY * t;
|
|
51
|
+
return [vx, vy, vz];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// src/runtime/condition-evaluator.ts
|
|
55
|
+
var SUSPICIOUS_KEYWORDS = [
|
|
56
|
+
"eval",
|
|
57
|
+
"process",
|
|
58
|
+
"require",
|
|
59
|
+
"__proto__",
|
|
60
|
+
"constructor"
|
|
61
|
+
];
|
|
62
|
+
function evaluateCondition(condition, evaluate) {
|
|
63
|
+
if (!condition) return false;
|
|
64
|
+
const condStr = String(condition);
|
|
65
|
+
if (SUSPICIOUS_KEYWORDS.some((kw) => condStr.toLowerCase().includes(kw))) {
|
|
66
|
+
chunkILRBGFVD_cjs.logger.warn("Suspicious condition blocked", { condition });
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
if (condStr.trim().toLowerCase() === "true") return true;
|
|
71
|
+
if (condStr.trim().toLowerCase() === "false") return false;
|
|
72
|
+
const comparisonPatterns = [
|
|
73
|
+
{ regex: /^(.+?)\s*(===|!==)\s*(.+)$/ },
|
|
74
|
+
{ regex: /^(.+?)\s*(==|!=|>=|<=|>|<)\s*(.+)$/ },
|
|
75
|
+
{ regex: /^(.+?)\s*(&&)\s*(.+)$/, logical: "and" },
|
|
76
|
+
{ regex: /^(.+?)\s*(\|\|)\s*(.+)$/, logical: "or" }
|
|
77
|
+
];
|
|
78
|
+
for (const { regex, logical } of comparisonPatterns) {
|
|
79
|
+
const match = condStr.match(regex);
|
|
80
|
+
if (match) {
|
|
81
|
+
const [, leftExpr, operator, rightExpr] = match;
|
|
82
|
+
const left = evaluate(leftExpr.trim());
|
|
83
|
+
const right = evaluate(rightExpr.trim());
|
|
84
|
+
if (logical === "and") return Boolean(left) && Boolean(right);
|
|
85
|
+
if (logical === "or") return Boolean(left) || Boolean(right);
|
|
86
|
+
switch (operator) {
|
|
87
|
+
case "===":
|
|
88
|
+
return left === right;
|
|
89
|
+
case "!==":
|
|
90
|
+
return left !== right;
|
|
91
|
+
case "==":
|
|
92
|
+
return left == right;
|
|
93
|
+
case "!=":
|
|
94
|
+
return left != right;
|
|
95
|
+
case ">=":
|
|
96
|
+
return Number(left) >= Number(right);
|
|
97
|
+
case "<=":
|
|
98
|
+
return Number(left) <= Number(right);
|
|
99
|
+
case ">":
|
|
100
|
+
return Number(left) > Number(right);
|
|
101
|
+
case "<":
|
|
102
|
+
return Number(left) < Number(right);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (condStr.startsWith("!")) {
|
|
107
|
+
return !evaluateCondition(condStr.slice(1).trim(), evaluate);
|
|
108
|
+
}
|
|
109
|
+
const value = evaluate(condStr.trim());
|
|
110
|
+
return Boolean(value);
|
|
111
|
+
} catch (error) {
|
|
112
|
+
chunkILRBGFVD_cjs.logger.error("Condition evaluation error", { condition, error });
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// src/runtime/particle-effects.ts
|
|
118
|
+
var DATA_TYPE_COLORS = {
|
|
119
|
+
string: "#ff6b35",
|
|
120
|
+
number: "#4ecdc4",
|
|
121
|
+
boolean: "#45b7d1",
|
|
122
|
+
object: "#96ceb4",
|
|
123
|
+
array: "#ffeaa7",
|
|
124
|
+
any: "#dda0dd",
|
|
125
|
+
move: "#ff69b4"
|
|
126
|
+
};
|
|
127
|
+
var DEFAULT_DATA_TYPE_COLOR = "#ffffff";
|
|
128
|
+
var CONNECTION_STREAM_STEPS = 20;
|
|
129
|
+
var FLOW_STREAM_MAX_COUNT = 50;
|
|
130
|
+
var DATAVIZ_ARRAY_MAX = 100;
|
|
131
|
+
var DATAVIZ_OBJECT_MAX = 50;
|
|
132
|
+
var DATAVIZ_OBJECT_KEY_MULT = 5;
|
|
133
|
+
var FLOW_STREAM_DEFAULT_COUNT = 10;
|
|
134
|
+
var DATAVIZ_DEFAULT_COUNT = 10;
|
|
135
|
+
var EXECUTION_EFFECT_COUNT = 30;
|
|
136
|
+
var CONNECTION_STREAM_LIFETIME_MS = 5e3;
|
|
137
|
+
var PARTICLE_DEFAULT_LIFETIME_MS = 3e3;
|
|
138
|
+
var PARTICLE_DEFAULT_SPEED = 0.01;
|
|
139
|
+
var CONNECTION_STREAM_SPEED = 0.02;
|
|
140
|
+
var FLOW_STREAM_COLOR = "#45b7d1";
|
|
141
|
+
var EXECUTION_EFFECT_COLOR = "#ff4500";
|
|
142
|
+
var DATAVIZ_COLOR = "#32cd32";
|
|
143
|
+
function getDataTypeColor(dataType) {
|
|
144
|
+
return DATA_TYPE_COLORS[dataType] ?? DEFAULT_DATA_TYPE_COLOR;
|
|
145
|
+
}
|
|
146
|
+
function createParticleEffect(particleSystems, name, position, color, count, maxParticlesPerSystem) {
|
|
147
|
+
const limitedCount = Math.min(count, maxParticlesPerSystem);
|
|
148
|
+
const particles = [];
|
|
149
|
+
for (let i = 0; i < limitedCount; i++) {
|
|
150
|
+
particles.push([
|
|
151
|
+
position[0] + (Math.random() - 0.5) * 2,
|
|
152
|
+
position[1] + (Math.random() - 0.5) * 2,
|
|
153
|
+
position[2] + (Math.random() - 0.5) * 2
|
|
154
|
+
]);
|
|
155
|
+
}
|
|
156
|
+
particleSystems.set(name, {
|
|
157
|
+
particles,
|
|
158
|
+
color,
|
|
159
|
+
lifetime: PARTICLE_DEFAULT_LIFETIME_MS,
|
|
160
|
+
speed: PARTICLE_DEFAULT_SPEED
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
function createConnectionStream(particleSystems, from, to, fromPos, toPos, dataType) {
|
|
164
|
+
const streamName = `connection_${from}_${to}`;
|
|
165
|
+
const particles = [];
|
|
166
|
+
for (let i = 0; i <= CONNECTION_STREAM_STEPS; i++) {
|
|
167
|
+
const t = i / CONNECTION_STREAM_STEPS;
|
|
168
|
+
particles.push([
|
|
169
|
+
fromPos[0] + (toPos[0] - fromPos[0]) * t,
|
|
170
|
+
fromPos[1] + (toPos[1] - fromPos[1]) * t,
|
|
171
|
+
fromPos[2] + (toPos[2] - fromPos[2]) * t
|
|
172
|
+
]);
|
|
173
|
+
}
|
|
174
|
+
particleSystems.set(streamName, {
|
|
175
|
+
particles,
|
|
176
|
+
color: getDataTypeColor(dataType),
|
|
177
|
+
lifetime: CONNECTION_STREAM_LIFETIME_MS,
|
|
178
|
+
speed: CONNECTION_STREAM_SPEED
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
function createFlowingStream(particleSystems, name, position, data, maxParticlesPerSystem) {
|
|
182
|
+
const count = Array.isArray(data) ? Math.min(data.length, FLOW_STREAM_MAX_COUNT) : FLOW_STREAM_DEFAULT_COUNT;
|
|
183
|
+
createParticleEffect(
|
|
184
|
+
particleSystems,
|
|
185
|
+
`${name}_flow`,
|
|
186
|
+
position,
|
|
187
|
+
FLOW_STREAM_COLOR,
|
|
188
|
+
count,
|
|
189
|
+
maxParticlesPerSystem
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
function createExecutionEffect(particleSystems, name, position, maxParticlesPerSystem) {
|
|
193
|
+
createParticleEffect(
|
|
194
|
+
particleSystems,
|
|
195
|
+
`${name}_execution`,
|
|
196
|
+
position,
|
|
197
|
+
EXECUTION_EFFECT_COLOR,
|
|
198
|
+
EXECUTION_EFFECT_COUNT,
|
|
199
|
+
maxParticlesPerSystem
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
function updateParticles(particleSystems, deltaTime) {
|
|
203
|
+
for (const [name, system] of particleSystems) {
|
|
204
|
+
system.lifetime -= deltaTime;
|
|
205
|
+
system.particles.forEach((particle) => {
|
|
206
|
+
particle[0] += (Math.random() - 0.5) * system.speed;
|
|
207
|
+
particle[1] += (Math.random() - 0.5) * system.speed;
|
|
208
|
+
particle[2] += (Math.random() - 0.5) * system.speed;
|
|
209
|
+
});
|
|
210
|
+
if (system.lifetime <= 0) {
|
|
211
|
+
particleSystems.delete(name);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
function createDataVisualization(particleSystems, name, data, position, maxParticlesPerSystem) {
|
|
216
|
+
let count = DATAVIZ_DEFAULT_COUNT;
|
|
217
|
+
if (Array.isArray(data)) {
|
|
218
|
+
count = Math.min(data.length, DATAVIZ_ARRAY_MAX);
|
|
219
|
+
} else if (typeof data === "object" && data !== null) {
|
|
220
|
+
count = Math.min(Object.keys(data).length * DATAVIZ_OBJECT_KEY_MULT, DATAVIZ_OBJECT_MAX);
|
|
221
|
+
}
|
|
222
|
+
createParticleEffect(
|
|
223
|
+
particleSystems,
|
|
224
|
+
`${name}_visualization`,
|
|
225
|
+
position,
|
|
226
|
+
DATAVIZ_COLOR,
|
|
227
|
+
count,
|
|
228
|
+
maxParticlesPerSystem
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// src/runtime/transformation.ts
|
|
233
|
+
var TAKE_DEFAULT_COUNT = 10;
|
|
234
|
+
async function applyTransformation(data, transform, ctx) {
|
|
235
|
+
const params = transform.parameters || {};
|
|
236
|
+
switch (transform.operation) {
|
|
237
|
+
case "filter": {
|
|
238
|
+
if (!Array.isArray(data)) return data;
|
|
239
|
+
const predicate = params.predicate;
|
|
240
|
+
if (predicate) {
|
|
241
|
+
return data.filter((item) => {
|
|
242
|
+
ctx.setVariable("_item", item);
|
|
243
|
+
return ctx.evaluateCondition(predicate);
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
return data.filter((item) => item !== null && item !== void 0);
|
|
247
|
+
}
|
|
248
|
+
case "map": {
|
|
249
|
+
if (!Array.isArray(data)) return data;
|
|
250
|
+
const mapper = params.mapper;
|
|
251
|
+
if (mapper) {
|
|
252
|
+
return data.map((item) => {
|
|
253
|
+
ctx.setVariable("_item", item);
|
|
254
|
+
return ctx.evaluateExpression(mapper);
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
return data.map((item) => ({ value: item, processed: true }));
|
|
258
|
+
}
|
|
259
|
+
case "reduce": {
|
|
260
|
+
if (!Array.isArray(data)) return data;
|
|
261
|
+
const initial = params.initial ?? 0;
|
|
262
|
+
const reducer = params.reducer;
|
|
263
|
+
if (reducer) {
|
|
264
|
+
return data.reduce((acc, item) => {
|
|
265
|
+
ctx.setVariable("_acc", acc);
|
|
266
|
+
ctx.setVariable("_item", item);
|
|
267
|
+
return ctx.evaluateExpression(reducer);
|
|
268
|
+
}, initial);
|
|
269
|
+
}
|
|
270
|
+
return data.reduce((acc, item) => acc + (typeof item === "number" ? item : 0), 0);
|
|
271
|
+
}
|
|
272
|
+
case "sort": {
|
|
273
|
+
if (!Array.isArray(data)) return data;
|
|
274
|
+
const key = params.key;
|
|
275
|
+
const desc = params.descending;
|
|
276
|
+
const sorted = [...data].sort((a, b) => {
|
|
277
|
+
const aVal = key ? a[key] : a;
|
|
278
|
+
const bVal = key ? b[key] : b;
|
|
279
|
+
if (aVal < bVal) return desc ? 1 : -1;
|
|
280
|
+
if (aVal > bVal) return desc ? -1 : 1;
|
|
281
|
+
return 0;
|
|
282
|
+
});
|
|
283
|
+
return sorted;
|
|
284
|
+
}
|
|
285
|
+
case "sum":
|
|
286
|
+
return Array.isArray(data) ? data.reduce((sum, item) => sum + (typeof item === "number" ? item : 0), 0) : data;
|
|
287
|
+
case "count":
|
|
288
|
+
return Array.isArray(data) ? data.length : 1;
|
|
289
|
+
case "unique":
|
|
290
|
+
return Array.isArray(data) ? Array.from(new Set(data)) : data;
|
|
291
|
+
case "flatten":
|
|
292
|
+
return Array.isArray(data) ? data.flat() : data;
|
|
293
|
+
case "reverse":
|
|
294
|
+
return Array.isArray(data) ? [...data].reverse() : data;
|
|
295
|
+
case "take": {
|
|
296
|
+
if (!Array.isArray(data)) return data;
|
|
297
|
+
const count = Number(params.count) || TAKE_DEFAULT_COUNT;
|
|
298
|
+
return data.slice(0, count);
|
|
299
|
+
}
|
|
300
|
+
case "skip": {
|
|
301
|
+
if (!Array.isArray(data)) return data;
|
|
302
|
+
const count = Number(params.count) || 0;
|
|
303
|
+
return data.slice(count);
|
|
304
|
+
}
|
|
305
|
+
default:
|
|
306
|
+
chunkILRBGFVD_cjs.logger.warn("Unknown transformation", { operation: transform.operation });
|
|
307
|
+
return data;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// src/runtime/easing.ts
|
|
312
|
+
function applyEasing(t, easing) {
|
|
313
|
+
switch (easing) {
|
|
314
|
+
case "easeIn":
|
|
315
|
+
return t * t;
|
|
316
|
+
case "easeOut":
|
|
317
|
+
return t * (2 - t);
|
|
318
|
+
case "easeInOut":
|
|
319
|
+
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
|
|
320
|
+
case "easeInQuad":
|
|
321
|
+
return t * t;
|
|
322
|
+
case "easeOutQuad":
|
|
323
|
+
return t * (2 - t);
|
|
324
|
+
case "easeInOutQuad":
|
|
325
|
+
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
|
|
326
|
+
case "linear":
|
|
327
|
+
default:
|
|
328
|
+
return t;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// src/runtime/animation-system.ts
|
|
333
|
+
function updateAnimations(animations, setVariable, now) {
|
|
334
|
+
for (const [key, anim] of animations) {
|
|
335
|
+
const elapsed = now - anim.startTime;
|
|
336
|
+
let progress = Math.min(elapsed / anim.duration, 1);
|
|
337
|
+
progress = applyEasing(progress, anim.easing);
|
|
338
|
+
const currentValue = anim.from + (anim.to - anim.from) * progress;
|
|
339
|
+
if (anim.yoyo && progress >= 1) {
|
|
340
|
+
anim.startTime = now;
|
|
341
|
+
[anim.from, anim.to] = [anim.to, anim.from];
|
|
342
|
+
}
|
|
343
|
+
setVariable(`${anim.target}.${anim.property}`, currentValue);
|
|
344
|
+
if (progress >= 1 && !anim.loop && !anim.yoyo) {
|
|
345
|
+
animations.delete(key);
|
|
346
|
+
} else if (progress >= 1 && anim.loop) {
|
|
347
|
+
anim.startTime = now;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
function broadcast(wss, type, payload) {
|
|
352
|
+
if (!wss) return;
|
|
353
|
+
const message = JSON.stringify({ type, payload });
|
|
354
|
+
wss.clients.forEach((client) => {
|
|
355
|
+
if (client.readyState === ws.WebSocket.OPEN) {
|
|
356
|
+
client.send(message);
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
function handleTimeControl(timeManager, command, value) {
|
|
361
|
+
if (!timeManager) return;
|
|
362
|
+
switch (command) {
|
|
363
|
+
case "play":
|
|
364
|
+
timeManager.play();
|
|
365
|
+
break;
|
|
366
|
+
case "pause":
|
|
367
|
+
timeManager.pause();
|
|
368
|
+
break;
|
|
369
|
+
case "toggle":
|
|
370
|
+
timeManager.togglePause();
|
|
371
|
+
break;
|
|
372
|
+
case "setSpeed":
|
|
373
|
+
if (typeof value === "number") {
|
|
374
|
+
timeManager.setTimeScale(value);
|
|
375
|
+
}
|
|
376
|
+
break;
|
|
377
|
+
case "setDate":
|
|
378
|
+
if (value) {
|
|
379
|
+
timeManager.setDate(new Date(value));
|
|
380
|
+
}
|
|
381
|
+
break;
|
|
382
|
+
case "syncRealTime":
|
|
383
|
+
timeManager.setDate(/* @__PURE__ */ new Date());
|
|
384
|
+
timeManager.setTimeScale(1);
|
|
385
|
+
timeManager.play();
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// src/runtime/holo-statement-executor.ts
|
|
391
|
+
var MAX_ITERATIONS = 1e3;
|
|
392
|
+
async function executeHoloProgram(statements, scopeOverride, ctx) {
|
|
393
|
+
const results = [];
|
|
394
|
+
ctx.telemetry.setGauge("execution_depth", ctx.telemetry.executionDepth());
|
|
395
|
+
for (const stmt of statements) {
|
|
396
|
+
ctx.telemetry.incrementCounter("statements_executed", 1, { type: stmt.type });
|
|
397
|
+
const res = await ctx.telemetry.measureLatency(
|
|
398
|
+
`execute_stmt_${stmt.type}`,
|
|
399
|
+
() => executeHoloStatement(stmt, scopeOverride, ctx)
|
|
400
|
+
);
|
|
401
|
+
results.push(res);
|
|
402
|
+
const last = results[results.length - 1];
|
|
403
|
+
if (last.success && last.output !== void 0 && stmt.type === "ReturnStatement") {
|
|
404
|
+
break;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
return results;
|
|
408
|
+
}
|
|
409
|
+
async function executeHoloStatement(stmt, scopeOverride, ctx) {
|
|
410
|
+
try {
|
|
411
|
+
switch (stmt.type) {
|
|
412
|
+
case "Assignment": {
|
|
413
|
+
const value = await ctx.evaluateHoloExpression(stmt.value, scopeOverride);
|
|
414
|
+
let finalValue = value;
|
|
415
|
+
if (stmt.operator !== "=") {
|
|
416
|
+
const current = ctx.getVariable(stmt.target, scopeOverride);
|
|
417
|
+
if (stmt.operator === "+=")
|
|
418
|
+
finalValue = Number(current) + Number(value);
|
|
419
|
+
else if (stmt.operator === "-=")
|
|
420
|
+
finalValue = Number(current) - Number(value);
|
|
421
|
+
else if (stmt.operator === "*=")
|
|
422
|
+
finalValue = Number(current) * Number(value);
|
|
423
|
+
else if (stmt.operator === "/=")
|
|
424
|
+
finalValue = Number(current) / Number(value);
|
|
425
|
+
}
|
|
426
|
+
ctx.setVariable(stmt.target, finalValue, scopeOverride);
|
|
427
|
+
return { success: true };
|
|
428
|
+
}
|
|
429
|
+
case "IfStatement": {
|
|
430
|
+
const condition = await ctx.evaluateHoloExpression(stmt.condition, scopeOverride);
|
|
431
|
+
if (condition) {
|
|
432
|
+
await executeHoloProgram(stmt.consequent, scopeOverride, ctx);
|
|
433
|
+
} else if (stmt.alternate) {
|
|
434
|
+
await executeHoloProgram(stmt.alternate, scopeOverride, ctx);
|
|
435
|
+
}
|
|
436
|
+
return { success: true };
|
|
437
|
+
}
|
|
438
|
+
case "WhileStatement": {
|
|
439
|
+
let iter = 0;
|
|
440
|
+
while (await ctx.evaluateHoloExpression(stmt.condition, scopeOverride)) {
|
|
441
|
+
if (iter++ > MAX_ITERATIONS) return { success: false, error: "Infinite loop" };
|
|
442
|
+
await executeHoloProgram(stmt.body, scopeOverride, ctx);
|
|
443
|
+
}
|
|
444
|
+
return { success: true };
|
|
445
|
+
}
|
|
446
|
+
case "ClassicForStatement": {
|
|
447
|
+
if (stmt.init) await executeHoloStatement(stmt.init, scopeOverride, ctx);
|
|
448
|
+
let iter = 0;
|
|
449
|
+
while (!stmt.test || await ctx.evaluateHoloExpression(stmt.test, scopeOverride)) {
|
|
450
|
+
if (iter++ > MAX_ITERATIONS) return { success: false, error: "Infinite loop" };
|
|
451
|
+
await executeHoloProgram(stmt.body, scopeOverride, ctx);
|
|
452
|
+
if (stmt.update) await executeHoloStatement(stmt.update, scopeOverride, ctx);
|
|
453
|
+
}
|
|
454
|
+
return { success: true };
|
|
455
|
+
}
|
|
456
|
+
case "VariableDeclaration": {
|
|
457
|
+
const value = stmt.value ? await ctx.evaluateHoloExpression(stmt.value, scopeOverride) : void 0;
|
|
458
|
+
const scope = scopeOverride || ctx.currentScope;
|
|
459
|
+
scope.variables.set(stmt.name, value);
|
|
460
|
+
return { success: true };
|
|
461
|
+
}
|
|
462
|
+
case "EmitStatement": {
|
|
463
|
+
const data = stmt.data ? await ctx.evaluateHoloExpression(stmt.data, scopeOverride) : void 0;
|
|
464
|
+
ctx.emit(stmt.event, data);
|
|
465
|
+
return { success: true };
|
|
466
|
+
}
|
|
467
|
+
case "AwaitStatement": {
|
|
468
|
+
const value = await ctx.evaluateHoloExpression(stmt.expression, scopeOverride);
|
|
469
|
+
if (value instanceof Promise) await value;
|
|
470
|
+
return { success: true };
|
|
471
|
+
}
|
|
472
|
+
case "ReturnStatement": {
|
|
473
|
+
const value = stmt.value ? await ctx.evaluateHoloExpression(stmt.value, scopeOverride) : null;
|
|
474
|
+
return { success: true, output: value };
|
|
475
|
+
}
|
|
476
|
+
case "ExpressionStatement": {
|
|
477
|
+
const val = await ctx.evaluateHoloExpression(stmt.expression, scopeOverride);
|
|
478
|
+
return { success: true, output: val };
|
|
479
|
+
}
|
|
480
|
+
default:
|
|
481
|
+
return {
|
|
482
|
+
success: false,
|
|
483
|
+
error: `Unknown stmt type: ${stmt.type}`
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
} catch (err) {
|
|
487
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
488
|
+
console.error(`[EXEC_ERROR] Statement ${stmt.type} failed:`, errMsg);
|
|
489
|
+
return { success: false, error: errMsg };
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// src/runtime/debug-executor.ts
|
|
494
|
+
var DEBUG_HOLOGRAM = {
|
|
495
|
+
shape: "pyramid",
|
|
496
|
+
color: "#ff1493",
|
|
497
|
+
size: 0.8,
|
|
498
|
+
glow: true,
|
|
499
|
+
interactive: true
|
|
500
|
+
};
|
|
501
|
+
async function executeDebug(node, ctx) {
|
|
502
|
+
const debugInfo = {
|
|
503
|
+
variables: Object.fromEntries(ctx.scopeVariables),
|
|
504
|
+
contextVariables: Object.fromEntries(ctx.contextVariables),
|
|
505
|
+
functions: Array.from(ctx.functions.keys()),
|
|
506
|
+
connections: ctx.connections.length,
|
|
507
|
+
callStack: [...ctx.callStack],
|
|
508
|
+
uiElements: Array.from(ctx.uiElements.keys()),
|
|
509
|
+
animations: Array.from(ctx.animations.keys()),
|
|
510
|
+
executionHistory: ctx.executionHistory.slice(-10)
|
|
511
|
+
};
|
|
512
|
+
const debugOrb = { ...DEBUG_HOLOGRAM };
|
|
513
|
+
ctx.setHologramState(`debug_${node.target || "program"}`, debugOrb);
|
|
514
|
+
ctx.logInfo("Debug info", debugInfo);
|
|
515
|
+
return {
|
|
516
|
+
success: true,
|
|
517
|
+
output: debugInfo,
|
|
518
|
+
hologram: debugOrb
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// src/runtime/io-node-executors.ts
|
|
523
|
+
async function executeServerNode(node, ctx) {
|
|
524
|
+
if (ctx.isPublicMode) {
|
|
525
|
+
return {
|
|
526
|
+
success: false,
|
|
527
|
+
error: "SecurityViolation: Server creation blocked in public mode.",
|
|
528
|
+
executionTime: 0
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
ctx.logInfo(`Starting server on port ${node.port}`);
|
|
532
|
+
return {
|
|
533
|
+
success: true,
|
|
534
|
+
output: `Server listening on port ${node.port}`,
|
|
535
|
+
hologram: node.hologram,
|
|
536
|
+
executionTime: 0
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
async function executeDatabaseNode(node, ctx) {
|
|
540
|
+
if (ctx.isPublicMode) {
|
|
541
|
+
return {
|
|
542
|
+
success: false,
|
|
543
|
+
error: "SecurityViolation: DB access blocked in public mode.",
|
|
544
|
+
executionTime: 0
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
ctx.logInfo(`Executing Query: ${node.query}`);
|
|
548
|
+
return {
|
|
549
|
+
success: true,
|
|
550
|
+
output: `Query executed: ${node.query}`,
|
|
551
|
+
hologram: node.hologram,
|
|
552
|
+
executionTime: 0
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
async function executeFetchNode(node, ctx) {
|
|
556
|
+
if (ctx.isPublicMode) {
|
|
557
|
+
return {
|
|
558
|
+
success: false,
|
|
559
|
+
error: "SecurityViolation: External fetch blocked in public mode.",
|
|
560
|
+
executionTime: 0
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
ctx.logInfo(`Fetching: ${node.url}`);
|
|
564
|
+
return {
|
|
565
|
+
success: true,
|
|
566
|
+
output: `Fetched data from ${node.url}`,
|
|
567
|
+
hologram: node.hologram,
|
|
568
|
+
executionTime: 0
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// src/runtime/declaration-executors.ts
|
|
573
|
+
async function executeStateDeclaration(node, ctx) {
|
|
574
|
+
const stateDirective = node.directives?.find((d) => d.type === "state");
|
|
575
|
+
if (stateDirective) {
|
|
576
|
+
ctx.updateState(stateDirective.body);
|
|
577
|
+
}
|
|
578
|
+
return { success: true, output: "State updated" };
|
|
579
|
+
}
|
|
580
|
+
async function executeMemoryDefinition(node, ctx) {
|
|
581
|
+
const startTime = Date.now();
|
|
582
|
+
const config = {};
|
|
583
|
+
for (const [key, val] of Object.entries(node.properties || {})) {
|
|
584
|
+
if (typeof val === "string") {
|
|
585
|
+
config[key] = ctx.evaluateExpression(val);
|
|
586
|
+
} else {
|
|
587
|
+
config[key] = val;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
return {
|
|
591
|
+
success: true,
|
|
592
|
+
output: {
|
|
593
|
+
type: node.type,
|
|
594
|
+
config
|
|
595
|
+
},
|
|
596
|
+
executionTime: Date.now() - startTime
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// src/runtime/orb-executor.ts
|
|
601
|
+
function isOrbData(v) {
|
|
602
|
+
return v !== null && typeof v === "object" && v.__type === "orb";
|
|
603
|
+
}
|
|
604
|
+
var DEFAULT_HOLOGRAM_COLOR = "#ffffff";
|
|
605
|
+
var DEFAULT_HOLOGRAM_SIZE = 1;
|
|
606
|
+
var DEFAULT_HOLOGRAM_SHAPE = "sphere";
|
|
607
|
+
var CREATION_PUFF_COLOR = "#00ffff";
|
|
608
|
+
var CREATION_PUFF_COUNT = 20;
|
|
609
|
+
function normalizePosition(position) {
|
|
610
|
+
if (!position) return [0, 0, 0];
|
|
611
|
+
if (Array.isArray(position)) {
|
|
612
|
+
return [
|
|
613
|
+
Number(position[0]) || 0,
|
|
614
|
+
Number(position[1]) || 0,
|
|
615
|
+
Number(position[2]) || 0
|
|
616
|
+
];
|
|
617
|
+
}
|
|
618
|
+
const p = position;
|
|
619
|
+
return [Number(p[0]) || 0, Number(p[1]) || 0, Number(p[2]) || 0];
|
|
620
|
+
}
|
|
621
|
+
async function executeOrb(node, ctx) {
|
|
622
|
+
const scale = ctx.getCurrentScale() || 1;
|
|
623
|
+
const existingRaw = ctx.getVariable(node.name);
|
|
624
|
+
const existingOrb = isOrbData(existingRaw) ? existingRaw : void 0;
|
|
625
|
+
const isUpdate = !!existingOrb;
|
|
626
|
+
const pos = normalizePosition(node.position);
|
|
627
|
+
const adjustedPos = [pos[0] * scale, pos[1] * scale, pos[2] * scale];
|
|
628
|
+
if (node.position) {
|
|
629
|
+
ctx.setSpatialPosition(node.name, adjustedPos);
|
|
630
|
+
}
|
|
631
|
+
const evaluatedProperties = {};
|
|
632
|
+
if (Array.isArray(node.properties)) {
|
|
633
|
+
for (const prop of node.properties) {
|
|
634
|
+
const val = prop.value;
|
|
635
|
+
evaluatedProperties[prop.key] = typeof val === "string" ? ctx.evaluateExpression(val) : val;
|
|
636
|
+
}
|
|
637
|
+
} else if (node.properties) {
|
|
638
|
+
for (const [key, val] of Object.entries(node.properties)) {
|
|
639
|
+
evaluatedProperties[key] = typeof val === "string" ? ctx.evaluateExpression(val) : val;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
const orbNodeExt = node;
|
|
643
|
+
if (orbNodeExt.template) {
|
|
644
|
+
const tpl = ctx.getTemplate(orbNodeExt.template);
|
|
645
|
+
if (tpl) {
|
|
646
|
+
if (tpl.properties) {
|
|
647
|
+
for (const [key, val] of Object.entries(tpl.properties)) {
|
|
648
|
+
if (evaluatedProperties[key] === void 0) {
|
|
649
|
+
evaluatedProperties[key] = typeof val === "string" ? ctx.evaluateExpression(val) : val;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
if (tpl.directives) {
|
|
654
|
+
const existingDirectives = node.directives || [];
|
|
655
|
+
node.directives = [...tpl.directives, ...existingDirectives];
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
const hologram = node.hologram ? {
|
|
660
|
+
...node.hologram,
|
|
661
|
+
size: (node.hologram.size || Number(evaluatedProperties.size) || Number(evaluatedProperties.scale) || DEFAULT_HOLOGRAM_SIZE) * scale
|
|
662
|
+
} : {
|
|
663
|
+
color: evaluatedProperties.color || DEFAULT_HOLOGRAM_COLOR,
|
|
664
|
+
size: (Number(evaluatedProperties.size) || Number(evaluatedProperties.scale) || DEFAULT_HOLOGRAM_SIZE) * scale,
|
|
665
|
+
shape: evaluatedProperties.geometry || DEFAULT_HOLOGRAM_SHAPE,
|
|
666
|
+
glow: !!evaluatedProperties.glow,
|
|
667
|
+
interactive: !!evaluatedProperties.interactive
|
|
668
|
+
};
|
|
669
|
+
if (isUpdate && node.template) {
|
|
670
|
+
const tpl = ctx.getTemplate(node.template);
|
|
671
|
+
const oldTpl = existingOrb?._templateRef;
|
|
672
|
+
if (tpl && oldTpl && tpl.version !== void 0 && oldTpl.version !== void 0) {
|
|
673
|
+
if (Number(tpl.version) > Number(oldTpl.version)) {
|
|
674
|
+
chunkILRBGFVD_cjs.logger.info(
|
|
675
|
+
`Template version increase detected for ${node.name}: ${oldTpl.version} -> ${tpl.version}`
|
|
676
|
+
);
|
|
677
|
+
const migrations = tpl.migrations || [];
|
|
678
|
+
const migration = migrations.find((m) => m.fromVersion === Number(oldTpl.version));
|
|
679
|
+
if (migration) {
|
|
680
|
+
chunkILRBGFVD_cjs.logger.info(`Executing migration from version ${oldTpl.version} for ${node.name}`);
|
|
681
|
+
await ctx.executeMigrationBlock(
|
|
682
|
+
existingOrb,
|
|
683
|
+
migration
|
|
684
|
+
);
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
const orbData = isUpdate ? existingOrb : {
|
|
690
|
+
__type: "orb",
|
|
691
|
+
id: node.name,
|
|
692
|
+
name: node.name,
|
|
693
|
+
created: Date.now(),
|
|
694
|
+
// Methods bound to this orb — fire-and-forget through builtins registry
|
|
695
|
+
show: () => ctx.getBuiltinFunction("show")([node.name]),
|
|
696
|
+
hide: () => ctx.getBuiltinFunction("hide")([node.name]),
|
|
697
|
+
pulse: (opts) => ctx.getBuiltinFunction("pulse")([node.name, opts])
|
|
698
|
+
};
|
|
699
|
+
if (isUpdate) {
|
|
700
|
+
orbData.properties = {
|
|
701
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
702
|
+
...orbData.properties,
|
|
703
|
+
...evaluatedProperties
|
|
704
|
+
};
|
|
705
|
+
} else {
|
|
706
|
+
orbData.properties = evaluatedProperties;
|
|
707
|
+
}
|
|
708
|
+
orbData.directives = node.directives || [];
|
|
709
|
+
orbData.position = adjustedPos;
|
|
710
|
+
orbData.hologram = hologram;
|
|
711
|
+
orbData._templateRef = node.template ? ctx.getTemplate(node.template) : void 0;
|
|
712
|
+
if (!isUpdate) {
|
|
713
|
+
ctx.setVariable(node.name, orbData);
|
|
714
|
+
}
|
|
715
|
+
if (hologram) {
|
|
716
|
+
ctx.setHologramState(node.name, hologram);
|
|
717
|
+
}
|
|
718
|
+
if (node.directives) {
|
|
719
|
+
ctx.applyDirectives(orbData);
|
|
720
|
+
}
|
|
721
|
+
if (!isUpdate) {
|
|
722
|
+
ctx.createParticleEffect(`${node.name}_creation`, adjustedPos, CREATION_PUFF_COLOR, CREATION_PUFF_COUNT);
|
|
723
|
+
}
|
|
724
|
+
if (ctx.isAgent(node)) {
|
|
725
|
+
if (!isUpdate || !ctx.getAgentRuntime(node.name)) {
|
|
726
|
+
const agentRuntime = ctx.acquireAgentRuntime();
|
|
727
|
+
agentRuntime.reset(node, ctx.parentRuntime);
|
|
728
|
+
ctx.setAgentRuntime(node.name, agentRuntime);
|
|
729
|
+
orbData.state = agentRuntime.getState();
|
|
730
|
+
node.directives?.filter((d) => d.type === "method").forEach((m) => {
|
|
731
|
+
orbData[m.name] = (...args) => agentRuntime.executeAction(m.name, args);
|
|
732
|
+
});
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
chunkILRBGFVD_cjs.logger.info(isUpdate ? "Orb updated" : "Orb created", {
|
|
736
|
+
name: node.name,
|
|
737
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
738
|
+
properties: Object.keys(orbData.properties),
|
|
739
|
+
scale
|
|
740
|
+
});
|
|
741
|
+
ctx.broadcast(isUpdate ? "orb_updated" : "orb_created", {
|
|
742
|
+
orb: {
|
|
743
|
+
id: node.name,
|
|
744
|
+
name: node.name,
|
|
745
|
+
position: adjustedPos,
|
|
746
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
747
|
+
properties: orbData.properties,
|
|
748
|
+
hologram,
|
|
749
|
+
traits: node.directives?.filter((d) => d.type === "trait").map((d) => d.name) || []
|
|
750
|
+
}
|
|
751
|
+
});
|
|
752
|
+
return {
|
|
753
|
+
success: true,
|
|
754
|
+
output: orbData,
|
|
755
|
+
hologram,
|
|
756
|
+
spatialPosition: adjustedPos
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
// src/runtime/narrative-executors.ts
|
|
761
|
+
async function executeNarrative(node, ctx) {
|
|
762
|
+
const startTime = Date.now();
|
|
763
|
+
chunkILRBGFVD_cjs.logger.info(`[Narrative] Initializing narrative: ${node.id}`);
|
|
764
|
+
for (const quest of node.quests) {
|
|
765
|
+
ctx.quests.set(quest.id, quest);
|
|
766
|
+
}
|
|
767
|
+
if (node.startNode) {
|
|
768
|
+
chunkILRBGFVD_cjs.logger.info(`[Narrative] Auto-starting at node: ${node.startNode}`);
|
|
769
|
+
}
|
|
770
|
+
return {
|
|
771
|
+
success: true,
|
|
772
|
+
output: `Narrative ${node.id} initialized with ${node.quests.length} quests`,
|
|
773
|
+
executionTime: Date.now() - startTime
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
async function executeQuest(node, ctx) {
|
|
777
|
+
const startTime = Date.now();
|
|
778
|
+
chunkILRBGFVD_cjs.logger.info(`[Narrative] Starting quest: ${node.title}`, { questId: node.id });
|
|
779
|
+
ctx.setActiveQuestId(node.id);
|
|
780
|
+
ctx.quests.set(node.id, node);
|
|
781
|
+
return {
|
|
782
|
+
success: true,
|
|
783
|
+
output: `Quest ${node.id} started`,
|
|
784
|
+
executionTime: Date.now() - startTime
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
async function executeDialogue(node, ctx) {
|
|
788
|
+
const startTime = Date.now();
|
|
789
|
+
chunkILRBGFVD_cjs.logger.info(`[Narrative] Dialogue: ${node.speaker} says "${node.text}"`);
|
|
790
|
+
ctx.setDialogueState({
|
|
791
|
+
currentNodeId: node.id,
|
|
792
|
+
speaker: node.speaker
|
|
793
|
+
});
|
|
794
|
+
return {
|
|
795
|
+
success: true,
|
|
796
|
+
output: `Dialogue node ${node.id} executed`,
|
|
797
|
+
executionTime: Date.now() - startTime
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
// src/runtime/graph-executors.ts
|
|
802
|
+
var FUNCTION_DEFAULT_HOLOGRAM = {
|
|
803
|
+
shape: "cube",
|
|
804
|
+
color: "#ff6b35",
|
|
805
|
+
size: 1.5,
|
|
806
|
+
glow: true,
|
|
807
|
+
interactive: true
|
|
808
|
+
};
|
|
809
|
+
var CONNECTION_HOLOGRAM_SIZE = 0.1;
|
|
810
|
+
var GATE_HOLOGRAM_SIZE = 1;
|
|
811
|
+
async function executeFunction(node, ctx) {
|
|
812
|
+
ctx.functions.set(node.name, node);
|
|
813
|
+
const hologram = {
|
|
814
|
+
...FUNCTION_DEFAULT_HOLOGRAM,
|
|
815
|
+
...node.hologram
|
|
816
|
+
};
|
|
817
|
+
ctx.hologramState.set(node.name, hologram);
|
|
818
|
+
chunkILRBGFVD_cjs.logger.info("Function defined", {
|
|
819
|
+
name: node.name,
|
|
820
|
+
params: node.parameters.map((p) => p.name)
|
|
821
|
+
});
|
|
822
|
+
return {
|
|
823
|
+
success: true,
|
|
824
|
+
output: `Function '${node.name}' defined with ${node.parameters.length} parameter(s)`,
|
|
825
|
+
hologram,
|
|
826
|
+
spatialPosition: node.position
|
|
827
|
+
};
|
|
828
|
+
}
|
|
829
|
+
async function executeConnection(node, ctx) {
|
|
830
|
+
ctx.connections.push(node);
|
|
831
|
+
const fromPos = ctx.spatialMemory.get(node.from);
|
|
832
|
+
const toPos = ctx.spatialMemory.get(node.to);
|
|
833
|
+
if (fromPos && toPos) {
|
|
834
|
+
ctx.createConnectionStream(node.from, node.to, fromPos, toPos, node.dataType);
|
|
835
|
+
}
|
|
836
|
+
if (node.bidirectional) {
|
|
837
|
+
ctx.on(`${node.from}.changed`, async (data) => {
|
|
838
|
+
ctx.setVariable(node.to, data);
|
|
839
|
+
ctx.emit(`${node.to}.changed`, data);
|
|
840
|
+
});
|
|
841
|
+
ctx.on(`${node.to}.changed`, async (data) => {
|
|
842
|
+
ctx.setVariable(node.from, data);
|
|
843
|
+
ctx.emit(`${node.from}.changed`, data);
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
chunkILRBGFVD_cjs.logger.info("Connection created", { from: node.from, to: node.to, dataType: node.dataType });
|
|
847
|
+
return {
|
|
848
|
+
success: true,
|
|
849
|
+
output: `Connected '${node.from}' to '${node.to}' (${node.dataType})`,
|
|
850
|
+
hologram: {
|
|
851
|
+
shape: "cylinder",
|
|
852
|
+
color: ctx.getDataTypeColor(node.dataType),
|
|
853
|
+
size: CONNECTION_HOLOGRAM_SIZE,
|
|
854
|
+
glow: true,
|
|
855
|
+
interactive: false
|
|
856
|
+
}
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
async function executeGate(node, ctx) {
|
|
860
|
+
try {
|
|
861
|
+
const condition = ctx.evaluateCondition(node.condition);
|
|
862
|
+
const path = condition ? node.truePath : node.falsePath;
|
|
863
|
+
chunkILRBGFVD_cjs.logger.info("Gate evaluation", { condition: node.condition, result: condition });
|
|
864
|
+
if (path.length > 0) {
|
|
865
|
+
const subResults = await ctx.executeProgram(path, ctx.callStackDepth() + 1);
|
|
866
|
+
const lastResult = subResults[subResults.length - 1];
|
|
867
|
+
const selectedPathContainsReturn = path.some((n) => n.type === "return");
|
|
868
|
+
if (selectedPathContainsReturn && lastResult?.success && lastResult.output !== void 0) {
|
|
869
|
+
return lastResult;
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
return {
|
|
873
|
+
success: true,
|
|
874
|
+
output: `Gate: took ${condition ? "true" : "false"} path`,
|
|
875
|
+
hologram: {
|
|
876
|
+
shape: "pyramid",
|
|
877
|
+
color: condition ? "#00ff00" : "#ff0000",
|
|
878
|
+
size: GATE_HOLOGRAM_SIZE,
|
|
879
|
+
glow: true,
|
|
880
|
+
interactive: true
|
|
881
|
+
}
|
|
882
|
+
};
|
|
883
|
+
} catch (error) {
|
|
884
|
+
return {
|
|
885
|
+
success: false,
|
|
886
|
+
error: `Gate execution failed: ${error}`
|
|
887
|
+
};
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
async function executeStream(node, ctx) {
|
|
891
|
+
let data = ctx.getVariable(node.source);
|
|
892
|
+
chunkILRBGFVD_cjs.logger.info("Stream processing", {
|
|
893
|
+
name: node.name,
|
|
894
|
+
source: node.source,
|
|
895
|
+
transforms: node.transformations.length
|
|
896
|
+
});
|
|
897
|
+
for (const transform of node.transformations) {
|
|
898
|
+
data = await ctx.applyTransformation(data, transform);
|
|
899
|
+
}
|
|
900
|
+
ctx.setVariable(`${node.name}_result`, data);
|
|
901
|
+
ctx.createFlowingStream(node.name, node.position || [0, 0, 0], data);
|
|
902
|
+
return {
|
|
903
|
+
success: true,
|
|
904
|
+
output: `Stream '${node.name}' processed ${Array.isArray(data) ? data.length : 1} item(s)`,
|
|
905
|
+
hologram: node.hologram,
|
|
906
|
+
spatialPosition: node.position
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
// src/runtime/simple-executors.ts
|
|
911
|
+
async function executeStateMachine(node, ctx) {
|
|
912
|
+
ctx.stateMachines.set(node.name, node);
|
|
913
|
+
return {
|
|
914
|
+
success: true,
|
|
915
|
+
output: { registered: node.name }
|
|
916
|
+
};
|
|
917
|
+
}
|
|
918
|
+
async function executeExpressionStatement(node, ctx) {
|
|
919
|
+
const value = ctx.evaluateExpression(node.expression);
|
|
920
|
+
return {
|
|
921
|
+
success: true,
|
|
922
|
+
output: value
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
async function executeCall(node, ctx) {
|
|
926
|
+
const funcName = node.target || "";
|
|
927
|
+
const args = node.args || [];
|
|
928
|
+
return ctx.callFunction(funcName, args);
|
|
929
|
+
}
|
|
930
|
+
async function executeEnvironment(node, ctx) {
|
|
931
|
+
ctx.setEnvironment({
|
|
932
|
+
...ctx.getEnvironment(),
|
|
933
|
+
...node.settings
|
|
934
|
+
});
|
|
935
|
+
return { success: true, output: "Environment updated" };
|
|
936
|
+
}
|
|
937
|
+
async function executeHoloTemplate(node, ctx) {
|
|
938
|
+
ctx.templates.set(node.name, node);
|
|
939
|
+
return { success: true, output: `Template ${node.name} registered` };
|
|
940
|
+
}
|
|
941
|
+
var NEXUS_HOLOGRAM = {
|
|
942
|
+
shape: "sphere",
|
|
943
|
+
color: "#9b59b6",
|
|
944
|
+
size: 3,
|
|
945
|
+
glow: true,
|
|
946
|
+
interactive: true
|
|
947
|
+
};
|
|
948
|
+
var STRUCTURE_HOLOGRAM = {
|
|
949
|
+
shape: "cube",
|
|
950
|
+
color: "#e74c3c",
|
|
951
|
+
size: 4,
|
|
952
|
+
glow: true,
|
|
953
|
+
interactive: true
|
|
954
|
+
};
|
|
955
|
+
async function executeStructure(node) {
|
|
956
|
+
const hologram = node.hologram || (node.type === "nexus" ? NEXUS_HOLOGRAM : STRUCTURE_HOLOGRAM);
|
|
957
|
+
return {
|
|
958
|
+
success: true,
|
|
959
|
+
output: { type: node.type, created: true },
|
|
960
|
+
hologram,
|
|
961
|
+
spatialPosition: node.position
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
async function executeAssignment(node, ctx) {
|
|
965
|
+
const value = ctx.evaluateExpression(String(node.value));
|
|
966
|
+
ctx.setVariable(node.name, value);
|
|
967
|
+
return {
|
|
968
|
+
success: true,
|
|
969
|
+
output: { assigned: node.name, value }
|
|
970
|
+
};
|
|
971
|
+
}
|
|
972
|
+
async function executeReturn(node, ctx) {
|
|
973
|
+
const expr = String(node.value || node.expression || "");
|
|
974
|
+
const value = ctx.evaluateExpression(expr);
|
|
975
|
+
return {
|
|
976
|
+
success: true,
|
|
977
|
+
output: value
|
|
978
|
+
};
|
|
979
|
+
}
|
|
980
|
+
async function executeScale(node, ctx) {
|
|
981
|
+
const parent = ctx.getScale();
|
|
982
|
+
const newMultiplier = parent.multiplier * node.multiplier;
|
|
983
|
+
ctx.setScale(newMultiplier, node.magnitude);
|
|
984
|
+
chunkILRBGFVD_cjs.logger.info("Scale context entering", {
|
|
985
|
+
magnitude: node.magnitude,
|
|
986
|
+
multiplier: newMultiplier
|
|
987
|
+
});
|
|
988
|
+
ctx.emit("scale:change", { multiplier: newMultiplier, magnitude: node.magnitude });
|
|
989
|
+
const results = await ctx.executeProgram(node.body, ctx.executionStackDepth());
|
|
990
|
+
ctx.setScale(parent.multiplier, parent.magnitude);
|
|
991
|
+
ctx.emit("scale:change", { multiplier: parent.multiplier });
|
|
992
|
+
return {
|
|
993
|
+
success: results.every((r) => r.success),
|
|
994
|
+
output: `Executed scale block: ${node.magnitude}`
|
|
995
|
+
};
|
|
996
|
+
}
|
|
997
|
+
async function executeComposition(node, ctx) {
|
|
998
|
+
if (node.body) {
|
|
999
|
+
const systemResults = await ctx.executeProgram(node.body.systems, ctx.executionStackDepth());
|
|
1000
|
+
const configResults = await ctx.executeProgram(node.body.configs, ctx.executionStackDepth());
|
|
1001
|
+
const childrenResults = await ctx.executeProgram(node.body.children, ctx.executionStackDepth());
|
|
1002
|
+
const allResults = [...systemResults, ...configResults, ...childrenResults];
|
|
1003
|
+
return {
|
|
1004
|
+
success: allResults.every((r) => r.success),
|
|
1005
|
+
output: `Composition ${node.name} executed with specialized blocks`
|
|
1006
|
+
};
|
|
1007
|
+
}
|
|
1008
|
+
return {
|
|
1009
|
+
success: (await ctx.executeProgram(node.children, ctx.executionStackDepth())).every(
|
|
1010
|
+
(r) => r.success
|
|
1011
|
+
),
|
|
1012
|
+
output: `Composition ${node.name} executed`
|
|
1013
|
+
};
|
|
1014
|
+
}
|
|
1015
|
+
async function executeFocus(node, ctx) {
|
|
1016
|
+
ctx.focusHistory.push(node.target);
|
|
1017
|
+
const results = await ctx.executeProgram(node.body, ctx.executionStackDepth());
|
|
1018
|
+
return {
|
|
1019
|
+
success: results.every((r) => r.success),
|
|
1020
|
+
output: `Focused on ${node.target}`
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
// src/runtime/info-executors.ts
|
|
1025
|
+
var VISUALIZE_HOLOGRAM = {
|
|
1026
|
+
shape: "cylinder",
|
|
1027
|
+
color: "#32cd32",
|
|
1028
|
+
size: 1.5,
|
|
1029
|
+
glow: true,
|
|
1030
|
+
interactive: true
|
|
1031
|
+
};
|
|
1032
|
+
async function executeVisualize(node, ctx) {
|
|
1033
|
+
const target = node.target || "";
|
|
1034
|
+
const data = ctx.getVariable(target);
|
|
1035
|
+
if (data === void 0) {
|
|
1036
|
+
return {
|
|
1037
|
+
success: false,
|
|
1038
|
+
error: `No data found for '${target}'`
|
|
1039
|
+
};
|
|
1040
|
+
}
|
|
1041
|
+
ctx.createDataVisualization(target, data, node.position || [0, 0, 0]);
|
|
1042
|
+
return {
|
|
1043
|
+
success: true,
|
|
1044
|
+
output: { visualizing: target, data },
|
|
1045
|
+
hologram: VISUALIZE_HOLOGRAM
|
|
1046
|
+
};
|
|
1047
|
+
}
|
|
1048
|
+
async function executeUIElement(node, ctx) {
|
|
1049
|
+
const element = {
|
|
1050
|
+
type: node.elementType,
|
|
1051
|
+
name: node.name,
|
|
1052
|
+
properties: { ...node.properties },
|
|
1053
|
+
visible: true,
|
|
1054
|
+
enabled: true
|
|
1055
|
+
};
|
|
1056
|
+
if (node.elementType === "textinput") {
|
|
1057
|
+
element.value = node.properties.value || "";
|
|
1058
|
+
} else if (node.elementType === "slider") {
|
|
1059
|
+
element.value = node.properties.value || node.properties.min || 0;
|
|
1060
|
+
} else if (node.elementType === "toggle") {
|
|
1061
|
+
element.value = node.properties.checked || false;
|
|
1062
|
+
}
|
|
1063
|
+
ctx.uiElements.set(node.name, element);
|
|
1064
|
+
if (node.events) {
|
|
1065
|
+
for (const [eventName, handlerName] of Object.entries(node.events)) {
|
|
1066
|
+
ctx.on(`${node.name}.${eventName}`, async () => {
|
|
1067
|
+
await ctx.callFunction(handlerName);
|
|
1068
|
+
});
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
chunkILRBGFVD_cjs.logger.info("UI element created", { type: node.elementType, name: node.name });
|
|
1072
|
+
return {
|
|
1073
|
+
success: true,
|
|
1074
|
+
output: element
|
|
1075
|
+
};
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
// src/runtime/holo-value.ts
|
|
1079
|
+
function resolveHoloValue(value) {
|
|
1080
|
+
if (value === null) return null;
|
|
1081
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
1082
|
+
return value;
|
|
1083
|
+
}
|
|
1084
|
+
if (Array.isArray(value)) {
|
|
1085
|
+
return value.map((e) => resolveHoloValue(e));
|
|
1086
|
+
}
|
|
1087
|
+
if (value.__bind) {
|
|
1088
|
+
return value;
|
|
1089
|
+
}
|
|
1090
|
+
const obj = {};
|
|
1091
|
+
for (const k in value) {
|
|
1092
|
+
obj[k] = resolveHoloValue(value[k]);
|
|
1093
|
+
}
|
|
1094
|
+
return obj;
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
// src/runtime/holo-composition-executor.ts
|
|
1098
|
+
async function executeHoloComposition(node, ctx) {
|
|
1099
|
+
for (const template of node.templates) {
|
|
1100
|
+
await executeHoloTemplate(
|
|
1101
|
+
template,
|
|
1102
|
+
ctx.simpleExecutorContext
|
|
1103
|
+
);
|
|
1104
|
+
}
|
|
1105
|
+
if (node.environment) {
|
|
1106
|
+
const envSettings = {};
|
|
1107
|
+
for (const prop of node.environment.properties) {
|
|
1108
|
+
envSettings[prop.key] = resolveHoloValue(prop.value);
|
|
1109
|
+
}
|
|
1110
|
+
ctx.setEnvironment({ ...ctx.getEnvironment(), ...envSettings });
|
|
1111
|
+
}
|
|
1112
|
+
const results = [];
|
|
1113
|
+
for (const object of node.objects) {
|
|
1114
|
+
results.push(await ctx.executeHoloObject(object));
|
|
1115
|
+
}
|
|
1116
|
+
return {
|
|
1117
|
+
success: results.every((r) => r.success),
|
|
1118
|
+
output: `HoloComposition ${node.name} executed`
|
|
1119
|
+
};
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
// src/runtime/system-executors.ts
|
|
1123
|
+
async function setupNetworking(node) {
|
|
1124
|
+
const startTime = Date.now();
|
|
1125
|
+
chunkILRBGFVD_cjs.logger.info("[Networking] Initializing multiplayer fabric...", node.properties);
|
|
1126
|
+
return {
|
|
1127
|
+
success: true,
|
|
1128
|
+
output: "Networking system provisioned",
|
|
1129
|
+
executionTime: Date.now() - startTime
|
|
1130
|
+
};
|
|
1131
|
+
}
|
|
1132
|
+
async function setupPhysics(node) {
|
|
1133
|
+
const startTime = Date.now();
|
|
1134
|
+
chunkILRBGFVD_cjs.logger.info("[Physics] Initializing spatial simulation engine...", node.properties);
|
|
1135
|
+
return {
|
|
1136
|
+
success: true,
|
|
1137
|
+
output: "Physics system provisioned",
|
|
1138
|
+
executionTime: Date.now() - startTime
|
|
1139
|
+
};
|
|
1140
|
+
}
|
|
1141
|
+
async function executeSystem(node) {
|
|
1142
|
+
const startTime = Date.now();
|
|
1143
|
+
const systemId = node.id;
|
|
1144
|
+
const properties = node.properties;
|
|
1145
|
+
chunkILRBGFVD_cjs.logger.info(`[Zero-Config] Provisioning system: ${systemId}`, properties);
|
|
1146
|
+
switch (systemId) {
|
|
1147
|
+
case "Networking":
|
|
1148
|
+
return setupNetworking(node);
|
|
1149
|
+
case "Physics":
|
|
1150
|
+
return setupPhysics(node);
|
|
1151
|
+
default:
|
|
1152
|
+
chunkILRBGFVD_cjs.logger.warn(`[Zero-Config] Unknown system: ${systemId}`);
|
|
1153
|
+
return {
|
|
1154
|
+
success: true,
|
|
1155
|
+
output: `System ${systemId} not recognized, skipping provisioning`,
|
|
1156
|
+
executionTime: Date.now() - startTime
|
|
1157
|
+
};
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
async function executeCoreConfig(node, environment) {
|
|
1161
|
+
const startTime = Date.now();
|
|
1162
|
+
chunkILRBGFVD_cjs.logger.info("[Zero-Config] Applying core configuration", node.properties);
|
|
1163
|
+
for (const [key, value] of Object.entries(node.properties)) {
|
|
1164
|
+
environment[key] = value;
|
|
1165
|
+
}
|
|
1166
|
+
return {
|
|
1167
|
+
success: true,
|
|
1168
|
+
output: "Core configuration applied",
|
|
1169
|
+
executionTime: Date.now() - startTime
|
|
1170
|
+
};
|
|
1171
|
+
}
|
|
1172
|
+
async function executeVisualMetadata(node) {
|
|
1173
|
+
chunkILRBGFVD_cjs.logger.info(`[Metadata] Visual metadata processed`, node.properties);
|
|
1174
|
+
return { success: true, output: "Visual metadata applied" };
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
// src/runtime/node-type-registry.ts
|
|
1178
|
+
var NODE_TYPE_HANDLERS = {
|
|
1179
|
+
// Orbs / objects (same handler, both keys)
|
|
1180
|
+
orb: (node, r) => executeOrb(node, r.buildOrbExecutorContext()),
|
|
1181
|
+
object: (node, r) => executeOrb(node, r.buildOrbExecutorContext()),
|
|
1182
|
+
// Narrative family
|
|
1183
|
+
narrative: (node, r) => executeNarrative(node, r.buildNarrativeContext()),
|
|
1184
|
+
quest: (node, r) => executeQuest(node, r.buildNarrativeContext()),
|
|
1185
|
+
dialogue: (node, r) => executeDialogue(node, r.buildNarrativeContext()),
|
|
1186
|
+
visual_metadata: (node) => executeVisualMetadata(node),
|
|
1187
|
+
// Graph family
|
|
1188
|
+
method: (node, r) => executeFunction(node, r.buildGraphExecutorContext()),
|
|
1189
|
+
function: (node, r) => executeFunction(node, r.buildGraphExecutorContext()),
|
|
1190
|
+
connection: (node, r) => executeConnection(node, r.buildGraphExecutorContext()),
|
|
1191
|
+
gate: (node, r) => executeGate(node, r.buildGraphExecutorContext()),
|
|
1192
|
+
stream: (node, r) => executeStream(node, r.buildGraphExecutorContext()),
|
|
1193
|
+
// Simple / expression family
|
|
1194
|
+
call: (node, r) => executeCall(
|
|
1195
|
+
node,
|
|
1196
|
+
r.buildSimpleExecutorContext()
|
|
1197
|
+
),
|
|
1198
|
+
assignment: (node, r) => executeAssignment(
|
|
1199
|
+
node,
|
|
1200
|
+
r.buildSimpleExecutorContext()
|
|
1201
|
+
),
|
|
1202
|
+
return: (node, r) => executeReturn(node, r.buildSimpleExecutorContext()),
|
|
1203
|
+
"expression-statement": (node, r) => executeExpressionStatement(
|
|
1204
|
+
node,
|
|
1205
|
+
r.buildSimpleExecutorContext()
|
|
1206
|
+
),
|
|
1207
|
+
scale: (node, r) => executeScale(node, r.buildSimpleExecutorContext()),
|
|
1208
|
+
focus: (node, r) => executeFocus(node, r.buildSimpleExecutorContext()),
|
|
1209
|
+
environment: (node, r) => executeEnvironment(node, r.buildSimpleExecutorContext()),
|
|
1210
|
+
// Info / UI family
|
|
1211
|
+
visualize: (node, r) => executeVisualize(node, r.buildInfoExecutorContext()),
|
|
1212
|
+
"2d-element": (node, r) => executeUIElement(node, r.buildInfoExecutorContext()),
|
|
1213
|
+
// Structure family (nexus + building = same handler)
|
|
1214
|
+
nexus: (node) => executeStructure(node),
|
|
1215
|
+
building: (node) => executeStructure(node),
|
|
1216
|
+
// Capitalization-sensitive branches (composition vs Composition, template vs Template)
|
|
1217
|
+
composition: (node, r) => executeComposition(node, r.buildSimpleExecutorContext()),
|
|
1218
|
+
Composition: (node, r) => executeHoloComposition(
|
|
1219
|
+
node,
|
|
1220
|
+
r.buildHoloCompositionContext()
|
|
1221
|
+
),
|
|
1222
|
+
template: (node, r) => r.executeTemplate(node),
|
|
1223
|
+
Template: (node, r) => executeHoloTemplate(
|
|
1224
|
+
node,
|
|
1225
|
+
r.buildSimpleExecutorContext()
|
|
1226
|
+
),
|
|
1227
|
+
// State family
|
|
1228
|
+
"state-machine": (node, r) => executeStateMachine(node, r.buildSimpleExecutorContext()),
|
|
1229
|
+
"state-declaration": (node, r) => r.executeStateDeclaration(
|
|
1230
|
+
node
|
|
1231
|
+
),
|
|
1232
|
+
// System
|
|
1233
|
+
system: (node) => executeSystem(node),
|
|
1234
|
+
core_config: (node, r) => executeCoreConfig(
|
|
1235
|
+
node,
|
|
1236
|
+
r.context.environment
|
|
1237
|
+
),
|
|
1238
|
+
// Migration: accepted but no executor — plain success record
|
|
1239
|
+
migration: async () => ({
|
|
1240
|
+
success: true,
|
|
1241
|
+
output: "Migration block registered"
|
|
1242
|
+
}),
|
|
1243
|
+
// IO family (slice 32 delegates)
|
|
1244
|
+
server: (node, r) => r.executeServerNode(node),
|
|
1245
|
+
database: (node, r) => r.executeDatabaseNode(node),
|
|
1246
|
+
fetch: (node, r) => r.executeFetchNode(node),
|
|
1247
|
+
execute: (node, r) => r.executeTarget(node),
|
|
1248
|
+
// Memory family
|
|
1249
|
+
memory: (node, r) => r.executeMemory(node),
|
|
1250
|
+
"semantic-memory": (node, r) => r.executeMemoryDefinition(
|
|
1251
|
+
node
|
|
1252
|
+
),
|
|
1253
|
+
"episodic-memory": (node, r) => r.executeMemoryDefinition(
|
|
1254
|
+
node
|
|
1255
|
+
),
|
|
1256
|
+
"procedural-memory": (node, r) => r.executeMemoryDefinition(
|
|
1257
|
+
node
|
|
1258
|
+
),
|
|
1259
|
+
// Control-flow family
|
|
1260
|
+
for: (node, r) => r.executeForLoop(
|
|
1261
|
+
node
|
|
1262
|
+
),
|
|
1263
|
+
forEach: (node, r) => r.executeForEachLoop(
|
|
1264
|
+
node
|
|
1265
|
+
),
|
|
1266
|
+
while: (node, r) => r.executeWhileLoop(
|
|
1267
|
+
node
|
|
1268
|
+
),
|
|
1269
|
+
if: (node, r) => r.executeIfStatement(
|
|
1270
|
+
node
|
|
1271
|
+
),
|
|
1272
|
+
match: (node, r) => r.executeMatch(
|
|
1273
|
+
node
|
|
1274
|
+
),
|
|
1275
|
+
// Debug + generic
|
|
1276
|
+
debug: (node, r) => r.executeDebug(node),
|
|
1277
|
+
generic: (node, r) => r.executeGeneric(node)
|
|
1278
|
+
};
|
|
1279
|
+
async function dispatchNode(node, runtime) {
|
|
1280
|
+
const nodeType = node.type;
|
|
1281
|
+
const handler = NODE_TYPE_HANDLERS[nodeType];
|
|
1282
|
+
if (!handler) {
|
|
1283
|
+
return {
|
|
1284
|
+
success: false,
|
|
1285
|
+
error: `Unknown node type: ${node.type}`
|
|
1286
|
+
};
|
|
1287
|
+
}
|
|
1288
|
+
return handler(node, runtime);
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
// src/runtime/system-variables.ts
|
|
1292
|
+
chunkE7JP3BS3_cjs.init_safeJsonParse();
|
|
1293
|
+
var DEFAULT_USER = {
|
|
1294
|
+
id: "user_123",
|
|
1295
|
+
name: "Alpha Explorer",
|
|
1296
|
+
level: 42,
|
|
1297
|
+
rank: "Legendary",
|
|
1298
|
+
achievements: ["First World", "Spirit Guide"],
|
|
1299
|
+
preferences: { theme: "holographic", language: "en" }
|
|
1300
|
+
};
|
|
1301
|
+
var DEFAULT_LOCATION = {
|
|
1302
|
+
city: "Neo Tokyo",
|
|
1303
|
+
region: "Holo-Sector 7",
|
|
1304
|
+
coordinates: { lat: 35.6895, lng: 139.6917 },
|
|
1305
|
+
altitude: 450
|
|
1306
|
+
};
|
|
1307
|
+
var DEFAULT_WEATHER = {
|
|
1308
|
+
condition: "Neon Mist",
|
|
1309
|
+
temperature: 24,
|
|
1310
|
+
humidity: 65,
|
|
1311
|
+
windSpeed: 12,
|
|
1312
|
+
unit: "C"
|
|
1313
|
+
};
|
|
1314
|
+
var DEFAULT_WALLET = {
|
|
1315
|
+
address: "0xHolo...42ff",
|
|
1316
|
+
balance: 1337.5,
|
|
1317
|
+
currency: "HOLO",
|
|
1318
|
+
network: "MainNet"
|
|
1319
|
+
};
|
|
1320
|
+
var DEFAULT_CHAT_STATUS = {
|
|
1321
|
+
active: true,
|
|
1322
|
+
typing: false,
|
|
1323
|
+
version: "1.0.0-brittney"
|
|
1324
|
+
};
|
|
1325
|
+
function updateSystemVariables(ctx) {
|
|
1326
|
+
const now = /* @__PURE__ */ new Date();
|
|
1327
|
+
ctx.setVariable("$time", now.toLocaleTimeString());
|
|
1328
|
+
ctx.setVariable("$date", now.toLocaleDateString());
|
|
1329
|
+
ctx.setVariable("$timestamp", now.getTime());
|
|
1330
|
+
ctx.setVariable("$hour", now.getHours());
|
|
1331
|
+
ctx.setVariable("$minute", now.getMinutes());
|
|
1332
|
+
ctx.setVariable("$second", now.getSeconds());
|
|
1333
|
+
if (ctx.getVariable("$user") === void 0) {
|
|
1334
|
+
ctx.setVariable("$user", DEFAULT_USER);
|
|
1335
|
+
}
|
|
1336
|
+
if (ctx.getVariable("$location") === void 0) {
|
|
1337
|
+
ctx.setVariable("$location", DEFAULT_LOCATION);
|
|
1338
|
+
}
|
|
1339
|
+
if (ctx.getVariable("$weather") === void 0) {
|
|
1340
|
+
ctx.setVariable("$weather", DEFAULT_WEATHER);
|
|
1341
|
+
}
|
|
1342
|
+
if (ctx.getVariable("$wallet") === void 0) {
|
|
1343
|
+
ctx.setVariable("$wallet", DEFAULT_WALLET);
|
|
1344
|
+
}
|
|
1345
|
+
if (ctx.getVariable("$ai_config") === void 0) {
|
|
1346
|
+
let configuredCount = 0;
|
|
1347
|
+
if (ctx.brittneyApiKeysJson) {
|
|
1348
|
+
try {
|
|
1349
|
+
const keys = chunkE7JP3BS3_cjs.readJson(ctx.brittneyApiKeysJson);
|
|
1350
|
+
configuredCount = Object.values(keys).filter((k) => !!k).length;
|
|
1351
|
+
} catch (_e) {
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
ctx.setVariable("$ai_config", {
|
|
1355
|
+
status: configuredCount > 0 ? "configured" : "pending",
|
|
1356
|
+
providerCount: configuredCount,
|
|
1357
|
+
lastUpdated: Date.now()
|
|
1358
|
+
});
|
|
1359
|
+
}
|
|
1360
|
+
if (ctx.getVariable("$chat_status") === void 0) {
|
|
1361
|
+
ctx.setVariable("$chat_status", DEFAULT_CHAT_STATUS);
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
// src/runtime/context-factory.ts
|
|
1366
|
+
function createEmptyContext() {
|
|
1367
|
+
return {
|
|
1368
|
+
variables: /* @__PURE__ */ new Map(),
|
|
1369
|
+
functions: /* @__PURE__ */ new Map(),
|
|
1370
|
+
exports: /* @__PURE__ */ new Map(),
|
|
1371
|
+
connections: [],
|
|
1372
|
+
spatialMemory: /* @__PURE__ */ new Map(),
|
|
1373
|
+
hologramState: /* @__PURE__ */ new Map(),
|
|
1374
|
+
executionStack: [],
|
|
1375
|
+
currentScale: 1,
|
|
1376
|
+
scaleMagnitude: "standard",
|
|
1377
|
+
focusHistory: [],
|
|
1378
|
+
environment: {},
|
|
1379
|
+
templates: /* @__PURE__ */ new Map(),
|
|
1380
|
+
// HS+ State
|
|
1381
|
+
state: chunkGJNCFRJU_cjs.createState({}),
|
|
1382
|
+
// Phase 13: State Machines
|
|
1383
|
+
stateMachines: /* @__PURE__ */ new Map(),
|
|
1384
|
+
// Narrative & Story State
|
|
1385
|
+
quests: /* @__PURE__ */ new Map(),
|
|
1386
|
+
completedQuests: /* @__PURE__ */ new Set()
|
|
1387
|
+
};
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
// src/runtime/holo-object-executor.ts
|
|
1391
|
+
var DEFAULT_SHAPE = "sphere";
|
|
1392
|
+
var DEFAULT_COLOR = "#ffffff";
|
|
1393
|
+
var DEFAULT_SIZE = 1;
|
|
1394
|
+
async function executeHoloObject(node, ctx) {
|
|
1395
|
+
const properties = {};
|
|
1396
|
+
for (const prop of node.properties) {
|
|
1397
|
+
properties[prop.key] = resolveHoloValue(prop.value);
|
|
1398
|
+
}
|
|
1399
|
+
if (node.state) {
|
|
1400
|
+
for (const prop of node.state.properties) {
|
|
1401
|
+
properties[prop.key] = resolveHoloValue(prop.value);
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
const position = properties.position;
|
|
1405
|
+
const hologram = {
|
|
1406
|
+
shape: properties.geometry || DEFAULT_SHAPE,
|
|
1407
|
+
color: properties.color || DEFAULT_COLOR,
|
|
1408
|
+
size: properties.scale || properties.size || DEFAULT_SIZE,
|
|
1409
|
+
glow: properties.glow || false,
|
|
1410
|
+
// interactive defaults to true unless explicitly set false
|
|
1411
|
+
interactive: properties.interactive !== false
|
|
1412
|
+
};
|
|
1413
|
+
const template = node.template ? ctx.getTemplate(node.template) : void 0;
|
|
1414
|
+
const orbNode = {
|
|
1415
|
+
type: "orb",
|
|
1416
|
+
name: node.name,
|
|
1417
|
+
position,
|
|
1418
|
+
hologram,
|
|
1419
|
+
properties,
|
|
1420
|
+
// @ts-expect-error — directive shape is intentionally loose here;
|
|
1421
|
+
// downstream dispatch normalizes.
|
|
1422
|
+
directives: [
|
|
1423
|
+
...node.directives || [],
|
|
1424
|
+
...(node.traits || []).map((t) => ({
|
|
1425
|
+
type: "trait",
|
|
1426
|
+
name: t.name,
|
|
1427
|
+
...t.config
|
|
1428
|
+
})),
|
|
1429
|
+
...template?.directives || []
|
|
1430
|
+
],
|
|
1431
|
+
traits: new Map(
|
|
1432
|
+
(node.traits || []).map((t) => [t.name, t.config])
|
|
1433
|
+
),
|
|
1434
|
+
children: node.children || []
|
|
1435
|
+
};
|
|
1436
|
+
if (template) {
|
|
1437
|
+
if (template.state) {
|
|
1438
|
+
for (const prop of template.state.properties) {
|
|
1439
|
+
if (properties[prop.key] === void 0) {
|
|
1440
|
+
properties[prop.key] = resolveHoloValue(prop.value);
|
|
1441
|
+
}
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
for (const prop of template.properties) {
|
|
1445
|
+
if (properties[prop.key] === void 0) {
|
|
1446
|
+
properties[prop.key] = resolveHoloValue(prop.value);
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
return ctx.executeOrb(orbNode);
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
// src/runtime/skills-directives.ts
|
|
1454
|
+
var TRAIT_UPDATE_DT = 1 / 60;
|
|
1455
|
+
function loadSkill(skill, ctx) {
|
|
1456
|
+
chunkILRBGFVD_cjs.logger.info(`[Procedural] Loading skill: ${skill.name} (${skill.id})`);
|
|
1457
|
+
const existing = ctx.proceduralSkills.get(skill.id);
|
|
1458
|
+
if (existing) {
|
|
1459
|
+
skill.successRate = (existing.successRate + (skill.successRate || 0)) / 2;
|
|
1460
|
+
} else {
|
|
1461
|
+
skill.successRate = skill.successRate || 0;
|
|
1462
|
+
}
|
|
1463
|
+
ctx.proceduralSkills.set(skill.id, skill);
|
|
1464
|
+
ctx.broadcastSkill(skill);
|
|
1465
|
+
}
|
|
1466
|
+
var AGENT_TRAIT_NAMES = /* @__PURE__ */ new Set(["llm_agent", "agent", "companion"]);
|
|
1467
|
+
function isAgent(node) {
|
|
1468
|
+
return !!node.directives?.some(
|
|
1469
|
+
(d) => d.type === "trait" && AGENT_TRAIT_NAMES.has(d.name)
|
|
1470
|
+
);
|
|
1471
|
+
}
|
|
1472
|
+
function applyDirectives(node, ctx) {
|
|
1473
|
+
if (!node.directives) return;
|
|
1474
|
+
for (const d of node.directives) {
|
|
1475
|
+
if (d.type === "trait") {
|
|
1476
|
+
chunkILRBGFVD_cjs.logger.info(`Applying trait ${d.name} to ${node.type}`);
|
|
1477
|
+
const handler = ctx.traitHandlers.get(d.name);
|
|
1478
|
+
if (handler) {
|
|
1479
|
+
handler.onAttach?.(node, d.config || {}, {
|
|
1480
|
+
emit: (event, payload) => ctx.emit(event, payload),
|
|
1481
|
+
getScaleMultiplier: () => ctx.getCurrentScale() || 1
|
|
1482
|
+
});
|
|
1483
|
+
}
|
|
1484
|
+
if (d.name === "chat") {
|
|
1485
|
+
ctx.emit("show-chat", d.config);
|
|
1486
|
+
}
|
|
1487
|
+
} else if (d.type === "state") {
|
|
1488
|
+
if (node && node.__type === "orb") {
|
|
1489
|
+
const stateBody = d.body;
|
|
1490
|
+
const existingProps = node.properties || {};
|
|
1491
|
+
for (const [key, val] of Object.entries(stateBody)) {
|
|
1492
|
+
if (existingProps[key] === void 0) {
|
|
1493
|
+
existingProps[key] = val;
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
node.properties = existingProps;
|
|
1497
|
+
}
|
|
1498
|
+
ctx.state.update(d.body);
|
|
1499
|
+
} else if (d.type === "lifecycle") {
|
|
1500
|
+
if (d.hook === "on_mount" || d.hook === "mount") {
|
|
1501
|
+
ctx.evaluateExpression(d.body);
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
function updateTraits(julianDate, ctx) {
|
|
1507
|
+
const delta = TRAIT_UPDATE_DT;
|
|
1508
|
+
for (const [name, value] of ctx.variables.entries()) {
|
|
1509
|
+
if (value && typeof value === "object" && value.__type === "orb") {
|
|
1510
|
+
const orb = value;
|
|
1511
|
+
if (!orb.directives) continue;
|
|
1512
|
+
for (const d of orb.directives || []) {
|
|
1513
|
+
if (d.type !== "trait") continue;
|
|
1514
|
+
const handler = ctx.traitHandlers.get(d.name);
|
|
1515
|
+
if (!handler || !handler.onUpdate) continue;
|
|
1516
|
+
const traitNode = orb;
|
|
1517
|
+
handler.onUpdate(
|
|
1518
|
+
traitNode,
|
|
1519
|
+
d.config || {},
|
|
1520
|
+
{
|
|
1521
|
+
emit: (event, payload) => {
|
|
1522
|
+
if (event === "position_update") {
|
|
1523
|
+
const posPayload = payload;
|
|
1524
|
+
if (posPayload?.position) {
|
|
1525
|
+
const p = posPayload.position;
|
|
1526
|
+
const tuple = Array.isArray(p) ? p : [p[0], p[1], p[2]];
|
|
1527
|
+
ctx.setOrbPosition(name, tuple);
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
return ctx.emit(event, payload);
|
|
1531
|
+
},
|
|
1532
|
+
getScaleMultiplier: () => ctx.getCurrentScale() || 1,
|
|
1533
|
+
julianDate,
|
|
1534
|
+
getNode: (nodeName) => ctx.variables.get(nodeName),
|
|
1535
|
+
getState: () => ctx.getState(),
|
|
1536
|
+
setState: (updates) => ctx.setState(updates)
|
|
1537
|
+
},
|
|
1538
|
+
delta
|
|
1539
|
+
);
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
// src/runtime/primitives.ts
|
|
1546
|
+
function handleShop(args, emit2) {
|
|
1547
|
+
const config = args[0] || {};
|
|
1548
|
+
emit2("shop", config);
|
|
1549
|
+
return { success: true, type: "shop", config };
|
|
1550
|
+
}
|
|
1551
|
+
function handleInventory(args, emit2) {
|
|
1552
|
+
const item = args[0];
|
|
1553
|
+
const action = args[1] || "add";
|
|
1554
|
+
emit2("inventory", { item, action });
|
|
1555
|
+
return { success: true, item, action };
|
|
1556
|
+
}
|
|
1557
|
+
function handlePurchase(args, emit2) {
|
|
1558
|
+
const productId = args[0];
|
|
1559
|
+
emit2("purchase", { productId });
|
|
1560
|
+
return { success: true, productId, status: "pending" };
|
|
1561
|
+
}
|
|
1562
|
+
function handlePresence(args, emit2) {
|
|
1563
|
+
const config = args[0] || {};
|
|
1564
|
+
emit2("presence", config);
|
|
1565
|
+
return { success: true, active: true };
|
|
1566
|
+
}
|
|
1567
|
+
function handleInvite(args, emit2) {
|
|
1568
|
+
const userId = args[0];
|
|
1569
|
+
emit2("invite", { userId });
|
|
1570
|
+
return { success: true, userId };
|
|
1571
|
+
}
|
|
1572
|
+
function handleShare(args, emit2) {
|
|
1573
|
+
const scriptId = args[0];
|
|
1574
|
+
const targetUserId = args[1];
|
|
1575
|
+
emit2("share", { scriptId, targetUserId });
|
|
1576
|
+
return { success: true, scriptId };
|
|
1577
|
+
}
|
|
1578
|
+
function handlePhysics(args, emit2) {
|
|
1579
|
+
const config = args[0] || {};
|
|
1580
|
+
emit2("physics", config);
|
|
1581
|
+
return {
|
|
1582
|
+
success: true,
|
|
1583
|
+
enabled: config.enabled !== false
|
|
1584
|
+
};
|
|
1585
|
+
}
|
|
1586
|
+
function handleGravity(args, emit2) {
|
|
1587
|
+
const value = args[0] ?? 9.81;
|
|
1588
|
+
emit2("gravity", { value });
|
|
1589
|
+
return { success: true, value };
|
|
1590
|
+
}
|
|
1591
|
+
function handleCollide(args, emit2) {
|
|
1592
|
+
const target = args[0];
|
|
1593
|
+
const handler = args[1];
|
|
1594
|
+
emit2("collide", { target, handler });
|
|
1595
|
+
return { success: true, target };
|
|
1596
|
+
}
|
|
1597
|
+
function handleAnimate(args, emit2) {
|
|
1598
|
+
const options = args[0] || {};
|
|
1599
|
+
emit2("animate", options);
|
|
1600
|
+
return { success: true, options };
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1603
|
+
// src/runtime/builtins-registry.ts
|
|
1604
|
+
var SHOW_PARTICLES = 15;
|
|
1605
|
+
var PULSATE_PARTICLES = 30;
|
|
1606
|
+
var SPAWN_PARTICLES = 25;
|
|
1607
|
+
var DESPAWN_PARTICLES = 30;
|
|
1608
|
+
var DEFAULT_PULSATE_DURATION_MS = 1e3;
|
|
1609
|
+
var DEFAULT_PULSATE_COLOR = "#ffffff";
|
|
1610
|
+
var SPAWN_COLOR = "#00ff00";
|
|
1611
|
+
var DESPAWN_COLOR = "#ff0000";
|
|
1612
|
+
function createBuiltinsMap(ctx, customFunctions) {
|
|
1613
|
+
const builtins = /* @__PURE__ */ new Map();
|
|
1614
|
+
if (customFunctions) {
|
|
1615
|
+
for (const [name, func] of Object.entries(customFunctions)) {
|
|
1616
|
+
builtins.set(name, func);
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
builtins.set("show", (args) => {
|
|
1620
|
+
const target = String(args[0]);
|
|
1621
|
+
const element = ctx.uiElements.get(target);
|
|
1622
|
+
if (element) element.visible = true;
|
|
1623
|
+
const hologram = ctx.hologramState.get(target);
|
|
1624
|
+
if (hologram) {
|
|
1625
|
+
ctx.createParticleEffect(`${target}_show`, [0, 0, 0], hologram.color, SHOW_PARTICLES);
|
|
1626
|
+
}
|
|
1627
|
+
chunkILRBGFVD_cjs.logger.info("show", { target });
|
|
1628
|
+
return { shown: target };
|
|
1629
|
+
});
|
|
1630
|
+
builtins.set("hide", (args) => {
|
|
1631
|
+
const target = String(args[0]);
|
|
1632
|
+
const element = ctx.uiElements.get(target);
|
|
1633
|
+
if (element) element.visible = false;
|
|
1634
|
+
chunkILRBGFVD_cjs.logger.info("hide", { target });
|
|
1635
|
+
return { hidden: target };
|
|
1636
|
+
});
|
|
1637
|
+
builtins.set("pulsate", (args) => {
|
|
1638
|
+
const target = String(args[0]);
|
|
1639
|
+
const options = args[1] || {};
|
|
1640
|
+
const duration = Number(options.duration) || DEFAULT_PULSATE_DURATION_MS;
|
|
1641
|
+
const color = String(options.color || DEFAULT_PULSATE_COLOR);
|
|
1642
|
+
const position = ctx.spatialMemory.get(target) || [0, 0, 0];
|
|
1643
|
+
ctx.createParticleEffect(`${target}_pulse`, position, color, PULSATE_PARTICLES);
|
|
1644
|
+
return { pulsing: target, duration };
|
|
1645
|
+
});
|
|
1646
|
+
builtins.set("animate", (args) => {
|
|
1647
|
+
const target = String(args[0]);
|
|
1648
|
+
const options = args[1] || {};
|
|
1649
|
+
const animation = {
|
|
1650
|
+
target,
|
|
1651
|
+
property: String(options.property || "position[1]"),
|
|
1652
|
+
from: Number(options.from || 0),
|
|
1653
|
+
to: Number(options.to || 1),
|
|
1654
|
+
duration: Number(options.duration || 1e3),
|
|
1655
|
+
startTime: Date.now(),
|
|
1656
|
+
easing: String(options.easing || "linear"),
|
|
1657
|
+
loop: Boolean(options.loop),
|
|
1658
|
+
yoyo: Boolean(options.yoyo)
|
|
1659
|
+
};
|
|
1660
|
+
ctx.animations.set(`${target}_${animation.property}`, animation);
|
|
1661
|
+
return { animating: target, animation };
|
|
1662
|
+
});
|
|
1663
|
+
builtins.set("spawn", async (args) => {
|
|
1664
|
+
const config = args[0];
|
|
1665
|
+
if (typeof config === "string") {
|
|
1666
|
+
const target = config;
|
|
1667
|
+
const position2 = args[1] || [0, 0, 0];
|
|
1668
|
+
ctx.spatialMemory.set(target, position2);
|
|
1669
|
+
ctx.createParticleEffect(`${target}_spawn`, position2, SPAWN_COLOR, SPAWN_PARTICLES);
|
|
1670
|
+
return { spawned: target, at: position2 };
|
|
1671
|
+
}
|
|
1672
|
+
const spawnConfig = config;
|
|
1673
|
+
const templateName = String(spawnConfig.template);
|
|
1674
|
+
const id = String(spawnConfig.id || `${templateName}_${Date.now()}`);
|
|
1675
|
+
const position = spawnConfig.position || [0, 0, 0];
|
|
1676
|
+
const template = ctx.templates.get(templateName);
|
|
1677
|
+
if (!template) {
|
|
1678
|
+
chunkILRBGFVD_cjs.logger.error(`[Mitosis] Template ${templateName} not found`);
|
|
1679
|
+
return { error: `Template ${templateName} not found` };
|
|
1680
|
+
}
|
|
1681
|
+
const spawnNode = {
|
|
1682
|
+
type: "orb",
|
|
1683
|
+
name: id,
|
|
1684
|
+
position,
|
|
1685
|
+
properties: { ...spawnConfig.config || {} },
|
|
1686
|
+
children: template.children,
|
|
1687
|
+
traits: template.traits,
|
|
1688
|
+
directives: template.directives
|
|
1689
|
+
};
|
|
1690
|
+
const holoTpl = template;
|
|
1691
|
+
if (holoTpl.state) {
|
|
1692
|
+
for (const prop of holoTpl.state.properties) {
|
|
1693
|
+
if (spawnNode.properties[prop.key] === void 0) {
|
|
1694
|
+
spawnNode.properties[prop.key] = resolveHoloValue(prop.value);
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
for (const prop of holoTpl.properties) {
|
|
1699
|
+
if (spawnNode.properties[prop.key] === void 0) {
|
|
1700
|
+
spawnNode.properties[prop.key] = resolveHoloValue(prop.value);
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
await ctx.executeOrb(spawnNode);
|
|
1704
|
+
if (spawnConfig.parentId || spawnConfig.parent_id) {
|
|
1705
|
+
const parentId = String(spawnConfig.parentId || spawnConfig.parent_id);
|
|
1706
|
+
await ctx.emit(`mitosis_spawned`, { parentId, childId: id });
|
|
1707
|
+
await ctx.emit(`${parentId}.mitosis_spawned`, { childId: id });
|
|
1708
|
+
}
|
|
1709
|
+
return { spawned: id, template: templateName };
|
|
1710
|
+
});
|
|
1711
|
+
builtins.set("notifyParent", async (args) => {
|
|
1712
|
+
const parentId = String(args[0]);
|
|
1713
|
+
const data = args[1];
|
|
1714
|
+
await ctx.emit(`mitosis_child_complete`, {
|
|
1715
|
+
parentId,
|
|
1716
|
+
childId: args[2] || "unknown",
|
|
1717
|
+
result: data
|
|
1718
|
+
});
|
|
1719
|
+
await ctx.emit(`${parentId}.mitosis_child_complete`, {
|
|
1720
|
+
childId: args[2] || "unknown",
|
|
1721
|
+
result: data
|
|
1722
|
+
});
|
|
1723
|
+
return { notified: parentId };
|
|
1724
|
+
});
|
|
1725
|
+
builtins.set("despawn", (args) => {
|
|
1726
|
+
const target = String(args[0]);
|
|
1727
|
+
if (ctx.hologramState.has(target)) {
|
|
1728
|
+
const pos = ctx.spatialMemory.get(target) || [0, 0, 0];
|
|
1729
|
+
ctx.createParticleEffect(`${target}_despawn`, pos, DESPAWN_COLOR, DESPAWN_PARTICLES);
|
|
1730
|
+
ctx.hologramState.delete(target);
|
|
1731
|
+
ctx.variables.delete(target);
|
|
1732
|
+
ctx.spatialMemory.delete(target);
|
|
1733
|
+
chunkILRBGFVD_cjs.logger.info("despawn", { target });
|
|
1734
|
+
return { despawned: target };
|
|
1735
|
+
}
|
|
1736
|
+
return { msg: "Target not found", target };
|
|
1737
|
+
});
|
|
1738
|
+
builtins.set("move", (args) => {
|
|
1739
|
+
const target = String(args[0]);
|
|
1740
|
+
const position = args[1] || [0, 0, 0];
|
|
1741
|
+
const current = ctx.spatialMemory.get(target);
|
|
1742
|
+
if (current) {
|
|
1743
|
+
ctx.spatialMemory.set(target, position);
|
|
1744
|
+
ctx.createConnectionStream(target, `${target}_dest`, current, position, "move");
|
|
1745
|
+
}
|
|
1746
|
+
return { moved: target, to: position };
|
|
1747
|
+
});
|
|
1748
|
+
builtins.set("set", (args) => {
|
|
1749
|
+
const target = String(args[0]);
|
|
1750
|
+
const value = args[1];
|
|
1751
|
+
ctx.setVariable(target, value);
|
|
1752
|
+
return { set: target, value };
|
|
1753
|
+
});
|
|
1754
|
+
builtins.set("get", (args) => {
|
|
1755
|
+
const target = String(args[0]);
|
|
1756
|
+
return ctx.getVariable(target);
|
|
1757
|
+
});
|
|
1758
|
+
builtins.set("add", (args) => Number(args[0]) + Number(args[1]));
|
|
1759
|
+
builtins.set("subtract", (args) => Number(args[0]) - Number(args[1]));
|
|
1760
|
+
builtins.set("multiply", (args) => Number(args[0]) * Number(args[1]));
|
|
1761
|
+
builtins.set(
|
|
1762
|
+
"divide",
|
|
1763
|
+
(args) => Number(args[1]) !== 0 ? Number(args[0]) / Number(args[1]) : 0
|
|
1764
|
+
);
|
|
1765
|
+
builtins.set("mod", (args) => Number(args[0]) % Number(args[1]));
|
|
1766
|
+
builtins.set("abs", (args) => Math.abs(Number(args[0])));
|
|
1767
|
+
builtins.set("floor", (args) => Math.floor(Number(args[0])));
|
|
1768
|
+
builtins.set("ceil", (args) => Math.ceil(Number(args[0])));
|
|
1769
|
+
builtins.set("round", (args) => Math.round(Number(args[0])));
|
|
1770
|
+
builtins.set("min", (args) => Math.min(...args.map(Number)));
|
|
1771
|
+
builtins.set("max", (args) => Math.max(...args.map(Number)));
|
|
1772
|
+
builtins.set("random", () => Math.random());
|
|
1773
|
+
builtins.set("concat", (args) => args.map(String).join(""));
|
|
1774
|
+
builtins.set("length", (args) => {
|
|
1775
|
+
const val = args[0];
|
|
1776
|
+
if (typeof val === "string") return val.length;
|
|
1777
|
+
if (Array.isArray(val)) return val.length;
|
|
1778
|
+
return 0;
|
|
1779
|
+
});
|
|
1780
|
+
builtins.set(
|
|
1781
|
+
"substring",
|
|
1782
|
+
(args) => String(args[0]).substring(Number(args[1]), Number(args[2]))
|
|
1783
|
+
);
|
|
1784
|
+
builtins.set("wait", async (args) => {
|
|
1785
|
+
const ms = Number(args[0]) || 0;
|
|
1786
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
1787
|
+
return { waited: ms };
|
|
1788
|
+
});
|
|
1789
|
+
builtins.set("print", (args) => {
|
|
1790
|
+
console.log(`[HoloScript]`, ...args);
|
|
1791
|
+
return { printed: args.join(" ") };
|
|
1792
|
+
});
|
|
1793
|
+
builtins.set("uppercase", (args) => String(args[0]).toUpperCase());
|
|
1794
|
+
builtins.set("lowercase", (args) => String(args[0]).toLowerCase());
|
|
1795
|
+
builtins.set("push", (args) => {
|
|
1796
|
+
const arr = args[0];
|
|
1797
|
+
if (Array.isArray(arr)) {
|
|
1798
|
+
arr.push(args[1]);
|
|
1799
|
+
return arr;
|
|
1800
|
+
}
|
|
1801
|
+
return [args[0], args[1]];
|
|
1802
|
+
});
|
|
1803
|
+
builtins.set("pop", (args) => {
|
|
1804
|
+
const arr = args[0];
|
|
1805
|
+
if (Array.isArray(arr)) return arr.pop();
|
|
1806
|
+
return void 0;
|
|
1807
|
+
});
|
|
1808
|
+
builtins.set("at", (args) => {
|
|
1809
|
+
const arr = args[0];
|
|
1810
|
+
const index = Number(args[1]);
|
|
1811
|
+
if (Array.isArray(arr)) return arr[index];
|
|
1812
|
+
return void 0;
|
|
1813
|
+
});
|
|
1814
|
+
builtins.set("showSettings", () => {
|
|
1815
|
+
void ctx.emit("show-settings");
|
|
1816
|
+
return true;
|
|
1817
|
+
});
|
|
1818
|
+
builtins.set("openChat", (args) => {
|
|
1819
|
+
const config = args[0] || {};
|
|
1820
|
+
void ctx.emit("show-chat", config);
|
|
1821
|
+
return true;
|
|
1822
|
+
});
|
|
1823
|
+
builtins.set("log", (args) => {
|
|
1824
|
+
chunkILRBGFVD_cjs.logger.info("HoloScript log", { args });
|
|
1825
|
+
return args[0];
|
|
1826
|
+
});
|
|
1827
|
+
builtins.set("print", (args) => {
|
|
1828
|
+
const message = args.map(String).join(" ");
|
|
1829
|
+
chunkILRBGFVD_cjs.logger.info("print", { message });
|
|
1830
|
+
return message;
|
|
1831
|
+
});
|
|
1832
|
+
builtins.set("typeof", (args) => typeof args[0]);
|
|
1833
|
+
builtins.set("isArray", (args) => Array.isArray(args[0]));
|
|
1834
|
+
builtins.set(
|
|
1835
|
+
"isNumber",
|
|
1836
|
+
(args) => typeof args[0] === "number" && !isNaN(args[0])
|
|
1837
|
+
);
|
|
1838
|
+
builtins.set("isString", (args) => typeof args[0] === "string");
|
|
1839
|
+
const emitFn = (event, data) => {
|
|
1840
|
+
void ctx.emit(event, data);
|
|
1841
|
+
};
|
|
1842
|
+
builtins.set("shop", (args) => handleShop(args, emitFn));
|
|
1843
|
+
builtins.set("inventory", (args) => handleInventory(args, emitFn));
|
|
1844
|
+
builtins.set("purchase", (args) => handlePurchase(args, emitFn));
|
|
1845
|
+
builtins.set("presence", (args) => handlePresence(args, emitFn));
|
|
1846
|
+
builtins.set("invite", (args) => handleInvite(args, emitFn));
|
|
1847
|
+
builtins.set("share", (args) => handleShare(args, emitFn));
|
|
1848
|
+
builtins.set("physics", (args) => handlePhysics(args, emitFn));
|
|
1849
|
+
builtins.set("gravity", (args) => handleGravity(args, emitFn));
|
|
1850
|
+
builtins.set("collide", (args) => handleCollide(args, emitFn));
|
|
1851
|
+
builtins.set("animate", (args) => handleAnimate(args, emitFn));
|
|
1852
|
+
builtins.set("calculate_arc", (args) => ctx.calculateArc(args));
|
|
1853
|
+
builtins.set(
|
|
1854
|
+
"sleep",
|
|
1855
|
+
(args) => new Promise((resolve) => setTimeout(resolve, Number(args[0]) || 0))
|
|
1856
|
+
);
|
|
1857
|
+
builtins.set("think", async (args) => {
|
|
1858
|
+
const activeNode = ctx.executionStack[ctx.executionStack.length - 1];
|
|
1859
|
+
if (!activeNode) return "No context";
|
|
1860
|
+
const agentId = activeNode.name;
|
|
1861
|
+
const agentRuntime = ctx.agentRuntimes.get(agentId);
|
|
1862
|
+
if (agentRuntime) {
|
|
1863
|
+
return await agentRuntime.think(String(args[0] || ""));
|
|
1864
|
+
}
|
|
1865
|
+
return "Thinking only available for agents.";
|
|
1866
|
+
});
|
|
1867
|
+
return builtins;
|
|
1868
|
+
}
|
|
1869
|
+
|
|
1870
|
+
// src/runtime/event-system.ts
|
|
1871
|
+
function onEvent(event, handler, ctx) {
|
|
1872
|
+
const handlers = ctx.eventHandlers.get(event) || [];
|
|
1873
|
+
handlers.push(handler);
|
|
1874
|
+
ctx.eventHandlers.set(event, handlers);
|
|
1875
|
+
}
|
|
1876
|
+
function offEvent(event, handler, ctx) {
|
|
1877
|
+
if (!handler) {
|
|
1878
|
+
ctx.eventHandlers.delete(event);
|
|
1879
|
+
} else {
|
|
1880
|
+
const handlers = ctx.eventHandlers.get(event) || [];
|
|
1881
|
+
ctx.eventHandlers.set(
|
|
1882
|
+
event,
|
|
1883
|
+
handlers.filter((h) => h !== handler)
|
|
1884
|
+
);
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
async function emit(event, data, ctx) {
|
|
1888
|
+
chunkILRBGFVD_cjs.logger.info(`[Runtime] Emitting event: ${event}`, data);
|
|
1889
|
+
if (event.includes(".")) {
|
|
1890
|
+
const [target, eventName] = event.split(".");
|
|
1891
|
+
const agent = ctx.agentRuntimes.get(target);
|
|
1892
|
+
if (agent) {
|
|
1893
|
+
await agent.onEvent(eventName, data);
|
|
1894
|
+
}
|
|
1895
|
+
const orb = ctx.variables.get(target);
|
|
1896
|
+
if (orb && typeof orb === "object" && orb.__type === "orb") {
|
|
1897
|
+
await forwardToTraits(orb, eventName, data, ctx);
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
const orbs = Array.from(ctx.variables.values()).filter(
|
|
1901
|
+
(v) => v && typeof v === "object" && v.__type === "orb"
|
|
1902
|
+
);
|
|
1903
|
+
for (const agent of ctx.agentRuntimes.values()) {
|
|
1904
|
+
await agent.onEvent(event, data);
|
|
1905
|
+
}
|
|
1906
|
+
for (const variable of orbs) {
|
|
1907
|
+
await forwardToTraits(variable, event, data, ctx);
|
|
1908
|
+
}
|
|
1909
|
+
const handlers = ctx.eventHandlers.get(event) || [];
|
|
1910
|
+
for (const handler of handlers) {
|
|
1911
|
+
try {
|
|
1912
|
+
await handler(data);
|
|
1913
|
+
} catch (error) {
|
|
1914
|
+
chunkILRBGFVD_cjs.logger.error("Event handler error", { event, error });
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
await ctx.globalBusEmit(event, data);
|
|
1918
|
+
if (data && typeof data === "object" && data.id) {
|
|
1919
|
+
ctx.sendStateMachineEvent(data.id, event);
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
async function forwardToTraits(orb, event, data, ctx) {
|
|
1923
|
+
if (!orb.directives) return;
|
|
1924
|
+
for (const d of orb.directives) {
|
|
1925
|
+
if (d.type !== "trait") continue;
|
|
1926
|
+
const handler = ctx.traitHandlers.get(d.name);
|
|
1927
|
+
if (!handler || !handler.onEvent) continue;
|
|
1928
|
+
const traitNode = orb;
|
|
1929
|
+
const eventPayload = {
|
|
1930
|
+
type: event,
|
|
1931
|
+
...data && typeof data === "object" ? data : {}
|
|
1932
|
+
};
|
|
1933
|
+
await handler.onEvent(
|
|
1934
|
+
traitNode,
|
|
1935
|
+
d.config || {},
|
|
1936
|
+
{
|
|
1937
|
+
emit: async (e, p) => await emit(e, p, ctx),
|
|
1938
|
+
getScaleMultiplier: () => ctx.getCurrentScale() || 1
|
|
1939
|
+
},
|
|
1940
|
+
eventPayload
|
|
1941
|
+
);
|
|
1942
|
+
}
|
|
1943
|
+
}
|
|
1944
|
+
async function triggerUIEvent(elementName, eventType, data, ctx) {
|
|
1945
|
+
const element = ctx.uiElements.get(elementName);
|
|
1946
|
+
if (!element) {
|
|
1947
|
+
chunkILRBGFVD_cjs.logger.warn("UI element not found", { elementName });
|
|
1948
|
+
return;
|
|
1949
|
+
}
|
|
1950
|
+
if (eventType === "change" && data !== void 0) {
|
|
1951
|
+
element.value = data;
|
|
1952
|
+
}
|
|
1953
|
+
await emit(`${elementName}.${eventType}`, data, ctx);
|
|
1954
|
+
}
|
|
1955
|
+
|
|
1956
|
+
// src/runtime/state-invalidation.ts
|
|
1957
|
+
var StateInvalidationRegistry = class {
|
|
1958
|
+
constructor() {
|
|
1959
|
+
this.records = /* @__PURE__ */ new Map();
|
|
1960
|
+
}
|
|
1961
|
+
/** Record an invalidation for `key`. No-op on an empty/invalid key. */
|
|
1962
|
+
record(key, nodeId) {
|
|
1963
|
+
if (typeof key !== "string" || key.length === 0) return;
|
|
1964
|
+
this.records.set(key, { key, at: Date.now(), nodeId });
|
|
1965
|
+
}
|
|
1966
|
+
/** True if `key` has an outstanding (unacknowledged) invalidation. */
|
|
1967
|
+
wasInvalidated(key) {
|
|
1968
|
+
return this.records.has(key);
|
|
1969
|
+
}
|
|
1970
|
+
/** Peek the invalidation record without acknowledging it. */
|
|
1971
|
+
get(key) {
|
|
1972
|
+
return this.records.get(key);
|
|
1973
|
+
}
|
|
1974
|
+
/**
|
|
1975
|
+
* Read-and-clear: returns the record (if any) and removes it, so a reader
|
|
1976
|
+
* that has refetched the value acknowledges the invalidation exactly once.
|
|
1977
|
+
*/
|
|
1978
|
+
consume(key) {
|
|
1979
|
+
const record = this.records.get(key);
|
|
1980
|
+
this.records.delete(key);
|
|
1981
|
+
return record;
|
|
1982
|
+
}
|
|
1983
|
+
/** All outstanding invalidations. */
|
|
1984
|
+
list() {
|
|
1985
|
+
return Array.from(this.records.values());
|
|
1986
|
+
}
|
|
1987
|
+
/** Drop all outstanding invalidations. */
|
|
1988
|
+
clear() {
|
|
1989
|
+
this.records.clear();
|
|
1990
|
+
}
|
|
1991
|
+
/** Count of outstanding invalidations. */
|
|
1992
|
+
get size() {
|
|
1993
|
+
return this.records.size;
|
|
1994
|
+
}
|
|
1995
|
+
};
|
|
1996
|
+
var defaultStateInvalidationRegistry = new StateInvalidationRegistry();
|
|
1997
|
+
function makeStateInvalidationHandler(registry) {
|
|
1998
|
+
return (data) => {
|
|
1999
|
+
const payload = data ?? {};
|
|
2000
|
+
if (typeof payload.key === "string") {
|
|
2001
|
+
const nodeId = payload.node && typeof payload.node.id === "string" ? payload.node.id : void 0;
|
|
2002
|
+
registry.record(payload.key, nodeId);
|
|
2003
|
+
}
|
|
2004
|
+
};
|
|
2005
|
+
}
|
|
2006
|
+
function attachStateInvalidationConsumer(ctx, registry = defaultStateInvalidationRegistry) {
|
|
2007
|
+
onEvent("persistent_expired", makeStateInvalidationHandler(registry), ctx);
|
|
2008
|
+
return registry;
|
|
2009
|
+
}
|
|
2010
|
+
|
|
2011
|
+
// src/runtime/ui-commands.ts
|
|
2012
|
+
var SHOW_PARTICLE_COUNT = 15;
|
|
2013
|
+
var HIDE_PARTICLE_COUNT = 10;
|
|
2014
|
+
var CREATE_PARTICLE_COUNT = 20;
|
|
2015
|
+
var PULSE_PARTICLE_COUNT = 30;
|
|
2016
|
+
var DELETE_PARTICLE_COUNT = 15;
|
|
2017
|
+
var HIDE_COLOR = "#ff0000";
|
|
2018
|
+
var DELETE_COLOR = "#ff0000";
|
|
2019
|
+
var PULSE_COLOR = "#ffff00";
|
|
2020
|
+
var DEFAULT_SHOW_HOLOGRAM = {
|
|
2021
|
+
shape: "orb",
|
|
2022
|
+
color: "#00ffff",
|
|
2023
|
+
size: 0.8,
|
|
2024
|
+
glow: true,
|
|
2025
|
+
interactive: true
|
|
2026
|
+
};
|
|
2027
|
+
var DEFAULT_CREATE_COLOR = "#00ffff";
|
|
2028
|
+
var DEFAULT_CREATE_SIZE = 1;
|
|
2029
|
+
var DEFAULT_ANIMATE_PROPERTY = "position[1]";
|
|
2030
|
+
var DEFAULT_ANIMATE_DURATION_MS = 1e3;
|
|
2031
|
+
var DEFAULT_PULSE_DURATION_MS = 500;
|
|
2032
|
+
var PULSE_SCALE_FROM = 1;
|
|
2033
|
+
var PULSE_SCALE_TO = 1.5;
|
|
2034
|
+
async function executeShowCommand(target, node, ctx) {
|
|
2035
|
+
const hologram = node.hologram || DEFAULT_SHOW_HOLOGRAM;
|
|
2036
|
+
const position = node.position || [0, 0, 0];
|
|
2037
|
+
ctx.spatialMemory.set(target, position);
|
|
2038
|
+
ctx.createParticleEffect(`${target}_show`, position, hologram.color, SHOW_PARTICLE_COUNT);
|
|
2039
|
+
chunkILRBGFVD_cjs.logger.info("Show command executed", { target, position });
|
|
2040
|
+
return { showed: target, hologram, position };
|
|
2041
|
+
}
|
|
2042
|
+
async function executeHideCommand(target, _node, ctx) {
|
|
2043
|
+
const position = ctx.spatialMemory.get(target) || [0, 0, 0];
|
|
2044
|
+
ctx.createParticleEffect(`${target}_hide`, position, HIDE_COLOR, HIDE_PARTICLE_COUNT);
|
|
2045
|
+
chunkILRBGFVD_cjs.logger.info("Hide command executed", { target });
|
|
2046
|
+
return { hidden: target };
|
|
2047
|
+
}
|
|
2048
|
+
async function executeCreateCommand(tokens, node, ctx) {
|
|
2049
|
+
if (tokens.length < 2) {
|
|
2050
|
+
return { error: "Create command requires shape and name" };
|
|
2051
|
+
}
|
|
2052
|
+
const shape = tokens[0];
|
|
2053
|
+
const name = tokens[1];
|
|
2054
|
+
const position = node.position || [0, 0, 0];
|
|
2055
|
+
const hologram = {
|
|
2056
|
+
shape,
|
|
2057
|
+
color: node.hologram?.color || DEFAULT_CREATE_COLOR,
|
|
2058
|
+
size: node.hologram?.size || DEFAULT_CREATE_SIZE,
|
|
2059
|
+
glow: node.hologram?.glow !== false,
|
|
2060
|
+
interactive: node.hologram?.interactive !== false
|
|
2061
|
+
};
|
|
2062
|
+
ctx.spatialMemory.set(name, position);
|
|
2063
|
+
ctx.createParticleEffect(`${name}_create`, position, hologram.color, CREATE_PARTICLE_COUNT);
|
|
2064
|
+
chunkILRBGFVD_cjs.logger.info("Create command executed", { shape, name, position });
|
|
2065
|
+
return { created: name, shape, hologram, position };
|
|
2066
|
+
}
|
|
2067
|
+
async function executeAnimateCommand(target, tokens, _node, ctx) {
|
|
2068
|
+
const property = tokens[0] || DEFAULT_ANIMATE_PROPERTY;
|
|
2069
|
+
const duration = parseInt(tokens[1] || String(DEFAULT_ANIMATE_DURATION_MS), 10);
|
|
2070
|
+
const animation = {
|
|
2071
|
+
target,
|
|
2072
|
+
property,
|
|
2073
|
+
from: 0,
|
|
2074
|
+
to: 1,
|
|
2075
|
+
duration,
|
|
2076
|
+
startTime: Date.now(),
|
|
2077
|
+
easing: "ease-in-out"
|
|
2078
|
+
};
|
|
2079
|
+
ctx.animations.set(`${target}_${property}`, animation);
|
|
2080
|
+
chunkILRBGFVD_cjs.logger.info("Animate command executed", { target, property, duration });
|
|
2081
|
+
return { animating: target, animation };
|
|
2082
|
+
}
|
|
2083
|
+
async function executePulseCommand(target, tokens, _node, ctx) {
|
|
2084
|
+
const duration = parseInt(tokens[0] || String(DEFAULT_PULSE_DURATION_MS), 10);
|
|
2085
|
+
const position = ctx.spatialMemory.get(target) || [0, 0, 0];
|
|
2086
|
+
ctx.createParticleEffect(`${target}_pulse`, position, PULSE_COLOR, PULSE_PARTICLE_COUNT);
|
|
2087
|
+
const animation = {
|
|
2088
|
+
target,
|
|
2089
|
+
property: "scale",
|
|
2090
|
+
from: PULSE_SCALE_FROM,
|
|
2091
|
+
to: PULSE_SCALE_TO,
|
|
2092
|
+
duration,
|
|
2093
|
+
startTime: Date.now(),
|
|
2094
|
+
easing: "sine",
|
|
2095
|
+
yoyo: true,
|
|
2096
|
+
loop: true
|
|
2097
|
+
};
|
|
2098
|
+
ctx.animations.set(`${target}_pulse`, animation);
|
|
2099
|
+
chunkILRBGFVD_cjs.logger.info("Pulse command executed", { target, duration });
|
|
2100
|
+
return { pulsing: target, duration };
|
|
2101
|
+
}
|
|
2102
|
+
async function executeMoveCommand(target, tokens, _node, ctx) {
|
|
2103
|
+
const x = parseFloat(tokens[0] || "0");
|
|
2104
|
+
const y = parseFloat(tokens[1] || "0");
|
|
2105
|
+
const z = parseFloat(tokens[2] || "0");
|
|
2106
|
+
const position = [x, y, z];
|
|
2107
|
+
const current = ctx.spatialMemory.get(target);
|
|
2108
|
+
if (current) {
|
|
2109
|
+
ctx.spatialMemory.set(target, position);
|
|
2110
|
+
ctx.createConnectionStream(target, `${target}_move`, current, position, "movement");
|
|
2111
|
+
} else {
|
|
2112
|
+
ctx.spatialMemory.set(target, position);
|
|
2113
|
+
}
|
|
2114
|
+
chunkILRBGFVD_cjs.logger.info("Move command executed", { target, position });
|
|
2115
|
+
return { moved: target, to: position };
|
|
2116
|
+
}
|
|
2117
|
+
async function executeDeleteCommand(target, _node, ctx) {
|
|
2118
|
+
const position = ctx.spatialMemory.get(target);
|
|
2119
|
+
if (position) {
|
|
2120
|
+
ctx.createParticleEffect(`${target}_delete`, position, DELETE_COLOR, DELETE_PARTICLE_COUNT);
|
|
2121
|
+
ctx.spatialMemory.delete(target);
|
|
2122
|
+
}
|
|
2123
|
+
chunkILRBGFVD_cjs.logger.info("Delete command executed", { target });
|
|
2124
|
+
return { deleted: target };
|
|
2125
|
+
}
|
|
2126
|
+
|
|
2127
|
+
// src/runtime/pattern-match.ts
|
|
2128
|
+
var WILDCARD_PATTERNS = /* @__PURE__ */ new Set(["_", "else", "default"]);
|
|
2129
|
+
var TYPE_PATTERNS = {
|
|
2130
|
+
string: (v) => typeof v === "string",
|
|
2131
|
+
number: (v) => typeof v === "number",
|
|
2132
|
+
boolean: (v) => typeof v === "boolean",
|
|
2133
|
+
array: (v) => Array.isArray(v),
|
|
2134
|
+
object: (v) => typeof v === "object" && v !== null
|
|
2135
|
+
};
|
|
2136
|
+
function patternMatches(pattern, value) {
|
|
2137
|
+
if (typeof pattern === "string" && WILDCARD_PATTERNS.has(pattern)) {
|
|
2138
|
+
return true;
|
|
2139
|
+
}
|
|
2140
|
+
if (pattern === value) {
|
|
2141
|
+
return true;
|
|
2142
|
+
}
|
|
2143
|
+
if (typeof pattern === "string" && pattern in TYPE_PATTERNS) {
|
|
2144
|
+
return TYPE_PATTERNS[pattern](value);
|
|
2145
|
+
}
|
|
2146
|
+
if (Array.isArray(pattern) && pattern.length === 2) {
|
|
2147
|
+
const [min, max] = pattern;
|
|
2148
|
+
if (typeof value === "number" && typeof min === "number" && typeof max === "number" && value >= min && value <= max) {
|
|
2149
|
+
return true;
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
return false;
|
|
2153
|
+
}
|
|
2154
|
+
|
|
2155
|
+
// src/runtime/control-flow.ts
|
|
2156
|
+
var WHILE_MAX_ITERATIONS = 1e4;
|
|
2157
|
+
async function executeForLoop(node, ctx) {
|
|
2158
|
+
const startTime = Date.now();
|
|
2159
|
+
const { variable, iterable, body } = node;
|
|
2160
|
+
try {
|
|
2161
|
+
const collection = ctx.evaluateExpression(String(iterable));
|
|
2162
|
+
if (!Array.isArray(collection) && typeof collection !== "object") {
|
|
2163
|
+
return {
|
|
2164
|
+
success: false,
|
|
2165
|
+
error: `Cannot iterate over non-iterable: ${typeof collection}`,
|
|
2166
|
+
executionTime: Date.now() - startTime
|
|
2167
|
+
};
|
|
2168
|
+
}
|
|
2169
|
+
const items = Array.isArray(collection) ? collection : collection && typeof collection === "object" ? Object.entries(collection) : [];
|
|
2170
|
+
let lastResult = { success: true, output: null };
|
|
2171
|
+
for (const item of items) {
|
|
2172
|
+
ctx.variables.set(variable, item);
|
|
2173
|
+
for (const bodyNode of body) {
|
|
2174
|
+
lastResult = await ctx.executeNode(bodyNode);
|
|
2175
|
+
if (!lastResult.success) break;
|
|
2176
|
+
}
|
|
2177
|
+
if (!lastResult.success) break;
|
|
2178
|
+
}
|
|
2179
|
+
ctx.variables.delete(variable);
|
|
2180
|
+
return {
|
|
2181
|
+
success: true,
|
|
2182
|
+
output: lastResult.output,
|
|
2183
|
+
executionTime: Date.now() - startTime
|
|
2184
|
+
};
|
|
2185
|
+
} catch (error) {
|
|
2186
|
+
return {
|
|
2187
|
+
success: false,
|
|
2188
|
+
error: `For loop error: ${error instanceof Error ? error.message : String(error)}`,
|
|
2189
|
+
executionTime: Date.now() - startTime
|
|
2190
|
+
};
|
|
2191
|
+
}
|
|
2192
|
+
}
|
|
2193
|
+
async function executeForEachLoop(node, ctx) {
|
|
2194
|
+
return executeForLoop(
|
|
2195
|
+
{ variable: node.variable, iterable: node.collection, body: node.body },
|
|
2196
|
+
ctx
|
|
2197
|
+
);
|
|
2198
|
+
}
|
|
2199
|
+
async function executeWhileLoop(node, ctx) {
|
|
2200
|
+
const startTime = Date.now();
|
|
2201
|
+
const { condition, body } = node;
|
|
2202
|
+
try {
|
|
2203
|
+
let iterations = 0;
|
|
2204
|
+
let lastResult = { success: true, output: null };
|
|
2205
|
+
while (ctx.evaluateCondition(String(condition))) {
|
|
2206
|
+
iterations++;
|
|
2207
|
+
if (iterations > WHILE_MAX_ITERATIONS) {
|
|
2208
|
+
return {
|
|
2209
|
+
success: false,
|
|
2210
|
+
error: `While loop exceeded maximum iterations (${WHILE_MAX_ITERATIONS})`,
|
|
2211
|
+
executionTime: Date.now() - startTime
|
|
2212
|
+
};
|
|
2213
|
+
}
|
|
2214
|
+
for (const bodyNode of body) {
|
|
2215
|
+
lastResult = await ctx.executeNode(bodyNode);
|
|
2216
|
+
if (!lastResult.success) break;
|
|
2217
|
+
}
|
|
2218
|
+
if (!lastResult.success) break;
|
|
2219
|
+
}
|
|
2220
|
+
return {
|
|
2221
|
+
success: true,
|
|
2222
|
+
output: lastResult.output,
|
|
2223
|
+
executionTime: Date.now() - startTime
|
|
2224
|
+
};
|
|
2225
|
+
} catch (error) {
|
|
2226
|
+
return {
|
|
2227
|
+
success: false,
|
|
2228
|
+
error: `While loop error: ${error instanceof Error ? error.message : String(error)}`,
|
|
2229
|
+
executionTime: Date.now() - startTime
|
|
2230
|
+
};
|
|
2231
|
+
}
|
|
2232
|
+
}
|
|
2233
|
+
async function executeIfStatement(node, ctx) {
|
|
2234
|
+
const startTime = Date.now();
|
|
2235
|
+
const { condition, body, elseBody } = node;
|
|
2236
|
+
try {
|
|
2237
|
+
const conditionResult = ctx.evaluateCondition(String(condition));
|
|
2238
|
+
const branchToExecute = conditionResult ? body : elseBody || [];
|
|
2239
|
+
let lastResult = { success: true, output: null };
|
|
2240
|
+
for (const bodyNode of branchToExecute) {
|
|
2241
|
+
lastResult = await ctx.executeNode(bodyNode);
|
|
2242
|
+
if (!lastResult.success) break;
|
|
2243
|
+
}
|
|
2244
|
+
return {
|
|
2245
|
+
success: true,
|
|
2246
|
+
output: lastResult.output,
|
|
2247
|
+
executionTime: Date.now() - startTime
|
|
2248
|
+
};
|
|
2249
|
+
} catch (error) {
|
|
2250
|
+
return {
|
|
2251
|
+
success: false,
|
|
2252
|
+
error: `If statement error: ${error instanceof Error ? error.message : String(error)}`,
|
|
2253
|
+
executionTime: Date.now() - startTime
|
|
2254
|
+
};
|
|
2255
|
+
}
|
|
2256
|
+
}
|
|
2257
|
+
async function executeMatch(node, ctx) {
|
|
2258
|
+
const startTime = Date.now();
|
|
2259
|
+
const { subject, cases } = node;
|
|
2260
|
+
try {
|
|
2261
|
+
const subjectValue = ctx.evaluateExpression(String(subject));
|
|
2262
|
+
for (const matchCase of cases || []) {
|
|
2263
|
+
const patternValue = ctx.evaluateExpression(String(matchCase.pattern));
|
|
2264
|
+
if (patternMatches(patternValue, subjectValue)) {
|
|
2265
|
+
if (matchCase.guard && !ctx.evaluateCondition(String(matchCase.guard))) {
|
|
2266
|
+
continue;
|
|
2267
|
+
}
|
|
2268
|
+
if (Array.isArray(matchCase.body)) {
|
|
2269
|
+
let lastResult = { success: true, output: null };
|
|
2270
|
+
for (const bodyNode of matchCase.body) {
|
|
2271
|
+
lastResult = await ctx.executeNode(bodyNode);
|
|
2272
|
+
if (!lastResult.success) break;
|
|
2273
|
+
}
|
|
2274
|
+
return lastResult;
|
|
2275
|
+
} else {
|
|
2276
|
+
const result = ctx.evaluateExpression(String(matchCase.body));
|
|
2277
|
+
return { success: true, output: result, executionTime: Date.now() - startTime };
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2281
|
+
return {
|
|
2282
|
+
success: false,
|
|
2283
|
+
error: "No pattern matched",
|
|
2284
|
+
executionTime: Date.now() - startTime
|
|
2285
|
+
};
|
|
2286
|
+
} catch (error) {
|
|
2287
|
+
return {
|
|
2288
|
+
success: false,
|
|
2289
|
+
error: `Match expression error: ${error instanceof Error ? error.message : String(error)}`,
|
|
2290
|
+
executionTime: Date.now() - startTime
|
|
2291
|
+
};
|
|
2292
|
+
}
|
|
2293
|
+
}
|
|
2294
|
+
|
|
2295
|
+
// src/runtime/holo-expression.ts
|
|
2296
|
+
var GET_MEMBER_PATH_CACHE = /* @__PURE__ */ new Map();
|
|
2297
|
+
var GET_MEMBER_PATH_MAX = 500;
|
|
2298
|
+
function getMemberPath(expr) {
|
|
2299
|
+
const key = JSON.stringify(expr);
|
|
2300
|
+
const cached = GET_MEMBER_PATH_CACHE.get(key);
|
|
2301
|
+
if (cached !== void 0 || GET_MEMBER_PATH_CACHE.has(key)) {
|
|
2302
|
+
return cached ?? null;
|
|
2303
|
+
}
|
|
2304
|
+
let result = null;
|
|
2305
|
+
if (expr.type === "Identifier") {
|
|
2306
|
+
result = expr.name;
|
|
2307
|
+
} else if (expr.type === "MemberExpression") {
|
|
2308
|
+
const parentPath = getMemberPath(expr.object);
|
|
2309
|
+
if (parentPath) result = `${parentPath}.${expr.property}`;
|
|
2310
|
+
}
|
|
2311
|
+
if (GET_MEMBER_PATH_CACHE.size >= GET_MEMBER_PATH_MAX) {
|
|
2312
|
+
const firstKey = GET_MEMBER_PATH_CACHE.keys().next().value;
|
|
2313
|
+
if (firstKey !== void 0) GET_MEMBER_PATH_CACHE.delete(firstKey);
|
|
2314
|
+
}
|
|
2315
|
+
GET_MEMBER_PATH_CACHE.set(key, result);
|
|
2316
|
+
return result;
|
|
2317
|
+
}
|
|
2318
|
+
async function evaluateHoloExpression(expr, scopeOverride, ctx) {
|
|
2319
|
+
switch (expr.type) {
|
|
2320
|
+
case "Literal":
|
|
2321
|
+
return expr.value;
|
|
2322
|
+
case "Identifier":
|
|
2323
|
+
return ctx.getVariable(expr.name, scopeOverride);
|
|
2324
|
+
case "MemberExpression": {
|
|
2325
|
+
const obj = await evaluateHoloExpression(expr.object, scopeOverride, ctx);
|
|
2326
|
+
if (obj && typeof obj === "object") {
|
|
2327
|
+
return obj[expr.property];
|
|
2328
|
+
}
|
|
2329
|
+
return void 0;
|
|
2330
|
+
}
|
|
2331
|
+
case "CallExpression": {
|
|
2332
|
+
if (!Array.isArray(expr.arguments)) {
|
|
2333
|
+
console.error("[CRITICAL] arguments is not an array for", JSON.stringify(expr));
|
|
2334
|
+
return void 0;
|
|
2335
|
+
}
|
|
2336
|
+
const callee = await evaluateHoloExpression(expr.callee, scopeOverride, ctx);
|
|
2337
|
+
const args = await Promise.all(
|
|
2338
|
+
expr.arguments.map(
|
|
2339
|
+
(a) => evaluateHoloExpression(a, scopeOverride, ctx)
|
|
2340
|
+
)
|
|
2341
|
+
);
|
|
2342
|
+
if (typeof callee === "function") {
|
|
2343
|
+
return callee(...args);
|
|
2344
|
+
}
|
|
2345
|
+
if (expr.callee.type === "Identifier") {
|
|
2346
|
+
const result = await ctx.callFunction(expr.callee.name, args);
|
|
2347
|
+
return result.output;
|
|
2348
|
+
}
|
|
2349
|
+
return void 0;
|
|
2350
|
+
}
|
|
2351
|
+
case "BinaryExpression": {
|
|
2352
|
+
const left = await evaluateHoloExpression(expr.left, scopeOverride, ctx);
|
|
2353
|
+
const right = await evaluateHoloExpression(expr.right, scopeOverride, ctx);
|
|
2354
|
+
switch (expr.operator) {
|
|
2355
|
+
case "+":
|
|
2356
|
+
return Number(left) + Number(right);
|
|
2357
|
+
case "-":
|
|
2358
|
+
return Number(left) - Number(right);
|
|
2359
|
+
case "*":
|
|
2360
|
+
return Number(left) * Number(right);
|
|
2361
|
+
case "/":
|
|
2362
|
+
return Number(left) / Number(right);
|
|
2363
|
+
case "==":
|
|
2364
|
+
return left == right;
|
|
2365
|
+
case "===":
|
|
2366
|
+
return left === right;
|
|
2367
|
+
case "!=":
|
|
2368
|
+
return left != right;
|
|
2369
|
+
case "!==":
|
|
2370
|
+
return left !== right;
|
|
2371
|
+
case "<":
|
|
2372
|
+
return Number(left) < Number(right);
|
|
2373
|
+
case ">":
|
|
2374
|
+
return Number(left) > Number(right);
|
|
2375
|
+
case "<=":
|
|
2376
|
+
return Number(left) <= Number(right);
|
|
2377
|
+
case ">=":
|
|
2378
|
+
return Number(left) >= Number(right);
|
|
2379
|
+
case "&&":
|
|
2380
|
+
return left && right;
|
|
2381
|
+
case "||":
|
|
2382
|
+
return left || right;
|
|
2383
|
+
default:
|
|
2384
|
+
return void 0;
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2387
|
+
case "ConditionalExpression": {
|
|
2388
|
+
const test = await evaluateHoloExpression(expr.test, scopeOverride, ctx);
|
|
2389
|
+
return test ? await evaluateHoloExpression(expr.consequent, scopeOverride, ctx) : await evaluateHoloExpression(expr.alternate, scopeOverride, ctx);
|
|
2390
|
+
}
|
|
2391
|
+
case "UpdateExpression": {
|
|
2392
|
+
const val = await evaluateHoloExpression(expr.argument, scopeOverride, ctx);
|
|
2393
|
+
const newVal = expr.operator === "++" ? val + 1 : val - 1;
|
|
2394
|
+
const path = getMemberPath(expr.argument);
|
|
2395
|
+
if (path) {
|
|
2396
|
+
ctx.setVariable(path, newVal, scopeOverride);
|
|
2397
|
+
}
|
|
2398
|
+
return expr.prefix ? newVal : val;
|
|
2399
|
+
}
|
|
2400
|
+
case "ArrayExpression": {
|
|
2401
|
+
return await Promise.all(
|
|
2402
|
+
expr.elements.map((e) => evaluateHoloExpression(e, scopeOverride, ctx))
|
|
2403
|
+
);
|
|
2404
|
+
}
|
|
2405
|
+
case "ObjectExpression": {
|
|
2406
|
+
const obj = {};
|
|
2407
|
+
for (const prop of expr.properties) {
|
|
2408
|
+
obj[prop.key] = await evaluateHoloExpression(prop.value, scopeOverride, ctx);
|
|
2409
|
+
}
|
|
2410
|
+
return obj;
|
|
2411
|
+
}
|
|
2412
|
+
default:
|
|
2413
|
+
return void 0;
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
function stringProperty(value) {
|
|
2417
|
+
return typeof value === "string" ? value : void 0;
|
|
2418
|
+
}
|
|
2419
|
+
function createDetachedParentRuntime() {
|
|
2420
|
+
const rootScope = { variables: /* @__PURE__ */ new Map() };
|
|
2421
|
+
return {
|
|
2422
|
+
async callFunction(functionName) {
|
|
2423
|
+
return {
|
|
2424
|
+
success: false,
|
|
2425
|
+
error: `Detached hydrated agent cannot call function: ${functionName}`
|
|
2426
|
+
};
|
|
2427
|
+
},
|
|
2428
|
+
getRootScope: () => rootScope,
|
|
2429
|
+
getVariable: () => void 0,
|
|
2430
|
+
async executeProgram() {
|
|
2431
|
+
return [{ success: false, error: "Detached hydrated agent cannot execute programs" }];
|
|
2432
|
+
},
|
|
2433
|
+
emit: async () => void 0,
|
|
2434
|
+
async executeHoloProgram() {
|
|
2435
|
+
return [{ success: false, error: "Detached hydrated agent cannot execute Holo programs" }];
|
|
2436
|
+
},
|
|
2437
|
+
evaluateExpression: () => void 0
|
|
2438
|
+
};
|
|
2439
|
+
}
|
|
2440
|
+
function textToEmbeddingFloat32(text, dim) {
|
|
2441
|
+
const out = new Float32Array(dim);
|
|
2442
|
+
let h = 5381;
|
|
2443
|
+
for (let i = 0; i < text.length; i++) {
|
|
2444
|
+
h = Math.imul(h, 33) ^ text.charCodeAt(i);
|
|
2445
|
+
h = h >>> 0;
|
|
2446
|
+
}
|
|
2447
|
+
for (let d = 0; d < dim; d++) {
|
|
2448
|
+
h = Math.imul(h, 1664525) + 1013904223;
|
|
2449
|
+
h = h >>> 0;
|
|
2450
|
+
out[d] = h / 4294967296 * 2 - 1;
|
|
2451
|
+
}
|
|
2452
|
+
return out;
|
|
2453
|
+
}
|
|
2454
|
+
var HoloScriptAgentRuntime = class _HoloScriptAgentRuntime {
|
|
2455
|
+
/**
|
|
2456
|
+
* Creates a new HoloScript agent runtime instance.
|
|
2457
|
+
*
|
|
2458
|
+
* @param agentNode - The OrbNode representing the agent template
|
|
2459
|
+
* @param parentRuntime - The parent runtime providing global context
|
|
2460
|
+
*
|
|
2461
|
+
* @example
|
|
2462
|
+
* ```typescript
|
|
2463
|
+
* const runtime = new HoloScriptAgentRuntime(miningAgentNode, mainRuntime);
|
|
2464
|
+
* ```
|
|
2465
|
+
*/
|
|
2466
|
+
constructor(agentNode, parentRuntime) {
|
|
2467
|
+
this.runningActions = /* @__PURE__ */ new Map();
|
|
2468
|
+
this.isDestroyed = false;
|
|
2469
|
+
// Episodic Memory & Semantic Extraction (Phase 7)
|
|
2470
|
+
this.rawEpisodes = [];
|
|
2471
|
+
this.semanticFacts = [];
|
|
2472
|
+
this.consolidationInterval = null;
|
|
2473
|
+
// JEPA action-planning loop (Phase 8)
|
|
2474
|
+
// Default latentDim=64, condDim=16 (action conditioning). Caller can swap
|
|
2475
|
+
// weights externally via this.jepaPredictor.setWeights() after training.
|
|
2476
|
+
this.jepaPredictor = new chunkTVHSPJ4N_cjs.JEPAPredictor({ latentDim: 64, condDim: 16 });
|
|
2477
|
+
this.jepaObjectiveNode = {};
|
|
2478
|
+
this.jepaObjectiveAttached = false;
|
|
2479
|
+
if (!agentNode || !parentRuntime) {
|
|
2480
|
+
return;
|
|
2481
|
+
}
|
|
2482
|
+
this.agentNode = agentNode;
|
|
2483
|
+
this.parentRuntime = parentRuntime;
|
|
2484
|
+
this.localState = new chunkGJNCFRJU_cjs.ReactiveState(agentNode.properties || {});
|
|
2485
|
+
this.bindDurableIdentity(agentNode.properties || {});
|
|
2486
|
+
this.initializeAgentContext();
|
|
2487
|
+
}
|
|
2488
|
+
/**
|
|
2489
|
+
* Rehydrate an agent identity from substrate-anchored seed data without relying
|
|
2490
|
+
* on the previous neural map. Reactive state, running actions, and episodes
|
|
2491
|
+
* start empty; only durable identity fields and semantic facts are replayed.
|
|
2492
|
+
*/
|
|
2493
|
+
static hydrate(seed, parentRuntime = createDetachedParentRuntime()) {
|
|
2494
|
+
const agentNode = {
|
|
2495
|
+
type: "orb",
|
|
2496
|
+
id: seed.handle,
|
|
2497
|
+
name: seed.handle,
|
|
2498
|
+
template: seed.brainCompositionRef,
|
|
2499
|
+
properties: {},
|
|
2500
|
+
directives: []
|
|
2501
|
+
};
|
|
2502
|
+
const runtime = new _HoloScriptAgentRuntime(agentNode, parentRuntime);
|
|
2503
|
+
runtime.applySeed(seed);
|
|
2504
|
+
return runtime;
|
|
2505
|
+
}
|
|
2506
|
+
/**
|
|
2507
|
+
* Reset the runtime for pooling reuse with new agent configuration.
|
|
2508
|
+
*
|
|
2509
|
+
* @param agentNode - New agent node to bind to this runtime
|
|
2510
|
+
* @param parentRuntime - Parent runtime for global context
|
|
2511
|
+
*/
|
|
2512
|
+
reset(agentNode, parentRuntime) {
|
|
2513
|
+
this.agentNode = agentNode;
|
|
2514
|
+
this.parentRuntime = parentRuntime;
|
|
2515
|
+
this.localState = new chunkGJNCFRJU_cjs.ReactiveState(agentNode.properties || {});
|
|
2516
|
+
this.runningActions.clear();
|
|
2517
|
+
this.isDestroyed = false;
|
|
2518
|
+
this.bindDurableIdentity(agentNode.properties || {});
|
|
2519
|
+
this.initializeAgentContext();
|
|
2520
|
+
}
|
|
2521
|
+
bindDurableIdentity(properties) {
|
|
2522
|
+
this.wallet = stringProperty(properties.wallet);
|
|
2523
|
+
this.handle = stringProperty(properties.handle) ?? this.agentNode.name;
|
|
2524
|
+
this.brainCompositionRef = stringProperty(properties.brainCompositionRef) ?? this.agentNode.template ?? this.agentNode.name;
|
|
2525
|
+
this.memorySnapshotHash = stringProperty(properties.memorySnapshotHash);
|
|
2526
|
+
this.resumeStepId = stringProperty(properties.resumeStepId);
|
|
2527
|
+
}
|
|
2528
|
+
applySeed(seed) {
|
|
2529
|
+
this.wallet = seed.wallet;
|
|
2530
|
+
this.handle = seed.handle;
|
|
2531
|
+
this.brainCompositionRef = seed.brainCompositionRef;
|
|
2532
|
+
this.memorySnapshotHash = seed.memorySnapshotHash;
|
|
2533
|
+
this.resumeStepId = seed.resumeStepId;
|
|
2534
|
+
this.semanticFacts = [...seed.semanticFacts ?? []];
|
|
2535
|
+
this.rawEpisodes = [];
|
|
2536
|
+
this.runningActions.clear();
|
|
2537
|
+
}
|
|
2538
|
+
durable() {
|
|
2539
|
+
return {
|
|
2540
|
+
wallet: this.wallet,
|
|
2541
|
+
handle: this.handle,
|
|
2542
|
+
brainCompositionRef: this.brainCompositionRef,
|
|
2543
|
+
memorySnapshotHash: this.memorySnapshotHash,
|
|
2544
|
+
resumeStepId: this.resumeStepId,
|
|
2545
|
+
semanticFacts: [...this.semanticFacts],
|
|
2546
|
+
annotations: {
|
|
2547
|
+
wallet: "durable",
|
|
2548
|
+
handle: "durable",
|
|
2549
|
+
brainCompositionRef: "durable",
|
|
2550
|
+
memorySnapshotHash: "durable",
|
|
2551
|
+
resumeStepId: "durable",
|
|
2552
|
+
semanticFacts: "durable"
|
|
2553
|
+
}
|
|
2554
|
+
};
|
|
2555
|
+
}
|
|
2556
|
+
losable() {
|
|
2557
|
+
return {
|
|
2558
|
+
reactiveState: this.localState.getSnapshot(),
|
|
2559
|
+
runningActions: Array.from(this.runningActions.keys()),
|
|
2560
|
+
rawEpisodes: [...this.rawEpisodes],
|
|
2561
|
+
annotations: {
|
|
2562
|
+
reactiveState: "losable",
|
|
2563
|
+
runningActions: "losable",
|
|
2564
|
+
rawEpisodes: "losable"
|
|
2565
|
+
}
|
|
2566
|
+
};
|
|
2567
|
+
}
|
|
2568
|
+
/**
|
|
2569
|
+
* Initialize the agent's execution context and memory consolidation.
|
|
2570
|
+
*/
|
|
2571
|
+
initializeAgentContext() {
|
|
2572
|
+
({
|
|
2573
|
+
id: this.agentNode.id || this.agentNode.name,
|
|
2574
|
+
type: this.agentNode.type,
|
|
2575
|
+
state: this.localState.getSnapshot(),
|
|
2576
|
+
properties: this.agentNode.properties});
|
|
2577
|
+
if (!this.consolidationInterval) {
|
|
2578
|
+
this.consolidationInterval = setInterval(() => this.consolidateMemory(), 3e4);
|
|
2579
|
+
}
|
|
2580
|
+
}
|
|
2581
|
+
/**
|
|
2582
|
+
* Records a raw episodic event into the agent's short-term history queue.
|
|
2583
|
+
*
|
|
2584
|
+
* @param action - The action that was performed
|
|
2585
|
+
* @param outcome - The result or outcome of the action
|
|
2586
|
+
* @param entitiesInvolved - List of entity IDs that were involved in the episode
|
|
2587
|
+
*
|
|
2588
|
+
* @example
|
|
2589
|
+
* ```typescript
|
|
2590
|
+
* agentRuntime.recordEpisode('mine_ore', 'collected 5 iron ore', ['ore_deposit_1', 'inventory']);
|
|
2591
|
+
* ```
|
|
2592
|
+
*/
|
|
2593
|
+
recordEpisode(action, outcome, entitiesInvolved) {
|
|
2594
|
+
this.rawEpisodes.push({
|
|
2595
|
+
id: `ep_${Date.now()}_${Math.random().toString(36).substring(7)}`,
|
|
2596
|
+
timestamp: Date.now(),
|
|
2597
|
+
action,
|
|
2598
|
+
outcome,
|
|
2599
|
+
entitiesInvolved
|
|
2600
|
+
});
|
|
2601
|
+
}
|
|
2602
|
+
/**
|
|
2603
|
+
* Internal idle tick leveraging the MemoryConsolidator subsystem to offload processing constraints.
|
|
2604
|
+
*/
|
|
2605
|
+
consolidateMemory() {
|
|
2606
|
+
if (this.isDestroyed || this.rawEpisodes.length < 5) return;
|
|
2607
|
+
const { newFacts, prunedEpisodes } = learning.MemoryConsolidator.compressEpisodes(this.rawEpisodes);
|
|
2608
|
+
if (newFacts.length > 0) {
|
|
2609
|
+
this.semanticFacts.push(...newFacts);
|
|
2610
|
+
this.rawEpisodes = this.rawEpisodes.filter((e) => !prunedEpisodes.includes(e.id));
|
|
2611
|
+
}
|
|
2612
|
+
this.semanticFacts = learning.MemoryConsolidator.pruneStaleFacts(this.semanticFacts);
|
|
2613
|
+
}
|
|
2614
|
+
/**
|
|
2615
|
+
* Lazily attach the JEPAObjective trait on first use so constructor stays fast.
|
|
2616
|
+
*/
|
|
2617
|
+
ensureJepaObjectiveAttached() {
|
|
2618
|
+
if (!this.jepaObjectiveAttached) {
|
|
2619
|
+
const config = this.getJepaObjectiveConfig();
|
|
2620
|
+
chunkTVHSPJ4N_cjs.jepObjectiveHandler.onAttach?.(
|
|
2621
|
+
this.jepaObjectiveNode,
|
|
2622
|
+
config,
|
|
2623
|
+
this.buildJepaTraitContext()
|
|
2624
|
+
);
|
|
2625
|
+
this.jepaObjectiveAttached = true;
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2628
|
+
getJepaObjectiveConfig() {
|
|
2629
|
+
const config = chunkTVHSPJ4N_cjs.jepObjectiveHandler.defaultConfig;
|
|
2630
|
+
if (!config) {
|
|
2631
|
+
throw new Error("JEPAObjective handler defaultConfig is required for offline training");
|
|
2632
|
+
}
|
|
2633
|
+
return config;
|
|
2634
|
+
}
|
|
2635
|
+
/**
|
|
2636
|
+
* Build a minimal TraitContext for the offline JEPA training call.
|
|
2637
|
+
* Losses are logged via the runtime logger; no external emit dependency.
|
|
2638
|
+
*/
|
|
2639
|
+
buildJepaTraitContext() {
|
|
2640
|
+
const agentName = this.agentNode?.name ?? "agent";
|
|
2641
|
+
return {
|
|
2642
|
+
vr: null,
|
|
2643
|
+
physics: null,
|
|
2644
|
+
audio: null,
|
|
2645
|
+
haptics: null,
|
|
2646
|
+
emit: (eventName, payload) => {
|
|
2647
|
+
if (eventName === "jepa:loss") {
|
|
2648
|
+
const p = payload;
|
|
2649
|
+
chunkILRBGFVD_cjs.logger.info(`[JEPA:${agentName}] step=${p.step} totalLoss=${p.totalLoss.toFixed(4)}`);
|
|
2650
|
+
} else if (eventName === "jepa:error") {
|
|
2651
|
+
const e = payload;
|
|
2652
|
+
chunkILRBGFVD_cjs.logger.warn(`[JEPA:${agentName}] error code=${e.code} ${e.message}`);
|
|
2653
|
+
}
|
|
2654
|
+
},
|
|
2655
|
+
getState: () => ({}),
|
|
2656
|
+
setState: () => {
|
|
2657
|
+
},
|
|
2658
|
+
getScaleMultiplier: () => 1,
|
|
2659
|
+
setScaleContext: () => {
|
|
2660
|
+
}
|
|
2661
|
+
};
|
|
2662
|
+
}
|
|
2663
|
+
/**
|
|
2664
|
+
* Store a JEPA training episode and trigger an offline JEPAObjective training
|
|
2665
|
+
* step. Called after each executeAction() to ensure every agent run generates
|
|
2666
|
+
* JEPA training data automatically.
|
|
2667
|
+
*
|
|
2668
|
+
* The (state, action, outcome) tuple is encoded as a `jepa:encode_pair` event
|
|
2669
|
+
* where context = JSON.stringify(state + action) and targetVec is derived from
|
|
2670
|
+
* the outcome string deterministically (same hash used by JEPAPredictor.plan).
|
|
2671
|
+
*/
|
|
2672
|
+
trainJepaOffline(stateBefore, action, outcome) {
|
|
2673
|
+
this.ensureJepaObjectiveAttached();
|
|
2674
|
+
const contextStr = JSON.stringify({ state: stateBefore, action });
|
|
2675
|
+
const config = this.getJepaObjectiveConfig();
|
|
2676
|
+
const latentDim = config.latentDim;
|
|
2677
|
+
const outcomeStr = outcome.success ? `success:${String(outcome.output ?? "")}` : `failure:${String(outcome.error ?? "")}`;
|
|
2678
|
+
const targetVec = textToEmbeddingFloat32(outcomeStr, latentDim);
|
|
2679
|
+
chunkTVHSPJ4N_cjs.jepObjectiveHandler.onEvent?.(
|
|
2680
|
+
this.jepaObjectiveNode,
|
|
2681
|
+
config,
|
|
2682
|
+
this.buildJepaTraitContext(),
|
|
2683
|
+
{
|
|
2684
|
+
type: "jepa:encode_pair",
|
|
2685
|
+
context: contextStr,
|
|
2686
|
+
targetVec,
|
|
2687
|
+
conditioning: void 0
|
|
2688
|
+
}
|
|
2689
|
+
);
|
|
2690
|
+
}
|
|
2691
|
+
/**
|
|
2692
|
+
* Lightweight fork-detection heuristic for runtime adapters.
|
|
2693
|
+
* Scans brain composition ref, template, and string properties for
|
|
2694
|
+
* HS010-blocked keywords, unknown compiler versions, non-canonical imports,
|
|
2695
|
+
* and no-op security traits. Self-contained (no mcp-server imports).
|
|
2696
|
+
*/
|
|
2697
|
+
checkForkSandbox() {
|
|
2698
|
+
const sources = [];
|
|
2699
|
+
if (this.brainCompositionRef) sources.push(this.brainCompositionRef);
|
|
2700
|
+
if (this.agentNode.template) sources.push(this.agentNode.template);
|
|
2701
|
+
for (const val of Object.values(this.agentNode.properties || {})) {
|
|
2702
|
+
if (typeof val === "string") sources.push(val);
|
|
2703
|
+
}
|
|
2704
|
+
const directives = this.agentNode.directives;
|
|
2705
|
+
if (directives) {
|
|
2706
|
+
for (const d of directives) {
|
|
2707
|
+
if (typeof d.body === "string") sources.push(d.body);
|
|
2708
|
+
}
|
|
2709
|
+
}
|
|
2710
|
+
const blockedKeywords = [
|
|
2711
|
+
"process",
|
|
2712
|
+
"fs",
|
|
2713
|
+
"require",
|
|
2714
|
+
"eval",
|
|
2715
|
+
"exec",
|
|
2716
|
+
"spawn",
|
|
2717
|
+
"child_process",
|
|
2718
|
+
"constructor",
|
|
2719
|
+
"prototype",
|
|
2720
|
+
"globalThis"
|
|
2721
|
+
];
|
|
2722
|
+
const canonicalVersions = ["7.0.0", "6.0.2", "6.0.1", "6.0.0"];
|
|
2723
|
+
for (const src of sources) {
|
|
2724
|
+
for (const kw of blockedKeywords) {
|
|
2725
|
+
if (new RegExp(`\\b${kw}\\b`).test(src)) {
|
|
2726
|
+
return { allowed: false, reason: `HS010-blocked-keyword:${kw}` };
|
|
2727
|
+
}
|
|
2728
|
+
}
|
|
2729
|
+
const versionMatch = src.match(/@compiler\s+version\s+["']?([\d.]+)["']?/i);
|
|
2730
|
+
if (versionMatch) {
|
|
2731
|
+
const claimed = versionMatch[1];
|
|
2732
|
+
if (!canonicalVersions.includes(claimed)) {
|
|
2733
|
+
return { allowed: false, reason: `unknown-compiler-version:${claimed}` };
|
|
2734
|
+
}
|
|
2735
|
+
}
|
|
2736
|
+
if (/\bfrom\s+['"](?!@holoscript\/)[@\w\/-]+['"]/.test(src)) {
|
|
2737
|
+
return { allowed: false, reason: "non-canonical-import" };
|
|
2738
|
+
}
|
|
2739
|
+
if (/(?:^|\s)@security_sandbox\b/.test(src) && !/\bimport\s+.*security-sandbox/.test(src)) {
|
|
2740
|
+
return { allowed: false, reason: "no-op-security-trait" };
|
|
2741
|
+
}
|
|
2742
|
+
}
|
|
2743
|
+
return { allowed: true };
|
|
2744
|
+
}
|
|
2745
|
+
/**
|
|
2746
|
+
* Execute an action (method) defined on the agent template.
|
|
2747
|
+
*
|
|
2748
|
+
* @param actionName - Name of the action/method to execute
|
|
2749
|
+
* @param args - Arguments to pass to the action method
|
|
2750
|
+
* @returns Promise resolving to execution result
|
|
2751
|
+
* @throws {Error} When agent is destroyed or action execution fails
|
|
2752
|
+
*
|
|
2753
|
+
* @example
|
|
2754
|
+
* ```typescript
|
|
2755
|
+
* const result = await agentRuntime.executeAction('patrol', ['north_sector']);
|
|
2756
|
+
* if (result.success) {
|
|
2757
|
+
* console.log('Patrol completed:', result.output);
|
|
2758
|
+
* }
|
|
2759
|
+
* ```
|
|
2760
|
+
*/
|
|
2761
|
+
async executeAction(actionName, args = []) {
|
|
2762
|
+
if (this.isDestroyed) return { success: false, error: "Agent destroyed" };
|
|
2763
|
+
const forkCheck = this.checkForkSandbox();
|
|
2764
|
+
if (!forkCheck.allowed) {
|
|
2765
|
+
chunkILRBGFVD_cjs.logger.warn(`[Agent:${this.agentNode.name}] ForkSandboxGate blocked action "${actionName}": ${forkCheck.reason}`);
|
|
2766
|
+
return { success: false, error: `ForkSandboxGate: ${forkCheck.reason}` };
|
|
2767
|
+
}
|
|
2768
|
+
const directives = this.agentNode.directives;
|
|
2769
|
+
const action = directives?.find((d) => d.type === "method" && d.name === actionName);
|
|
2770
|
+
if (!action) {
|
|
2771
|
+
return this.parentRuntime.callFunction(actionName, args);
|
|
2772
|
+
}
|
|
2773
|
+
chunkILRBGFVD_cjs.logger.info(`[Agent:${this.agentNode.name}] Executing action: ${actionName}`);
|
|
2774
|
+
const stateBefore = this.localState.getSnapshot();
|
|
2775
|
+
const agentScope = {
|
|
2776
|
+
variables: /* @__PURE__ */ new Map(),
|
|
2777
|
+
parent: this.parentRuntime.getRootScope()
|
|
2778
|
+
};
|
|
2779
|
+
const agentData = this.parentRuntime.getVariable(this.agentNode.name);
|
|
2780
|
+
if (agentData && !agentData.state) {
|
|
2781
|
+
agentData.state = this.localState.getProxy();
|
|
2782
|
+
}
|
|
2783
|
+
agentScope.variables.set(
|
|
2784
|
+
"this",
|
|
2785
|
+
agentData || {
|
|
2786
|
+
id: this.agentNode.name,
|
|
2787
|
+
state: this.localState.getProxy(),
|
|
2788
|
+
properties: this.agentNode.properties
|
|
2789
|
+
}
|
|
2790
|
+
);
|
|
2791
|
+
if (action.parameters && args) {
|
|
2792
|
+
action.parameters.forEach((param, i) => {
|
|
2793
|
+
agentScope.variables.set(param.name, args[i]);
|
|
2794
|
+
});
|
|
2795
|
+
}
|
|
2796
|
+
let executionResult = { success: false, error: "Action did not complete" };
|
|
2797
|
+
try {
|
|
2798
|
+
if (Array.isArray(action.body)) {
|
|
2799
|
+
const results = await this.parentRuntime.executeHoloProgram(action.body, agentScope);
|
|
2800
|
+
const success = results.every((r) => r.success);
|
|
2801
|
+
executionResult = {
|
|
2802
|
+
success,
|
|
2803
|
+
output: results[results.length - 1]?.output,
|
|
2804
|
+
error: results.find((r) => !r.success)?.error
|
|
2805
|
+
};
|
|
2806
|
+
} else {
|
|
2807
|
+
const results = await this.parentRuntime.executeProgram(action.body, 1);
|
|
2808
|
+
const success = results.every((r) => r.success);
|
|
2809
|
+
executionResult = {
|
|
2810
|
+
success,
|
|
2811
|
+
output: results[results.length - 1]?.output,
|
|
2812
|
+
error: results.find((r) => !r.success)?.error
|
|
2813
|
+
};
|
|
2814
|
+
}
|
|
2815
|
+
} finally {
|
|
2816
|
+
this.runningActions.delete(actionName);
|
|
2817
|
+
}
|
|
2818
|
+
const outcomeStr = executionResult.success ? `success:${String(executionResult.output ?? "")}` : `failure:${String(executionResult.error ?? "")}`;
|
|
2819
|
+
this.recordEpisode(actionName, outcomeStr, [this.agentNode.name]);
|
|
2820
|
+
try {
|
|
2821
|
+
this.trainJepaOffline(stateBefore, actionName, executionResult);
|
|
2822
|
+
} catch (trainErr) {
|
|
2823
|
+
chunkILRBGFVD_cjs.logger.warn(
|
|
2824
|
+
`[JEPA:${this.agentNode.name}] trainJepaOffline error: ${String(trainErr)}`
|
|
2825
|
+
);
|
|
2826
|
+
}
|
|
2827
|
+
return executionResult;
|
|
2828
|
+
}
|
|
2829
|
+
/**
|
|
2830
|
+
* Autonomous 'thinking' cycle using LLM for decision making.
|
|
2831
|
+
*
|
|
2832
|
+
* @param prompt - Optional specific prompt for the LLM, defaults to general decision prompt
|
|
2833
|
+
* @returns Promise resolving to the LLM's decision as a string
|
|
2834
|
+
*
|
|
2835
|
+
* @example
|
|
2836
|
+
* ```typescript
|
|
2837
|
+
* const decision = await agentRuntime.think('Should I retreat or continue attacking?');
|
|
2838
|
+
* console.log('Agent decision:', decision);
|
|
2839
|
+
* ```
|
|
2840
|
+
*/
|
|
2841
|
+
async think(prompt) {
|
|
2842
|
+
chunkILRBGFVD_cjs.logger.info(`[Agent:${this.agentNode.name}] Thinking...`);
|
|
2843
|
+
const directives = this.agentNode.directives;
|
|
2844
|
+
const candidateActions = (directives ?? []).filter((d) => d.type === "method" && d.name).map((d) => d.name);
|
|
2845
|
+
let jepaSuggestion;
|
|
2846
|
+
if (candidateActions.length > 0) {
|
|
2847
|
+
const stateSnapshot = JSON.stringify(this.localState.getSnapshot());
|
|
2848
|
+
const planResult = this.jepaPredictor.plan(stateSnapshot, candidateActions);
|
|
2849
|
+
jepaSuggestion = planResult.action;
|
|
2850
|
+
chunkILRBGFVD_cjs.logger.info(
|
|
2851
|
+
`[JEPA:${this.agentNode.name}] plan() \u2192 "${planResult.action}" confidence=${planResult.confidence.toFixed(4)}`
|
|
2852
|
+
);
|
|
2853
|
+
}
|
|
2854
|
+
const effectivePrompt = jepaSuggestion ? `${prompt ?? "Decide the next best action based on current state."} JEPA predictor suggests: "${jepaSuggestion}".` : prompt ?? "Decide the next best action based on current state.";
|
|
2855
|
+
const result = await this.parentRuntime.emit("agent_think", {
|
|
2856
|
+
agentId: this.agentNode.name,
|
|
2857
|
+
context: this.localState.getSnapshot(),
|
|
2858
|
+
prompt: effectivePrompt,
|
|
2859
|
+
jepaSuggestion
|
|
2860
|
+
});
|
|
2861
|
+
return result?.decision || jepaSuggestion || "No clear decision made.";
|
|
2862
|
+
}
|
|
2863
|
+
/**
|
|
2864
|
+
* Handle lifecycle events for this specific agent.
|
|
2865
|
+
*
|
|
2866
|
+
* @param eventType - The type of event being handled
|
|
2867
|
+
* @param data - Event data to bind to the execution scope
|
|
2868
|
+
*
|
|
2869
|
+
* @example
|
|
2870
|
+
* ```typescript
|
|
2871
|
+
* await agentRuntime.onEvent('enemy_spotted', {
|
|
2872
|
+
* enemy: 'orc_warrior',
|
|
2873
|
+
* distance: 50
|
|
2874
|
+
* });
|
|
2875
|
+
* ```
|
|
2876
|
+
*/
|
|
2877
|
+
async onEvent(eventType, data) {
|
|
2878
|
+
if (this.isDestroyed) return;
|
|
2879
|
+
const directives = this.agentNode.directives;
|
|
2880
|
+
const handler = directives?.find((d) => d.type === "lifecycle" && d.hook === eventType);
|
|
2881
|
+
if (handler) {
|
|
2882
|
+
const eventScope = {
|
|
2883
|
+
variables: /* @__PURE__ */ new Map(),
|
|
2884
|
+
parent: this.parentRuntime.getRootScope()
|
|
2885
|
+
};
|
|
2886
|
+
if (data && typeof data === "object") {
|
|
2887
|
+
for (const [key, val] of Object.entries(data)) {
|
|
2888
|
+
eventScope.variables.set(key, val);
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
eventScope.variables.set("eventData", data);
|
|
2892
|
+
directives?.forEach((d) => {
|
|
2893
|
+
if (d.type === "method" && d.name) {
|
|
2894
|
+
eventScope.variables.set(d.name, ((...args) => this.executeAction(d.name, args)));
|
|
2895
|
+
}
|
|
2896
|
+
});
|
|
2897
|
+
const params = handler.parameters;
|
|
2898
|
+
if (params && Array.isArray(params) && data && typeof data === "object") {
|
|
2899
|
+
const dataRecord = data;
|
|
2900
|
+
params.forEach((param) => {
|
|
2901
|
+
if (dataRecord[param.name] !== void 0) {
|
|
2902
|
+
eventScope.variables.set(param.name, dataRecord[param.name]);
|
|
2903
|
+
}
|
|
2904
|
+
});
|
|
2905
|
+
}
|
|
2906
|
+
const agentData = this.parentRuntime.getVariable(this.agentNode.name);
|
|
2907
|
+
if (agentData && !agentData.state) {
|
|
2908
|
+
agentData.state = this.localState.getProxy();
|
|
2909
|
+
}
|
|
2910
|
+
eventScope.variables.set(
|
|
2911
|
+
"this",
|
|
2912
|
+
agentData || {
|
|
2913
|
+
id: this.agentNode.name,
|
|
2914
|
+
state: this.localState.getProxy(),
|
|
2915
|
+
properties: this.agentNode.properties
|
|
2916
|
+
}
|
|
2917
|
+
);
|
|
2918
|
+
try {
|
|
2919
|
+
if (Array.isArray(handler.body)) {
|
|
2920
|
+
await this.parentRuntime.executeHoloProgram(handler.body, eventScope);
|
|
2921
|
+
} else {
|
|
2922
|
+
this.parentRuntime.evaluateExpression(handler.body);
|
|
2923
|
+
}
|
|
2924
|
+
} finally {
|
|
2925
|
+
}
|
|
2926
|
+
}
|
|
2927
|
+
}
|
|
2928
|
+
/**
|
|
2929
|
+
* Clean up the agent runtime, stopping all running processes and timers.
|
|
2930
|
+
*/
|
|
2931
|
+
destroy() {
|
|
2932
|
+
this.isDestroyed = true;
|
|
2933
|
+
this.runningActions.clear();
|
|
2934
|
+
if (this.consolidationInterval) {
|
|
2935
|
+
clearInterval(this.consolidationInterval);
|
|
2936
|
+
this.consolidationInterval = null;
|
|
2937
|
+
}
|
|
2938
|
+
chunkILRBGFVD_cjs.logger.info(`[Agent:${this.agentNode?.name ?? "unbound"}] Runtime destroyed.`);
|
|
2939
|
+
}
|
|
2940
|
+
/**
|
|
2941
|
+
* Get the agent's unique identifier.
|
|
2942
|
+
*
|
|
2943
|
+
* @returns The agent's ID or name
|
|
2944
|
+
*/
|
|
2945
|
+
get id() {
|
|
2946
|
+
return this.agentNode.id || this.agentNode.name;
|
|
2947
|
+
}
|
|
2948
|
+
/**
|
|
2949
|
+
* Get the agent's current reactive state proxy.
|
|
2950
|
+
*
|
|
2951
|
+
* @returns Proxy object for the agent's state
|
|
2952
|
+
*/
|
|
2953
|
+
get state() {
|
|
2954
|
+
return this.localState.getProxy();
|
|
2955
|
+
}
|
|
2956
|
+
/**
|
|
2957
|
+
* Get the agent's current reactive state proxy.
|
|
2958
|
+
*
|
|
2959
|
+
* @returns Proxy object for the agent's state
|
|
2960
|
+
*/
|
|
2961
|
+
getState() {
|
|
2962
|
+
return this.localState.getProxy();
|
|
2963
|
+
}
|
|
2964
|
+
};
|
|
2965
|
+
|
|
2966
|
+
// src/extensions/ExtensionRegistry.ts
|
|
2967
|
+
var ExtensionRegistry = class {
|
|
2968
|
+
constructor(runtime) {
|
|
2969
|
+
this.extensions = /* @__PURE__ */ new Map();
|
|
2970
|
+
this.runtime = runtime;
|
|
2971
|
+
}
|
|
2972
|
+
/**
|
|
2973
|
+
* Load an extension into the runtime
|
|
2974
|
+
*/
|
|
2975
|
+
loadExtension(extension) {
|
|
2976
|
+
if (this.extensions.has(extension.id)) {
|
|
2977
|
+
chunkILRBGFVD_cjs.logger.warn(`Extension ${extension.id} is already loaded.`);
|
|
2978
|
+
return;
|
|
2979
|
+
}
|
|
2980
|
+
const context = {
|
|
2981
|
+
registerTrait: (name, handler) => {
|
|
2982
|
+
chunkILRBGFVD_cjs.logger.info(`[Extension:${extension.id}] Registering trait: ${name}`);
|
|
2983
|
+
this.runtime.registerTrait(name, handler);
|
|
2984
|
+
},
|
|
2985
|
+
registerFunction: (name, fn) => {
|
|
2986
|
+
chunkILRBGFVD_cjs.logger.info(`[Extension:${extension.id}] Registering function: ${name}`);
|
|
2987
|
+
this.runtime.registerGlobalFunction(name, fn);
|
|
2988
|
+
},
|
|
2989
|
+
logger: chunkILRBGFVD_cjs.logger
|
|
2990
|
+
};
|
|
2991
|
+
try {
|
|
2992
|
+
extension.onLoad(context);
|
|
2993
|
+
this.extensions.set(extension.id, extension);
|
|
2994
|
+
chunkILRBGFVD_cjs.logger.info(`Extension loaded: ${extension.id} v${extension.version}`);
|
|
2995
|
+
} catch (error) {
|
|
2996
|
+
chunkILRBGFVD_cjs.logger.error(`Failed to load extension ${extension.id}:`, {
|
|
2997
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2998
|
+
});
|
|
2999
|
+
throw error;
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
3002
|
+
/**
|
|
3003
|
+
* Unload an extension
|
|
3004
|
+
*/
|
|
3005
|
+
unloadingExtension(id) {
|
|
3006
|
+
const extension = this.extensions.get(id);
|
|
3007
|
+
if (!extension) return;
|
|
3008
|
+
try {
|
|
3009
|
+
const context = {
|
|
3010
|
+
registerTrait: () => {
|
|
3011
|
+
},
|
|
3012
|
+
registerFunction: () => {
|
|
3013
|
+
},
|
|
3014
|
+
logger: chunkILRBGFVD_cjs.logger
|
|
3015
|
+
};
|
|
3016
|
+
extension.onUnload(context);
|
|
3017
|
+
} catch (e) {
|
|
3018
|
+
chunkILRBGFVD_cjs.logger.error(`Error unloading extension ${id}`, {
|
|
3019
|
+
error: e instanceof Error ? e.message : String(e)
|
|
3020
|
+
});
|
|
3021
|
+
}
|
|
3022
|
+
this.extensions.delete(id);
|
|
3023
|
+
chunkILRBGFVD_cjs.logger.info(`Extension unloaded: ${id}`);
|
|
3024
|
+
}
|
|
3025
|
+
getExtension(id) {
|
|
3026
|
+
return this.extensions.get(id);
|
|
3027
|
+
}
|
|
3028
|
+
};
|
|
3029
|
+
|
|
3030
|
+
// src/HoloScriptRuntime.ts
|
|
3031
|
+
var RUNTIME_SECURITY_LIMITS = {
|
|
3032
|
+
maxExecutionDepth: 50,
|
|
3033
|
+
maxTotalNodes: 1e3,
|
|
3034
|
+
maxExecutionTimeMs: 5e3,
|
|
3035
|
+
maxParticlesPerSystem: 1e3,
|
|
3036
|
+
maxCallStackDepth: 100
|
|
3037
|
+
};
|
|
3038
|
+
function isOrbData2(v) {
|
|
3039
|
+
return v !== null && typeof v === "object" && v.__type === "orb";
|
|
3040
|
+
}
|
|
3041
|
+
var HoloScriptRuntime = class {
|
|
3042
|
+
constructor(_importLoader, customFunctions) {
|
|
3043
|
+
this.particleSystems = /* @__PURE__ */ new Map();
|
|
3044
|
+
this.executionHistory = [];
|
|
3045
|
+
this.agentRuntimes = /* @__PURE__ */ new Map();
|
|
3046
|
+
this.startTime = 0;
|
|
3047
|
+
this.nodeCount = 0;
|
|
3048
|
+
this.callStack = [];
|
|
3049
|
+
this.eventHandlers = /* @__PURE__ */ new Map();
|
|
3050
|
+
this.animations = /* @__PURE__ */ new Map();
|
|
3051
|
+
this.uiElements = /* @__PURE__ */ new Map();
|
|
3052
|
+
this.proceduralSkills = /* @__PURE__ */ new Map();
|
|
3053
|
+
this.traitHandlers = /* @__PURE__ */ new Map();
|
|
3054
|
+
this.context = createEmptyContext();
|
|
3055
|
+
this.currentScope = { variables: this.context.variables };
|
|
3056
|
+
this.builtinFunctions = this.initBuiltins(customFunctions);
|
|
3057
|
+
this.agentPool = new engineRuntime__namespace.ObjectPool(
|
|
3058
|
+
() => new HoloScriptAgentRuntime(),
|
|
3059
|
+
// Preallocation mode (optional args)
|
|
3060
|
+
(agent) => agent.destroy(),
|
|
3061
|
+
50
|
|
3062
|
+
);
|
|
3063
|
+
engineRuntime__namespace.registerVoiceSynthesizer("default", new engineRuntime__namespace.BaseVoiceSynthesizer());
|
|
3064
|
+
engineRuntime__namespace.registerEmotionDetector("default", new engineRuntime__namespace.LocalEmotionDetector());
|
|
3065
|
+
engineRuntime__namespace.registerSpeechRecognizer("default", new engineRuntime__namespace.MockSpeechRecognizer());
|
|
3066
|
+
for (const [name, fn] of this.builtinFunctions) {
|
|
3067
|
+
this.context.functions.set(name, ((...spreadArgs) => fn(spreadArgs)));
|
|
3068
|
+
}
|
|
3069
|
+
attachStateInvalidationConsumer(this.buildEventSystemContext(), defaultStateInvalidationRegistry);
|
|
3070
|
+
this.registerFunction("get_attended_entities", (args) => {
|
|
3071
|
+
const topK = typeof args[0] === "number" ? args[0] : 10;
|
|
3072
|
+
const selfRaw = this.context.variables.get("self");
|
|
3073
|
+
const selfNode = isOrbData2(selfRaw) ? selfRaw : void 0;
|
|
3074
|
+
const observerPos = selfNode?.position ?? [0, 0, 0];
|
|
3075
|
+
const entities = [];
|
|
3076
|
+
this.context.spatialMemory.forEach((pos, id) => {
|
|
3077
|
+
if (id !== selfNode?.name) {
|
|
3078
|
+
const entityRaw = this.context.variables.get(id);
|
|
3079
|
+
const entityOrb = isOrbData2(entityRaw) ? entityRaw : void 0;
|
|
3080
|
+
entities.push({
|
|
3081
|
+
id,
|
|
3082
|
+
position: pos,
|
|
3083
|
+
velocity: entityOrb?.velocity,
|
|
3084
|
+
saliencyBase: typeof entityOrb?.saliency === "number" ? entityOrb.saliency : void 0
|
|
3085
|
+
});
|
|
3086
|
+
}
|
|
3087
|
+
});
|
|
3088
|
+
return orbital.AttentionEngine.getTopKEntities(
|
|
3089
|
+
observerPos,
|
|
3090
|
+
entities,
|
|
3091
|
+
topK
|
|
3092
|
+
);
|
|
3093
|
+
});
|
|
3094
|
+
this.traitHandlers.set("mitosis", chunkTVHSPJ4N_cjs.mitosisHandler);
|
|
3095
|
+
this.traitHandlers.set("orbital", chunkTVHSPJ4N_cjs.orbitalHandler);
|
|
3096
|
+
this.extensionRegistry = new ExtensionRegistry(this);
|
|
3097
|
+
engineRuntime__namespace.stateMachineInterpreter.setHookExecutor((code) => this.evaluateExpression(code));
|
|
3098
|
+
engineRuntime__namespace.stateMachineInterpreter.setGuardEvaluator((expr) => this.evaluateExpression(expr));
|
|
3099
|
+
}
|
|
3100
|
+
/**
|
|
3101
|
+
* Initialize built-in functions
|
|
3102
|
+
*/
|
|
3103
|
+
/** Construct a BuiltinsContext bound to this runtime. (Slice 28) */
|
|
3104
|
+
buildBuiltinsContext() {
|
|
3105
|
+
return {
|
|
3106
|
+
uiElements: this.uiElements,
|
|
3107
|
+
hologramState: this.context.hologramState,
|
|
3108
|
+
spatialMemory: this.context.spatialMemory,
|
|
3109
|
+
animations: this.animations,
|
|
3110
|
+
variables: this.context.variables,
|
|
3111
|
+
templates: this.context.templates,
|
|
3112
|
+
executionStack: this.context.executionStack,
|
|
3113
|
+
agentRuntimes: this.agentRuntimes,
|
|
3114
|
+
createParticleEffect: (name, position, color, count) => this.createParticleEffect(name, position, color, count),
|
|
3115
|
+
createConnectionStream: (from, to, fromPos, toPos, dataType) => this.createConnectionStream(from, to, fromPos, toPos, dataType),
|
|
3116
|
+
emit: (event, data) => this.emit(event, data),
|
|
3117
|
+
setVariable: (name, value) => this.setVariable(name, value),
|
|
3118
|
+
getVariable: (name) => this.getVariable(name),
|
|
3119
|
+
executeOrb: (orbNode) => executeOrb(orbNode, this.buildOrbExecutorContext()),
|
|
3120
|
+
calculateArc: (args) => this.handleCalculateArc(args)
|
|
3121
|
+
};
|
|
3122
|
+
}
|
|
3123
|
+
/**
|
|
3124
|
+
* Initialize built-in functions (W1-T4 slice 28: impl extracted to
|
|
3125
|
+
* ./runtime/builtins-registry). Thin wrapper that constructs the
|
|
3126
|
+
* context bag + delegates to createBuiltinsMap.
|
|
3127
|
+
*/
|
|
3128
|
+
initBuiltins(customFunctions) {
|
|
3129
|
+
return createBuiltinsMap(this.buildBuiltinsContext(), customFunctions);
|
|
3130
|
+
}
|
|
3131
|
+
/**
|
|
3132
|
+
* Register a global function from an extension
|
|
3133
|
+
*/
|
|
3134
|
+
registerGlobalFunction(name, fn) {
|
|
3135
|
+
this.context.functions.set(name, ((...spreadArgs) => fn(spreadArgs)));
|
|
3136
|
+
}
|
|
3137
|
+
/**
|
|
3138
|
+
* Register a custom trait from an extension
|
|
3139
|
+
*/
|
|
3140
|
+
registerTrait(name, handler) {
|
|
3141
|
+
const vrName = name;
|
|
3142
|
+
this.traitHandlers.set(vrName, handler);
|
|
3143
|
+
chunkILRBGFVD_cjs.logger.info(`Registered trait: ${name}`);
|
|
3144
|
+
}
|
|
3145
|
+
/**
|
|
3146
|
+
* Get the extension registry
|
|
3147
|
+
*/
|
|
3148
|
+
getExtensionRegistry() {
|
|
3149
|
+
return this.extensionRegistry;
|
|
3150
|
+
}
|
|
3151
|
+
/**
|
|
3152
|
+
* Execute a single AST node.
|
|
3153
|
+
*
|
|
3154
|
+
* W1-T4 slice 34: the 225-LOC switch that used to live here is now a
|
|
3155
|
+
* Map<nodeType, handler> in ./runtime/node-type-registry. This method
|
|
3156
|
+
* keeps only the bookkeeping (executionStack push/pop, executionHistory
|
|
3157
|
+
* append, startTime/executionTime, error catch) — dispatch is a table
|
|
3158
|
+
* lookup. Adding a new node type is a one-line registry entry.
|
|
3159
|
+
*/
|
|
3160
|
+
async executeNode(node) {
|
|
3161
|
+
const startTime = Date.now();
|
|
3162
|
+
try {
|
|
3163
|
+
this.context.executionStack.push(node);
|
|
3164
|
+
const result = await dispatchNode(
|
|
3165
|
+
node,
|
|
3166
|
+
this
|
|
3167
|
+
);
|
|
3168
|
+
result.executionTime = Date.now() - startTime;
|
|
3169
|
+
this.executionHistory.push(result);
|
|
3170
|
+
this.context.executionStack.pop();
|
|
3171
|
+
return result;
|
|
3172
|
+
} catch (error) {
|
|
3173
|
+
const execTime = Date.now() - startTime;
|
|
3174
|
+
const errorResult = {
|
|
3175
|
+
success: false,
|
|
3176
|
+
error: error instanceof Error ? error.message : String(error),
|
|
3177
|
+
executionTime: execTime
|
|
3178
|
+
};
|
|
3179
|
+
this.executionHistory.push(errorResult);
|
|
3180
|
+
this.context.executionStack.pop();
|
|
3181
|
+
return errorResult;
|
|
3182
|
+
}
|
|
3183
|
+
}
|
|
3184
|
+
/**
|
|
3185
|
+
* Execute multiple nodes or a single node (unified entry point)
|
|
3186
|
+
*/
|
|
3187
|
+
async execute(nodes) {
|
|
3188
|
+
this.startTime = Date.now();
|
|
3189
|
+
this.nodeCount = 0;
|
|
3190
|
+
if (Array.isArray(nodes)) {
|
|
3191
|
+
const results = await this.executeProgram(nodes);
|
|
3192
|
+
const success = results.every((r) => r.success);
|
|
3193
|
+
const lastResult = results[results.length - 1];
|
|
3194
|
+
let output = success ? `Program executed (${results.length} nodes)` : "Program failed";
|
|
3195
|
+
if (lastResult && lastResult.success && lastResult.output !== void 0) {
|
|
3196
|
+
output = lastResult.output;
|
|
3197
|
+
}
|
|
3198
|
+
return {
|
|
3199
|
+
success,
|
|
3200
|
+
output,
|
|
3201
|
+
error: results.find((r) => !r.success)?.error
|
|
3202
|
+
};
|
|
3203
|
+
} else {
|
|
3204
|
+
return this.executeNode(nodes);
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
/**
|
|
3208
|
+
* Execute multiple nodes in sequence
|
|
3209
|
+
*/
|
|
3210
|
+
async executeProgram(nodes, depth = 0) {
|
|
3211
|
+
if (depth === 0) {
|
|
3212
|
+
this.startTime = Date.now();
|
|
3213
|
+
this.nodeCount = 0;
|
|
3214
|
+
}
|
|
3215
|
+
if (depth > RUNTIME_SECURITY_LIMITS.maxExecutionDepth) {
|
|
3216
|
+
chunkILRBGFVD_cjs.logger.error("Max execution depth exceeded", { depth });
|
|
3217
|
+
return [
|
|
3218
|
+
{
|
|
3219
|
+
success: false,
|
|
3220
|
+
error: `Max execution depth exceeded (${RUNTIME_SECURITY_LIMITS.maxExecutionDepth})`,
|
|
3221
|
+
executionTime: 0
|
|
3222
|
+
}
|
|
3223
|
+
];
|
|
3224
|
+
}
|
|
3225
|
+
const results = [];
|
|
3226
|
+
for (const node of nodes) {
|
|
3227
|
+
this.nodeCount++;
|
|
3228
|
+
if (this.nodeCount > RUNTIME_SECURITY_LIMITS.maxTotalNodes) {
|
|
3229
|
+
chunkILRBGFVD_cjs.logger.error("Max total nodes exceeded", { count: this.nodeCount });
|
|
3230
|
+
results.push({
|
|
3231
|
+
success: false,
|
|
3232
|
+
error: "Max total nodes exceeded",
|
|
3233
|
+
executionTime: Date.now() - this.startTime
|
|
3234
|
+
});
|
|
3235
|
+
break;
|
|
3236
|
+
}
|
|
3237
|
+
if (Date.now() - this.startTime > RUNTIME_SECURITY_LIMITS.maxExecutionTimeMs) {
|
|
3238
|
+
chunkILRBGFVD_cjs.logger.error("Execution timeout", { duration: Date.now() - this.startTime });
|
|
3239
|
+
results.push({
|
|
3240
|
+
success: false,
|
|
3241
|
+
error: "Execution timeout",
|
|
3242
|
+
executionTime: Date.now() - this.startTime
|
|
3243
|
+
});
|
|
3244
|
+
break;
|
|
3245
|
+
}
|
|
3246
|
+
const result = await this.executeNode(node);
|
|
3247
|
+
results.push(result);
|
|
3248
|
+
if (!result.success && node.type !== "visualize") {
|
|
3249
|
+
break;
|
|
3250
|
+
}
|
|
3251
|
+
if (node.type === "return") {
|
|
3252
|
+
break;
|
|
3253
|
+
}
|
|
3254
|
+
}
|
|
3255
|
+
return results;
|
|
3256
|
+
}
|
|
3257
|
+
/**
|
|
3258
|
+
* Call a function with arguments
|
|
3259
|
+
*/
|
|
3260
|
+
async callFunction(name, args = []) {
|
|
3261
|
+
const builtin = this.builtinFunctions.get(name);
|
|
3262
|
+
if (builtin) {
|
|
3263
|
+
try {
|
|
3264
|
+
const result = await builtin(args);
|
|
3265
|
+
return {
|
|
3266
|
+
success: true,
|
|
3267
|
+
output: result
|
|
3268
|
+
};
|
|
3269
|
+
} catch (error) {
|
|
3270
|
+
return {
|
|
3271
|
+
success: false,
|
|
3272
|
+
error: `Built-in function ${name} failed: ${error}`
|
|
3273
|
+
};
|
|
3274
|
+
}
|
|
3275
|
+
}
|
|
3276
|
+
const func = this.context.functions.get(name);
|
|
3277
|
+
if (!func) {
|
|
3278
|
+
return {
|
|
3279
|
+
success: false,
|
|
3280
|
+
error: `Function '${name}' not found`
|
|
3281
|
+
};
|
|
3282
|
+
}
|
|
3283
|
+
if (typeof func === "function") {
|
|
3284
|
+
try {
|
|
3285
|
+
const result = await func(...args);
|
|
3286
|
+
return {
|
|
3287
|
+
success: true,
|
|
3288
|
+
output: result
|
|
3289
|
+
};
|
|
3290
|
+
} catch (error) {
|
|
3291
|
+
return {
|
|
3292
|
+
success: false,
|
|
3293
|
+
error: `Extension function ${name} failed: ${error}`
|
|
3294
|
+
};
|
|
3295
|
+
}
|
|
3296
|
+
}
|
|
3297
|
+
if (this.callStack.length >= RUNTIME_SECURITY_LIMITS.maxCallStackDepth) {
|
|
3298
|
+
return {
|
|
3299
|
+
success: false,
|
|
3300
|
+
error: `Max call stack depth exceeded (${RUNTIME_SECURITY_LIMITS.maxCallStackDepth})`
|
|
3301
|
+
};
|
|
3302
|
+
}
|
|
3303
|
+
const parentScope = this.currentScope;
|
|
3304
|
+
this.currentScope = {
|
|
3305
|
+
variables: /* @__PURE__ */ new Map(),
|
|
3306
|
+
parent: parentScope
|
|
3307
|
+
};
|
|
3308
|
+
func.parameters.forEach((param, index) => {
|
|
3309
|
+
const value = index < args.length ? args[index] : param.defaultValue;
|
|
3310
|
+
this.currentScope.variables.set(param.name, value);
|
|
3311
|
+
});
|
|
3312
|
+
this.callStack.push(name);
|
|
3313
|
+
let returnValue = void 0;
|
|
3314
|
+
try {
|
|
3315
|
+
const results = await this.executeProgram(func.body, this.callStack.length);
|
|
3316
|
+
const lastResult = results[results.length - 1];
|
|
3317
|
+
if (lastResult?.output !== void 0) {
|
|
3318
|
+
returnValue = lastResult.output;
|
|
3319
|
+
}
|
|
3320
|
+
this.createExecutionEffect(name, func.position || [0, 0, 0]);
|
|
3321
|
+
return {
|
|
3322
|
+
success: results.every((r) => r.success),
|
|
3323
|
+
output: returnValue,
|
|
3324
|
+
hologram: func.hologram,
|
|
3325
|
+
spatialPosition: func.position
|
|
3326
|
+
};
|
|
3327
|
+
} finally {
|
|
3328
|
+
this.currentScope = parentScope;
|
|
3329
|
+
this.callStack.pop();
|
|
3330
|
+
}
|
|
3331
|
+
}
|
|
3332
|
+
/**
|
|
3333
|
+
* Set a variable in current scope
|
|
3334
|
+
*/
|
|
3335
|
+
setVariable(name, value, scopeOverride) {
|
|
3336
|
+
if (name.includes(".")) {
|
|
3337
|
+
const parts = name.split(".");
|
|
3338
|
+
const objName = parts[0];
|
|
3339
|
+
const propPath = parts.slice(1);
|
|
3340
|
+
let obj = this.getVariable(objName, scopeOverride);
|
|
3341
|
+
if (obj === void 0 || typeof obj !== "object" || obj === null) {
|
|
3342
|
+
obj = {};
|
|
3343
|
+
const scope = scopeOverride || this.currentScope;
|
|
3344
|
+
scope.variables.set(objName, obj);
|
|
3345
|
+
}
|
|
3346
|
+
let current = obj;
|
|
3347
|
+
for (let i = 0; i < propPath.length - 1; i++) {
|
|
3348
|
+
if (current[propPath[i]] === void 0 || typeof current[propPath[i]] !== "object") {
|
|
3349
|
+
current[propPath[i]] = {};
|
|
3350
|
+
}
|
|
3351
|
+
current = current[propPath[i]];
|
|
3352
|
+
}
|
|
3353
|
+
current[propPath[propPath.length - 1]] = value;
|
|
3354
|
+
} else {
|
|
3355
|
+
const scope = scopeOverride || this.currentScope;
|
|
3356
|
+
scope.variables.set(name, value);
|
|
3357
|
+
}
|
|
3358
|
+
if (this.wss && typeof value === "object" && value !== null && value.__type === "orb") {
|
|
3359
|
+
this.broadcast("orb_update", { orb: value });
|
|
3360
|
+
} else if (this.wss && name.includes(".")) {
|
|
3361
|
+
const root = name.split(".")[0];
|
|
3362
|
+
const rootVar = this.getVariable(root, scopeOverride);
|
|
3363
|
+
if (rootVar && typeof rootVar === "object" && rootVar.__type === "orb") {
|
|
3364
|
+
this.broadcast("orb_update", { orb: rootVar });
|
|
3365
|
+
}
|
|
3366
|
+
}
|
|
3367
|
+
}
|
|
3368
|
+
/**
|
|
3369
|
+
* Get a variable from scope chain
|
|
3370
|
+
*/
|
|
3371
|
+
getVariable(name, scopeOverride) {
|
|
3372
|
+
if (name.includes(".")) {
|
|
3373
|
+
const parts = name.split(".");
|
|
3374
|
+
let value = this.getVariable(parts[0], scopeOverride);
|
|
3375
|
+
for (let i = 1; i < parts.length && value !== void 0; i++) {
|
|
3376
|
+
if (typeof value === "object" && value !== null) {
|
|
3377
|
+
value = value[parts[i]];
|
|
3378
|
+
} else {
|
|
3379
|
+
return void 0;
|
|
3380
|
+
}
|
|
3381
|
+
}
|
|
3382
|
+
return value;
|
|
3383
|
+
}
|
|
3384
|
+
let scope = scopeOverride || this.currentScope;
|
|
3385
|
+
while (scope) {
|
|
3386
|
+
if (scope.variables.has(name)) {
|
|
3387
|
+
return scope.variables.get(name);
|
|
3388
|
+
}
|
|
3389
|
+
scope = scope.parent;
|
|
3390
|
+
}
|
|
3391
|
+
if (this.context.variables.has(name)) {
|
|
3392
|
+
return this.context.variables.get(name);
|
|
3393
|
+
}
|
|
3394
|
+
if (this.context.functions.has(name)) {
|
|
3395
|
+
return this.context.functions.get(name);
|
|
3396
|
+
}
|
|
3397
|
+
return void 0;
|
|
3398
|
+
}
|
|
3399
|
+
/**
|
|
3400
|
+
* Evaluate an expression in current context
|
|
3401
|
+
*/
|
|
3402
|
+
evaluateExpression(expr) {
|
|
3403
|
+
if (!expr || typeof expr !== "string") return expr;
|
|
3404
|
+
const evaluator = new chunkGJNCFRJU_cjs.ExpressionEvaluator(this.context.state.getSnapshot());
|
|
3405
|
+
const varContext = {};
|
|
3406
|
+
this.context.variables.forEach((v, k) => varContext[k] = v);
|
|
3407
|
+
evaluator.updateContext(varContext);
|
|
3408
|
+
return evaluator.evaluate(expr);
|
|
3409
|
+
}
|
|
3410
|
+
// ============================================================================
|
|
3411
|
+
// Node Executors
|
|
3412
|
+
// ============================================================================
|
|
3413
|
+
// W1-T4 slice 26: executeOrb extracted to ./runtime/orb-executor.
|
|
3414
|
+
// Closes board task task_1776940471985_57z8.
|
|
3415
|
+
// W1-T4 slice 20: executeFunction / executeConnection / executeGate /
|
|
3416
|
+
// executeStream extracted to ./runtime/graph-executors.
|
|
3417
|
+
/**
|
|
3418
|
+
* Execute State Machine declaration (Phase 13)
|
|
3419
|
+
*/
|
|
3420
|
+
// W1-T4 slice 17: executeStateMachine / executeExpressionStatement /
|
|
3421
|
+
// executeCall extracted to ./runtime/simple-executors.
|
|
3422
|
+
// W1-T4 slice 31: executeDebug extracted to ./runtime/debug-executor.
|
|
3423
|
+
// Thin wrapper binds runtime state-map references + logger into a
|
|
3424
|
+
// DebugExecutorContext and forwards to the pure executor.
|
|
3425
|
+
async executeDebug(node) {
|
|
3426
|
+
return executeDebug(node, this.buildDebugExecutorContext());
|
|
3427
|
+
}
|
|
3428
|
+
buildDebugExecutorContext() {
|
|
3429
|
+
return {
|
|
3430
|
+
scopeVariables: this.currentScope.variables,
|
|
3431
|
+
contextVariables: this.context.variables,
|
|
3432
|
+
functions: this.context.functions,
|
|
3433
|
+
connections: this.context.connections,
|
|
3434
|
+
callStack: this.callStack,
|
|
3435
|
+
uiElements: this.uiElements,
|
|
3436
|
+
animations: this.animations,
|
|
3437
|
+
executionHistory: this.executionHistory,
|
|
3438
|
+
setHologramState: (key, hologram) => {
|
|
3439
|
+
this.context.hologramState.set(key, hologram);
|
|
3440
|
+
},
|
|
3441
|
+
logInfo: (message, payload) => {
|
|
3442
|
+
chunkILRBGFVD_cjs.logger.info(message, payload);
|
|
3443
|
+
}
|
|
3444
|
+
};
|
|
3445
|
+
}
|
|
3446
|
+
// W1-T4 slice 22: executeVisualize / executeUIElement extracted to ./runtime/info-executors.
|
|
3447
|
+
/**
|
|
3448
|
+
* Execute generic voice commands
|
|
3449
|
+
* Handles commands like: show, hide, animate, pulse, create
|
|
3450
|
+
*/
|
|
3451
|
+
async executeGeneric(_node) {
|
|
3452
|
+
const genericNode = _node;
|
|
3453
|
+
const command = String(genericNode.command || "").trim().toLowerCase();
|
|
3454
|
+
const tokens = command.split(/\s+/);
|
|
3455
|
+
const action = tokens[0];
|
|
3456
|
+
const target = tokens[1];
|
|
3457
|
+
chunkILRBGFVD_cjs.logger.info("Executing generic command", { command, action, target });
|
|
3458
|
+
try {
|
|
3459
|
+
let result;
|
|
3460
|
+
const uiCtx = this.buildUICommandContext();
|
|
3461
|
+
switch (action) {
|
|
3462
|
+
case "show":
|
|
3463
|
+
result = await executeShowCommand(target, genericNode, uiCtx);
|
|
3464
|
+
break;
|
|
3465
|
+
case "hide":
|
|
3466
|
+
result = await executeHideCommand(target, genericNode, uiCtx);
|
|
3467
|
+
break;
|
|
3468
|
+
case "create":
|
|
3469
|
+
case "summon":
|
|
3470
|
+
result = await executeCreateCommand(tokens.slice(1), genericNode, uiCtx);
|
|
3471
|
+
break;
|
|
3472
|
+
case "animate":
|
|
3473
|
+
result = await executeAnimateCommand(target, tokens.slice(2), genericNode, uiCtx);
|
|
3474
|
+
break;
|
|
3475
|
+
case "pulse":
|
|
3476
|
+
result = await executePulseCommand(target, tokens.slice(2), genericNode, uiCtx);
|
|
3477
|
+
break;
|
|
3478
|
+
case "move":
|
|
3479
|
+
result = await executeMoveCommand(target, tokens.slice(2), genericNode, uiCtx);
|
|
3480
|
+
break;
|
|
3481
|
+
case "delete":
|
|
3482
|
+
case "remove":
|
|
3483
|
+
result = await executeDeleteCommand(target, genericNode, uiCtx);
|
|
3484
|
+
break;
|
|
3485
|
+
default:
|
|
3486
|
+
chunkILRBGFVD_cjs.logger.warn("Unknown voice command action", { action, command });
|
|
3487
|
+
result = {
|
|
3488
|
+
executed: false,
|
|
3489
|
+
message: `Unknown command: ${action}`
|
|
3490
|
+
};
|
|
3491
|
+
}
|
|
3492
|
+
return {
|
|
3493
|
+
success: true,
|
|
3494
|
+
output: result
|
|
3495
|
+
};
|
|
3496
|
+
} catch (error) {
|
|
3497
|
+
return {
|
|
3498
|
+
success: false,
|
|
3499
|
+
error: `Generic command execution failed: ${String(error)}`
|
|
3500
|
+
};
|
|
3501
|
+
}
|
|
3502
|
+
}
|
|
3503
|
+
// W1-T4 slice 18: show/hide/create/animate/pulse/move/delete commands
|
|
3504
|
+
// extracted to ./runtime/ui-commands. Methods deleted — dispatch is
|
|
3505
|
+
// inlined above using buildUICommandContext().
|
|
3506
|
+
// W1-T4 slice 19: executeStructure / executeAssignment / executeReturn
|
|
3507
|
+
// added to ./runtime/simple-executors.
|
|
3508
|
+
// ============================================================================
|
|
3509
|
+
// Condition Evaluation
|
|
3510
|
+
// ============================================================================
|
|
3511
|
+
/**
|
|
3512
|
+
* Thin wrapper over the extracted pure evaluator (W1-T4 slice 3,
|
|
3513
|
+
* see ./runtime/condition-evaluator). Callers pass the runtime's
|
|
3514
|
+
* `evaluateExpression` as the expression-resolution callback.
|
|
3515
|
+
*/
|
|
3516
|
+
evaluateCondition(condition) {
|
|
3517
|
+
return evaluateCondition(condition, (expr) => this.evaluateExpression(expr));
|
|
3518
|
+
}
|
|
3519
|
+
// ============================================================================
|
|
3520
|
+
// Transformation
|
|
3521
|
+
// ============================================================================
|
|
3522
|
+
/**
|
|
3523
|
+
* Thin wrapper over the extracted pure transformation operations
|
|
3524
|
+
* (W1-T4 slice 5, see ./runtime/transformation). Threads
|
|
3525
|
+
* setVariable / evaluateCondition / evaluateExpression through
|
|
3526
|
+
* a context object so the pure module stays free of `this` binding.
|
|
3527
|
+
*/
|
|
3528
|
+
async applyTransformation(data, transform) {
|
|
3529
|
+
return applyTransformation(data, transform, {
|
|
3530
|
+
setVariable: (name, value) => this.setVariable(name, value),
|
|
3531
|
+
evaluateCondition: (expr) => this.evaluateCondition(expr),
|
|
3532
|
+
evaluateExpression: (expr) => this.evaluateExpression(expr)
|
|
3533
|
+
});
|
|
3534
|
+
}
|
|
3535
|
+
// ============================================================================
|
|
3536
|
+
// Event System
|
|
3537
|
+
// ============================================================================
|
|
3538
|
+
/**
|
|
3539
|
+
* Outstanding state invalidations (PersistentTrait TTL expiries). A reader
|
|
3540
|
+
* checks `stateInvalidations.wasInvalidated(key)` before trusting a cached
|
|
3541
|
+
* value and `consume(key)` once it has refetched. Closes the
|
|
3542
|
+
* `persistent_expired`-into-void capability gap.
|
|
3543
|
+
*/
|
|
3544
|
+
get stateInvalidations() {
|
|
3545
|
+
return defaultStateInvalidationRegistry;
|
|
3546
|
+
}
|
|
3547
|
+
/** Construct an EventSystemContext bound to this runtime. (Slice 29) */
|
|
3548
|
+
buildEventSystemContext() {
|
|
3549
|
+
return {
|
|
3550
|
+
eventHandlers: this.eventHandlers,
|
|
3551
|
+
agentRuntimes: this.agentRuntimes,
|
|
3552
|
+
variables: this.context.variables,
|
|
3553
|
+
traitHandlers: this.traitHandlers,
|
|
3554
|
+
uiElements: this.uiElements,
|
|
3555
|
+
getCurrentScale: () => this.context.currentScale,
|
|
3556
|
+
// EventBus.emit is sync (returns void) but the EventSystemContext
|
|
3557
|
+
// contract requires Promise<void> so trait-side emits can `await`
|
|
3558
|
+
// through a unified interface. Wrap with Promise.resolve.
|
|
3559
|
+
globalBusEmit: (event, data) => {
|
|
3560
|
+
chunkSMIWS6DE_cjs.getSharedEventBus().emit(event, data);
|
|
3561
|
+
return Promise.resolve();
|
|
3562
|
+
},
|
|
3563
|
+
sendStateMachineEvent: (id, event) => engineRuntime__namespace.stateMachineInterpreter.sendEvent(id, event)
|
|
3564
|
+
};
|
|
3565
|
+
}
|
|
3566
|
+
/**
|
|
3567
|
+
* Register event handler.
|
|
3568
|
+
* (W1-T4 slice 29: impl extracted to ./runtime/event-system.)
|
|
3569
|
+
*/
|
|
3570
|
+
on(event, handler) {
|
|
3571
|
+
onEvent(event, handler, this.buildEventSystemContext());
|
|
3572
|
+
}
|
|
3573
|
+
/**
|
|
3574
|
+
* Register host function. Stays in HSR — direct builtinFunctions
|
|
3575
|
+
* write, not part of the event-system concern.
|
|
3576
|
+
*/
|
|
3577
|
+
registerFunction(name, handler) {
|
|
3578
|
+
this.builtinFunctions.set(name, handler);
|
|
3579
|
+
chunkILRBGFVD_cjs.logger.info(`Host function registered: ${name}`);
|
|
3580
|
+
}
|
|
3581
|
+
/**
|
|
3582
|
+
* Remove event handler.
|
|
3583
|
+
* (W1-T4 slice 29: impl extracted to ./runtime/event-system.)
|
|
3584
|
+
*/
|
|
3585
|
+
off(event, handler) {
|
|
3586
|
+
offEvent(event, handler, this.buildEventSystemContext());
|
|
3587
|
+
}
|
|
3588
|
+
/**
|
|
3589
|
+
* Emit event through the full 5-stage dispatch.
|
|
3590
|
+
* (W1-T4 slice 29: impl extracted to ./runtime/event-system.)
|
|
3591
|
+
*/
|
|
3592
|
+
async emit(event, data) {
|
|
3593
|
+
return emit(event, data, this.buildEventSystemContext());
|
|
3594
|
+
}
|
|
3595
|
+
/**
|
|
3596
|
+
* Trigger UI event — update element.value + fire dotted event.
|
|
3597
|
+
* (W1-T4 slice 29: impl extracted to ./runtime/event-system.)
|
|
3598
|
+
*/
|
|
3599
|
+
async triggerUIEvent(elementName, eventType, data) {
|
|
3600
|
+
return triggerUIEvent(elementName, eventType, data, this.buildEventSystemContext());
|
|
3601
|
+
}
|
|
3602
|
+
// W1-T4 slice 29: forwardToTraits extracted to ./runtime/event-system
|
|
3603
|
+
// (private in HSR, now a module function; no wrapper needed — the only
|
|
3604
|
+
// former caller is emit, which now calls the extracted forwardToTraits directly).
|
|
3605
|
+
// ============================================================================
|
|
3606
|
+
// Animation System
|
|
3607
|
+
// ============================================================================
|
|
3608
|
+
/**
|
|
3609
|
+
* Update all animations (W1-T4 slice 6: per-tick lerp extracted to
|
|
3610
|
+
* ./runtime/animation-system). Also ticks system variables — that
|
|
3611
|
+
* coupling lives in HSR because `updateSystemVariables` touches
|
|
3612
|
+
* too much runtime state to cleanly extract yet.
|
|
3613
|
+
*/
|
|
3614
|
+
updateAnimations() {
|
|
3615
|
+
updateAnimations(
|
|
3616
|
+
this.animations,
|
|
3617
|
+
(name, value) => this.setVariable(name, value),
|
|
3618
|
+
Date.now()
|
|
3619
|
+
);
|
|
3620
|
+
this.updateSystemVariables();
|
|
3621
|
+
}
|
|
3622
|
+
/**
|
|
3623
|
+
* Update real-life and system variables ($time, $user, etc.)
|
|
3624
|
+
*/
|
|
3625
|
+
/**
|
|
3626
|
+
* Update real-life and system variables ($time, $user, etc.)
|
|
3627
|
+
* (W1-T4 slice 9: impl extracted to ./runtime/system-variables).
|
|
3628
|
+
* Threads setVariable/getVariable callbacks plus the already-read
|
|
3629
|
+
* brittney_api_keys JSON string so the pure module has no
|
|
3630
|
+
* hidden dependency on browser `localStorage`.
|
|
3631
|
+
*/
|
|
3632
|
+
updateSystemVariables() {
|
|
3633
|
+
const brittneyApiKeysJson = typeof localStorage !== "undefined" ? localStorage.getItem("brittney_api_keys") : null;
|
|
3634
|
+
updateSystemVariables({
|
|
3635
|
+
setVariable: (name, value) => this.setVariable(name, value),
|
|
3636
|
+
getVariable: (name) => this.getVariable(name),
|
|
3637
|
+
brittneyApiKeysJson
|
|
3638
|
+
});
|
|
3639
|
+
}
|
|
3640
|
+
// ==========================================================================
|
|
3641
|
+
// COMMERCE / SOCIAL / PHYSICS / ANIMATION PRIMITIVES
|
|
3642
|
+
// (W1-T4 slice 8: extracted to ./runtime/primitives, registered
|
|
3643
|
+
// inline in initBuiltins via emit-injection — no wrappers needed)
|
|
3644
|
+
//
|
|
3645
|
+
// handleCalculateArc (below) stays — it's structured differently
|
|
3646
|
+
// from the emit-pattern primitives: it does real math via
|
|
3647
|
+
// calculateArc (slice 2), not an event dispatch.
|
|
3648
|
+
// ==========================================================================
|
|
3649
|
+
/**
|
|
3650
|
+
* Handle calculate_arc(start, end, speed)
|
|
3651
|
+
* W1-T4 slice 2: math extracted to ./runtime/physics-math.calculateArc
|
|
3652
|
+
*/
|
|
3653
|
+
handleCalculateArc(args) {
|
|
3654
|
+
if (args.length < 3) return [0, 0, 0];
|
|
3655
|
+
const start = args[0];
|
|
3656
|
+
const end = args[1];
|
|
3657
|
+
const speed = args[2];
|
|
3658
|
+
return calculateArc(start, end, speed);
|
|
3659
|
+
}
|
|
3660
|
+
// ============================================================================
|
|
3661
|
+
// Particle Effects (W1-T4 slice 4: impls extracted to ./runtime/particle-effects)
|
|
3662
|
+
//
|
|
3663
|
+
// Methods below are thin wrappers that thread `this.particleSystems`
|
|
3664
|
+
// (the Map) and the security limit into the pure implementations.
|
|
3665
|
+
// Call sites elsewhere in HSR remain unchanged.
|
|
3666
|
+
// ============================================================================
|
|
3667
|
+
createParticleEffect(name, position, color, count) {
|
|
3668
|
+
createParticleEffect(
|
|
3669
|
+
this.particleSystems,
|
|
3670
|
+
name,
|
|
3671
|
+
position,
|
|
3672
|
+
color,
|
|
3673
|
+
count,
|
|
3674
|
+
RUNTIME_SECURITY_LIMITS.maxParticlesPerSystem
|
|
3675
|
+
);
|
|
3676
|
+
}
|
|
3677
|
+
createConnectionStream(from, to, fromPos, toPos, dataType) {
|
|
3678
|
+
createConnectionStream(this.particleSystems, from, to, fromPos, toPos, dataType);
|
|
3679
|
+
}
|
|
3680
|
+
createFlowingStream(name, position, data) {
|
|
3681
|
+
createFlowingStream(
|
|
3682
|
+
this.particleSystems,
|
|
3683
|
+
name,
|
|
3684
|
+
position,
|
|
3685
|
+
data,
|
|
3686
|
+
RUNTIME_SECURITY_LIMITS.maxParticlesPerSystem
|
|
3687
|
+
);
|
|
3688
|
+
}
|
|
3689
|
+
createExecutionEffect(name, position) {
|
|
3690
|
+
createExecutionEffect(
|
|
3691
|
+
this.particleSystems,
|
|
3692
|
+
name,
|
|
3693
|
+
position,
|
|
3694
|
+
RUNTIME_SECURITY_LIMITS.maxParticlesPerSystem
|
|
3695
|
+
);
|
|
3696
|
+
}
|
|
3697
|
+
createDataVisualization(name, data, position) {
|
|
3698
|
+
createDataVisualization(
|
|
3699
|
+
this.particleSystems,
|
|
3700
|
+
name,
|
|
3701
|
+
data,
|
|
3702
|
+
position,
|
|
3703
|
+
RUNTIME_SECURITY_LIMITS.maxParticlesPerSystem
|
|
3704
|
+
);
|
|
3705
|
+
}
|
|
3706
|
+
getDataTypeColor(dataType) {
|
|
3707
|
+
return getDataTypeColor(dataType);
|
|
3708
|
+
}
|
|
3709
|
+
// ============================================================================
|
|
3710
|
+
// Visualizer Server
|
|
3711
|
+
// ============================================================================
|
|
3712
|
+
startVisualizationServer(port = 8080) {
|
|
3713
|
+
try {
|
|
3714
|
+
this.wss = new ws.WebSocketServer({ port });
|
|
3715
|
+
chunkILRBGFVD_cjs.logger.info(`[Visualizer] WebSocket server started on port ${port}`);
|
|
3716
|
+
this.timeManager = new orbital.TimeManager(/* @__PURE__ */ new Date());
|
|
3717
|
+
this.timeManager.onUpdate((julianDate, date) => {
|
|
3718
|
+
this.updateTraits(julianDate);
|
|
3719
|
+
this.broadcast("time_update", {
|
|
3720
|
+
julianDate,
|
|
3721
|
+
date: date.toISOString(),
|
|
3722
|
+
timeScale: this.timeManager.getTimeScale(),
|
|
3723
|
+
isPaused: this.timeManager.getIsPaused()
|
|
3724
|
+
});
|
|
3725
|
+
});
|
|
3726
|
+
this.timeManager.start();
|
|
3727
|
+
this.updateTraits(this.timeManager.getJulianDate());
|
|
3728
|
+
this.wss.on("connection", (ws) => {
|
|
3729
|
+
chunkILRBGFVD_cjs.logger.info("[Visualizer] Client connected");
|
|
3730
|
+
const orbs = Array.from(this.context.variables.entries()).filter(
|
|
3731
|
+
([_, v]) => v && typeof v === "object" && v.__type === "orb"
|
|
3732
|
+
).map(([id, v]) => {
|
|
3733
|
+
const orbData = v;
|
|
3734
|
+
return {
|
|
3735
|
+
id,
|
|
3736
|
+
name: orbData.name || id,
|
|
3737
|
+
position: Array.isArray(orbData.position) ? [orbData.position[0], orbData.position[1], orbData.position[2]] : orbData.position,
|
|
3738
|
+
properties: orbData.properties || {},
|
|
3739
|
+
hologram: orbData.hologram || (() => {
|
|
3740
|
+
const props = orbData.properties;
|
|
3741
|
+
return {
|
|
3742
|
+
color: props?.color || "#ffffff",
|
|
3743
|
+
size: props?.size || props?.scale || 1,
|
|
3744
|
+
shape: props?.geometry || "sphere",
|
|
3745
|
+
glow: props?.glow || false
|
|
3746
|
+
};
|
|
3747
|
+
})(),
|
|
3748
|
+
traits: orbData.traits || []
|
|
3749
|
+
};
|
|
3750
|
+
});
|
|
3751
|
+
ws.send(
|
|
3752
|
+
JSON.stringify({
|
|
3753
|
+
type: "init",
|
|
3754
|
+
orbs,
|
|
3755
|
+
time: this.timeManager ? this.timeManager.getState() : null
|
|
3756
|
+
})
|
|
3757
|
+
);
|
|
3758
|
+
ws.on("message", (message) => {
|
|
3759
|
+
try {
|
|
3760
|
+
const data = chunkE7JP3BS3_cjs.readJson(message.toString());
|
|
3761
|
+
if (data.type === "time_control") {
|
|
3762
|
+
if (typeof data.command === "string") {
|
|
3763
|
+
this.handleTimeControl(data.command, data.value);
|
|
3764
|
+
}
|
|
3765
|
+
}
|
|
3766
|
+
} catch (e) {
|
|
3767
|
+
chunkILRBGFVD_cjs.logger.error("[Visualizer] Failed to parse message", { error: String(e) });
|
|
3768
|
+
}
|
|
3769
|
+
});
|
|
3770
|
+
});
|
|
3771
|
+
} catch (error) {
|
|
3772
|
+
chunkILRBGFVD_cjs.logger.error("[Visualizer] Failed to start server", { error: String(error) });
|
|
3773
|
+
}
|
|
3774
|
+
}
|
|
3775
|
+
/**
|
|
3776
|
+
* Handle time control commands from visualizer
|
|
3777
|
+
* (W1-T4 slice 7: impl extracted to ./runtime/visualizer-server)
|
|
3778
|
+
*/
|
|
3779
|
+
handleTimeControl(command, value) {
|
|
3780
|
+
handleTimeControl(this.timeManager, command, value);
|
|
3781
|
+
}
|
|
3782
|
+
/**
|
|
3783
|
+
* Broadcast a typed message to all connected WebSocket clients.
|
|
3784
|
+
* (W1-T4 slice 7: impl extracted to ./runtime/visualizer-server)
|
|
3785
|
+
*/
|
|
3786
|
+
broadcast(type, payload) {
|
|
3787
|
+
broadcast(this.wss, type, payload);
|
|
3788
|
+
}
|
|
3789
|
+
// ============================================================================
|
|
3790
|
+
// Public API
|
|
3791
|
+
// ============================================================================
|
|
3792
|
+
getParticleSystems() {
|
|
3793
|
+
return new Map(this.particleSystems);
|
|
3794
|
+
}
|
|
3795
|
+
/**
|
|
3796
|
+
* Advance all particle systems by deltaTime.
|
|
3797
|
+
* (W1-T4 slice 14: impl extracted to ./runtime/particle-effects)
|
|
3798
|
+
*/
|
|
3799
|
+
updateParticles(deltaTime) {
|
|
3800
|
+
updateParticles(this.particleSystems, deltaTime);
|
|
3801
|
+
}
|
|
3802
|
+
getContext() {
|
|
3803
|
+
return { ...this.context };
|
|
3804
|
+
}
|
|
3805
|
+
getUIElements() {
|
|
3806
|
+
return new Map(this.uiElements);
|
|
3807
|
+
}
|
|
3808
|
+
getUIElement(name) {
|
|
3809
|
+
return this.uiElements.get(name);
|
|
3810
|
+
}
|
|
3811
|
+
getAnimations() {
|
|
3812
|
+
return new Map(this.animations);
|
|
3813
|
+
}
|
|
3814
|
+
reset() {
|
|
3815
|
+
this.context = createEmptyContext();
|
|
3816
|
+
this.currentScope = { variables: this.context.variables };
|
|
3817
|
+
this.callStack = [];
|
|
3818
|
+
this.particleSystems.clear();
|
|
3819
|
+
this.executionHistory = [];
|
|
3820
|
+
this.eventHandlers.clear();
|
|
3821
|
+
this.animations.clear();
|
|
3822
|
+
this.uiElements.clear();
|
|
3823
|
+
}
|
|
3824
|
+
// W1-T4 slice 10: createEmptyContext extracted to ./runtime/context-factory
|
|
3825
|
+
// (was a private method here; now called directly as module function
|
|
3826
|
+
// at the 2 internal call sites — no wrapper needed).
|
|
3827
|
+
// W1-T4 slice 21: executeScale added to ./runtime/simple-executors.
|
|
3828
|
+
// W1-T4 slice 17: executeFocus / executeEnvironment extracted to ./runtime/simple-executors.
|
|
3829
|
+
// W1-T4 slice 21: executeComposition added to ./runtime/simple-executors.
|
|
3830
|
+
// W1-T4 slice 13: resolveHoloValue extracted to ./runtime/holo-value
|
|
3831
|
+
// (pure recursive helper; private method deleted — 4 internal call
|
|
3832
|
+
// sites now use the imported function directly).
|
|
3833
|
+
// W1-T4 slice 24: executeHoloComposition extracted to ./runtime/holo-composition-executor.
|
|
3834
|
+
// W1-T4 slice 17: executeHoloTemplate extracted to ./runtime/simple-executors.
|
|
3835
|
+
// W1-T4 slice 25: executeHoloObject extracted to ./runtime/holo-object-executor.
|
|
3836
|
+
// Closes board task task_1776940617322_ee53.
|
|
3837
|
+
/**
|
|
3838
|
+
* Execute a block of HoloStatements (HoloNode AST)
|
|
3839
|
+
*/
|
|
3840
|
+
// W1-T4 slice 30: executeHoloProgram + executeHoloStatement extracted
|
|
3841
|
+
// to ./runtime/holo-statement-executor. Thin wrappers bind this
|
|
3842
|
+
// runtime's getVariable/setVariable/emit/evaluateHoloExpression +
|
|
3843
|
+
// telemetry into a HoloStatementContext and forward to the pure
|
|
3844
|
+
// recursive executor.
|
|
3845
|
+
async executeHoloProgram(statements, scopeOverride) {
|
|
3846
|
+
return executeHoloProgram(statements, scopeOverride, this.buildHoloStatementContext());
|
|
3847
|
+
}
|
|
3848
|
+
async executeHoloStatement(stmt, scopeOverride) {
|
|
3849
|
+
return executeHoloStatement(stmt, scopeOverride, this.buildHoloStatementContext());
|
|
3850
|
+
}
|
|
3851
|
+
buildHoloStatementContext() {
|
|
3852
|
+
return {
|
|
3853
|
+
currentScope: this.currentScope,
|
|
3854
|
+
getVariable: (name, scope) => this.getVariable(name, scope),
|
|
3855
|
+
setVariable: (name, value, scope) => {
|
|
3856
|
+
this.setVariable(name, value, scope);
|
|
3857
|
+
},
|
|
3858
|
+
emit: (event, data) => {
|
|
3859
|
+
void this.emit(event, data);
|
|
3860
|
+
},
|
|
3861
|
+
evaluateHoloExpression: (expr, scopeOverride) => this.evaluateHoloExpression(expr, scopeOverride),
|
|
3862
|
+
telemetry: {
|
|
3863
|
+
setGauge: (name, value) => {
|
|
3864
|
+
chunkSMIWS6DE_cjs.telemetry.setGauge(name, value);
|
|
3865
|
+
},
|
|
3866
|
+
incrementCounter: (name, value, labels) => {
|
|
3867
|
+
chunkSMIWS6DE_cjs.telemetry.incrementCounter(name, value, labels);
|
|
3868
|
+
},
|
|
3869
|
+
measureLatency: (name, fn) => chunkSMIWS6DE_cjs.telemetry.measureLatency(name, fn),
|
|
3870
|
+
executionDepth: () => this.context.executionStack.length
|
|
3871
|
+
}
|
|
3872
|
+
};
|
|
3873
|
+
}
|
|
3874
|
+
// W1-T4 slice: evaluateHoloExpression + getMemberPath extracted to
|
|
3875
|
+
// ./runtime/holo-expression. Thin wrapper binds this runtime's
|
|
3876
|
+
// getVariable/setVariable/callFunction into a HoloExpressionContext
|
|
3877
|
+
// and forwards to the pure recursive evaluator. Memoization (max 500,
|
|
3878
|
+
// FIFO) is preserved via a module-level cache in the pure module.
|
|
3879
|
+
evaluateHoloExpression(expr, scopeOverride) {
|
|
3880
|
+
return evaluateHoloExpression(expr, scopeOverride, this.buildHoloExpressionContext());
|
|
3881
|
+
}
|
|
3882
|
+
buildHoloExpressionContext() {
|
|
3883
|
+
return {
|
|
3884
|
+
getVariable: (name, scope) => this.getVariable(name, scope),
|
|
3885
|
+
setVariable: (name, value, scope) => this.setVariable(name, value, scope),
|
|
3886
|
+
callFunction: (name, args) => this.callFunction(name, args)
|
|
3887
|
+
};
|
|
3888
|
+
}
|
|
3889
|
+
// W1-T4 slice 16: executeSystem / setupNetworking / setupPhysics /
|
|
3890
|
+
// executeCoreConfig extracted to ./runtime/system-executors. Methods
|
|
3891
|
+
// deleted; dispatch calls the pure functions inline.
|
|
3892
|
+
// =========================================================================
|
|
3893
|
+
// Control Flow Execution (W1-T4 slice 12: impls extracted to
|
|
3894
|
+
// ./runtime/control-flow — wrappers below share a ControlFlowContext
|
|
3895
|
+
// that threads evaluateExpression / evaluateCondition / executeNode /
|
|
3896
|
+
// variables through a narrow boundary).
|
|
3897
|
+
// =========================================================================
|
|
3898
|
+
/** Construct a ControlFlowContext bound to this runtime's state. */
|
|
3899
|
+
buildControlFlowContext() {
|
|
3900
|
+
return {
|
|
3901
|
+
evaluateExpression: (expr) => this.evaluateExpression(expr),
|
|
3902
|
+
evaluateCondition: (expr) => this.evaluateCondition(expr),
|
|
3903
|
+
executeNode: (n) => this.executeNode(n),
|
|
3904
|
+
variables: this.context.variables
|
|
3905
|
+
};
|
|
3906
|
+
}
|
|
3907
|
+
/** @for item in iterable { body } */
|
|
3908
|
+
async executeForLoop(node) {
|
|
3909
|
+
return executeForLoop(node, this.buildControlFlowContext());
|
|
3910
|
+
}
|
|
3911
|
+
/** @forEach item in collection { body } */
|
|
3912
|
+
async executeForEachLoop(node) {
|
|
3913
|
+
return executeForEachLoop(node, this.buildControlFlowContext());
|
|
3914
|
+
}
|
|
3915
|
+
/** @while condition { body } (10k-iteration safety cap) */
|
|
3916
|
+
async executeWhileLoop(node) {
|
|
3917
|
+
return executeWhileLoop(node, this.buildControlFlowContext());
|
|
3918
|
+
}
|
|
3919
|
+
/** @if condition { body } @else { elseBody } */
|
|
3920
|
+
async executeIfStatement(node) {
|
|
3921
|
+
return executeIfStatement(node, this.buildControlFlowContext());
|
|
3922
|
+
}
|
|
3923
|
+
/** @match subject { pattern => result, ... } */
|
|
3924
|
+
async executeMatch(node) {
|
|
3925
|
+
return executeMatch(node, this.buildControlFlowContext());
|
|
3926
|
+
}
|
|
3927
|
+
// W1-T4 slice 11: patternMatches extracted to ./runtime/pattern-match
|
|
3928
|
+
// (pure helper; deleted method — only caller is executeMatch above,
|
|
3929
|
+
// now using patternMatchesPure directly).
|
|
3930
|
+
// W1-T4 slice 15: executeNarrative / executeQuest / executeDialogue
|
|
3931
|
+
// extracted to ./runtime/narrative-executors. Methods deleted —
|
|
3932
|
+
// dispatch calls the pure functions directly with a shared context.
|
|
3933
|
+
/** Construct an OrbExecutorContext bound to this runtime. (Slice 26) */
|
|
3934
|
+
buildOrbExecutorContext() {
|
|
3935
|
+
return {
|
|
3936
|
+
getCurrentScale: () => this.context.currentScale,
|
|
3937
|
+
getVariable: (name) => this.getVariable(name),
|
|
3938
|
+
setVariable: (name, value) => this.setVariable(name, value),
|
|
3939
|
+
setSpatialPosition: (name, pos) => {
|
|
3940
|
+
this.context.spatialMemory.set(name, pos);
|
|
3941
|
+
},
|
|
3942
|
+
evaluateExpression: (expr) => this.evaluateExpression(expr),
|
|
3943
|
+
getTemplate: (name) => this.context.templates.get(name),
|
|
3944
|
+
setHologramState: (name, hologram) => {
|
|
3945
|
+
this.context.hologramState.set(name, hologram);
|
|
3946
|
+
},
|
|
3947
|
+
executeMigrationBlock: (existingOrb, migration) => this.executeMigrationBlock(existingOrb, migration),
|
|
3948
|
+
getBuiltinFunction: (name) => this.builtinFunctions.get(name),
|
|
3949
|
+
applyDirectives: (node) => this.applyDirectives(node),
|
|
3950
|
+
isAgent: (node) => this.isAgent(node),
|
|
3951
|
+
getAgentRuntime: (name) => this.agentRuntimes.get(name),
|
|
3952
|
+
setAgentRuntime: (name, runtime) => {
|
|
3953
|
+
this.agentRuntimes.set(name, runtime);
|
|
3954
|
+
},
|
|
3955
|
+
acquireAgentRuntime: () => this.agentPool.acquire(),
|
|
3956
|
+
parentRuntime: this,
|
|
3957
|
+
createParticleEffect: (name, position, color, count) => this.createParticleEffect(name, position, color, count),
|
|
3958
|
+
broadcast: (event, payload) => this.broadcast(event, payload)
|
|
3959
|
+
};
|
|
3960
|
+
}
|
|
3961
|
+
/** Construct a HoloObjectContext bound to this runtime. (Slice 25) */
|
|
3962
|
+
buildHoloObjectContext() {
|
|
3963
|
+
return {
|
|
3964
|
+
getTemplate: (name) => this.context.templates.get(name),
|
|
3965
|
+
executeOrb: (orbNode) => executeOrb(orbNode, this.buildOrbExecutorContext())
|
|
3966
|
+
};
|
|
3967
|
+
}
|
|
3968
|
+
/** Construct a HoloCompositionContext bound to this runtime. (Slice 24) */
|
|
3969
|
+
buildHoloCompositionContext() {
|
|
3970
|
+
return {
|
|
3971
|
+
simpleExecutorContext: this.buildSimpleExecutorContext(),
|
|
3972
|
+
executeHoloObject: (node) => executeHoloObject(node, this.buildHoloObjectContext()),
|
|
3973
|
+
getEnvironment: () => this.context.environment,
|
|
3974
|
+
setEnvironment: (env) => {
|
|
3975
|
+
this.context.environment = env;
|
|
3976
|
+
}
|
|
3977
|
+
};
|
|
3978
|
+
}
|
|
3979
|
+
/** Construct an InfoExecutorContext bound to this runtime. (Slice 22) */
|
|
3980
|
+
buildInfoExecutorContext() {
|
|
3981
|
+
return {
|
|
3982
|
+
getVariable: (name) => this.getVariable(name),
|
|
3983
|
+
createDataVisualization: (name, data, position) => this.createDataVisualization(name, data, position),
|
|
3984
|
+
uiElements: this.uiElements,
|
|
3985
|
+
on: (event, handler) => this.on(event, handler),
|
|
3986
|
+
callFunction: (name) => this.callFunction(name)
|
|
3987
|
+
};
|
|
3988
|
+
}
|
|
3989
|
+
/** Construct a GraphExecutorContext bound to this runtime. (Slice 20) */
|
|
3990
|
+
buildGraphExecutorContext() {
|
|
3991
|
+
return {
|
|
3992
|
+
functions: this.context.functions,
|
|
3993
|
+
connections: this.context.connections,
|
|
3994
|
+
hologramState: this.context.hologramState,
|
|
3995
|
+
spatialMemory: this.context.spatialMemory,
|
|
3996
|
+
on: (event, handler) => this.on(event, handler),
|
|
3997
|
+
emit: (event, data) => {
|
|
3998
|
+
void this.emit(event, data);
|
|
3999
|
+
},
|
|
4000
|
+
getVariable: (name) => this.getVariable(name),
|
|
4001
|
+
setVariable: (name, value) => this.setVariable(name, value),
|
|
4002
|
+
createConnectionStream: (from, to, fromPos, toPos, dataType) => this.createConnectionStream(from, to, fromPos, toPos, dataType),
|
|
4003
|
+
createFlowingStream: (name, position, data) => this.createFlowingStream(name, position, data),
|
|
4004
|
+
getDataTypeColor: (dataType) => this.getDataTypeColor(dataType),
|
|
4005
|
+
evaluateCondition: (expr) => this.evaluateCondition(expr),
|
|
4006
|
+
executeProgram: (nodes, depth) => this.executeProgram(nodes, depth),
|
|
4007
|
+
callStackDepth: () => this.callStack.length,
|
|
4008
|
+
applyTransformation: (data, transform) => this.applyTransformation(data, transform)
|
|
4009
|
+
};
|
|
4010
|
+
}
|
|
4011
|
+
/** Construct a UICommandContext bound to this runtime. (Slice 18) */
|
|
4012
|
+
buildUICommandContext() {
|
|
4013
|
+
return {
|
|
4014
|
+
spatialMemory: this.context.spatialMemory,
|
|
4015
|
+
animations: this.animations,
|
|
4016
|
+
createParticleEffect: (name, position, color, count) => this.createParticleEffect(name, position, color, count),
|
|
4017
|
+
createConnectionStream: (from, to, fromPos, toPos, dataType) => this.createConnectionStream(from, to, fromPos, toPos, dataType)
|
|
4018
|
+
};
|
|
4019
|
+
}
|
|
4020
|
+
/** Construct a SimpleExecutorContext bound to this runtime. (Slice 17) */
|
|
4021
|
+
buildSimpleExecutorContext() {
|
|
4022
|
+
return {
|
|
4023
|
+
stateMachines: this.context.stateMachines,
|
|
4024
|
+
templates: this.context.templates,
|
|
4025
|
+
getEnvironment: () => this.context.environment,
|
|
4026
|
+
setEnvironment: (env) => {
|
|
4027
|
+
this.context.environment = env;
|
|
4028
|
+
},
|
|
4029
|
+
focusHistory: this.context.focusHistory,
|
|
4030
|
+
executionStackDepth: () => this.context.executionStack.length,
|
|
4031
|
+
evaluateExpression: (expr) => this.evaluateExpression(expr),
|
|
4032
|
+
callFunction: (name, args) => this.callFunction(name, args),
|
|
4033
|
+
executeProgram: (nodes, depth) => this.executeProgram(nodes, depth),
|
|
4034
|
+
setVariable: (name, value) => this.setVariable(name, value),
|
|
4035
|
+
setScale: (multiplier, magnitude) => {
|
|
4036
|
+
this.context.currentScale = multiplier;
|
|
4037
|
+
this.context.scaleMagnitude = magnitude;
|
|
4038
|
+
},
|
|
4039
|
+
getScale: () => ({
|
|
4040
|
+
multiplier: this.context.currentScale,
|
|
4041
|
+
magnitude: this.context.scaleMagnitude
|
|
4042
|
+
}),
|
|
4043
|
+
emit: (event, data) => {
|
|
4044
|
+
void this.emit(event, data);
|
|
4045
|
+
}
|
|
4046
|
+
};
|
|
4047
|
+
}
|
|
4048
|
+
/** Construct a NarrativeContext bound to this runtime's quest/dialogue state. */
|
|
4049
|
+
buildNarrativeContext() {
|
|
4050
|
+
return {
|
|
4051
|
+
quests: this.context.quests,
|
|
4052
|
+
setActiveQuestId: (id) => {
|
|
4053
|
+
this.context.activeQuestId = id;
|
|
4054
|
+
},
|
|
4055
|
+
setDialogueState: (state) => {
|
|
4056
|
+
this.context.dialogueState = state;
|
|
4057
|
+
}
|
|
4058
|
+
};
|
|
4059
|
+
}
|
|
4060
|
+
// W1-T4 slice 16: executeVisualMetadata / setupNetworking / setupPhysics
|
|
4061
|
+
// extracted to ./runtime/system-executors.
|
|
4062
|
+
async executeTemplate(node) {
|
|
4063
|
+
const existing = this.context.templates.get(node.name);
|
|
4064
|
+
if (existing) {
|
|
4065
|
+
node._previousVersion = existing.version;
|
|
4066
|
+
}
|
|
4067
|
+
this.context.templates.set(node.name, node);
|
|
4068
|
+
return {
|
|
4069
|
+
success: true,
|
|
4070
|
+
output: `Template ${node.name} registered (v${node.version || "unknown"})`
|
|
4071
|
+
};
|
|
4072
|
+
}
|
|
4073
|
+
/**
|
|
4074
|
+
* Execute a migration script for an object
|
|
4075
|
+
*/
|
|
4076
|
+
async executeMigrationBlock(orb, migration) {
|
|
4077
|
+
chunkILRBGFVD_cjs.logger.info(`Running migration for ${orb.name}...`);
|
|
4078
|
+
const previousScope = this.currentScope;
|
|
4079
|
+
this.currentScope = {
|
|
4080
|
+
variables: /* @__PURE__ */ new Map([
|
|
4081
|
+
["this", orb],
|
|
4082
|
+
["self", orb]
|
|
4083
|
+
]),
|
|
4084
|
+
parent: previousScope
|
|
4085
|
+
};
|
|
4086
|
+
try {
|
|
4087
|
+
const parser = new chunkJIYN45TV_cjs.HoloScriptCodeParser();
|
|
4088
|
+
const result = parser.parse(migration.body);
|
|
4089
|
+
if (result.errors.length > 0) {
|
|
4090
|
+
chunkILRBGFVD_cjs.logger.error(`Migration parse errors for ${orb.name}:`, {
|
|
4091
|
+
errors: result.errors
|
|
4092
|
+
});
|
|
4093
|
+
return;
|
|
4094
|
+
}
|
|
4095
|
+
await this.executeProgram(result.ast, 0);
|
|
4096
|
+
} finally {
|
|
4097
|
+
this.currentScope = previousScope;
|
|
4098
|
+
}
|
|
4099
|
+
chunkILRBGFVD_cjs.logger.info(`Migration complete for ${orb.name}`);
|
|
4100
|
+
}
|
|
4101
|
+
// W1-T4 slice 32: server/database/fetch executors extracted to
|
|
4102
|
+
// ./runtime/io-node-executors. Thin wrappers thread the public-mode
|
|
4103
|
+
// gate + logger into an IoNodeContext and forward to pure functions.
|
|
4104
|
+
async executeServerNode(node) {
|
|
4105
|
+
return executeServerNode(node, this.buildIoNodeContext());
|
|
4106
|
+
}
|
|
4107
|
+
async executeDatabaseNode(node) {
|
|
4108
|
+
return executeDatabaseNode(node, this.buildIoNodeContext());
|
|
4109
|
+
}
|
|
4110
|
+
async executeFetchNode(node) {
|
|
4111
|
+
return executeFetchNode(node, this.buildIoNodeContext());
|
|
4112
|
+
}
|
|
4113
|
+
buildIoNodeContext() {
|
|
4114
|
+
return {
|
|
4115
|
+
isPublicMode: this.context.mode === "public",
|
|
4116
|
+
logInfo: (msg) => {
|
|
4117
|
+
chunkILRBGFVD_cjs.logger.info(msg);
|
|
4118
|
+
}
|
|
4119
|
+
};
|
|
4120
|
+
}
|
|
4121
|
+
async executeTarget(node) {
|
|
4122
|
+
const target = this.context.functions.get(node.target);
|
|
4123
|
+
if (!target) {
|
|
4124
|
+
return {
|
|
4125
|
+
success: false,
|
|
4126
|
+
error: `Function ${node.target} not found`,
|
|
4127
|
+
executionTime: 0
|
|
4128
|
+
};
|
|
4129
|
+
}
|
|
4130
|
+
const result = await executeFunction(target, this.buildGraphExecutorContext());
|
|
4131
|
+
this.createExecutionEffect(node.target, target.position || [0, 0, 0]);
|
|
4132
|
+
return {
|
|
4133
|
+
success: true,
|
|
4134
|
+
output: `Executed ${node.target}`,
|
|
4135
|
+
hologram: {
|
|
4136
|
+
shape: "sphere",
|
|
4137
|
+
color: "#ff4500",
|
|
4138
|
+
size: 1.2,
|
|
4139
|
+
glow: true,
|
|
4140
|
+
interactive: false
|
|
4141
|
+
},
|
|
4142
|
+
executionTime: result.executionTime
|
|
4143
|
+
};
|
|
4144
|
+
}
|
|
4145
|
+
// W1-T4 slice 33: executeStateDeclaration extracted to
|
|
4146
|
+
// ./runtime/declaration-executors. Thin wrapper.
|
|
4147
|
+
async executeStateDeclaration(node) {
|
|
4148
|
+
return executeStateDeclaration(node, this.buildDeclarationContext());
|
|
4149
|
+
}
|
|
4150
|
+
// ============================================================================
|
|
4151
|
+
// Memory Syntactic Execution (Phase 7 / EVOLVE)
|
|
4152
|
+
// ============================================================================
|
|
4153
|
+
async executeMemory(node) {
|
|
4154
|
+
const startTime = Date.now();
|
|
4155
|
+
chunkILRBGFVD_cjs.logger.info(`[Memory] Initializing memory block: ${node.name}`);
|
|
4156
|
+
const memoryState = {
|
|
4157
|
+
id: node.name,
|
|
4158
|
+
type: "agent-memory"
|
|
4159
|
+
};
|
|
4160
|
+
if (node.semantic) {
|
|
4161
|
+
const semResult = await this.executeNode(node.semantic);
|
|
4162
|
+
if (semResult.success) memoryState.semantic = semResult.output;
|
|
4163
|
+
}
|
|
4164
|
+
if (node.episodic) {
|
|
4165
|
+
const epResult = await this.executeNode(node.episodic);
|
|
4166
|
+
if (epResult.success) memoryState.episodic = epResult.output;
|
|
4167
|
+
}
|
|
4168
|
+
if (node.procedural) {
|
|
4169
|
+
const procResult = await this.executeNode(node.procedural);
|
|
4170
|
+
if (procResult.success) memoryState.procedural = procResult.output;
|
|
4171
|
+
}
|
|
4172
|
+
this.context.variables.set(node.name, memoryState);
|
|
4173
|
+
this.emit("memory_initialized", { memoryId: node.name, config: memoryState });
|
|
4174
|
+
return {
|
|
4175
|
+
success: true,
|
|
4176
|
+
output: memoryState,
|
|
4177
|
+
executionTime: Date.now() - startTime
|
|
4178
|
+
};
|
|
4179
|
+
}
|
|
4180
|
+
/**
|
|
4181
|
+
* Load a procedural skill (W1-T4 slice 27: impl extracted to
|
|
4182
|
+
* ./runtime/skills-directives). Kept as public wrapper so external
|
|
4183
|
+
* callers still hit HSR's API surface.
|
|
4184
|
+
*/
|
|
4185
|
+
loadSkill(skill) {
|
|
4186
|
+
loadSkill(skill, {
|
|
4187
|
+
proceduralSkills: this.proceduralSkills,
|
|
4188
|
+
broadcastSkill: (s) => mesh.StateSynchronizer.getInstance().broadcastSkill(s)
|
|
4189
|
+
});
|
|
4190
|
+
}
|
|
4191
|
+
async executeSkill(skillId, contextVariables = {}) {
|
|
4192
|
+
const skill = this.proceduralSkills.get(skillId);
|
|
4193
|
+
if (!skill) {
|
|
4194
|
+
throw new Error(`[Procedural] Skill '${skillId}' not found.`);
|
|
4195
|
+
}
|
|
4196
|
+
chunkILRBGFVD_cjs.logger.info(`[Procedural] Executing skill: ${skill.name}`);
|
|
4197
|
+
const startTime = Date.now();
|
|
4198
|
+
const previousScope = this.currentScope;
|
|
4199
|
+
this.currentScope = { variables: new Map(previousScope.variables), parent: previousScope };
|
|
4200
|
+
for (const [key, val] of Object.entries(contextVariables)) {
|
|
4201
|
+
this.currentScope.variables.set(key, val);
|
|
4202
|
+
}
|
|
4203
|
+
try {
|
|
4204
|
+
const result = await this.executeNode(skill.action);
|
|
4205
|
+
if (result.success) {
|
|
4206
|
+
skill.successRate = Math.min(100, skill.successRate + 1);
|
|
4207
|
+
} else {
|
|
4208
|
+
skill.successRate = Math.max(0, skill.successRate - 1);
|
|
4209
|
+
}
|
|
4210
|
+
mesh.StateSynchronizer.getInstance().broadcastSkill(skill);
|
|
4211
|
+
return {
|
|
4212
|
+
...result,
|
|
4213
|
+
executionTime: Date.now() - startTime
|
|
4214
|
+
};
|
|
4215
|
+
} finally {
|
|
4216
|
+
this.currentScope = previousScope;
|
|
4217
|
+
}
|
|
4218
|
+
}
|
|
4219
|
+
// W1-T4 slice 33: executeMemoryDefinition extracted to
|
|
4220
|
+
// ./runtime/declaration-executors. Thin wrapper.
|
|
4221
|
+
async executeMemoryDefinition(node) {
|
|
4222
|
+
return executeMemoryDefinition(node, this.buildDeclarationContext());
|
|
4223
|
+
}
|
|
4224
|
+
buildDeclarationContext() {
|
|
4225
|
+
return {
|
|
4226
|
+
updateState: (body) => {
|
|
4227
|
+
this.context.state.update(body);
|
|
4228
|
+
},
|
|
4229
|
+
evaluateExpression: (expr) => this.evaluateExpression(expr)
|
|
4230
|
+
};
|
|
4231
|
+
}
|
|
4232
|
+
/**
|
|
4233
|
+
* Walk orb directives applying trait / state / lifecycle handlers.
|
|
4234
|
+
* (W1-T4 slice 27: impl extracted to ./runtime/skills-directives.)
|
|
4235
|
+
*/
|
|
4236
|
+
applyDirectives(node) {
|
|
4237
|
+
applyDirectives(node, {
|
|
4238
|
+
traitHandlers: this.traitHandlers,
|
|
4239
|
+
emit: (event, payload) => {
|
|
4240
|
+
void this.emit(event, payload);
|
|
4241
|
+
},
|
|
4242
|
+
getCurrentScale: () => this.context.currentScale,
|
|
4243
|
+
state: this.context.state,
|
|
4244
|
+
evaluateExpression: (expr) => this.evaluateExpression(expr)
|
|
4245
|
+
});
|
|
4246
|
+
}
|
|
4247
|
+
getExecutionHistory() {
|
|
4248
|
+
return [...this.executionHistory];
|
|
4249
|
+
}
|
|
4250
|
+
getHologramStates() {
|
|
4251
|
+
return new Map(this.context.hologramState);
|
|
4252
|
+
}
|
|
4253
|
+
getCallStack() {
|
|
4254
|
+
return [...this.callStack];
|
|
4255
|
+
}
|
|
4256
|
+
getState() {
|
|
4257
|
+
return this.context.state.getSnapshot();
|
|
4258
|
+
}
|
|
4259
|
+
getRootScope() {
|
|
4260
|
+
return this.currentScope;
|
|
4261
|
+
}
|
|
4262
|
+
/**
|
|
4263
|
+
* Predicate: is this orb an agent? (W1-T4 slice 27: extracted.)
|
|
4264
|
+
*/
|
|
4265
|
+
isAgent(node) {
|
|
4266
|
+
return isAgent(node);
|
|
4267
|
+
}
|
|
4268
|
+
/**
|
|
4269
|
+
* Get current simulation time (Julian date) for orbital calculations
|
|
4270
|
+
*/
|
|
4271
|
+
getSimulationTime() {
|
|
4272
|
+
return this.timeManager?.getJulianDate() || 0;
|
|
4273
|
+
}
|
|
4274
|
+
/**
|
|
4275
|
+
* Set orb position and broadcast update
|
|
4276
|
+
*/
|
|
4277
|
+
setOrbPosition(orbName, position) {
|
|
4278
|
+
const orb = this.context.variables.get(orbName);
|
|
4279
|
+
if (orb && typeof orb === "object" && orb.__type === "orb") {
|
|
4280
|
+
orb.position = position;
|
|
4281
|
+
this.broadcast("orb_update", {
|
|
4282
|
+
orb: {
|
|
4283
|
+
id: orbName,
|
|
4284
|
+
name: orbName,
|
|
4285
|
+
position
|
|
4286
|
+
}
|
|
4287
|
+
});
|
|
4288
|
+
}
|
|
4289
|
+
}
|
|
4290
|
+
/**
|
|
4291
|
+
* Per-frame trait update — dispatches onUpdate on all active
|
|
4292
|
+
* orbs (W1-T4 slice 27: impl extracted to ./runtime/skills-directives).
|
|
4293
|
+
*/
|
|
4294
|
+
updateTraits(julianDate) {
|
|
4295
|
+
updateTraits(julianDate, {
|
|
4296
|
+
variables: this.context.variables,
|
|
4297
|
+
traitHandlers: this.traitHandlers,
|
|
4298
|
+
emit: (event, payload) => this.emit(event, payload),
|
|
4299
|
+
getCurrentScale: () => this.context.currentScale,
|
|
4300
|
+
setOrbPosition: (name, position) => this.setOrbPosition(name, position),
|
|
4301
|
+
getState: () => this.getState(),
|
|
4302
|
+
setState: (updates) => this.context.state.update(updates)
|
|
4303
|
+
});
|
|
4304
|
+
}
|
|
4305
|
+
};
|
|
4306
|
+
|
|
4307
|
+
exports.HoloScriptAgentRuntime = HoloScriptAgentRuntime;
|
|
4308
|
+
exports.HoloScriptRuntime = HoloScriptRuntime;
|
|
4309
|
+
//# sourceMappingURL=chunk-MQWAT42R.cjs.map
|
|
4310
|
+
//# sourceMappingURL=chunk-MQWAT42R.cjs.map
|