unspaghettit 0.2.0 → 0.4.0
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 +56 -18
- package/build/client/_app/immutable/assets/0.DCOD5ne_.css +1 -0
- package/build/client/_app/immutable/assets/0.DCOD5ne_.css.br +0 -0
- package/build/client/_app/immutable/assets/0.DCOD5ne_.css.gz +0 -0
- package/build/client/_app/immutable/assets/12.nv0I59TU.css.gz +0 -0
- package/build/client/_app/immutable/assets/3.B3akUL9A.css.gz +0 -0
- package/build/client/_app/immutable/assets/BehaviorGraph.Bk0xQRZk.css +1 -0
- package/build/client/_app/immutable/assets/BehaviorGraph.Bk0xQRZk.css.br +0 -0
- package/build/client/_app/immutable/assets/BehaviorGraph.Bk0xQRZk.css.gz +0 -0
- package/build/client/_app/immutable/chunks/B3vnQs252.js +1 -0
- package/build/client/_app/immutable/chunks/B3vnQs252.js.br +0 -0
- package/build/client/_app/immutable/chunks/B3vnQs252.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{CxyLMlpt2.js → BANF9BhQ2.js} +1 -1
- package/build/client/_app/immutable/chunks/BANF9BhQ2.js.br +0 -0
- package/build/client/_app/immutable/chunks/BANF9BhQ2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BJdTO_n6.js +1 -0
- package/build/client/_app/immutable/chunks/BJdTO_n6.js.br +0 -0
- package/build/client/_app/immutable/chunks/BJdTO_n6.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BPl9BITm.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BQ9GodWX2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bcyn5YUg.js +4 -0
- package/build/client/_app/immutable/chunks/Bcyn5YUg.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bcyn5YUg.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bfc9rQXP.js +1 -0
- package/build/client/_app/immutable/chunks/Bfc9rQXP.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bfc9rQXP.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{BfMYiIUi.js → BjxqhpPG.js} +1 -1
- package/build/client/_app/immutable/chunks/BjxqhpPG.js.br +0 -0
- package/build/client/_app/immutable/chunks/BjxqhpPG.js.gz +0 -0
- package/build/client/_app/immutable/chunks/ByaoVvNB.js +1 -0
- package/build/client/_app/immutable/chunks/ByaoVvNB.js.br +0 -0
- package/build/client/_app/immutable/chunks/ByaoVvNB.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BzLd0mTH.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C8b3IMj8.js +1 -0
- package/build/client/_app/immutable/chunks/C8b3IMj8.js.br +0 -0
- package/build/client/_app/immutable/chunks/C8b3IMj8.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CXvvf4uQ.js +1 -0
- package/build/client/_app/immutable/chunks/CXvvf4uQ.js.br +0 -0
- package/build/client/_app/immutable/chunks/CXvvf4uQ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Cl7Z3e6-.js.gz +0 -0
- package/build/client/_app/immutable/chunks/ClC4qR7W2.js +2 -0
- package/build/client/_app/immutable/chunks/ClC4qR7W2.js.br +0 -0
- package/build/client/_app/immutable/chunks/ClC4qR7W2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CuGlh1c2.js +1 -0
- package/build/client/_app/immutable/chunks/CuGlh1c2.js.br +0 -0
- package/build/client/_app/immutable/chunks/CuGlh1c2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CwzIdrQR.js +1 -0
- package/build/client/_app/immutable/chunks/CwzIdrQR.js.br +0 -0
- package/build/client/_app/immutable/chunks/CwzIdrQR.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D5speDV82.js +908 -0
- package/build/client/_app/immutable/chunks/D5speDV82.js.br +0 -0
- package/build/client/_app/immutable/chunks/D5speDV82.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D64sGJRN.js +1 -0
- package/build/client/_app/immutable/chunks/D64sGJRN.js.br +0 -0
- package/build/client/_app/immutable/chunks/D64sGJRN.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DNaA4QRO2.js +1 -0
- package/build/client/_app/immutable/chunks/DNaA4QRO2.js.br +0 -0
- package/build/client/_app/immutable/chunks/DNaA4QRO2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Da59TXPe.js +1 -0
- package/build/client/_app/immutable/chunks/Da59TXPe.js.br +2 -0
- package/build/client/_app/immutable/chunks/Da59TXPe.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DhTiE3j02.js +2 -0
- package/build/client/_app/immutable/chunks/DhTiE3j02.js.br +0 -0
- package/build/client/_app/immutable/chunks/DhTiE3j02.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Dhqg7r_2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DmyaDy4d2.js +1 -0
- package/build/client/_app/immutable/chunks/DmyaDy4d2.js.br +0 -0
- package/build/client/_app/immutable/chunks/DmyaDy4d2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DryaQyjN2.js +1 -0
- package/build/client/_app/immutable/chunks/DryaQyjN2.js.br +0 -0
- package/build/client/_app/immutable/chunks/DryaQyjN2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DtK8qK5Q2.js +1 -0
- package/build/client/_app/immutable/chunks/DtK8qK5Q2.js.br +0 -0
- package/build/client/_app/immutable/chunks/DtK8qK5Q2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DtblIi6X2.js +1 -0
- package/build/client/_app/immutable/chunks/DtblIi6X2.js.br +1 -0
- package/build/client/_app/immutable/chunks/DtblIi6X2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/UkzDDeO42.js +1 -0
- package/build/client/_app/immutable/chunks/UkzDDeO42.js.br +0 -0
- package/build/client/_app/immutable/chunks/UkzDDeO42.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Vu8LzrwP2.js +1 -0
- package/build/client/_app/immutable/chunks/Vu8LzrwP2.js.br +0 -0
- package/build/client/_app/immutable/chunks/Vu8LzrwP2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/_b612aVb.js +1 -0
- package/build/client/_app/immutable/chunks/_b612aVb.js.br +0 -0
- package/build/client/_app/immutable/chunks/_b612aVb.js.gz +0 -0
- package/build/client/_app/immutable/chunks/aNMRV4sP2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/cMamJTsF.js.gz +0 -0
- package/build/client/_app/immutable/chunks/ib21i2T_.js.gz +0 -0
- package/build/client/_app/immutable/chunks/kNaey6uv.js.gz +0 -0
- package/build/client/_app/immutable/chunks/oVMDLirx.js +1 -0
- package/build/client/_app/immutable/chunks/oVMDLirx.js.br +0 -0
- package/build/client/_app/immutable/chunks/oVMDLirx.js.gz +0 -0
- package/build/client/_app/immutable/chunks/olAc024e.js +1 -0
- package/build/client/_app/immutable/chunks/olAc024e.js.br +0 -0
- package/build/client/_app/immutable/chunks/olAc024e.js.gz +0 -0
- package/build/client/_app/immutable/chunks/suTxxv1t.js.gz +0 -0
- package/build/client/_app/immutable/chunks/wXIHzLMQ2.js +1 -0
- package/build/client/_app/immutable/chunks/wXIHzLMQ2.js.br +0 -0
- package/build/client/_app/immutable/chunks/wXIHzLMQ2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/wrqalH0a.js +1 -0
- package/build/client/_app/immutable/chunks/wrqalH0a.js.br +0 -0
- package/build/client/_app/immutable/chunks/wrqalH0a.js.gz +0 -0
- package/build/client/_app/immutable/chunks/x60Tn5kT.js +1 -0
- package/build/client/_app/immutable/chunks/x60Tn5kT.js.br +0 -0
- package/build/client/_app/immutable/chunks/x60Tn5kT.js.gz +0 -0
- package/build/client/_app/immutable/chunks/xihTtKlq.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{BOrLmFwJ.js → yShDxCNj.js} +1 -1
- package/build/client/_app/immutable/chunks/yShDxCNj.js.br +2 -0
- package/build/client/_app/immutable/chunks/yShDxCNj.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.Etd-exTb.js +2 -0
- package/build/client/_app/immutable/entry/app.Etd-exTb.js.br +0 -0
- package/build/client/_app/immutable/entry/app.Etd-exTb.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.DY2B3u4g.js +1 -0
- package/build/client/_app/immutable/entry/start.DY2B3u4g.js.br +0 -0
- package/build/client/_app/immutable/entry/start.DY2B3u4g.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.tKfYV3__.js +8 -0
- package/build/client/_app/immutable/nodes/0.tKfYV3__.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.tKfYV3__.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{1.KYdA6ppX.js → 1.CER5ICKt.js} +1 -1
- package/build/client/_app/immutable/nodes/1.CER5ICKt.js.br +1 -0
- package/build/client/_app/immutable/nodes/1.CER5ICKt.js.gz +0 -0
- package/build/client/_app/immutable/nodes/10.rT7cD8kX.js +1 -0
- package/build/client/_app/immutable/nodes/10.rT7cD8kX.js.br +0 -0
- package/build/client/_app/immutable/nodes/10.rT7cD8kX.js.gz +0 -0
- package/build/client/_app/immutable/nodes/11.BAnV_Y5Y.js +2 -0
- package/build/client/_app/immutable/nodes/11.BAnV_Y5Y.js.br +0 -0
- package/build/client/_app/immutable/nodes/11.BAnV_Y5Y.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{9.CMW6a2Lg.js → 12.DCTRFMqo.js} +4 -3
- package/build/client/_app/immutable/nodes/12.DCTRFMqo.js.br +0 -0
- package/build/client/_app/immutable/nodes/12.DCTRFMqo.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{2.DBz20KgG.js → 2.CF488WWF.js} +1 -1
- package/build/client/_app/immutable/nodes/2.CF488WWF.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.CF488WWF.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.CP7CPPVH.js +1 -0
- package/build/client/_app/immutable/nodes/3.CP7CPPVH.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.CP7CPPVH.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.D1bxCSiM.js +3 -0
- package/build/client/_app/immutable/nodes/4.D1bxCSiM.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.D1bxCSiM.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.D6jZgh9y.js +48 -0
- package/build/client/_app/immutable/nodes/5.D6jZgh9y.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.D6jZgh9y.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.BrBFUA0s.js +1 -0
- package/build/client/_app/immutable/nodes/6.BrBFUA0s.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.BrBFUA0s.js.gz +0 -0
- package/build/client/_app/immutable/nodes/7.pajo8MfM.js +3 -0
- package/build/client/_app/immutable/nodes/7.pajo8MfM.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.pajo8MfM.js.gz +0 -0
- package/build/client/_app/immutable/nodes/8.Cc80_Igi.js +5 -0
- package/build/client/_app/immutable/nodes/8.Cc80_Igi.js.br +0 -0
- package/build/client/_app/immutable/nodes/8.Cc80_Igi.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{7.CemgNJfw.js → 9.D72NaL3l.js} +1 -1
- package/build/client/_app/immutable/nodes/9.D72NaL3l.js.br +1 -0
- package/build/client/_app/immutable/nodes/9.D72NaL3l.js.gz +0 -0
- package/build/client/_app/version.json +1 -1
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/client/lyriks_logo.svg +148 -0
- package/build/client/lyriks_logo.svg.br +0 -0
- package/build/client/lyriks_logo.svg.gz +0 -0
- package/build/server/chunks/0-8YZc572z.js +15 -0
- package/build/server/chunks/0-8YZc572z.js.map +1 -0
- package/build/server/chunks/1-DxkfSJLu.js +9 -0
- package/build/server/chunks/{1-DPpKAKXV.js.map → 1-DxkfSJLu.js.map} +1 -1
- package/build/server/chunks/10-DkObdGtU.js +9 -0
- package/build/server/chunks/10-DkObdGtU.js.map +1 -0
- package/build/server/chunks/11-DL94HxpZ.js +9 -0
- package/build/server/chunks/11-DL94HxpZ.js.map +1 -0
- package/build/server/chunks/12-CI74sCkt.js +9 -0
- package/build/server/chunks/12-CI74sCkt.js.map +1 -0
- package/build/server/chunks/2-qhWwQ4eL.js +9 -0
- package/build/server/chunks/2-qhWwQ4eL.js.map +1 -0
- package/build/server/chunks/3-CzoZtSTp.js +16 -0
- package/build/server/chunks/3-CzoZtSTp.js.map +1 -0
- package/build/server/chunks/4-CDa9DBsh.js +16 -0
- package/build/server/chunks/4-CDa9DBsh.js.map +1 -0
- package/build/server/chunks/5-qD2xxOrq.js +9 -0
- package/build/server/chunks/5-qD2xxOrq.js.map +1 -0
- package/build/server/chunks/6-B4mWzvDn.js +9 -0
- package/build/server/chunks/6-B4mWzvDn.js.map +1 -0
- package/build/server/chunks/7-zExv-fTN.js +9 -0
- package/build/server/chunks/7-zExv-fTN.js.map +1 -0
- package/build/server/chunks/8-BVrGdQg4.js +9 -0
- package/build/server/chunks/{6-QQ7r8Rd5.js.map → 8-BVrGdQg4.js.map} +1 -1
- package/build/server/chunks/9-BnZLRMYA.js +9 -0
- package/build/server/chunks/9-BnZLRMYA.js.map +1 -0
- package/build/server/chunks/BehaviorGraph-C-9z37Sm.js +788 -0
- package/build/server/chunks/BehaviorGraph-C-9z37Sm.js.map +1 -0
- package/build/server/chunks/Clock-BfMWQpmJ.js +5 -0
- package/build/server/chunks/Clock-BfMWQpmJ.js.map +1 -0
- package/build/server/chunks/DeleteDomain-BvHEgAyp.js +24 -0
- package/build/server/chunks/DeleteDomain-BvHEgAyp.js.map +1 -0
- package/build/server/chunks/{FeatureValidator-B8qEjAUW.js → DeleteFeature-DnK8sBJI.js} +142 -77
- package/build/server/chunks/DeleteFeature-DnK8sBJI.js.map +1 -0
- package/build/server/chunks/DeleteProject-BXZcehHZ.js +41 -0
- package/build/server/chunks/DeleteProject-BXZcehHZ.js.map +1 -0
- package/build/server/chunks/Effect-BJtLR-6l.js +46 -0
- package/build/server/chunks/Effect-BJtLR-6l.js.map +1 -0
- package/build/server/chunks/{FeatureCard-BQOY6gJQ.js → FeatureCard-Bb50FEfp.js} +4 -4
- package/build/server/chunks/{FeatureCard-BQOY6gJQ.js.map → FeatureCard-Bb50FEfp.js.map} +1 -1
- package/build/server/chunks/{FeatureJson-Bv-qiOSf.js → FeatureJson-DYvMEAub.js} +2 -2
- package/build/server/chunks/{FeatureJson-Bv-qiOSf.js.map → FeatureJson-DYvMEAub.js.map} +1 -1
- package/build/server/chunks/{FeatureTransforms-UWDHmWEg.js → FeatureTransforms-B0aI_CJD.js} +10 -3
- package/build/server/chunks/FeatureTransforms-B0aI_CJD.js.map +1 -0
- package/build/server/chunks/{ManageTagsDialog-DBxA3tM2.js → ManageTagsDialog-D5xbAVNB.js} +5 -5
- package/build/server/chunks/ManageTagsDialog-D5xbAVNB.js.map +1 -0
- package/build/server/chunks/{ProgressBar-CfhccQ83.js → ProgressBar-CUC2EZqG.js} +3 -3
- package/build/server/chunks/ProgressBar-CUC2EZqG.js.map +1 -0
- package/build/server/chunks/{ProjectsIndex-CoDrvRya.js → ProjectsIndex-FgIu9dBp.js} +135 -14
- package/build/server/chunks/ProjectsIndex-FgIu9dBp.js.map +1 -0
- package/build/server/chunks/{RenameTag-BuWLMl1m.js → RenameTag-DWIIR4Bx.js} +3 -6
- package/build/server/chunks/RenameTag-DWIIR4Bx.js.map +1 -0
- package/build/server/chunks/ScenarioApplier-YPKECfZe.js +55 -0
- package/build/server/chunks/ScenarioApplier-YPKECfZe.js.map +1 -0
- package/build/server/chunks/SimulatorEngine-DM1F9nCO.js +1391 -0
- package/build/server/chunks/SimulatorEngine-DM1F9nCO.js.map +1 -0
- package/build/server/chunks/StateValue-BBjWox8f.js +105 -0
- package/build/server/chunks/StateValue-BBjWox8f.js.map +1 -0
- package/build/server/chunks/{TagDotStrip-B1XQ0m0Y.js → TagDotStrip-0rn-IJVE.js} +4 -4
- package/build/server/chunks/TagDotStrip-0rn-IJVE.js.map +1 -0
- package/build/server/chunks/{TagFilterSelect-DbO0Qduh.js → TagFilterSelect-Dbu-7Dg4.js} +5 -5
- package/build/server/chunks/{TagFilterSelect-DbO0Qduh.js.map → TagFilterSelect-Dbu-7Dg4.js.map} +1 -1
- package/build/server/chunks/{TagPalette-CtMNYCmu.js → TagPalette-CpdTiC_7.js} +101 -9
- package/build/server/chunks/TagPalette-CpdTiC_7.js.map +1 -0
- package/build/server/chunks/TransitionCatalog-CYXUANy6.js +271 -0
- package/build/server/chunks/TransitionCatalog-CYXUANy6.js.map +1 -0
- package/build/server/chunks/_layout.svelte-pSSG85WT.js +1342 -0
- package/build/server/chunks/_layout.svelte-pSSG85WT.js.map +1 -0
- package/build/server/chunks/{_page.svelte-BKTveFAj.js → _page.svelte-BNH3szkk.js} +22 -17
- package/build/server/chunks/{_page.svelte-BKTveFAj.js.map → _page.svelte-BNH3szkk.js.map} +1 -1
- package/build/server/chunks/_page.svelte-BcuGvUt1.js +37 -0
- package/build/server/chunks/{_page.svelte-B7hT3P8E.js.map → _page.svelte-BcuGvUt1.js.map} +1 -1
- package/build/server/chunks/_page.svelte-BoOMG5Y0.js +37 -0
- package/build/server/chunks/{_page.svelte-De508ek8.js.map → _page.svelte-BoOMG5Y0.js.map} +1 -1
- package/build/server/chunks/{_page.svelte-BqSC-1vK.js → _page.svelte-C4PRh_wP.js} +104 -54
- package/build/server/chunks/_page.svelte-C4PRh_wP.js.map +1 -0
- package/build/server/chunks/_page.svelte-Cqn34NXy.js +74 -0
- package/build/server/chunks/_page.svelte-Cqn34NXy.js.map +1 -0
- package/build/server/chunks/{_page.svelte-B1s7jxaQ.js → _page.svelte-DSCeOGv7.js} +15 -10
- package/build/server/chunks/_page.svelte-DSCeOGv7.js.map +1 -0
- package/build/server/chunks/_page.svelte-DqWdGt48.js +182 -0
- package/build/server/chunks/_page.svelte-DqWdGt48.js.map +1 -0
- package/build/server/chunks/_page.svelte-DsQHSEl4.js +49 -0
- package/build/server/chunks/_page.svelte-DsQHSEl4.js.map +1 -0
- package/build/server/chunks/{_page.svelte-BKKCa9H5.js → _page.svelte-Uioz8hsG.js} +18 -11
- package/build/server/chunks/{_page.svelte-BKKCa9H5.js.map → _page.svelte-Uioz8hsG.js.map} +1 -1
- package/build/server/chunks/{_page.svelte-Zf9H4KOP.js → _page.svelte-p38jot9e.js} +81 -478
- package/build/server/chunks/_page.svelte-p38jot9e.js.map +1 -0
- package/build/server/chunks/{_page.svelte-BtI2zZ_Z.js → _page.svelte-yN5kzgJ9.js} +251 -447
- package/build/server/chunks/_page.svelte-yN5kzgJ9.js.map +1 -0
- package/build/server/chunks/{_server.ts-DsbbVoOn.js → _server.ts-1CtrHhte.js} +4 -4
- package/build/server/chunks/{_server.ts-DsbbVoOn.js.map → _server.ts-1CtrHhte.js.map} +1 -1
- package/build/server/chunks/{_server.ts-CWvU15tL.js → _server.ts-71Qx1lQb.js} +4 -4
- package/build/server/chunks/{_server.ts-CWvU15tL.js.map → _server.ts-71Qx1lQb.js.map} +1 -1
- package/build/server/chunks/_server.ts-BAyekGHB.js +961 -0
- package/build/server/chunks/_server.ts-BAyekGHB.js.map +1 -0
- package/build/server/chunks/{_server.ts-BihpbxOW.js → _server.ts-BLWhU22T.js} +4 -4
- package/build/server/chunks/{_server.ts-BihpbxOW.js.map → _server.ts-BLWhU22T.js.map} +1 -1
- package/build/server/chunks/{_server.ts-YnfXkeMJ.js → _server.ts-C7EVZVxv.js} +22 -13
- package/build/server/chunks/_server.ts-C7EVZVxv.js.map +1 -0
- package/build/server/chunks/{_server.ts-vcaqdwxS.js → _server.ts-CGjYuLmo.js} +12 -7
- package/build/server/chunks/_server.ts-CGjYuLmo.js.map +1 -0
- package/build/server/chunks/{_server.ts-Dy5zQHe2.js → _server.ts-CX6H8fSE.js} +8 -31
- package/build/server/chunks/_server.ts-CX6H8fSE.js.map +1 -0
- package/build/server/chunks/{_server.ts-BuoQ02BW.js → _server.ts-CyEdTCLr.js} +4 -4
- package/build/server/chunks/{_server.ts-BuoQ02BW.js.map → _server.ts-CyEdTCLr.js.map} +1 -1
- package/build/server/chunks/_server.ts-DKVTM9Pj.js +77 -0
- package/build/server/chunks/_server.ts-DKVTM9Pj.js.map +1 -0
- package/build/server/chunks/{_server.ts-0uNTZKwF.js → _server.ts-Dip65hLJ.js} +15 -9
- package/build/server/chunks/_server.ts-Dip65hLJ.js.map +1 -0
- package/build/server/chunks/{_server.ts-D4EO0VHu.js → _server.ts-Dm0tCs2i.js} +5 -5
- package/build/server/chunks/{_server.ts-D4EO0VHu.js.map → _server.ts-Dm0tCs2i.js.map} +1 -1
- package/build/server/chunks/{_server.ts-BIBWjQI-.js → _server.ts-DsYwK_uW.js} +4 -4
- package/build/server/chunks/{_server.ts-BIBWjQI-.js.map → _server.ts-DsYwK_uW.js.map} +1 -1
- package/build/server/chunks/{_server.ts-DDa0Nk_S.js → _server.ts-RCEgegYU.js} +4 -4
- package/build/server/chunks/{_server.ts-DDa0Nk_S.js.map → _server.ts-RCEgegYU.js.map} +1 -1
- package/build/server/chunks/_server.ts-XOLAT4dd.js +146 -0
- package/build/server/chunks/_server.ts-XOLAT4dd.js.map +1 -0
- package/build/server/chunks/_server.ts-afh_zLVi.js +69 -0
- package/build/server/chunks/_server.ts-afh_zLVi.js.map +1 -0
- package/build/server/chunks/{browserContainer-CNX7ANld.js → browserContainer-BdldtueJ.js} +71 -1378
- package/build/server/chunks/browserContainer-BdldtueJ.js.map +1 -0
- package/build/server/chunks/buildSearchDocs-Cyfrnw9G.js +337 -0
- package/build/server/chunks/buildSearchDocs-Cyfrnw9G.js.map +1 -0
- package/build/server/chunks/{builderModeStore.svelte-ihupr-3p.js → builderModeStore.svelte-BEZMQEqn.js} +223 -11
- package/build/server/chunks/builderModeStore.svelte-BEZMQEqn.js.map +1 -0
- package/build/server/chunks/client-C9Cat4DK.js +51 -0
- package/build/server/chunks/{client-DfpLcAZ9.js.map → client-C9Cat4DK.js.map} +1 -1
- package/build/server/chunks/{error.svelte-C35KOpru.js → error.svelte-CzVR_A6P.js} +5 -5
- package/build/server/chunks/{error.svelte-C35KOpru.js.map → error.svelte-CzVR_A6P.js.map} +1 -1
- package/build/server/chunks/featureQueueContext-DuXpyTdC.js +32 -0
- package/build/server/chunks/featureQueueContext-DuXpyTdC.js.map +1 -0
- package/build/server/chunks/featureStore.svelte-DHZf88gu.js +162 -0
- package/build/server/chunks/featureStore.svelte-DHZf88gu.js.map +1 -0
- package/build/server/chunks/{projectsStore.svelte-QDz5PchX.js → featuresStore.svelte-bUyQBg1-.js} +95 -3
- package/build/server/chunks/featuresStore.svelte-bUyQBg1-.js.map +1 -0
- package/build/server/chunks/{hooks.server-Rv301GTB.js → hooks.server-y3jdg_sB.js} +6 -2
- package/build/server/chunks/hooks.server-y3jdg_sB.js.map +1 -0
- package/build/server/chunks/humanize-CkCPfeWi.js +53 -0
- package/build/server/chunks/humanize-CkCPfeWi.js.map +1 -0
- package/build/server/chunks/{index-server-7H0jzj0M.js → index-server-DvBux_Gf.js} +47 -2
- package/build/server/chunks/{index-server-7H0jzj0M.js.map → index-server-DvBux_Gf.js.map} +1 -1
- package/build/server/chunks/{internal-BPKrFkK1.js → internal-BFt8yDlf.js} +5 -5
- package/build/server/chunks/{internal-BPKrFkK1.js.map → internal-BFt8yDlf.js.map} +1 -1
- package/build/server/chunks/projectBundleClient-BtvWPh87.js +168 -0
- package/build/server/chunks/projectBundleClient-BtvWPh87.js.map +1 -0
- package/build/server/chunks/projectContextStore.svelte-jRJGJZ42.js +141 -0
- package/build/server/chunks/projectContextStore.svelte-jRJGJZ42.js.map +1 -0
- package/build/server/chunks/projectFeaturesStore.svelte-BwNEtDIL.js +87 -0
- package/build/server/chunks/projectFeaturesStore.svelte-BwNEtDIL.js.map +1 -0
- package/build/server/chunks/projectStore.svelte-BNuLNxk_.js +230 -0
- package/build/server/chunks/projectStore.svelte-BNuLNxk_.js.map +1 -0
- package/build/server/chunks/{reconcile-Dv7jS3C8.js → reconcile-CVG2LSlW.js} +54 -267
- package/build/server/chunks/reconcile-CVG2LSlW.js.map +1 -0
- package/build/server/chunks/registry-DqAn_hVE.js +21 -0
- package/build/server/chunks/registry-DqAn_hVE.js.map +1 -0
- package/build/server/chunks/{snapshotRepository-BPXCjX92.js → snapshotRepository-8f-2wTrb.js} +30 -5
- package/build/server/chunks/snapshotRepository-8f-2wTrb.js.map +1 -0
- package/build/server/chunks/{state-CpLVNZq7.js → state-CZZtjXLE.js} +3 -3
- package/build/server/chunks/{state-CpLVNZq7.js.map → state-CZZtjXLE.js.map} +1 -1
- package/build/server/chunks/{sync-DZ3dn761.js → sync-Bn6eSUhC.js} +3 -3
- package/build/server/chunks/{sync-DZ3dn761.js.map → sync-Bn6eSUhC.js.map} +1 -1
- package/build/server/chunks/{syncBridge-BwXzPdjJ.js → syncAwareRepositories-DvUjq5Q6.js} +27 -3
- package/build/server/chunks/syncAwareRepositories-DvUjq5Q6.js.map +1 -0
- package/build/server/chunks/{tagPaletteStore.svelte-DfZOBvgY.js → tagPaletteStore.svelte-C71bdzDl.js} +4 -4
- package/build/server/chunks/{tagPaletteStore.svelte-DfZOBvgY.js.map → tagPaletteStore.svelte-C71bdzDl.js.map} +1 -1
- package/build/server/index.js +2 -2
- package/build/server/index.js.map +1 -1
- package/build/server/manifest.js +74 -29
- package/build/server/manifest.js.map +1 -1
- package/cli/README.md +70 -2
- package/cli/commands/check.ts +190 -0
- package/cli/commands/ci.ts +71 -0
- package/cli/commands/coverage-ingest.ts +112 -0
- package/cli/commands/dashboard.ts +14 -0
- package/cli/commands/init.ts +26 -0
- package/cli/commands/scenarios-adapter.ts +96 -0
- package/cli/commands/theme.ts +62 -0
- package/cli/scenarios/adapter-scaffold.ts +99 -0
- package/cli/scenarios/codegen.ts +7 -1
- package/cli/scenarios/results.ts +85 -0
- package/cli/skills/unspa-audit/SKILL.md +19 -0
- package/cli/skills/unspa-edit/SKILL.md +20 -3
- package/cli/skills/unspa-implement/SKILL.md +28 -0
- package/cli/unspa.ts +136 -2
- package/cli/util/context-files.ts +18 -2
- package/cli/util/theme.ts +34 -0
- package/mcp-server/bin.ts +104 -104
- package/mcp-server/migrate-defaults.ts +164 -164
- package/mcp-server/repo-link.ts +142 -134
- package/mcp-server/resources/guide.ts +24 -4
- package/mcp-server/resources/operations.ts +3 -0
- package/mcp-server/seed-snapshots.ts +22 -22
- package/mcp-server/server.ts +8 -4
- package/mcp-server/sync-aware-repos.ts +79 -79
- package/mcp-server/sync-notifier.ts +180 -127
- package/mcp-server/tools/_codegen.ts +115 -115
- package/mcp-server/tools/_entity_builders.ts +30 -0
- package/mcp-server/tools/_shared.ts +210 -210
- package/mcp-server/tools/action.ts +210 -210
- package/mcp-server/tools/batch.ts +29 -5
- package/mcp-server/tools/effect.ts +139 -135
- package/mcp-server/tools/entity.ts +132 -132
- package/mcp-server/tools/entityField.ts +132 -132
- package/mcp-server/tools/event.ts +116 -116
- package/mcp-server/tools/feature.ts +264 -264
- package/mcp-server/tools/invariant.ts +275 -275
- package/mcp-server/tools/persona.ts +141 -141
- package/mcp-server/tools/project.ts +500 -391
- package/mcp-server/tools/reachabilityGoal.ts +97 -0
- package/mcp-server/tools/read.ts +526 -483
- package/mcp-server/tools/reorder.ts +114 -114
- package/mcp-server/tools/resource.ts +194 -194
- package/mcp-server/tools/rule.ts +302 -302
- package/mcp-server/tools/scenario.ts +4 -1
- package/mcp-server/tools/specGaps.ts +221 -221
- package/mcp-server/tools/state.ts +10 -2
- package/mcp-server/tools/surface.ts +102 -102
- package/mcp-server/tools/transition.ts +96 -96
- package/mcp-server/tools/verification.ts +131 -0
- package/package.json +15 -2
- package/src/app.css +208 -9
- package/src/app.html +15 -1
- package/src/features/behavior-model/application/ports/FeatureRepository.ts +16 -16
- package/src/features/behavior-model/application/use-cases/CreateFeature.ts +24 -24
- package/src/features/behavior-model/application/use-cases/DeleteFeature.ts +8 -8
- package/src/features/behavior-model/application/use-cases/GetFeature.ts +9 -9
- package/src/features/behavior-model/application/use-cases/ListFeatures.ts +10 -10
- package/src/features/behavior-model/application/use-cases/MutateFeature.ts +90 -90
- package/src/features/behavior-model/application/use-cases/SaveFeature.ts +31 -31
- package/src/features/behavior-model/domain/entities/Entity.ts +45 -45
- package/src/features/behavior-model/domain/entities/EventDefinition.ts +35 -35
- package/src/features/behavior-model/domain/entities/Feature.ts +10 -0
- package/src/features/behavior-model/domain/entities/Persona.ts +33 -33
- package/src/features/behavior-model/domain/entities/ReachabilityGoal.ts +39 -0
- package/src/features/behavior-model/domain/entities/Resource.ts +54 -54
- package/src/features/behavior-model/domain/entities/Scenario.ts +15 -0
- package/src/features/behavior-model/domain/entities/StateDefinition.ts +13 -0
- package/src/features/behavior-model/domain/entities/Surface.ts +75 -75
- package/src/features/behavior-model/domain/entities/index.ts +9 -9
- package/src/features/behavior-model/domain/services/BehaviorGraphModel.ts +556 -0
- package/src/features/behavior-model/domain/services/DerivedState.ts +67 -0
- package/src/features/behavior-model/domain/services/EffectApplier.ts +112 -3
- package/src/features/behavior-model/domain/services/EffectiveEntities.ts +166 -166
- package/src/features/behavior-model/domain/services/EntityDeducer.ts +83 -83
- package/src/features/behavior-model/domain/services/EventCatalog.ts +141 -141
- package/src/features/behavior-model/domain/services/FeatureExpressionNormalizer.ts +43 -5
- package/src/features/behavior-model/domain/services/FeatureSharedStateNormalizer.ts +24 -3
- package/src/features/behavior-model/domain/services/FeatureTransforms.ts +33 -0
- package/src/features/behavior-model/domain/services/FeatureValidator.ts +124 -16
- package/src/features/behavior-model/domain/services/PersonaApplier.ts +39 -39
- package/src/features/behavior-model/domain/services/ResourceDeducer.ts +64 -64
- package/src/features/behavior-model/domain/services/ResourceUsage.ts +79 -79
- package/src/features/behavior-model/domain/services/ScenarioApplier.ts +40 -40
- package/src/features/behavior-model/domain/services/SharedStateDefinitions.ts +32 -32
- package/src/features/behavior-model/domain/services/StatePathReferences.ts +249 -217
- package/src/features/behavior-model/domain/services/TransitionCatalog.ts +173 -173
- package/src/features/behavior-model/domain/value-objects/Effect.ts +100 -3
- package/src/features/behavior-model/domain/value-objects/EntityFieldType.ts +57 -57
- package/src/features/behavior-model/domain/value-objects/Expression.ts +22 -2
- package/src/features/behavior-model/domain/value-objects/ParameterType.ts +57 -57
- package/src/features/behavior-model/domain/value-objects/Resource.ts +210 -210
- package/src/features/behavior-model/domain/value-objects/RuleCategory.ts +57 -57
- package/src/features/behavior-model/domain/value-objects/RuleCondition.ts +52 -1
- package/src/features/behavior-model/domain/value-objects/SimulationClock.ts +35 -0
- package/src/features/behavior-model/domain/value-objects/ids.ts +2 -0
- package/src/features/behavior-model/infrastructure/io/FeatureJson.ts +89 -89
- package/src/features/behavior-model/infrastructure/persistence/HttpFeatureRepository.ts +43 -43
- package/src/features/behavior-model/infrastructure/persistence/JsonFolderFeatureRepository.ts +10 -0
- package/src/features/behavior-model/infrastructure/persistence/snapshot-discovery.ts +76 -76
- package/src/features/behavior-model/infrastructure/seed/seedStorefront.ts +967 -967
- package/src/features/behavior-model/presentation/adapters/VisBehaviorGraphRenderer.ts +501 -0
- package/src/features/behavior-model/presentation/components/ActionEditor.svelte +683 -682
- package/src/features/behavior-model/presentation/components/ActionsEditor.svelte +232 -232
- package/src/features/behavior-model/presentation/components/BehaviorGraph.svelte +568 -0
- package/src/features/behavior-model/presentation/components/EffectEditor.svelte +168 -168
- package/src/features/behavior-model/presentation/components/EntityEditor.svelte +241 -248
- package/src/features/behavior-model/presentation/components/EntityFieldRow.svelte +180 -181
- package/src/features/behavior-model/presentation/components/EntityManager.svelte +252 -251
- package/src/features/behavior-model/presentation/components/EventsManager.svelte +373 -372
- package/src/features/behavior-model/presentation/components/FeatureEditor.svelte +396 -348
- package/src/features/behavior-model/presentation/components/FeatureHeader.svelte +165 -148
- package/src/features/behavior-model/presentation/components/FeatureHealthStrip.svelte +110 -110
- package/src/features/behavior-model/presentation/components/HistoryPanel.svelte +154 -154
- package/src/features/behavior-model/presentation/components/NewFeatureForm.svelte +66 -66
- package/src/features/behavior-model/presentation/components/ParameterNameSelect.svelte +84 -84
- package/src/features/behavior-model/presentation/components/ParametersEditor.svelte +411 -411
- package/src/features/behavior-model/presentation/components/PersonaEditor.svelte +244 -244
- package/src/features/behavior-model/presentation/components/PersonasManager.svelte +130 -130
- package/src/features/behavior-model/presentation/components/ReachabilityGoalEditor.svelte +230 -0
- package/src/features/behavior-model/presentation/components/ReachabilityGoalsEditor.svelte +86 -0
- package/src/features/behavior-model/presentation/components/ResourcesManager.svelte +291 -290
- package/src/features/behavior-model/presentation/components/ScenariosEditor.svelte +496 -496
- package/src/features/behavior-model/presentation/components/StateDefinitionsEditor.svelte +356 -356
- package/src/features/behavior-model/presentation/components/SurfaceEntitiesView.svelte +88 -88
- package/src/features/behavior-model/presentation/components/SurfaceInvariantsEditor.svelte +76 -76
- package/src/features/behavior-model/presentation/components/SurfaceList.svelte +300 -300
- package/src/features/behavior-model/presentation/components/SurfaceMetaEditor.svelte +158 -156
- package/src/features/behavior-model/presentation/components/SurfacePanel.svelte +198 -198
- package/src/features/behavior-model/presentation/components/SurfacePersonasView.svelte +122 -122
- package/src/features/behavior-model/presentation/components/SurfaceResourcesView.svelte +113 -113
- package/src/features/behavior-model/presentation/components/SurfaceRulesEditor.svelte +69 -69
- package/src/features/behavior-model/presentation/components/TransitionsManager.svelte +322 -321
- package/src/features/behavior-model/presentation/context/featureQueueContext.ts +78 -0
- package/src/features/behavior-model/presentation/stores/editorStore.svelte.ts +132 -131
- package/src/features/behavior-model/presentation/stores/featureStore.svelte.ts +177 -177
- package/src/features/behavior-model/presentation/stores/featuresStore.svelte.ts +98 -98
- package/src/features/behavior-model/presentation/view-models/BehaviorGraphTheme.ts +44 -0
- package/src/features/behavior-model/presentation/view-models/factories.ts +181 -132
- package/src/features/builder-mode/domain/BuilderModeDashboard.ts +7 -1
- package/src/features/builder-mode/presentation/components/BuilderModeDashboard.svelte +78 -16
- package/src/features/builder-mode/presentation/components/BuilderTagChips.svelte +25 -0
- package/src/features/builder-mode/presentation/stores/builderModeStore.svelte.ts +247 -3
- package/src/features/domains/infrastructure/persistence/JsonFolderDomainRepository.ts +9 -0
- package/src/features/global-search/application/use-cases/LoadSearchIndex.ts +70 -0
- package/src/features/global-search/domain/SearchDoc.ts +111 -0
- package/src/features/global-search/domain/buildSearchDocs.ts +483 -0
- package/src/features/global-search/domain/searchNav.ts +58 -0
- package/src/features/global-search/domain/searchScoring.ts +81 -0
- package/src/features/global-search/infrastructure/adapters/defaultSearchHost.ts +28 -0
- package/src/features/global-search/presentation/components/GlobalSearch.svelte +262 -0
- package/src/features/global-search/presentation/ports/SearchHostPorts.ts +41 -0
- package/src/features/global-search/presentation/searchKindMeta.ts +108 -0
- package/src/features/global-search/presentation/stores/globalSearchStore.svelte.ts +171 -0
- package/src/features/implementation-queue/presentation/components/FloatingQueueWidget.svelte +264 -0
- package/src/features/implementation-queue/presentation/stores/globalQueueStore.svelte.ts +172 -0
- package/src/features/implementation-status/application/ports/ImplementationStatusRepository.ts +8 -8
- package/src/features/implementation-status/application/use-cases/GetImplementationStatus.ts +8 -8
- package/src/features/implementation-status/domain/ApplyCapturedToSpec.ts +323 -322
- package/src/features/implementation-status/domain/FieldDiff.ts +238 -236
- package/src/features/implementation-status/infrastructure/persistence/InMemoryImplementationStatusRepository.ts +21 -21
- package/src/features/implementation-status/presentation/components/ImplementationStatusPanel.svelte +831 -831
- package/src/features/implementation-status/presentation/stores/implementationStatusStore.svelte.ts +97 -97
- package/src/features/library/application/use-cases/ApplyBlueprintsToFeature.ts +33 -33
- package/src/features/library/domain/services/BlueprintApplier.ts +94 -94
- package/src/features/library/infrastructure/blueprints/auth/ResetPasswordBlueprint.ts +332 -332
- package/src/features/library/infrastructure/blueprints/auth/SignInBlueprint.ts +281 -281
- package/src/features/library/infrastructure/blueprints/auth/SignUpBlueprint.ts +299 -299
- package/src/features/library/infrastructure/blueprints/auth/VerifyEmailBlueprint.ts +288 -288
- package/src/features/library/infrastructure/blueprints/auth/shared.ts +146 -146
- package/src/features/library/infrastructure/blueprints/commerce/CartBlueprint.ts +222 -222
- package/src/features/library/infrastructure/blueprints/commerce/CatalogBlueprint.ts +190 -190
- package/src/features/library/infrastructure/blueprints/commerce/CheckoutBlueprint.ts +322 -322
- package/src/features/library/infrastructure/blueprints/commerce/OrderConfirmationBlueprint.ts +172 -172
- package/src/features/library/infrastructure/blueprints/commerce/ProductDetailsBlueprint.ts +290 -290
- package/src/features/library/infrastructure/blueprints/content/ReviewsBlueprint.ts +392 -392
- package/src/features/library/infrastructure/blueprints/onboarding/OnboardingWizardBlueprint.ts +344 -344
- package/src/features/library/infrastructure/blueprints/utility/CanvasBlueprint.ts +419 -419
- package/src/features/library/infrastructure/blueprints/utility/CookieConsentBlueprint.ts +195 -195
- package/src/features/library/infrastructure/blueprints/utility/NotFoundBlueprint.ts +86 -86
- package/src/features/library/infrastructure/blueprints/utility/SearchPaletteBlueprint.ts +192 -192
- package/src/features/library/infrastructure/blueprints/utility/StoreLocatorBlueprint.ts +221 -221
- package/src/features/library/infrastructure/blueprints/utility/TaskBoardBlueprint.ts +196 -196
- package/src/features/maturity/application/use-cases/ScoreFeature.ts +7 -7
- package/src/features/maturity/domain/MaturityReport.ts +70 -70
- package/src/features/maturity/domain/MaturityScorer.ts +1001 -985
- package/src/features/maturity/presentation/components/MaturityPanel.svelte +376 -372
- package/src/features/mcp-tools/application/tools/dryRunSimulate.ts +24 -24
- package/src/features/mcp-tools/application/tools/findStateReferences.ts +19 -19
- package/src/features/mcp-tools/application/tools/generateTypes.ts +0 -1
- package/src/features/mcp-tools/application/tools/getAction.ts +165 -165
- package/src/features/mcp-tools/application/tools/getFeature.ts +5 -5
- package/src/features/mcp-tools/application/tools/getFeatureIndex.ts +79 -79
- package/src/features/mcp-tools/application/tools/getNeighborhood.ts +319 -319
- package/src/features/mcp-tools/application/tools/getSurface.ts +86 -86
- package/src/features/mcp-tools/application/tools/index.ts +56 -56
- package/src/features/mcp-tools/application/tools/listActions.ts +49 -49
- package/src/features/mcp-tools/application/tools/listFeatures.ts +7 -7
- package/src/features/mcp-tools/application/tools/scoreFeature.ts +153 -153
- package/src/features/projects/application/ports/ProjectRepository.ts +14 -14
- package/src/features/projects/application/use-cases/AddFeatureToProject.ts +23 -23
- package/src/features/projects/application/use-cases/CreateProject.ts +16 -16
- package/src/features/projects/application/use-cases/FindProjectContainingFeature.ts +23 -23
- package/src/features/projects/application/use-cases/GetProjectAggregate.ts +131 -131
- package/src/features/projects/application/use-cases/ImportProjectBundle.ts +45 -0
- package/src/features/projects/application/use-cases/MoveFeatureInProject.ts +36 -36
- package/src/features/projects/application/use-cases/RemoveFeatureFromProject.ts +23 -23
- package/src/features/projects/domain/entities/Project.ts +12 -0
- package/src/features/projects/domain/services/InheritedFromProject.ts +130 -130
- package/src/features/projects/infrastructure/persistence/JsonFolderProjectRepository.ts +9 -0
- package/src/features/projects/presentation/components/ProjectCard.svelte +27 -8
- package/src/features/projects/presentation/components/ProjectEditor.svelte +23 -19
- package/src/features/projects/presentation/components/ProjectFeaturesPanel.svelte +433 -433
- package/src/features/projects/presentation/components/ProjectsIndex.svelte +54 -10
- package/src/features/projects/presentation/stores/projectContextStore.svelte.ts +170 -170
- package/src/features/projects/presentation/stores/projectFeaturesStore.svelte.ts +114 -114
- package/src/features/projects/presentation/stores/projectStore.svelte.ts +265 -266
- package/src/features/projects/presentation/stores/projectsStore.svelte.ts +134 -134
- package/src/features/simulator/application/use-cases/RunScenarios.ts +27 -1
- package/src/features/simulator/application/use-cases/SimulateAction.ts +47 -47
- package/src/features/simulator/domain/SimulationResult.ts +79 -79
- package/src/features/simulator/domain/SimulatorEngine.ts +43 -9
- package/src/features/simulator/domain/StateExplorer.ts +369 -0
- package/src/features/simulator/domain/SurfaceReachability.ts +130 -0
- package/src/features/simulator/presentation/components/ParameterInputs.svelte +277 -277
- package/src/features/simulator/presentation/components/PersonaPicker.svelte +52 -52
- package/src/features/simulator/presentation/components/ScenarioPicker.svelte +42 -45
- package/src/features/simulator/presentation/components/SidePanel.svelte +170 -170
- package/src/features/simulator/presentation/components/SimulationResultView.svelte +394 -394
- package/src/features/simulator/presentation/components/SimulatorPanel.svelte +293 -293
- package/src/features/simulator/presentation/components/StateInspector.svelte +101 -101
- package/src/features/simulator/presentation/stores/simulatorStore.svelte.ts +268 -268
- package/src/features/tutorial/presentation/components/CodeBlock.svelte +5 -1
- package/src/features/verification/application/ports/BehavioralIndexReader.ts +12 -0
- package/src/features/verification/application/use-cases/VerifyFeatures.ts +151 -0
- package/src/features/verification/domain/DriftReport.ts +37 -0
- package/src/features/verification/domain/EventCoherenceReport.ts +27 -0
- package/src/features/verification/domain/IndexedImplementation.ts +27 -0
- package/src/features/verification/domain/VerificationReport.ts +59 -0
- package/src/features/verification/domain/VerificationThresholds.ts +52 -0
- package/src/features/verification/domain/VerificationVerdict.ts +43 -0
- package/src/features/verification/domain/aggregateVerdict.ts +244 -0
- package/src/features/verification/domain/analyzeEventCoherence.ts +43 -0
- package/src/features/verification/domain/detectDrift.ts +166 -0
- package/src/features/verification/domain/verifiedCoverage.ts +37 -0
- package/src/features/verification/infrastructure/persistence/FileBehavioralIndexReader.ts +81 -0
- package/src/features/verification/infrastructure/persistence/StaticBehavioralIndexReader.ts +15 -0
- package/src/features/verification/presentation/components/VerifyPanel.svelte +74 -0
- package/src/features/verification/presentation/stores/verificationStore.svelte.ts +64 -0
- package/src/hooks.server.ts +11 -1
- package/src/lib/server/openLocalDirectory.ts +40 -0
- package/src/lib/server/searchIndex.ts +161 -0
- package/src/lib/server/snapshotRepository.ts +37 -37
- package/src/lib/server/sync/YDocManager.ts +391 -391
- package/src/lib/server/sync/historyStore.ts +276 -276
- package/src/lib/server/sync/wsServer.ts +1 -1
- package/src/lib/sync/protocol.ts +147 -147
- package/src/lib/sync/roomId.ts +33 -33
- package/src/lib/theme/registry.ts +77 -0
- package/src/lib/theme/themeStore.svelte.ts +64 -0
- package/src/routes/+layout.svelte +288 -30
- package/src/routes/api/domains/[id]/+server.ts +7 -3
- package/src/routes/api/projects/[id]/+server.ts +14 -4
- package/src/routes/api/projects/import/+server.ts +16 -38
- package/src/routes/api/search-index/+server.ts +16 -0
- package/src/routes/api/snapshots/[id]/+server.ts +56 -44
- package/src/routes/api/snapshots/[id]/implementation-status/+server.ts +13 -13
- package/src/routes/api/snapshots/[id]/verify/+server.ts +37 -0
- package/src/routes/api/sync/reload/+server.ts +157 -157
- package/src/routes/api/system/hub-directory/+server.ts +24 -0
- package/src/routes/features/+page.svelte +484 -484
- package/src/routes/features/[id]/+page.svelte +55 -49
- package/src/routes/features/[id]/graph/+page.svelte +39 -0
- package/src/routes/features/[id]/verify/+page.svelte +89 -0
- package/src/routes/mcp/+page.svelte +16 -1
- package/src/routes/projects/[id]/+page.svelte +70 -70
- package/src/routes/projects/[id]/graph/+page.svelte +79 -0
- package/src/routes/tutorial/+page.svelte +3 -2
- package/src/shared/infrastructure/browserContainer.ts +61 -61
- package/src/shared/presentation/components/KebabMenu.svelte +95 -0
- package/src/shared/presentation/components/MenuItem.svelte +29 -0
- package/src/shared/presentation/components/ProgressBar.svelte +1 -1
- package/src/shared/presentation/toast/SyncToast.svelte +14 -3
- package/src/shared/presentation/toast/viewLinkResolver.ts +32 -0
- package/static/lyriks_logo.svg +148 -0
- package/vite.config.ts +47 -47
- package/build/client/_app/immutable/assets/0.DFMDYAU9.css +0 -1
- package/build/client/_app/immutable/assets/0.DFMDYAU9.css.br +0 -0
- package/build/client/_app/immutable/assets/0.DFMDYAU9.css.gz +0 -0
- package/build/client/_app/immutable/assets/9.nv0I59TU.css.gz +0 -0
- package/build/client/_app/immutable/chunks/BO66rBOa2.js +0 -1
- package/build/client/_app/immutable/chunks/BO66rBOa2.js.br +0 -0
- package/build/client/_app/immutable/chunks/BO66rBOa2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BOrLmFwJ.js.br +0 -0
- package/build/client/_app/immutable/chunks/BOrLmFwJ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/BfMYiIUi.js.br +0 -0
- package/build/client/_app/immutable/chunks/BfMYiIUi.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bp2_Vghh.js +0 -1
- package/build/client/_app/immutable/chunks/Bp2_Vghh.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bp2_Vghh.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Bp8HpEPe2.js +0 -4
- package/build/client/_app/immutable/chunks/Bp8HpEPe2.js.br +0 -0
- package/build/client/_app/immutable/chunks/Bp8HpEPe2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/C8rRKIXT.js +0 -1
- package/build/client/_app/immutable/chunks/C8rRKIXT.js.br +0 -0
- package/build/client/_app/immutable/chunks/C8rRKIXT.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CJjJLwzv2.js +0 -1
- package/build/client/_app/immutable/chunks/CJjJLwzv2.js.br +0 -0
- package/build/client/_app/immutable/chunks/CJjJLwzv2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CxyLMlpt2.js.br +0 -0
- package/build/client/_app/immutable/chunks/CxyLMlpt2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D6jhrpTg.js +0 -1
- package/build/client/_app/immutable/chunks/D6jhrpTg.js.br +0 -0
- package/build/client/_app/immutable/chunks/D6jhrpTg.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D8YEa1po.js +0 -1
- package/build/client/_app/immutable/chunks/D8YEa1po.js.br +0 -0
- package/build/client/_app/immutable/chunks/D8YEa1po.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D9dKmajw.js +0 -1
- package/build/client/_app/immutable/chunks/D9dKmajw.js.br +0 -0
- package/build/client/_app/immutable/chunks/D9dKmajw.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DBJWcC6Y.js +0 -1
- package/build/client/_app/immutable/chunks/DBJWcC6Y.js.br +0 -0
- package/build/client/_app/immutable/chunks/DBJWcC6Y.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DHoA038D.js +0 -1
- package/build/client/_app/immutable/chunks/DHoA038D.js.br +0 -2
- package/build/client/_app/immutable/chunks/DHoA038D.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DKgYpi6_.js +0 -1
- package/build/client/_app/immutable/chunks/DKgYpi6_.js.br +0 -0
- package/build/client/_app/immutable/chunks/DKgYpi6_.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DatGSObE.js +0 -1
- package/build/client/_app/immutable/chunks/DatGSObE.js.br +0 -0
- package/build/client/_app/immutable/chunks/DatGSObE.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Dg0acPpT.js +0 -1
- package/build/client/_app/immutable/chunks/Dg0acPpT.js.br +0 -0
- package/build/client/_app/immutable/chunks/Dg0acPpT.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DjWKKtqp.js +0 -1
- package/build/client/_app/immutable/chunks/DjWKKtqp.js.br +0 -1
- package/build/client/_app/immutable/chunks/DjWKKtqp.js.gz +0 -0
- package/build/client/_app/immutable/chunks/Dq0DUAz1.js +0 -1
- package/build/client/_app/immutable/chunks/Dq0DUAz1.js.br +0 -0
- package/build/client/_app/immutable/chunks/Dq0DUAz1.js.gz +0 -0
- package/build/client/_app/immutable/chunks/HKLi1Yz3.js +0 -1
- package/build/client/_app/immutable/chunks/HKLi1Yz3.js.br +0 -0
- package/build/client/_app/immutable/chunks/HKLi1Yz3.js.gz +0 -0
- package/build/client/_app/immutable/chunks/N7PXjlRH.js +0 -1
- package/build/client/_app/immutable/chunks/N7PXjlRH.js.br +0 -0
- package/build/client/_app/immutable/chunks/N7PXjlRH.js.gz +0 -0
- package/build/client/_app/immutable/chunks/hpWJNn0t2.js +0 -2
- package/build/client/_app/immutable/chunks/hpWJNn0t2.js.br +0 -0
- package/build/client/_app/immutable/chunks/hpWJNn0t2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/iQu0D9Ux.js +0 -1
- package/build/client/_app/immutable/chunks/iQu0D9Ux.js.br +0 -0
- package/build/client/_app/immutable/chunks/iQu0D9Ux.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.CLgh6Mx_.js +0 -2
- package/build/client/_app/immutable/entry/app.CLgh6Mx_.js.br +0 -0
- package/build/client/_app/immutable/entry/app.CLgh6Mx_.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.D5GPCQZD.js +0 -1
- package/build/client/_app/immutable/entry/start.D5GPCQZD.js.br +0 -0
- package/build/client/_app/immutable/entry/start.D5GPCQZD.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.BOoI-hsu.js +0 -4
- package/build/client/_app/immutable/nodes/0.BOoI-hsu.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.BOoI-hsu.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.KYdA6ppX.js.br +0 -2
- package/build/client/_app/immutable/nodes/1.KYdA6ppX.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.DBz20KgG.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.DBz20KgG.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.19DIoFtw.js +0 -1
- package/build/client/_app/immutable/nodes/3.19DIoFtw.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.19DIoFtw.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.BvMzqBJj.js +0 -3
- package/build/client/_app/immutable/nodes/4.BvMzqBJj.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.BvMzqBJj.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.Dq6obSGG.js +0 -42
- package/build/client/_app/immutable/nodes/5.Dq6obSGG.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.Dq6obSGG.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.BOHISqs-.js +0 -5
- package/build/client/_app/immutable/nodes/6.BOHISqs-.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.BOHISqs-.js.gz +0 -0
- package/build/client/_app/immutable/nodes/7.CemgNJfw.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.CemgNJfw.js.gz +0 -0
- package/build/client/_app/immutable/nodes/8.DejSfIYh.js +0 -5
- package/build/client/_app/immutable/nodes/8.DejSfIYh.js.br +0 -0
- package/build/client/_app/immutable/nodes/8.DejSfIYh.js.gz +0 -0
- package/build/client/_app/immutable/nodes/9.CMW6a2Lg.js.br +0 -0
- package/build/client/_app/immutable/nodes/9.CMW6a2Lg.js.gz +0 -0
- package/build/server/chunks/0-C_o0oz-N.js +0 -15
- package/build/server/chunks/0-C_o0oz-N.js.map +0 -1
- package/build/server/chunks/1-DPpKAKXV.js +0 -9
- package/build/server/chunks/2-AlfFqtL1.js +0 -9
- package/build/server/chunks/2-AlfFqtL1.js.map +0 -1
- package/build/server/chunks/3-vbjUt_51.js +0 -16
- package/build/server/chunks/3-vbjUt_51.js.map +0 -1
- package/build/server/chunks/4-BNow4x6D.js +0 -16
- package/build/server/chunks/4-BNow4x6D.js.map +0 -1
- package/build/server/chunks/5-D7OCJpxD.js +0 -9
- package/build/server/chunks/5-D7OCJpxD.js.map +0 -1
- package/build/server/chunks/6-QQ7r8Rd5.js +0 -9
- package/build/server/chunks/7-CbPLGaIG.js +0 -9
- package/build/server/chunks/7-CbPLGaIG.js.map +0 -1
- package/build/server/chunks/8-CVO-E-sf.js +0 -9
- package/build/server/chunks/8-CVO-E-sf.js.map +0 -1
- package/build/server/chunks/9-DxT1baO5.js +0 -9
- package/build/server/chunks/9-DxT1baO5.js.map +0 -1
- package/build/server/chunks/FeatureTransforms-UWDHmWEg.js.map +0 -1
- package/build/server/chunks/FeatureValidator-B8qEjAUW.js.map +0 -1
- package/build/server/chunks/ManageTagsDialog-DBxA3tM2.js.map +0 -1
- package/build/server/chunks/ProgressBar-CfhccQ83.js.map +0 -1
- package/build/server/chunks/ProjectsIndex-CoDrvRya.js.map +0 -1
- package/build/server/chunks/RenameTag-BuWLMl1m.js.map +0 -1
- package/build/server/chunks/TagDotStrip-B1XQ0m0Y.js.map +0 -1
- package/build/server/chunks/TagPalette-CtMNYCmu.js.map +0 -1
- package/build/server/chunks/_layout.svelte-BREws55o.js +0 -616
- package/build/server/chunks/_layout.svelte-BREws55o.js.map +0 -1
- package/build/server/chunks/_page.svelte-B1s7jxaQ.js.map +0 -1
- package/build/server/chunks/_page.svelte-B7hT3P8E.js +0 -29
- package/build/server/chunks/_page.svelte-BqSC-1vK.js.map +0 -1
- package/build/server/chunks/_page.svelte-BtI2zZ_Z.js.map +0 -1
- package/build/server/chunks/_page.svelte-De508ek8.js +0 -29
- package/build/server/chunks/_page.svelte-Zf9H4KOP.js.map +0 -1
- package/build/server/chunks/_server.ts-0uNTZKwF.js.map +0 -1
- package/build/server/chunks/_server.ts-DcZPhyhK.js +0 -59
- package/build/server/chunks/_server.ts-DcZPhyhK.js.map +0 -1
- package/build/server/chunks/_server.ts-Dy5zQHe2.js.map +0 -1
- package/build/server/chunks/_server.ts-YnfXkeMJ.js.map +0 -1
- package/build/server/chunks/_server.ts-vcaqdwxS.js.map +0 -1
- package/build/server/chunks/browserContainer-CNX7ANld.js.map +0 -1
- package/build/server/chunks/builderModeStore.svelte-ihupr-3p.js.map +0 -1
- package/build/server/chunks/client-DfpLcAZ9.js +0 -24
- package/build/server/chunks/featuresStore.svelte-DR1gYZyu.js +0 -98
- package/build/server/chunks/featuresStore.svelte-DR1gYZyu.js.map +0 -1
- package/build/server/chunks/hooks.server-Rv301GTB.js.map +0 -1
- package/build/server/chunks/identityStore.svelte-IIvW2_3b.js +0 -59
- package/build/server/chunks/identityStore.svelte-IIvW2_3b.js.map +0 -1
- package/build/server/chunks/projectsStore.svelte-QDz5PchX.js.map +0 -1
- package/build/server/chunks/reconcile-Dv7jS3C8.js.map +0 -1
- package/build/server/chunks/snapshotRepository-BPXCjX92.js.map +0 -1
- package/build/server/chunks/syncBridge-BwXzPdjJ.js.map +0 -1
- package/src/features/implementation-queue/presentation/components/QueuePanel.svelte +0 -204
- package/src/features/implementation-queue/presentation/stores/queueStore.svelte.ts +0 -143
- /package/build/client/_app/immutable/assets/{9.nv0I59TU.css → 12.nv0I59TU.css} +0 -0
- /package/build/client/_app/immutable/assets/{9.nv0I59TU.css.br → 12.nv0I59TU.css.br} +0 -0
|
@@ -76,7 +76,33 @@ export type NotCondition = {
|
|
|
76
76
|
|
|
77
77
|
export type CompositeRuleCondition = AllCondition | AnyCondition | NotCondition;
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
/**
|
|
80
|
+
* Quantifier over the elements of an array-typed state path. `all_match` holds
|
|
81
|
+
* when EVERY element satisfies `where`; `any_match` holds when AT LEAST ONE
|
|
82
|
+
* does. This is the per-element guarantee that `count_where` (a count) and the
|
|
83
|
+
* boolean combinators (over sibling conditions, not elements) could never
|
|
84
|
+
* express — e.g. the invariant "every order line has qty > 0".
|
|
85
|
+
*
|
|
86
|
+
* Evaluation binds each element into the snapshot under the `as` name, then
|
|
87
|
+
* evaluates `where` as an ordinary condition. So with `as: "item"` over an
|
|
88
|
+
* array of objects, the body reads `item.qty`; over an array of scalars it
|
|
89
|
+
* reads `item` directly. The body may also reference outer state paths
|
|
90
|
+
* (e.g. compare `item.qty` to a threshold elsewhere in state).
|
|
91
|
+
*
|
|
92
|
+
* Vacuous truth: `all_match` over a missing/empty array is TRUE, `any_match`
|
|
93
|
+
* is FALSE — the standard ∀/∃ semantics.
|
|
94
|
+
*/
|
|
95
|
+
export type QuantifierCondition = {
|
|
96
|
+
readonly kind: 'all_match' | 'any_match';
|
|
97
|
+
readonly overPath: StatePath;
|
|
98
|
+
readonly as: string;
|
|
99
|
+
readonly where: RuleCondition;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export type RuleCondition =
|
|
103
|
+
| LeafRuleCondition
|
|
104
|
+
| CompositeRuleCondition
|
|
105
|
+
| QuantifierCondition;
|
|
80
106
|
|
|
81
107
|
/**
|
|
82
108
|
* Runtime guard: a composite condition carries a `kind` matching one of
|
|
@@ -91,6 +117,20 @@ export const isCompositeCondition = (
|
|
|
91
117
|
return k === 'all' || k === 'any' || k === 'not';
|
|
92
118
|
};
|
|
93
119
|
|
|
120
|
+
/**
|
|
121
|
+
* Runtime guard: a quantifier condition (`all_match` / `any_match`). Kept
|
|
122
|
+
* separate from `isCompositeCondition` because quantifiers introduce a scoped
|
|
123
|
+
* element binding and so are evaluated/walked differently from the plain
|
|
124
|
+
* boolean combinators.
|
|
125
|
+
*/
|
|
126
|
+
export const isQuantifierCondition = (
|
|
127
|
+
c: unknown
|
|
128
|
+
): c is QuantifierCondition => {
|
|
129
|
+
if (!c || typeof c !== 'object') return false;
|
|
130
|
+
const k = (c as { kind?: unknown }).kind;
|
|
131
|
+
return k === 'all_match' || k === 'any_match';
|
|
132
|
+
};
|
|
133
|
+
|
|
94
134
|
/**
|
|
95
135
|
* Walks a condition tree and yields every leaf comparison it contains.
|
|
96
136
|
* Use when a consumer (path collector, graph builder, indexer) needs to
|
|
@@ -111,6 +151,17 @@ export const flattenLeafConditions = (
|
|
|
111
151
|
else for (const sub of node.conditions) walk(sub);
|
|
112
152
|
return;
|
|
113
153
|
}
|
|
154
|
+
if (isQuantifierCondition(node)) {
|
|
155
|
+
// Surface the array source as a synthetic `exists` leaf so every
|
|
156
|
+
// path-validator / collector that walks leaves sees the quantified
|
|
157
|
+
// array reference and keeps working unchanged. The body is NOT
|
|
158
|
+
// descended into: its leaves reference the scoped element binding
|
|
159
|
+
// (`as`), which isn't a declared outer state path and would be a false
|
|
160
|
+
// "unknown path" to those consumers. Body evaluation is handled
|
|
161
|
+
// directly by the condition evaluator, which understands the binding.
|
|
162
|
+
out.push({ left: node.overPath, operator: 'exists' });
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
114
165
|
out.push(node);
|
|
115
166
|
};
|
|
116
167
|
walk(c);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { asStatePath, readPath, writePath, type StateSnapshot, type StatePath } from './StatePath';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Reserved state path holding the simulation clock — a NUMBER in logical time
|
|
5
|
+
* units chosen by the model (seconds, minutes, ticks; the engine doesn't care).
|
|
6
|
+
* It is the single source of "now" that conditions and invariants compare
|
|
7
|
+
* stored timestamps against ("session.expiresAt greater_than clock.now"), and
|
|
8
|
+
* the `advance_time` effect / scenario `timeAdvance` are the only sanctioned
|
|
9
|
+
* ways to move it forward.
|
|
10
|
+
*
|
|
11
|
+
* Time is EXPLICIT state, never wall-clock: a scenario that advances the clock
|
|
12
|
+
* by N and re-runs an action is fully deterministic and replayable, which is
|
|
13
|
+
* what makes "after 30 minutes the token is expired" verifiable instead of
|
|
14
|
+
* flaky. The path is implicitly available on every surface (the validator
|
|
15
|
+
* treats it as always-declared). The engine does NOT auto-seed it — the clock
|
|
16
|
+
* materializes the first time it is advanced — but it reads as 0 until then via
|
|
17
|
+
* `readNow`, so future-deadline comparisons behave as "time 0".
|
|
18
|
+
*/
|
|
19
|
+
export const CLOCK_NOW_PATH: StatePath = asStatePath('clock.now');
|
|
20
|
+
|
|
21
|
+
/** Read the current clock value, defaulting to 0 when unset/non-numeric. */
|
|
22
|
+
export const readNow = (snapshot: StateSnapshot): number => {
|
|
23
|
+
const v = readPath(snapshot, CLOCK_NOW_PATH);
|
|
24
|
+
return typeof v === 'number' && Number.isFinite(v) ? v : 0;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Advance the clock by `by` logical units. Time never runs backward: a negative
|
|
29
|
+
* or non-finite delta is clamped to 0 (a no-op), so a malformed duration can't
|
|
30
|
+
* un-expire something already expired.
|
|
31
|
+
*/
|
|
32
|
+
export const advanceClock = (snapshot: StateSnapshot, by: number): StateSnapshot => {
|
|
33
|
+
const delta = typeof by === 'number' && Number.isFinite(by) && by > 0 ? by : 0;
|
|
34
|
+
return writePath(snapshot, CLOCK_NOW_PATH, readNow(snapshot) + delta);
|
|
35
|
+
};
|
|
@@ -16,6 +16,7 @@ export type EntityFieldId = Brand<string, 'EntityFieldId'>;
|
|
|
16
16
|
export type ScenarioId = Brand<string, 'ScenarioId'>;
|
|
17
17
|
export type EventDefinitionId = Brand<string, 'EventDefinitionId'>;
|
|
18
18
|
export type ValueSetId = Brand<string, 'ValueSetId'>;
|
|
19
|
+
export type ReachabilityGoalId = Brand<string, 'ReachabilityGoalId'>;
|
|
19
20
|
|
|
20
21
|
export const asFeatureId = (v: string): FeatureId => v as FeatureId;
|
|
21
22
|
export const asSurfaceId = (v: string): SurfaceId => v as SurfaceId;
|
|
@@ -33,3 +34,4 @@ export const asEntityFieldId = (v: string): EntityFieldId => v as EntityFieldId;
|
|
|
33
34
|
export const asScenarioId = (v: string): ScenarioId => v as ScenarioId;
|
|
34
35
|
export const asEventDefinitionId = (v: string): EventDefinitionId => v as EventDefinitionId;
|
|
35
36
|
export const asValueSetId = (v: string): ValueSetId => v as ValueSetId;
|
|
37
|
+
export const asReachabilityGoalId = (v: string): ReachabilityGoalId => v as ReachabilityGoalId;
|
|
@@ -1,96 +1,96 @@
|
|
|
1
|
-
import type { Entity } from '$features/behavior-model/domain/entities/Entity';
|
|
2
|
-
import type { Feature } from '$features/behavior-model/domain/entities/Feature';
|
|
3
|
-
import type { Surface } from '$features/behavior-model/domain/entities/Surface';
|
|
4
|
-
import { normalizeFeatureEmittedEvents } from '$features/behavior-model/domain/services/FeatureEmittedEventsNormalizer';
|
|
5
|
-
import { normalizeFeatureExpressions } from '$features/behavior-model/domain/services/FeatureExpressionNormalizer';
|
|
1
|
+
import type { Entity } from '$features/behavior-model/domain/entities/Entity';
|
|
2
|
+
import type { Feature } from '$features/behavior-model/domain/entities/Feature';
|
|
3
|
+
import type { Surface } from '$features/behavior-model/domain/entities/Surface';
|
|
4
|
+
import { normalizeFeatureEmittedEvents } from '$features/behavior-model/domain/services/FeatureEmittedEventsNormalizer';
|
|
5
|
+
import { normalizeFeatureExpressions } from '$features/behavior-model/domain/services/FeatureExpressionNormalizer';
|
|
6
6
|
import { normalizeFeatureRuleCategories } from '$features/behavior-model/domain/services/FeatureRuleCategoryNormalizer';
|
|
7
7
|
import { normalizeFeatureSharedState } from '$features/behavior-model/domain/services/FeatureSharedStateNormalizer';
|
|
8
8
|
import { normalizeTags } from '$shared/domain/Tags';
|
|
9
|
-
|
|
10
|
-
export type FeatureExportEnvelope = {
|
|
11
|
-
readonly format: 'unspaghettit';
|
|
12
|
-
readonly version: 1;
|
|
13
|
-
readonly feature: Feature;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export const exportFeatureToJson = (feature: Feature): string => {
|
|
17
|
-
const envelope: FeatureExportEnvelope = {
|
|
18
|
-
format: 'unspaghettit',
|
|
19
|
-
version: 1,
|
|
20
|
-
feature
|
|
21
|
-
};
|
|
22
|
-
return JSON.stringify(envelope, null, 2);
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Pre-rename JSON snapshots stored the Surface's user-action list under the
|
|
27
|
-
* key `capabilities`. The TS field is now `actions`. Migrate on read so old
|
|
28
|
-
* files keep loading without a separate batch migration step. New writes
|
|
29
|
-
* always use the new key.
|
|
30
|
-
*/
|
|
31
|
-
const migrateSurface = (raw: Record<string, unknown>): Surface => {
|
|
32
|
-
if ('actions' in raw) return raw as unknown as Surface;
|
|
33
|
-
if ('capabilities' in raw) {
|
|
34
|
-
const { capabilities, ...rest } = raw;
|
|
35
|
-
return { ...rest, actions: capabilities } as unknown as Surface;
|
|
36
|
-
}
|
|
37
|
-
return raw as unknown as Surface;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export const importFeatureFromJson = (raw: string): Feature => {
|
|
41
|
-
let parsed: unknown;
|
|
42
|
-
try {
|
|
43
|
-
parsed = JSON.parse(raw);
|
|
44
|
-
} catch (error) {
|
|
45
|
-
throw new Error(`Invalid JSON: ${(error as Error).message}`);
|
|
46
|
-
}
|
|
47
|
-
if (!parsed || typeof parsed !== 'object') {
|
|
48
|
-
throw new Error('Expected a feature export object');
|
|
49
|
-
}
|
|
50
|
-
// Accept both the new `feature` envelope key and the legacy `experience`
|
|
51
|
-
// key so older snapshots keep loading. New writes always use `feature`.
|
|
52
|
-
const envelope = parsed as {
|
|
53
|
-
format?: string;
|
|
54
|
-
version?: number;
|
|
55
|
-
feature?: Feature;
|
|
56
|
-
experience?: Feature;
|
|
57
|
-
};
|
|
58
|
-
if (envelope.format !== 'unspaghettit') {
|
|
59
|
-
throw new Error('Not an Unspaghettit export (missing format field)');
|
|
60
|
-
}
|
|
61
|
-
if (envelope.version !== 1) {
|
|
62
|
-
throw new Error(`Unsupported export version: ${envelope.version}`);
|
|
63
|
-
}
|
|
64
|
-
const feature = envelope.feature ?? envelope.experience;
|
|
65
|
-
if (!feature) {
|
|
66
|
-
throw new Error('Export envelope is missing a feature');
|
|
67
|
-
}
|
|
68
|
-
const rawSurfaces =
|
|
69
|
-
(feature as unknown as { surfaces?: readonly unknown[] }).surfaces ?? [];
|
|
70
|
-
const surfaces = rawSurfaces.map((s) => migrateSurface(s as Record<string, unknown>));
|
|
71
|
-
// Pre-rename JSON used `data[]` for first-class entity records; new files
|
|
72
|
-
// write `entities[]`. Accept either so legacy snapshots still load.
|
|
73
|
-
const expRaw = feature as unknown as {
|
|
74
|
-
entities?: readonly unknown[];
|
|
75
|
-
data?: readonly unknown[];
|
|
76
|
-
};
|
|
77
|
-
const entities = (expRaw.entities ?? expRaw.data ?? []) as readonly Entity[];
|
|
78
|
-
// Normalize Expression trees and emittedEvents on import so legacy
|
|
79
|
-
// snapshots load with healed-in-memory data. Expression normalization
|
|
80
|
-
// wraps raw scalars in `{kind:"literal",value}`; emittedEvents normalization
|
|
81
|
-
// merges every emit_event effect's name into the action's declared list.
|
|
82
|
-
return normalizeFeatureSharedState(
|
|
83
|
-
normalizeFeatureRuleCategories(
|
|
84
|
-
normalizeFeatureEmittedEvents(
|
|
9
|
+
|
|
10
|
+
export type FeatureExportEnvelope = {
|
|
11
|
+
readonly format: 'unspaghettit';
|
|
12
|
+
readonly version: 1;
|
|
13
|
+
readonly feature: Feature;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const exportFeatureToJson = (feature: Feature): string => {
|
|
17
|
+
const envelope: FeatureExportEnvelope = {
|
|
18
|
+
format: 'unspaghettit',
|
|
19
|
+
version: 1,
|
|
20
|
+
feature
|
|
21
|
+
};
|
|
22
|
+
return JSON.stringify(envelope, null, 2);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Pre-rename JSON snapshots stored the Surface's user-action list under the
|
|
27
|
+
* key `capabilities`. The TS field is now `actions`. Migrate on read so old
|
|
28
|
+
* files keep loading without a separate batch migration step. New writes
|
|
29
|
+
* always use the new key.
|
|
30
|
+
*/
|
|
31
|
+
const migrateSurface = (raw: Record<string, unknown>): Surface => {
|
|
32
|
+
if ('actions' in raw) return raw as unknown as Surface;
|
|
33
|
+
if ('capabilities' in raw) {
|
|
34
|
+
const { capabilities, ...rest } = raw;
|
|
35
|
+
return { ...rest, actions: capabilities } as unknown as Surface;
|
|
36
|
+
}
|
|
37
|
+
return raw as unknown as Surface;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const importFeatureFromJson = (raw: string): Feature => {
|
|
41
|
+
let parsed: unknown;
|
|
42
|
+
try {
|
|
43
|
+
parsed = JSON.parse(raw);
|
|
44
|
+
} catch (error) {
|
|
45
|
+
throw new Error(`Invalid JSON: ${(error as Error).message}`);
|
|
46
|
+
}
|
|
47
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
48
|
+
throw new Error('Expected a feature export object');
|
|
49
|
+
}
|
|
50
|
+
// Accept both the new `feature` envelope key and the legacy `experience`
|
|
51
|
+
// key so older snapshots keep loading. New writes always use `feature`.
|
|
52
|
+
const envelope = parsed as {
|
|
53
|
+
format?: string;
|
|
54
|
+
version?: number;
|
|
55
|
+
feature?: Feature;
|
|
56
|
+
experience?: Feature;
|
|
57
|
+
};
|
|
58
|
+
if (envelope.format !== 'unspaghettit') {
|
|
59
|
+
throw new Error('Not an Unspaghettit export (missing format field)');
|
|
60
|
+
}
|
|
61
|
+
if (envelope.version !== 1) {
|
|
62
|
+
throw new Error(`Unsupported export version: ${envelope.version}`);
|
|
63
|
+
}
|
|
64
|
+
const feature = envelope.feature ?? envelope.experience;
|
|
65
|
+
if (!feature) {
|
|
66
|
+
throw new Error('Export envelope is missing a feature');
|
|
67
|
+
}
|
|
68
|
+
const rawSurfaces =
|
|
69
|
+
(feature as unknown as { surfaces?: readonly unknown[] }).surfaces ?? [];
|
|
70
|
+
const surfaces = rawSurfaces.map((s) => migrateSurface(s as Record<string, unknown>));
|
|
71
|
+
// Pre-rename JSON used `data[]` for first-class entity records; new files
|
|
72
|
+
// write `entities[]`. Accept either so legacy snapshots still load.
|
|
73
|
+
const expRaw = feature as unknown as {
|
|
74
|
+
entities?: readonly unknown[];
|
|
75
|
+
data?: readonly unknown[];
|
|
76
|
+
};
|
|
77
|
+
const entities = (expRaw.entities ?? expRaw.data ?? []) as readonly Entity[];
|
|
78
|
+
// Normalize Expression trees and emittedEvents on import so legacy
|
|
79
|
+
// snapshots load with healed-in-memory data. Expression normalization
|
|
80
|
+
// wraps raw scalars in `{kind:"literal",value}`; emittedEvents normalization
|
|
81
|
+
// merges every emit_event effect's name into the action's declared list.
|
|
82
|
+
return normalizeFeatureSharedState(
|
|
83
|
+
normalizeFeatureRuleCategories(
|
|
84
|
+
normalizeFeatureEmittedEvents(
|
|
85
85
|
normalizeFeatureExpressions({
|
|
86
86
|
...feature,
|
|
87
87
|
tags: normalizeTags(feature.tags),
|
|
88
88
|
surfaces,
|
|
89
|
-
personas: feature.personas ?? [],
|
|
90
|
-
resources: feature.resources ?? [],
|
|
91
|
-
entities
|
|
92
|
-
})
|
|
93
|
-
)
|
|
94
|
-
)
|
|
95
|
-
);
|
|
96
|
-
};
|
|
89
|
+
personas: feature.personas ?? [],
|
|
90
|
+
resources: feature.resources ?? [],
|
|
91
|
+
entities
|
|
92
|
+
})
|
|
93
|
+
)
|
|
94
|
+
)
|
|
95
|
+
);
|
|
96
|
+
};
|
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
FeatureRepository,
|
|
3
|
-
FeatureSummary
|
|
4
|
-
} from '$features/behavior-model/application/ports/FeatureRepository';
|
|
5
|
-
import type { Feature } from '$features/behavior-model/domain/entities/Feature';
|
|
6
|
-
import type { FeatureId } from '$features/behavior-model/domain/value-objects/ids';
|
|
7
|
-
import { apiFetch } from '$shared/security/apiFetch';
|
|
8
|
-
|
|
9
|
-
const BASE = '/api/snapshots';
|
|
10
|
-
const itemUrl = (id: string) => `${BASE}/${encodeURIComponent(id)}`;
|
|
11
|
-
|
|
12
|
-
export class HttpFeatureRepository implements FeatureRepository {
|
|
13
|
-
async list(): Promise<readonly FeatureSummary[]> {
|
|
14
|
-
const res = await apiFetch(BASE);
|
|
15
|
-
if (!res.ok) throw new Error(`Snapshot list failed (${res.status})`);
|
|
16
|
-
const body = (await res.json()) as { summaries: readonly FeatureSummary[] };
|
|
17
|
-
return body.summaries;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async get(id: FeatureId): Promise<Feature | null> {
|
|
21
|
-
const res = await apiFetch(itemUrl(id));
|
|
22
|
-
if (res.status === 404) return null;
|
|
23
|
-
if (!res.ok) throw new Error(`Snapshot get failed (${res.status})`);
|
|
24
|
-
return (await res.json()) as Feature;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async save(feature: Feature): Promise<void> {
|
|
28
|
-
const res = await apiFetch(itemUrl(feature.id), {
|
|
29
|
-
method: 'PUT',
|
|
30
|
-
headers: { 'Content-Type': 'application/json' },
|
|
31
|
-
body: JSON.stringify(feature)
|
|
32
|
-
});
|
|
33
|
-
if (!res.ok) {
|
|
34
|
-
const text = await res.text().catch(() => '');
|
|
35
|
-
throw new Error(`Snapshot save failed (${res.status})${text ? `: ${text}` : ''}`);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async delete(id: FeatureId): Promise<void> {
|
|
40
|
-
const res = await apiFetch(itemUrl(id), { method: 'DELETE' });
|
|
41
|
-
if (!res.ok && res.status !== 404) throw new Error(`Snapshot delete failed (${res.status})`);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
1
|
+
import type {
|
|
2
|
+
FeatureRepository,
|
|
3
|
+
FeatureSummary
|
|
4
|
+
} from '$features/behavior-model/application/ports/FeatureRepository';
|
|
5
|
+
import type { Feature } from '$features/behavior-model/domain/entities/Feature';
|
|
6
|
+
import type { FeatureId } from '$features/behavior-model/domain/value-objects/ids';
|
|
7
|
+
import { apiFetch } from '$shared/security/apiFetch';
|
|
8
|
+
|
|
9
|
+
const BASE = '/api/snapshots';
|
|
10
|
+
const itemUrl = (id: string) => `${BASE}/${encodeURIComponent(id)}`;
|
|
11
|
+
|
|
12
|
+
export class HttpFeatureRepository implements FeatureRepository {
|
|
13
|
+
async list(): Promise<readonly FeatureSummary[]> {
|
|
14
|
+
const res = await apiFetch(BASE);
|
|
15
|
+
if (!res.ok) throw new Error(`Snapshot list failed (${res.status})`);
|
|
16
|
+
const body = (await res.json()) as { summaries: readonly FeatureSummary[] };
|
|
17
|
+
return body.summaries;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async get(id: FeatureId): Promise<Feature | null> {
|
|
21
|
+
const res = await apiFetch(itemUrl(id));
|
|
22
|
+
if (res.status === 404) return null;
|
|
23
|
+
if (!res.ok) throw new Error(`Snapshot get failed (${res.status})`);
|
|
24
|
+
return (await res.json()) as Feature;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async save(feature: Feature): Promise<void> {
|
|
28
|
+
const res = await apiFetch(itemUrl(feature.id), {
|
|
29
|
+
method: 'PUT',
|
|
30
|
+
headers: { 'Content-Type': 'application/json' },
|
|
31
|
+
body: JSON.stringify(feature)
|
|
32
|
+
});
|
|
33
|
+
if (!res.ok) {
|
|
34
|
+
const text = await res.text().catch(() => '');
|
|
35
|
+
throw new Error(`Snapshot save failed (${res.status})${text ? `: ${text}` : ''}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async delete(id: FeatureId): Promise<void> {
|
|
40
|
+
const res = await apiFetch(itemUrl(id), { method: 'DELETE' });
|
|
41
|
+
if (!res.ok && res.status !== 404) throw new Error(`Snapshot delete failed (${res.status})`);
|
|
42
|
+
}
|
|
43
|
+
}
|
package/src/features/behavior-model/infrastructure/persistence/JsonFolderFeatureRepository.ts
CHANGED
|
@@ -65,6 +65,16 @@ export class JsonFolderFeatureRepository implements FeatureRepository {
|
|
|
65
65
|
return found ? found.feature : null;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Server-only bulk read: every full Feature in ONE directory pass. Not on the
|
|
70
|
+
* {@link FeatureRepository} port — it exists so derived artifacts (notably the
|
|
71
|
+
* global-search index) can build in O(N) instead of the O(N²) that
|
|
72
|
+
* `list()` + a `get()` per id incurs (each `get` re-walks the whole folder).
|
|
73
|
+
*/
|
|
74
|
+
async listFull(): Promise<readonly Feature[]> {
|
|
75
|
+
return this.readAll().map((s) => s.feature);
|
|
76
|
+
}
|
|
77
|
+
|
|
68
78
|
async save(feature: Feature): Promise<void> {
|
|
69
79
|
// Re-resolve the owning project on every save: when a feature is reassigned
|
|
70
80
|
// (add_feature_to_project / remove_feature_from_project), the very next
|
|
@@ -1,76 +1,76 @@
|
|
|
1
|
-
import { existsSync, readdirSync, statSync } from 'node:fs';
|
|
2
|
-
import { homedir } from 'node:os';
|
|
3
|
-
import { isAbsolute, join, parse, resolve } from 'node:path';
|
|
4
|
-
|
|
5
|
-
export type SnapshotDirectorySource = 'override' | 'walk' | 'hub-default';
|
|
6
|
-
|
|
7
|
-
export type SnapshotDirectory = {
|
|
8
|
-
readonly directory: string;
|
|
9
|
-
readonly source: SnapshotDirectorySource;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export type DiscoverOptions = {
|
|
13
|
-
readonly override?: string;
|
|
14
|
-
readonly cwd?: string;
|
|
15
|
-
/** Home directory used to resolve the shared hub. Defaults to os.homedir(). */
|
|
16
|
-
readonly home?: string;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const SNAPSHOT_SUFFIXES = ['.feature.json', '.project.json'];
|
|
20
|
-
const FOLDER_NAME = 'unspa';
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Shared snapshot hub layout: `<home>/.unspa-hub/unspa`. The `.unspa-hub`
|
|
24
|
-
* parent is the well-known launch point for `unspa dashboard`; the `unspa`
|
|
25
|
-
* subfolder is the snapshot directory itself. This is the default home for
|
|
26
|
-
* every project's behavior model — `unspa init` no longer scaffolds a per-repo
|
|
27
|
-
* `unspa/` folder, so when neither an explicit override nor a walk-up hit is
|
|
28
|
-
* found, both the dashboard and the MCP server land here on the first run. The
|
|
29
|
-
* folder is created lazily on first write (`ensureProjectDir` does `mkdir -p`).
|
|
30
|
-
*
|
|
31
|
-
* `homedir()` + `path.join` keep this correct on Windows, macOS, and Linux.
|
|
32
|
-
*/
|
|
33
|
-
export const HUB_ROOT_SEGMENT = '.unspa-hub';
|
|
34
|
-
export const HUB_SNAPSHOTS_SEGMENT = FOLDER_NAME;
|
|
35
|
-
|
|
36
|
-
export const defaultHubDirectory = (home: string = homedir()): string =>
|
|
37
|
-
join(home, HUB_ROOT_SEGMENT, HUB_SNAPSHOTS_SEGMENT);
|
|
38
|
-
|
|
39
|
-
const containsSnapshot = (dir: string): boolean => {
|
|
40
|
-
if (!existsSync(dir)) return false;
|
|
41
|
-
if (!statSync(dir).isDirectory()) return false;
|
|
42
|
-
return readdirSync(dir).some((entry) =>
|
|
43
|
-
SNAPSHOT_SUFFIXES.some((suffix) => entry.endsWith(suffix))
|
|
44
|
-
);
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
export const discoverSnapshotDirectory = (
|
|
48
|
-
opts: DiscoverOptions = {}
|
|
49
|
-
): SnapshotDirectory => {
|
|
50
|
-
const cwd = opts.cwd ?? process.cwd();
|
|
51
|
-
|
|
52
|
-
if (opts.override !== undefined) {
|
|
53
|
-
const directory = isAbsolute(opts.override) ? opts.override : resolve(cwd, opts.override);
|
|
54
|
-
return { directory, source: 'override' };
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
let current = resolve(cwd);
|
|
58
|
-
const { root } = parse(current);
|
|
59
|
-
while (true) {
|
|
60
|
-
const candidate = resolve(current, FOLDER_NAME);
|
|
61
|
-
if (containsSnapshot(candidate)) {
|
|
62
|
-
return { directory: candidate, source: 'walk' };
|
|
63
|
-
}
|
|
64
|
-
if (current === root) break;
|
|
65
|
-
const parent = resolve(current, '..');
|
|
66
|
-
if (parent === current) break;
|
|
67
|
-
current = parent;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Nothing checked into this tree: fall back to the shared hub rather than an
|
|
71
|
-
// empty `<cwd>/unspa`. This is what makes hub mode the zero-config default —
|
|
72
|
-
// the MCP entry needs no UNSPA_SNAPSHOTS and `unspa dashboard` finds the same
|
|
73
|
-
// folder no matter where it's launched from. A per-repo `unspa/` (custom
|
|
74
|
-
// install) still wins above via the walk-up.
|
|
75
|
-
return { directory: defaultHubDirectory(opts.home), source: 'hub-default' };
|
|
76
|
-
};
|
|
1
|
+
import { existsSync, readdirSync, statSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { isAbsolute, join, parse, resolve } from 'node:path';
|
|
4
|
+
|
|
5
|
+
export type SnapshotDirectorySource = 'override' | 'walk' | 'hub-default';
|
|
6
|
+
|
|
7
|
+
export type SnapshotDirectory = {
|
|
8
|
+
readonly directory: string;
|
|
9
|
+
readonly source: SnapshotDirectorySource;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type DiscoverOptions = {
|
|
13
|
+
readonly override?: string;
|
|
14
|
+
readonly cwd?: string;
|
|
15
|
+
/** Home directory used to resolve the shared hub. Defaults to os.homedir(). */
|
|
16
|
+
readonly home?: string;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const SNAPSHOT_SUFFIXES = ['.feature.json', '.project.json'];
|
|
20
|
+
const FOLDER_NAME = 'unspa';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Shared snapshot hub layout: `<home>/.unspa-hub/unspa`. The `.unspa-hub`
|
|
24
|
+
* parent is the well-known launch point for `unspa dashboard`; the `unspa`
|
|
25
|
+
* subfolder is the snapshot directory itself. This is the default home for
|
|
26
|
+
* every project's behavior model — `unspa init` no longer scaffolds a per-repo
|
|
27
|
+
* `unspa/` folder, so when neither an explicit override nor a walk-up hit is
|
|
28
|
+
* found, both the dashboard and the MCP server land here on the first run. The
|
|
29
|
+
* folder is created lazily on first write (`ensureProjectDir` does `mkdir -p`).
|
|
30
|
+
*
|
|
31
|
+
* `homedir()` + `path.join` keep this correct on Windows, macOS, and Linux.
|
|
32
|
+
*/
|
|
33
|
+
export const HUB_ROOT_SEGMENT = '.unspa-hub';
|
|
34
|
+
export const HUB_SNAPSHOTS_SEGMENT = FOLDER_NAME;
|
|
35
|
+
|
|
36
|
+
export const defaultHubDirectory = (home: string = homedir()): string =>
|
|
37
|
+
join(home, HUB_ROOT_SEGMENT, HUB_SNAPSHOTS_SEGMENT);
|
|
38
|
+
|
|
39
|
+
const containsSnapshot = (dir: string): boolean => {
|
|
40
|
+
if (!existsSync(dir)) return false;
|
|
41
|
+
if (!statSync(dir).isDirectory()) return false;
|
|
42
|
+
return readdirSync(dir).some((entry) =>
|
|
43
|
+
SNAPSHOT_SUFFIXES.some((suffix) => entry.endsWith(suffix))
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const discoverSnapshotDirectory = (
|
|
48
|
+
opts: DiscoverOptions = {}
|
|
49
|
+
): SnapshotDirectory => {
|
|
50
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
51
|
+
|
|
52
|
+
if (opts.override !== undefined) {
|
|
53
|
+
const directory = isAbsolute(opts.override) ? opts.override : resolve(cwd, opts.override);
|
|
54
|
+
return { directory, source: 'override' };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
let current = resolve(cwd);
|
|
58
|
+
const { root } = parse(current);
|
|
59
|
+
while (true) {
|
|
60
|
+
const candidate = resolve(current, FOLDER_NAME);
|
|
61
|
+
if (containsSnapshot(candidate)) {
|
|
62
|
+
return { directory: candidate, source: 'walk' };
|
|
63
|
+
}
|
|
64
|
+
if (current === root) break;
|
|
65
|
+
const parent = resolve(current, '..');
|
|
66
|
+
if (parent === current) break;
|
|
67
|
+
current = parent;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Nothing checked into this tree: fall back to the shared hub rather than an
|
|
71
|
+
// empty `<cwd>/unspa`. This is what makes hub mode the zero-config default —
|
|
72
|
+
// the MCP entry needs no UNSPA_SNAPSHOTS and `unspa dashboard` finds the same
|
|
73
|
+
// folder no matter where it's launched from. A per-repo `unspa/` (custom
|
|
74
|
+
// install) still wins above via the walk-up.
|
|
75
|
+
return { directory: defaultHubDirectory(opts.home), source: 'hub-default' };
|
|
76
|
+
};
|