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
|
@@ -29,7 +29,9 @@ many Features. Use `add_feature_to_project` to attach.
|
|
|
29
29
|
## The domain in 60 seconds
|
|
30
30
|
|
|
31
31
|
A **Feature** holds `surfaces[]`, `personas[]`, `resources[]`, `entities[]`,
|
|
32
|
-
`events[]`,
|
|
32
|
+
`events[]`, `featureInvariants[]` (cross-surface safety), `reachabilityGoals[]`
|
|
33
|
+
(liveness: `reachable` / `always_reachable` target states), and optional
|
|
34
|
+
`devContext`, `expectedActions[]`, `nonGoals[]`.
|
|
33
35
|
|
|
34
36
|
A **Surface** is one context (screen, terminal, workflow, canvas, ...) with
|
|
35
37
|
`stateDefinitions[]`, `actions[]`, `rules[]`, `invariants[]`,
|
|
@@ -117,7 +119,10 @@ Atomic state-from-state-and-param write:
|
|
|
117
119
|
`remove_surface_rule`, `add_action_invariant`,
|
|
118
120
|
`update_action_invariant`, `remove_action_invariant`,
|
|
119
121
|
`add_surface_invariant`, `update_surface_invariant`,
|
|
120
|
-
`remove_surface_invariant`, `
|
|
122
|
+
`remove_surface_invariant`, `add_feature_invariant`,
|
|
123
|
+
`update_feature_invariant`, `remove_feature_invariant`,
|
|
124
|
+
`add_reachability_goal`, `update_reachability_goal`, `remove_reachability_goal`,
|
|
125
|
+
`add_transition`, `update_transition`,
|
|
121
126
|
`remove_transition`, `add_effect`, `update_effect`, `remove_effect`,
|
|
122
127
|
`add_event`, `update_event`, `remove_event`, `add_scenario`,
|
|
123
128
|
`update_scenario`, `remove_scenario`, `add_persona`, `update_persona`,
|
|
@@ -126,7 +131,16 @@ Atomic state-from-state-and-param write:
|
|
|
126
131
|
`update_entity_field`, `remove_entity_field`,
|
|
127
132
|
`create_project`, `update_project`, `replace_project`, `delete_project`,
|
|
128
133
|
`add_feature_to_project`, `remove_feature_from_project`,
|
|
129
|
-
`move_feature_in_project
|
|
134
|
+
`move_feature_in_project`, `add_project_invariant`,
|
|
135
|
+
`update_project_invariant`, `remove_project_invariant`.
|
|
136
|
+
|
|
137
|
+
**Cross-feature invariants** live on the Project, not a feature:
|
|
138
|
+
`project.projectInvariants` are safety properties spanning member features
|
|
139
|
+
(referencing state paths in different features, which a feature invariant
|
|
140
|
+
can't). Author with `add_project_invariant` / `update_project_invariant` /
|
|
141
|
+
`remove_project_invariant`; the model checker enforces them across the
|
|
142
|
+
project's state. Use a feature invariant when the property is within one
|
|
143
|
+
feature, a project invariant when it spans two or more.
|
|
130
144
|
|
|
131
145
|
Use the granular tools for one-off tweaks. For anything ≥ 2 ops, use
|
|
132
146
|
`apply_batch`.
|
|
@@ -138,6 +152,9 @@ Use the granular tools for one-off tweaks. For anything ≥ 2 ops, use
|
|
|
138
152
|
| `get_spec_gaps` | Spec-depth diagnostics. Prioritized critical + recommended gaps. |
|
|
139
153
|
| `get_implementation_gaps` | Implementation coverage gaps (spec vs. `.unspa.json` index). |
|
|
140
154
|
| `get_implementation_status` | Detailed per-action / per-surface coverage report. |
|
|
155
|
+
| `model_check` | Bounded state-space exploration: invariant counterexamples (shortest action path), dead actions, deadlocks, unreachable surfaces, reachability-goal results. |
|
|
156
|
+
| `verify` | One gated `pass`/`warn`/`fail` verdict per feature (scenarios + maturity + reachability + model check + drift + event coherence) — the in-chat form of `unspa check`. |
|
|
157
|
+
| `get_drift` | Implementations audited against an older spec than the one now on disk (stale / unversioned / orphan). |
|
|
141
158
|
|
|
142
159
|
## Workflow
|
|
143
160
|
|
|
@@ -183,6 +183,34 @@ own key will be reported as missing even when the parent is `implemented`.
|
|
|
183
183
|
`get_spec_gaps` to catch shallow specs that *look* covered but lack
|
|
184
184
|
scenarios, blocking validation rules, etc.
|
|
185
185
|
|
|
186
|
+
## Prove the code matches the spec (close the loop)
|
|
187
|
+
|
|
188
|
+
Recording a `{file, line}` says "implemented", not "correct". To turn the
|
|
189
|
+
feature's scenarios into a real code-vs-spec test:
|
|
190
|
+
|
|
191
|
+
1. `unspa scenarios adapter <featureId>` — scaffolds `unspa.adapter.ts`, one
|
|
192
|
+
`case` per scenario-bearing action, pre-seeded with the `.unspa.json`
|
|
193
|
+
implementation locations. Fill each `case` so it drives the real code from
|
|
194
|
+
`input.initialState` + `input.parameters` and returns `{ status, finalState }`.
|
|
195
|
+
2. `unspa scenarios export <featureId>` — generates a Vitest spec whose oracle
|
|
196
|
+
is the simulator's prediction for each scenario.
|
|
197
|
+
3. Run vitest with the JSON reporter:
|
|
198
|
+
`vitest run <spec> --reporter=json --outputFile=unspa-results.json`. Green
|
|
199
|
+
means the implementation agrees with the spec on every authored scenario; a
|
|
200
|
+
failure is a real spec↔code divergence — fix the code (or the spec, if the
|
|
201
|
+
spec was wrong) and re-run.
|
|
202
|
+
4. `unspa coverage ingest unspa-results.json` — stamps `verifiedAt` on every
|
|
203
|
+
action whose scenarios all passed (and clears it on a regression), promoting
|
|
204
|
+
those entities from "claimed implemented" to **proven against the spec**.
|
|
205
|
+
5. CI: `unspa ci` drops a workflow running `unspa check`; add
|
|
206
|
+
`--min-verified <pct>` to require that share of actions be proven, and run
|
|
207
|
+
the generated scenario spec + ingest in the same job so the code is gated
|
|
208
|
+
against the spec on every push.
|
|
209
|
+
|
|
210
|
+
This is the experimental wedge — the adapter contract may shift between minor
|
|
211
|
+
versions. Recording presence in `.unspa.json` (step 5 above) is still the
|
|
212
|
+
baseline; this proves the behavior on top of it.
|
|
213
|
+
|
|
186
214
|
## "Don't ask, just build" mode
|
|
187
215
|
|
|
188
216
|
If the user's prompt signals one-shot autonomy ("one pass", "make
|
package/cli/unspa.ts
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';
|
|
2
2
|
import { Command } from 'commander';
|
|
3
|
+
import { runCheckCommand } from './commands/check';
|
|
4
|
+
import { runCiCommand } from './commands/ci';
|
|
5
|
+
import { runCoverageIngestCommand } from './commands/coverage-ingest';
|
|
3
6
|
import { runDashboardCommand } from './commands/dashboard';
|
|
4
7
|
import { runInitCommand } from './commands/init';
|
|
5
8
|
import { runLinkCommand } from './commands/link';
|
|
6
9
|
import { runListCommand } from './commands/list';
|
|
10
|
+
import { runScenariosAdapterCommand } from './commands/scenarios-adapter';
|
|
7
11
|
import { runScenariosExportCommand } from './commands/scenarios-export';
|
|
8
12
|
import { runServeCommand } from './commands/serve';
|
|
13
|
+
import { runThemeCommand } from './commands/theme';
|
|
9
14
|
import { runUninstallCommand } from './commands/uninstall';
|
|
10
15
|
import { runViewCommand } from './commands/view';
|
|
11
16
|
import { log } from './util/log';
|
|
@@ -68,6 +73,7 @@ program
|
|
|
68
73
|
.option('--no-skills', 'Skip installing the bundled unspa skills under .claude/skills/.')
|
|
69
74
|
.option('--fun', 'Pre-check the opt-in narrative skills (worldbuild + worldplay) in the skill picker. Also implicitly on when the CLI is invoked as `unspaghettit`.')
|
|
70
75
|
.option('--with <views>', 'Comma list of opt-in dashboard views to enable (e.g. "builder"). Expert is always on. Without it, interactive init offers the Builder view.')
|
|
76
|
+
.option('--theme <id>', 'Set the dashboard colour theme at install (e.g. "lyriks"). Cosmetic only; persists so `unspa dashboard` boots with it. Switchable later via `unspa theme set` or the in-app header switcher.')
|
|
71
77
|
.option('-y, --yes', 'Accept defaults. Non-interactive (CI / scripts).')
|
|
72
78
|
.action(async (opts) => {
|
|
73
79
|
if (opts.scope !== 'project' && opts.scope !== 'global') {
|
|
@@ -87,7 +93,8 @@ program
|
|
|
87
93
|
local: opts.local === true,
|
|
88
94
|
custom: opts.custom === true,
|
|
89
95
|
fun: opts.fun === true || FUN_MODE_BY_INVOCATION,
|
|
90
|
-
withViews: opts.with
|
|
96
|
+
withViews: opts.with,
|
|
97
|
+
theme: opts.theme
|
|
91
98
|
});
|
|
92
99
|
process.exit(code);
|
|
93
100
|
});
|
|
@@ -108,8 +115,9 @@ program
|
|
|
108
115
|
.option('-h, --host <host>', 'Host to bind (default: 127.0.0.1). Pass 0.0.0.0 to expose on the LAN; the dashboard has no auth, so do this only on trusted networks.')
|
|
109
116
|
.option('-s, --snapshots <dir>', 'Point the dashboard at a specific snapshots folder (sets UNSPA_SNAPSHOTS for this run). Handy for a one-off look at a custom hub or another repo.')
|
|
110
117
|
.option('--view <ids>', 'Comma list of optional views to enable beyond Expert (e.g. "builder"). Expert is always on and is the default; with no extra views the header shows no switcher.')
|
|
118
|
+
.option('--theme <id>', 'Colour theme to boot with (e.g. "lyriks"). Cosmetic only; overrides the persisted `unspa theme set` choice for this run. The in-app header switcher can still change it live.')
|
|
111
119
|
.action(async (opts) => {
|
|
112
|
-
const code = await runDashboardCommand({ port: opts.port, host: opts.host, snapshots: opts.snapshots, views: opts.view });
|
|
120
|
+
const code = await runDashboardCommand({ port: opts.port, host: opts.host, snapshots: opts.snapshots, views: opts.view, theme: opts.theme });
|
|
113
121
|
process.exit(code);
|
|
114
122
|
});
|
|
115
123
|
|
|
@@ -126,6 +134,61 @@ program
|
|
|
126
134
|
process.exit(code);
|
|
127
135
|
});
|
|
128
136
|
|
|
137
|
+
program
|
|
138
|
+
.command('check [featureId]')
|
|
139
|
+
.description('Verify the spec headlessly and exit non-zero on failure (CI gate). Runs every scenario as an executable spec test, scores maturity, analyses surface reachability, optionally model-checks the reachable state space, and reports spec→code drift. Scopes to the repo\'s linked project by default; pass a featureId or --project to narrow.')
|
|
140
|
+
.option('-s, --snapshots <dir>', 'Verify a specific snapshots folder (defaults to walk-up, then the shared hub).')
|
|
141
|
+
.option('--project <id>', 'Verify a specific project\'s features (overrides the .unspa.json link).')
|
|
142
|
+
.option('--model-check', 'Also run bounded model checking (exhaustive state-space exploration). Off by default; it is the costly part.')
|
|
143
|
+
.option('--max-depth <n>', 'Model-check action-depth bound (default 6).', (v) => Number.parseInt(v, 10))
|
|
144
|
+
.option('--max-states <n>', 'Model-check state cap (default 2000).', (v) => Number.parseInt(v, 10))
|
|
145
|
+
.option('--min-maturity <n>', 'Fail any feature scoring below this maturity percentage.', (v) => Number.parseInt(v, 10))
|
|
146
|
+
.option('--min-verified <n>', 'Fail any feature where fewer than N% of actions are proven against code (via `unspa coverage ingest`).', (v) => Number.parseInt(v, 10))
|
|
147
|
+
.option('--max-scenario-failures <n>', 'Tolerate up to N failing scenarios before failing (default 0).', (v) => Number.parseInt(v, 10))
|
|
148
|
+
.option('--require-scenarios', 'Fail a feature that has no scenarios authored.')
|
|
149
|
+
.option('--fail-on-drift', 'Fail when an implementation was audited against an older spec (default: warn only).')
|
|
150
|
+
.option('--fail-on-dead-actions', 'Fail when an action never fires within the model-check bound (default: warn only).')
|
|
151
|
+
.option('--fail-on-unmet-goals', 'Fail when a reachability/liveness goal is unmet (default: warn only). Requires --model-check.')
|
|
152
|
+
.option('--allow-invariant-violations', 'Downgrade reachable invariant violations from failure to warning.')
|
|
153
|
+
.option('--json', 'Emit the full verification report as JSON instead of the human view.')
|
|
154
|
+
.action(async (featureId, opts) => {
|
|
155
|
+
const code = await runCheckCommand({
|
|
156
|
+
featureId,
|
|
157
|
+
snapshots: opts.snapshots,
|
|
158
|
+
project: opts.project,
|
|
159
|
+
json: opts.json === true,
|
|
160
|
+
modelCheck: opts.modelCheck === true,
|
|
161
|
+
maxDepth: opts.maxDepth,
|
|
162
|
+
maxStates: opts.maxStates,
|
|
163
|
+
minMaturity: opts.minMaturity,
|
|
164
|
+
minVerified: opts.minVerified,
|
|
165
|
+
maxScenarioFailures: opts.maxScenarioFailures,
|
|
166
|
+
requireScenarios: opts.requireScenarios === true,
|
|
167
|
+
failOnDrift: opts.failOnDrift === true,
|
|
168
|
+
failOnDeadActions: opts.failOnDeadActions === true,
|
|
169
|
+
failOnUnmetGoals: opts.failOnUnmetGoals === true,
|
|
170
|
+
allowInvariantViolations: opts.allowInvariantViolations === true
|
|
171
|
+
});
|
|
172
|
+
process.exit(code);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
program
|
|
176
|
+
.command('ci')
|
|
177
|
+
.description('Scaffold a GitHub Actions workflow (.github/workflows/unspaghettit.yml) that runs `unspa check` on every push / PR, so the spec gates CI. Requires the model to travel with the repo (`unspa init --local`). Refuses to clobber without --force.')
|
|
178
|
+
.option('-o, --out <path>', 'Output path (default: .github/workflows/unspaghettit.yml).')
|
|
179
|
+
.option('--model-check', 'Run bounded model checking in the workflow (deeper: invariant + liveness counterexamples).')
|
|
180
|
+
.option('--dry-run', 'Print the workflow to stdout instead of writing it.')
|
|
181
|
+
.option('-f, --force', 'Overwrite an existing workflow file.')
|
|
182
|
+
.action(async (opts) => {
|
|
183
|
+
const code = await runCiCommand({
|
|
184
|
+
out: opts.out,
|
|
185
|
+
modelCheck: opts.modelCheck === true,
|
|
186
|
+
dryRun: opts.dryRun === true,
|
|
187
|
+
force: opts.force === true
|
|
188
|
+
});
|
|
189
|
+
process.exit(code);
|
|
190
|
+
});
|
|
191
|
+
|
|
129
192
|
program
|
|
130
193
|
.command('link')
|
|
131
194
|
.description('Bind this repo to a single project via .unspa.json so the MCP scopes its queries to that project (and the LLM picks the right feature from the project\'s members for the task at hand). Pass --unlink to remove the binding.')
|
|
@@ -192,6 +255,38 @@ view
|
|
|
192
255
|
process.exit(await runViewCommand({ action: 'remove', id, snapshots: opts.snapshots }));
|
|
193
256
|
});
|
|
194
257
|
|
|
258
|
+
// `theme list|set|reset` — pick the dashboard's colour skin. Purely cosmetic
|
|
259
|
+
// (it never changes which features exist), persisted next to the model in
|
|
260
|
+
// `<snapshots>/theme.json` so `unspa dashboard` boots with it. The in-app
|
|
261
|
+
// header switcher flips it live in the browser without touching this file.
|
|
262
|
+
const theme = program
|
|
263
|
+
.command('theme')
|
|
264
|
+
.description('Pick the dashboard colour theme (cosmetic). The in-app header switcher can also flip it live.');
|
|
265
|
+
|
|
266
|
+
theme
|
|
267
|
+
.command('list')
|
|
268
|
+
.description('Show the available themes and which one is the persisted default.')
|
|
269
|
+
.option('-s, --snapshots <dir>', 'Target a specific snapshots folder (defaults to walk-up, then the shared hub).')
|
|
270
|
+
.action(async (opts) => {
|
|
271
|
+
process.exit(await runThemeCommand({ action: 'list', snapshots: opts.snapshots }));
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
theme
|
|
275
|
+
.command('set <id>')
|
|
276
|
+
.description('Set the dashboard theme (e.g. "lyriks"). Persists so `unspa dashboard` uses it.')
|
|
277
|
+
.option('-s, --snapshots <dir>', 'Target a specific snapshots folder.')
|
|
278
|
+
.action(async (id, opts) => {
|
|
279
|
+
process.exit(await runThemeCommand({ action: 'set', id, snapshots: opts.snapshots }));
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
theme
|
|
283
|
+
.command('reset')
|
|
284
|
+
.description('Revert to the default theme.')
|
|
285
|
+
.option('-s, --snapshots <dir>', 'Target a specific snapshots folder.')
|
|
286
|
+
.action(async (opts) => {
|
|
287
|
+
process.exit(await runThemeCommand({ action: 'reset', snapshots: opts.snapshots }));
|
|
288
|
+
});
|
|
289
|
+
|
|
195
290
|
// `scenarios export <featureId>` — generates a Vitest spec from the feature's
|
|
196
291
|
// scenarios, using the deterministic simulator as the assertion oracle. The
|
|
197
292
|
// user writes a thin adapter that calls their real implementation; the
|
|
@@ -226,6 +321,45 @@ scenarios
|
|
|
226
321
|
process.exit(code);
|
|
227
322
|
});
|
|
228
323
|
|
|
324
|
+
scenarios
|
|
325
|
+
.command('adapter <featureId>')
|
|
326
|
+
.description('[experimental] Scaffold the UnspaAdapter stub for a feature: one case per scenario-bearing action, pre-seeded with the implementation location from .unspa.json. Fill the TODOs, then `scenarios export` + vitest closes the spec↔code loop. Refuses to clobber without --force.')
|
|
327
|
+
.option('-o, --out <path>', 'Output file path. Defaults to ./unspa.adapter.ts (so the export command\'s default import resolves).')
|
|
328
|
+
.option('--adapter-export <name>', 'Named export for the adapter.', 'adapter')
|
|
329
|
+
.option('--dry-run', 'Print the generated adapter to stdout instead of writing it.')
|
|
330
|
+
.option('-f, --force', 'Overwrite the output file if it already exists.')
|
|
331
|
+
.action(async (featureId, opts) => {
|
|
332
|
+
const code = await runScenariosAdapterCommand({
|
|
333
|
+
featureId,
|
|
334
|
+
out: opts.out,
|
|
335
|
+
adapterExport: opts.adapterExport,
|
|
336
|
+
dryRun: opts.dryRun === true,
|
|
337
|
+
force: opts.force === true
|
|
338
|
+
});
|
|
339
|
+
process.exit(code);
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
// `coverage ingest <file>` — close the spec↔code proof loop. Reads a Vitest
|
|
343
|
+
// JSON report of the generated scenario spec and stamps `verifiedAt` on the
|
|
344
|
+
// matching .unspa.json action entries, promoting them from "claimed
|
|
345
|
+
// implemented" to "proven against the spec". Gate on it with
|
|
346
|
+
// `unspa check --min-verified`.
|
|
347
|
+
const coverage = program
|
|
348
|
+
.command('coverage')
|
|
349
|
+
.description('Work with implementation coverage recorded in .unspa.json.');
|
|
350
|
+
|
|
351
|
+
coverage
|
|
352
|
+
.command('ingest <resultsFile>')
|
|
353
|
+
.description('[experimental] Read a Vitest JSON report (vitest run --reporter=json --outputFile=<file>) of the generated scenario spec and mark each action whose scenarios all passed as verified in .unspa.json (clears stale verifications that now fail). Recording only; gate with `unspa check --min-verified`.')
|
|
354
|
+
.option('--dry-run', 'Report what would change without writing .unspa.json.')
|
|
355
|
+
.action(async (resultsFile, opts) => {
|
|
356
|
+
const code = await runCoverageIngestCommand({
|
|
357
|
+
file: resultsFile,
|
|
358
|
+
dryRun: opts.dryRun === true
|
|
359
|
+
});
|
|
360
|
+
process.exit(code);
|
|
361
|
+
});
|
|
362
|
+
|
|
229
363
|
program.parseAsync(process.argv).catch((err) => {
|
|
230
364
|
log.err((err as Error).message);
|
|
231
365
|
process.exit(1);
|
|
@@ -27,6 +27,11 @@ per-repo install (\`unspa init --local\`). Open the dashboard with
|
|
|
27
27
|
\`unspa dashboard\` (http://localhost:3000) to see surfaces, actions, simulator,
|
|
28
28
|
maturity, and implementation coverage.
|
|
29
29
|
|
|
30
|
+
When using the CLI hub, treat \`~/.unspa-hub/unspa\` as the source of truth.
|
|
31
|
+
Dashboard localhost ports are only views over that folder and may change per
|
|
32
|
+
run. Do not inspect Docker containers, unrelated app integrations, or another
|
|
33
|
+
product's embedded Unspa data unless the user explicitly asks for that source.
|
|
34
|
+
|
|
30
35
|
### Editing the model. Use the MCP, don't re-emit JSON
|
|
31
36
|
|
|
32
37
|
The Unspaghettit **MCP server** is registered for this repo. Prefer its tools over
|
|
@@ -40,8 +45,13 @@ and produce smaller diffs. Workflow:
|
|
|
40
45
|
3. For multi-step edits use \`apply_batch\`. N ops in one atomic load + validate +
|
|
41
46
|
save. Add ops can capture their new id under \`op.ref\` so later ops in the same
|
|
42
47
|
batch reference it via \`*Ref\` (e.g. \`surfaceRef:"shop"\`).
|
|
43
|
-
4. Validate
|
|
44
|
-
\`
|
|
48
|
+
4. Validate before committing: \`dry_run_simulate\` (pure, no persist),
|
|
49
|
+
\`run_all_scenarios\`, \`model_check\` (bounded state-space exploration —
|
|
50
|
+
invariant counterexamples with the action path, dead actions, deadlocks,
|
|
51
|
+
reachability, reachability-goal results), and \`score_feature\` (maturity).
|
|
52
|
+
Gate the whole feature/project in one call with \`verify\` — the in-chat form
|
|
53
|
+
of the \`unspa check\` CI command. \`get_drift\` finds code audited against an
|
|
54
|
+
older spec than the one now on disk.
|
|
45
55
|
5. Run \`find_state_references\` before renaming or removing a state path.
|
|
46
56
|
|
|
47
57
|
### \`.unspa.json\`. Record implementations in the index
|
|
@@ -69,6 +79,12 @@ in its \`orphans\` block with a fix hint.
|
|
|
69
79
|
Each entry stores \`{ file, line, signature, ... }\`. After editing the index,
|
|
70
80
|
call \`sync_from_index\` so the MCP refreshes the coverage report.
|
|
71
81
|
|
|
82
|
+
To PROVE coverage (not just claim it), run the feature's scenarios against the
|
|
83
|
+
real code: \`unspa scenarios export <featureId>\` → \`vitest run --reporter=json\`
|
|
84
|
+
→ \`unspa coverage ingest <report>\`. That stamps \`verifiedAt\` on actions whose
|
|
85
|
+
scenarios all passed; \`verify\` / \`unspa check --min-verified\` gate on the
|
|
86
|
+
proven share.
|
|
87
|
+
|
|
72
88
|
### Don't
|
|
73
89
|
|
|
74
90
|
- Don't regenerate an entire feature JSON from scratch; mutate via the MCP.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Persisted dashboard-theme selection, stored next to the model the dashboard
|
|
6
|
+
* shows (`<snapshots>/theme.json`). Purely cosmetic — picks the colour skin the
|
|
7
|
+
* UI renders with. `unspa dashboard` reads it and exposes it to the app as
|
|
8
|
+
* `PUBLIC_UNSPA_THEME`; the in-app header switcher can still override it live
|
|
9
|
+
* in the browser. A missing/malformed file means the default theme.
|
|
10
|
+
*/
|
|
11
|
+
const FILE_NAME = 'theme.json';
|
|
12
|
+
|
|
13
|
+
type ThemeConfig = { readonly theme?: unknown };
|
|
14
|
+
|
|
15
|
+
export const themeConfigPath = (snapshotsDir: string): string => join(snapshotsDir, FILE_NAME);
|
|
16
|
+
|
|
17
|
+
/** Read the selected theme id; tolerant of a missing/malformed file. */
|
|
18
|
+
export const readSelectedTheme = (snapshotsDir: string): string => {
|
|
19
|
+
try {
|
|
20
|
+
const parsed = JSON.parse(readFileSync(themeConfigPath(snapshotsDir), 'utf8')) as ThemeConfig;
|
|
21
|
+
return typeof parsed.theme === 'string' ? parsed.theme.trim().toLowerCase() : 'default';
|
|
22
|
+
} catch {
|
|
23
|
+
return 'default';
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/** Persist the selected theme id (normalized: trimmed, lowercased). */
|
|
28
|
+
export const writeSelectedTheme = (snapshotsDir: string, theme: string): string => {
|
|
29
|
+
const next = theme.trim().toLowerCase() || 'default';
|
|
30
|
+
const path = themeConfigPath(snapshotsDir);
|
|
31
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
32
|
+
writeFileSync(path, `${JSON.stringify({ theme: next }, null, 2)}\n`, 'utf8');
|
|
33
|
+
return next;
|
|
34
|
+
};
|
package/mcp-server/bin.ts
CHANGED
|
@@ -1,104 +1,104 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
-
import { JsonFolderFeatureRepository } from '../src/features/behavior-model/infrastructure/persistence/JsonFolderFeatureRepository';
|
|
4
|
-
import { discoverSnapshotDirectory } from '../src/features/behavior-model/infrastructure/persistence/snapshot-discovery';
|
|
5
|
-
import { JsonFolderImplementationStatusRepository } from '../src/features/implementation-status/infrastructure/persistence/JsonFolderImplementationStatusRepository';
|
|
6
|
-
import { JsonFolderProjectRepository } from '../src/features/projects/infrastructure/persistence/JsonFolderProjectRepository';
|
|
7
|
-
import { migrateFlatLayoutAndLog } from '../src/shared/infrastructure/persistence/snapshotLayout';
|
|
8
|
-
import { discoverRepoLink } from './repo-link';
|
|
9
|
-
import { buildServer } from './server';
|
|
10
|
-
import {
|
|
11
|
-
SyncAwareFeatureRepository,
|
|
12
|
-
SyncAwareImplementationStatusRepository,
|
|
13
|
-
SyncAwareProjectRepository
|
|
14
|
-
} from './sync-aware-repos';
|
|
15
|
-
|
|
16
|
-
const parseArgs = (argv: readonly string[]): { override?: string; link?: string } => {
|
|
17
|
-
const out: { override?: string; link?: string } = {};
|
|
18
|
-
for (let i = 0; i < argv.length; i += 1) {
|
|
19
|
-
const arg = argv[i];
|
|
20
|
-
if (arg === '--snapshots' || arg === '-s') {
|
|
21
|
-
const next = argv[i + 1];
|
|
22
|
-
if (!next) throw new Error('--snapshots requires a directory path');
|
|
23
|
-
out.override = next;
|
|
24
|
-
i += 1;
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
if (arg && arg.startsWith('--snapshots=')) {
|
|
28
|
-
out.override = arg.slice('--snapshots='.length);
|
|
29
|
-
continue;
|
|
30
|
-
}
|
|
31
|
-
if (arg === '--link' || arg === '-l') {
|
|
32
|
-
const next = argv[i + 1];
|
|
33
|
-
if (!next) throw new Error('--link requires a path to .unspa.json or its parent folder');
|
|
34
|
-
out.link = next;
|
|
35
|
-
i += 1;
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
if (arg && arg.startsWith('--link=')) {
|
|
39
|
-
out.link = arg.slice('--link='.length);
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return out;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const main = async (): Promise<void> => {
|
|
47
|
-
const args = parseArgs(process.argv.slice(2));
|
|
48
|
-
const override = args.override ?? process.env.UNSPA_SNAPSHOTS;
|
|
49
|
-
const { directory, source } = discoverSnapshotDirectory({ override });
|
|
50
|
-
const linkOverride = args.link ?? process.env.UNSPA_LINK;
|
|
51
|
-
|
|
52
|
-
// Snapshot the link state once for the startup banner; the live repoContext
|
|
53
|
-
// below re-resolves on every property access, so subsequent `unspa link` /
|
|
54
|
-
// file edits are picked up without restarting the MCP server.
|
|
55
|
-
const initialLink = discoverRepoLink(process.cwd(), linkOverride);
|
|
56
|
-
|
|
57
|
-
// Diagnostics go to stderr. Stdout is reserved for the JSON-RPC stream.
|
|
58
|
-
process.stderr.write(`[unspa-mcp] snapshots: ${directory} (${source})\n`);
|
|
59
|
-
migrateFlatLayoutAndLog(directory, 'unspa-mcp');
|
|
60
|
-
if (initialLink.link) {
|
|
61
|
-
process.stderr.write(
|
|
62
|
-
`[unspa-mcp] repo linked to project: ${initialLink.link.projectName ?? '(unknown)'} (${initialLink.link.projectId})\n`
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const repo = new SyncAwareFeatureRepository(new JsonFolderFeatureRepository(directory));
|
|
67
|
-
const statusRepo = new SyncAwareImplementationStatusRepository(
|
|
68
|
-
new JsonFolderImplementationStatusRepository(directory)
|
|
69
|
-
);
|
|
70
|
-
const projectRepo = new SyncAwareProjectRepository(
|
|
71
|
-
new JsonFolderProjectRepository(directory)
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
// Live `.unspa.json` lookup. Tools read `repoContext.link` / `.linkPath`
|
|
75
|
-
// on every invocation, so if the developer runs `unspa link` while the AI
|
|
76
|
-
// client is connected the next tool call sees the new state — no restart
|
|
77
|
-
// required. Per-access stat walk is a few microseconds; cheap enough that
|
|
78
|
-
// we don't memoize.
|
|
79
|
-
const cwd = process.cwd();
|
|
80
|
-
const repoContext = {
|
|
81
|
-
get cwd() {
|
|
82
|
-
return cwd;
|
|
83
|
-
},
|
|
84
|
-
get link() {
|
|
85
|
-
return discoverRepoLink(cwd, linkOverride).link;
|
|
86
|
-
},
|
|
87
|
-
get linkPath() {
|
|
88
|
-
return discoverRepoLink(cwd, linkOverride).path;
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
const server = buildServer(repo, {
|
|
93
|
-
statusRepo,
|
|
94
|
-
projectRepo,
|
|
95
|
-
repoContext
|
|
96
|
-
});
|
|
97
|
-
const transport = new StdioServerTransport();
|
|
98
|
-
await server.connect(transport);
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
main().catch((err) => {
|
|
102
|
-
process.stderr.write(`[unspa-mcp] fatal: ${(err as Error).message}\n`);
|
|
103
|
-
process.exit(1);
|
|
104
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { JsonFolderFeatureRepository } from '../src/features/behavior-model/infrastructure/persistence/JsonFolderFeatureRepository';
|
|
4
|
+
import { discoverSnapshotDirectory } from '../src/features/behavior-model/infrastructure/persistence/snapshot-discovery';
|
|
5
|
+
import { JsonFolderImplementationStatusRepository } from '../src/features/implementation-status/infrastructure/persistence/JsonFolderImplementationStatusRepository';
|
|
6
|
+
import { JsonFolderProjectRepository } from '../src/features/projects/infrastructure/persistence/JsonFolderProjectRepository';
|
|
7
|
+
import { migrateFlatLayoutAndLog } from '../src/shared/infrastructure/persistence/snapshotLayout';
|
|
8
|
+
import { discoverRepoLink } from './repo-link';
|
|
9
|
+
import { buildServer } from './server';
|
|
10
|
+
import {
|
|
11
|
+
SyncAwareFeatureRepository,
|
|
12
|
+
SyncAwareImplementationStatusRepository,
|
|
13
|
+
SyncAwareProjectRepository
|
|
14
|
+
} from './sync-aware-repos';
|
|
15
|
+
|
|
16
|
+
const parseArgs = (argv: readonly string[]): { override?: string; link?: string } => {
|
|
17
|
+
const out: { override?: string; link?: string } = {};
|
|
18
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
19
|
+
const arg = argv[i];
|
|
20
|
+
if (arg === '--snapshots' || arg === '-s') {
|
|
21
|
+
const next = argv[i + 1];
|
|
22
|
+
if (!next) throw new Error('--snapshots requires a directory path');
|
|
23
|
+
out.override = next;
|
|
24
|
+
i += 1;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (arg && arg.startsWith('--snapshots=')) {
|
|
28
|
+
out.override = arg.slice('--snapshots='.length);
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (arg === '--link' || arg === '-l') {
|
|
32
|
+
const next = argv[i + 1];
|
|
33
|
+
if (!next) throw new Error('--link requires a path to .unspa.json or its parent folder');
|
|
34
|
+
out.link = next;
|
|
35
|
+
i += 1;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (arg && arg.startsWith('--link=')) {
|
|
39
|
+
out.link = arg.slice('--link='.length);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const main = async (): Promise<void> => {
|
|
47
|
+
const args = parseArgs(process.argv.slice(2));
|
|
48
|
+
const override = args.override ?? process.env.UNSPA_SNAPSHOTS;
|
|
49
|
+
const { directory, source } = discoverSnapshotDirectory({ override });
|
|
50
|
+
const linkOverride = args.link ?? process.env.UNSPA_LINK;
|
|
51
|
+
|
|
52
|
+
// Snapshot the link state once for the startup banner; the live repoContext
|
|
53
|
+
// below re-resolves on every property access, so subsequent `unspa link` /
|
|
54
|
+
// file edits are picked up without restarting the MCP server.
|
|
55
|
+
const initialLink = discoverRepoLink(process.cwd(), linkOverride);
|
|
56
|
+
|
|
57
|
+
// Diagnostics go to stderr. Stdout is reserved for the JSON-RPC stream.
|
|
58
|
+
process.stderr.write(`[unspa-mcp] snapshots: ${directory} (${source})\n`);
|
|
59
|
+
migrateFlatLayoutAndLog(directory, 'unspa-mcp');
|
|
60
|
+
if (initialLink.link) {
|
|
61
|
+
process.stderr.write(
|
|
62
|
+
`[unspa-mcp] repo linked to project: ${initialLink.link.projectName ?? '(unknown)'} (${initialLink.link.projectId})\n`
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const repo = new SyncAwareFeatureRepository(new JsonFolderFeatureRepository(directory));
|
|
67
|
+
const statusRepo = new SyncAwareImplementationStatusRepository(
|
|
68
|
+
new JsonFolderImplementationStatusRepository(directory)
|
|
69
|
+
);
|
|
70
|
+
const projectRepo = new SyncAwareProjectRepository(
|
|
71
|
+
new JsonFolderProjectRepository(directory)
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
// Live `.unspa.json` lookup. Tools read `repoContext.link` / `.linkPath`
|
|
75
|
+
// on every invocation, so if the developer runs `unspa link` while the AI
|
|
76
|
+
// client is connected the next tool call sees the new state — no restart
|
|
77
|
+
// required. Per-access stat walk is a few microseconds; cheap enough that
|
|
78
|
+
// we don't memoize.
|
|
79
|
+
const cwd = process.cwd();
|
|
80
|
+
const repoContext = {
|
|
81
|
+
get cwd() {
|
|
82
|
+
return cwd;
|
|
83
|
+
},
|
|
84
|
+
get link() {
|
|
85
|
+
return discoverRepoLink(cwd, linkOverride).link;
|
|
86
|
+
},
|
|
87
|
+
get linkPath() {
|
|
88
|
+
return discoverRepoLink(cwd, linkOverride).path;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const server = buildServer(repo, {
|
|
93
|
+
statusRepo,
|
|
94
|
+
projectRepo,
|
|
95
|
+
repoContext
|
|
96
|
+
});
|
|
97
|
+
const transport = new StdioServerTransport();
|
|
98
|
+
await server.connect(transport);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
main().catch((err) => {
|
|
102
|
+
process.stderr.write(`[unspa-mcp] fatal: ${(err as Error).message}\n`);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
});
|