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.
Files changed (772) hide show
  1. package/README.md +56 -18
  2. package/build/client/_app/immutable/assets/0.DCOD5ne_.css +1 -0
  3. package/build/client/_app/immutable/assets/0.DCOD5ne_.css.br +0 -0
  4. package/build/client/_app/immutable/assets/0.DCOD5ne_.css.gz +0 -0
  5. package/build/client/_app/immutable/assets/12.nv0I59TU.css.gz +0 -0
  6. package/build/client/_app/immutable/assets/3.B3akUL9A.css.gz +0 -0
  7. package/build/client/_app/immutable/assets/BehaviorGraph.Bk0xQRZk.css +1 -0
  8. package/build/client/_app/immutable/assets/BehaviorGraph.Bk0xQRZk.css.br +0 -0
  9. package/build/client/_app/immutable/assets/BehaviorGraph.Bk0xQRZk.css.gz +0 -0
  10. package/build/client/_app/immutable/chunks/B3vnQs252.js +1 -0
  11. package/build/client/_app/immutable/chunks/B3vnQs252.js.br +0 -0
  12. package/build/client/_app/immutable/chunks/B3vnQs252.js.gz +0 -0
  13. package/build/client/_app/immutable/chunks/{CxyLMlpt2.js → BANF9BhQ2.js} +1 -1
  14. package/build/client/_app/immutable/chunks/BANF9BhQ2.js.br +0 -0
  15. package/build/client/_app/immutable/chunks/BANF9BhQ2.js.gz +0 -0
  16. package/build/client/_app/immutable/chunks/BJdTO_n6.js +1 -0
  17. package/build/client/_app/immutable/chunks/BJdTO_n6.js.br +0 -0
  18. package/build/client/_app/immutable/chunks/BJdTO_n6.js.gz +0 -0
  19. package/build/client/_app/immutable/chunks/BPl9BITm.js.gz +0 -0
  20. package/build/client/_app/immutable/chunks/BQ9GodWX2.js.gz +0 -0
  21. package/build/client/_app/immutable/chunks/Bcyn5YUg.js +4 -0
  22. package/build/client/_app/immutable/chunks/Bcyn5YUg.js.br +0 -0
  23. package/build/client/_app/immutable/chunks/Bcyn5YUg.js.gz +0 -0
  24. package/build/client/_app/immutable/chunks/Bfc9rQXP.js +1 -0
  25. package/build/client/_app/immutable/chunks/Bfc9rQXP.js.br +0 -0
  26. package/build/client/_app/immutable/chunks/Bfc9rQXP.js.gz +0 -0
  27. package/build/client/_app/immutable/chunks/{BfMYiIUi.js → BjxqhpPG.js} +1 -1
  28. package/build/client/_app/immutable/chunks/BjxqhpPG.js.br +0 -0
  29. package/build/client/_app/immutable/chunks/BjxqhpPG.js.gz +0 -0
  30. package/build/client/_app/immutable/chunks/ByaoVvNB.js +1 -0
  31. package/build/client/_app/immutable/chunks/ByaoVvNB.js.br +0 -0
  32. package/build/client/_app/immutable/chunks/ByaoVvNB.js.gz +0 -0
  33. package/build/client/_app/immutable/chunks/BzLd0mTH.js.gz +0 -0
  34. package/build/client/_app/immutable/chunks/C8b3IMj8.js +1 -0
  35. package/build/client/_app/immutable/chunks/C8b3IMj8.js.br +0 -0
  36. package/build/client/_app/immutable/chunks/C8b3IMj8.js.gz +0 -0
  37. package/build/client/_app/immutable/chunks/CXvvf4uQ.js +1 -0
  38. package/build/client/_app/immutable/chunks/CXvvf4uQ.js.br +0 -0
  39. package/build/client/_app/immutable/chunks/CXvvf4uQ.js.gz +0 -0
  40. package/build/client/_app/immutable/chunks/Cl7Z3e6-.js.gz +0 -0
  41. package/build/client/_app/immutable/chunks/ClC4qR7W2.js +2 -0
  42. package/build/client/_app/immutable/chunks/ClC4qR7W2.js.br +0 -0
  43. package/build/client/_app/immutable/chunks/ClC4qR7W2.js.gz +0 -0
  44. package/build/client/_app/immutable/chunks/CuGlh1c2.js +1 -0
  45. package/build/client/_app/immutable/chunks/CuGlh1c2.js.br +0 -0
  46. package/build/client/_app/immutable/chunks/CuGlh1c2.js.gz +0 -0
  47. package/build/client/_app/immutable/chunks/CwzIdrQR.js +1 -0
  48. package/build/client/_app/immutable/chunks/CwzIdrQR.js.br +0 -0
  49. package/build/client/_app/immutable/chunks/CwzIdrQR.js.gz +0 -0
  50. package/build/client/_app/immutable/chunks/D5speDV82.js +908 -0
  51. package/build/client/_app/immutable/chunks/D5speDV82.js.br +0 -0
  52. package/build/client/_app/immutable/chunks/D5speDV82.js.gz +0 -0
  53. package/build/client/_app/immutable/chunks/D64sGJRN.js +1 -0
  54. package/build/client/_app/immutable/chunks/D64sGJRN.js.br +0 -0
  55. package/build/client/_app/immutable/chunks/D64sGJRN.js.gz +0 -0
  56. package/build/client/_app/immutable/chunks/DNaA4QRO2.js +1 -0
  57. package/build/client/_app/immutable/chunks/DNaA4QRO2.js.br +0 -0
  58. package/build/client/_app/immutable/chunks/DNaA4QRO2.js.gz +0 -0
  59. package/build/client/_app/immutable/chunks/Da59TXPe.js +1 -0
  60. package/build/client/_app/immutable/chunks/Da59TXPe.js.br +2 -0
  61. package/build/client/_app/immutable/chunks/Da59TXPe.js.gz +0 -0
  62. package/build/client/_app/immutable/chunks/DhTiE3j02.js +2 -0
  63. package/build/client/_app/immutable/chunks/DhTiE3j02.js.br +0 -0
  64. package/build/client/_app/immutable/chunks/DhTiE3j02.js.gz +0 -0
  65. package/build/client/_app/immutable/chunks/Dhqg7r_2.js.gz +0 -0
  66. package/build/client/_app/immutable/chunks/DmyaDy4d2.js +1 -0
  67. package/build/client/_app/immutable/chunks/DmyaDy4d2.js.br +0 -0
  68. package/build/client/_app/immutable/chunks/DmyaDy4d2.js.gz +0 -0
  69. package/build/client/_app/immutable/chunks/DryaQyjN2.js +1 -0
  70. package/build/client/_app/immutable/chunks/DryaQyjN2.js.br +0 -0
  71. package/build/client/_app/immutable/chunks/DryaQyjN2.js.gz +0 -0
  72. package/build/client/_app/immutable/chunks/DtK8qK5Q2.js +1 -0
  73. package/build/client/_app/immutable/chunks/DtK8qK5Q2.js.br +0 -0
  74. package/build/client/_app/immutable/chunks/DtK8qK5Q2.js.gz +0 -0
  75. package/build/client/_app/immutable/chunks/DtblIi6X2.js +1 -0
  76. package/build/client/_app/immutable/chunks/DtblIi6X2.js.br +1 -0
  77. package/build/client/_app/immutable/chunks/DtblIi6X2.js.gz +0 -0
  78. package/build/client/_app/immutable/chunks/UkzDDeO42.js +1 -0
  79. package/build/client/_app/immutable/chunks/UkzDDeO42.js.br +0 -0
  80. package/build/client/_app/immutable/chunks/UkzDDeO42.js.gz +0 -0
  81. package/build/client/_app/immutable/chunks/Vu8LzrwP2.js +1 -0
  82. package/build/client/_app/immutable/chunks/Vu8LzrwP2.js.br +0 -0
  83. package/build/client/_app/immutable/chunks/Vu8LzrwP2.js.gz +0 -0
  84. package/build/client/_app/immutable/chunks/_b612aVb.js +1 -0
  85. package/build/client/_app/immutable/chunks/_b612aVb.js.br +0 -0
  86. package/build/client/_app/immutable/chunks/_b612aVb.js.gz +0 -0
  87. package/build/client/_app/immutable/chunks/aNMRV4sP2.js.gz +0 -0
  88. package/build/client/_app/immutable/chunks/cMamJTsF.js.gz +0 -0
  89. package/build/client/_app/immutable/chunks/ib21i2T_.js.gz +0 -0
  90. package/build/client/_app/immutable/chunks/kNaey6uv.js.gz +0 -0
  91. package/build/client/_app/immutable/chunks/oVMDLirx.js +1 -0
  92. package/build/client/_app/immutable/chunks/oVMDLirx.js.br +0 -0
  93. package/build/client/_app/immutable/chunks/oVMDLirx.js.gz +0 -0
  94. package/build/client/_app/immutable/chunks/olAc024e.js +1 -0
  95. package/build/client/_app/immutable/chunks/olAc024e.js.br +0 -0
  96. package/build/client/_app/immutable/chunks/olAc024e.js.gz +0 -0
  97. package/build/client/_app/immutable/chunks/suTxxv1t.js.gz +0 -0
  98. package/build/client/_app/immutable/chunks/wXIHzLMQ2.js +1 -0
  99. package/build/client/_app/immutable/chunks/wXIHzLMQ2.js.br +0 -0
  100. package/build/client/_app/immutable/chunks/wXIHzLMQ2.js.gz +0 -0
  101. package/build/client/_app/immutable/chunks/wrqalH0a.js +1 -0
  102. package/build/client/_app/immutable/chunks/wrqalH0a.js.br +0 -0
  103. package/build/client/_app/immutable/chunks/wrqalH0a.js.gz +0 -0
  104. package/build/client/_app/immutable/chunks/x60Tn5kT.js +1 -0
  105. package/build/client/_app/immutable/chunks/x60Tn5kT.js.br +0 -0
  106. package/build/client/_app/immutable/chunks/x60Tn5kT.js.gz +0 -0
  107. package/build/client/_app/immutable/chunks/xihTtKlq.js.gz +0 -0
  108. package/build/client/_app/immutable/chunks/{BOrLmFwJ.js → yShDxCNj.js} +1 -1
  109. package/build/client/_app/immutable/chunks/yShDxCNj.js.br +2 -0
  110. package/build/client/_app/immutable/chunks/yShDxCNj.js.gz +0 -0
  111. package/build/client/_app/immutable/entry/app.Etd-exTb.js +2 -0
  112. package/build/client/_app/immutable/entry/app.Etd-exTb.js.br +0 -0
  113. package/build/client/_app/immutable/entry/app.Etd-exTb.js.gz +0 -0
  114. package/build/client/_app/immutable/entry/start.DY2B3u4g.js +1 -0
  115. package/build/client/_app/immutable/entry/start.DY2B3u4g.js.br +0 -0
  116. package/build/client/_app/immutable/entry/start.DY2B3u4g.js.gz +0 -0
  117. package/build/client/_app/immutable/nodes/0.tKfYV3__.js +8 -0
  118. package/build/client/_app/immutable/nodes/0.tKfYV3__.js.br +0 -0
  119. package/build/client/_app/immutable/nodes/0.tKfYV3__.js.gz +0 -0
  120. package/build/client/_app/immutable/nodes/{1.KYdA6ppX.js → 1.CER5ICKt.js} +1 -1
  121. package/build/client/_app/immutable/nodes/1.CER5ICKt.js.br +1 -0
  122. package/build/client/_app/immutable/nodes/1.CER5ICKt.js.gz +0 -0
  123. package/build/client/_app/immutable/nodes/10.rT7cD8kX.js +1 -0
  124. package/build/client/_app/immutable/nodes/10.rT7cD8kX.js.br +0 -0
  125. package/build/client/_app/immutable/nodes/10.rT7cD8kX.js.gz +0 -0
  126. package/build/client/_app/immutable/nodes/11.BAnV_Y5Y.js +2 -0
  127. package/build/client/_app/immutable/nodes/11.BAnV_Y5Y.js.br +0 -0
  128. package/build/client/_app/immutable/nodes/11.BAnV_Y5Y.js.gz +0 -0
  129. package/build/client/_app/immutable/nodes/{9.CMW6a2Lg.js → 12.DCTRFMqo.js} +4 -3
  130. package/build/client/_app/immutable/nodes/12.DCTRFMqo.js.br +0 -0
  131. package/build/client/_app/immutable/nodes/12.DCTRFMqo.js.gz +0 -0
  132. package/build/client/_app/immutable/nodes/{2.DBz20KgG.js → 2.CF488WWF.js} +1 -1
  133. package/build/client/_app/immutable/nodes/2.CF488WWF.js.br +0 -0
  134. package/build/client/_app/immutable/nodes/2.CF488WWF.js.gz +0 -0
  135. package/build/client/_app/immutable/nodes/3.CP7CPPVH.js +1 -0
  136. package/build/client/_app/immutable/nodes/3.CP7CPPVH.js.br +0 -0
  137. package/build/client/_app/immutable/nodes/3.CP7CPPVH.js.gz +0 -0
  138. package/build/client/_app/immutable/nodes/4.D1bxCSiM.js +3 -0
  139. package/build/client/_app/immutable/nodes/4.D1bxCSiM.js.br +0 -0
  140. package/build/client/_app/immutable/nodes/4.D1bxCSiM.js.gz +0 -0
  141. package/build/client/_app/immutable/nodes/5.D6jZgh9y.js +48 -0
  142. package/build/client/_app/immutable/nodes/5.D6jZgh9y.js.br +0 -0
  143. package/build/client/_app/immutable/nodes/5.D6jZgh9y.js.gz +0 -0
  144. package/build/client/_app/immutable/nodes/6.BrBFUA0s.js +1 -0
  145. package/build/client/_app/immutable/nodes/6.BrBFUA0s.js.br +0 -0
  146. package/build/client/_app/immutable/nodes/6.BrBFUA0s.js.gz +0 -0
  147. package/build/client/_app/immutable/nodes/7.pajo8MfM.js +3 -0
  148. package/build/client/_app/immutable/nodes/7.pajo8MfM.js.br +0 -0
  149. package/build/client/_app/immutable/nodes/7.pajo8MfM.js.gz +0 -0
  150. package/build/client/_app/immutable/nodes/8.Cc80_Igi.js +5 -0
  151. package/build/client/_app/immutable/nodes/8.Cc80_Igi.js.br +0 -0
  152. package/build/client/_app/immutable/nodes/8.Cc80_Igi.js.gz +0 -0
  153. package/build/client/_app/immutable/nodes/{7.CemgNJfw.js → 9.D72NaL3l.js} +1 -1
  154. package/build/client/_app/immutable/nodes/9.D72NaL3l.js.br +1 -0
  155. package/build/client/_app/immutable/nodes/9.D72NaL3l.js.gz +0 -0
  156. package/build/client/_app/version.json +1 -1
  157. package/build/client/_app/version.json.br +0 -0
  158. package/build/client/_app/version.json.gz +0 -0
  159. package/build/client/lyriks_logo.svg +148 -0
  160. package/build/client/lyriks_logo.svg.br +0 -0
  161. package/build/client/lyriks_logo.svg.gz +0 -0
  162. package/build/server/chunks/0-8YZc572z.js +15 -0
  163. package/build/server/chunks/0-8YZc572z.js.map +1 -0
  164. package/build/server/chunks/1-DxkfSJLu.js +9 -0
  165. package/build/server/chunks/{1-DPpKAKXV.js.map → 1-DxkfSJLu.js.map} +1 -1
  166. package/build/server/chunks/10-DkObdGtU.js +9 -0
  167. package/build/server/chunks/10-DkObdGtU.js.map +1 -0
  168. package/build/server/chunks/11-DL94HxpZ.js +9 -0
  169. package/build/server/chunks/11-DL94HxpZ.js.map +1 -0
  170. package/build/server/chunks/12-CI74sCkt.js +9 -0
  171. package/build/server/chunks/12-CI74sCkt.js.map +1 -0
  172. package/build/server/chunks/2-qhWwQ4eL.js +9 -0
  173. package/build/server/chunks/2-qhWwQ4eL.js.map +1 -0
  174. package/build/server/chunks/3-CzoZtSTp.js +16 -0
  175. package/build/server/chunks/3-CzoZtSTp.js.map +1 -0
  176. package/build/server/chunks/4-CDa9DBsh.js +16 -0
  177. package/build/server/chunks/4-CDa9DBsh.js.map +1 -0
  178. package/build/server/chunks/5-qD2xxOrq.js +9 -0
  179. package/build/server/chunks/5-qD2xxOrq.js.map +1 -0
  180. package/build/server/chunks/6-B4mWzvDn.js +9 -0
  181. package/build/server/chunks/6-B4mWzvDn.js.map +1 -0
  182. package/build/server/chunks/7-zExv-fTN.js +9 -0
  183. package/build/server/chunks/7-zExv-fTN.js.map +1 -0
  184. package/build/server/chunks/8-BVrGdQg4.js +9 -0
  185. package/build/server/chunks/{6-QQ7r8Rd5.js.map → 8-BVrGdQg4.js.map} +1 -1
  186. package/build/server/chunks/9-BnZLRMYA.js +9 -0
  187. package/build/server/chunks/9-BnZLRMYA.js.map +1 -0
  188. package/build/server/chunks/BehaviorGraph-C-9z37Sm.js +788 -0
  189. package/build/server/chunks/BehaviorGraph-C-9z37Sm.js.map +1 -0
  190. package/build/server/chunks/Clock-BfMWQpmJ.js +5 -0
  191. package/build/server/chunks/Clock-BfMWQpmJ.js.map +1 -0
  192. package/build/server/chunks/DeleteDomain-BvHEgAyp.js +24 -0
  193. package/build/server/chunks/DeleteDomain-BvHEgAyp.js.map +1 -0
  194. package/build/server/chunks/{FeatureValidator-B8qEjAUW.js → DeleteFeature-DnK8sBJI.js} +142 -77
  195. package/build/server/chunks/DeleteFeature-DnK8sBJI.js.map +1 -0
  196. package/build/server/chunks/DeleteProject-BXZcehHZ.js +41 -0
  197. package/build/server/chunks/DeleteProject-BXZcehHZ.js.map +1 -0
  198. package/build/server/chunks/Effect-BJtLR-6l.js +46 -0
  199. package/build/server/chunks/Effect-BJtLR-6l.js.map +1 -0
  200. package/build/server/chunks/{FeatureCard-BQOY6gJQ.js → FeatureCard-Bb50FEfp.js} +4 -4
  201. package/build/server/chunks/{FeatureCard-BQOY6gJQ.js.map → FeatureCard-Bb50FEfp.js.map} +1 -1
  202. package/build/server/chunks/{FeatureJson-Bv-qiOSf.js → FeatureJson-DYvMEAub.js} +2 -2
  203. package/build/server/chunks/{FeatureJson-Bv-qiOSf.js.map → FeatureJson-DYvMEAub.js.map} +1 -1
  204. package/build/server/chunks/{FeatureTransforms-UWDHmWEg.js → FeatureTransforms-B0aI_CJD.js} +10 -3
  205. package/build/server/chunks/FeatureTransforms-B0aI_CJD.js.map +1 -0
  206. package/build/server/chunks/{ManageTagsDialog-DBxA3tM2.js → ManageTagsDialog-D5xbAVNB.js} +5 -5
  207. package/build/server/chunks/ManageTagsDialog-D5xbAVNB.js.map +1 -0
  208. package/build/server/chunks/{ProgressBar-CfhccQ83.js → ProgressBar-CUC2EZqG.js} +3 -3
  209. package/build/server/chunks/ProgressBar-CUC2EZqG.js.map +1 -0
  210. package/build/server/chunks/{ProjectsIndex-CoDrvRya.js → ProjectsIndex-FgIu9dBp.js} +135 -14
  211. package/build/server/chunks/ProjectsIndex-FgIu9dBp.js.map +1 -0
  212. package/build/server/chunks/{RenameTag-BuWLMl1m.js → RenameTag-DWIIR4Bx.js} +3 -6
  213. package/build/server/chunks/RenameTag-DWIIR4Bx.js.map +1 -0
  214. package/build/server/chunks/ScenarioApplier-YPKECfZe.js +55 -0
  215. package/build/server/chunks/ScenarioApplier-YPKECfZe.js.map +1 -0
  216. package/build/server/chunks/SimulatorEngine-DM1F9nCO.js +1391 -0
  217. package/build/server/chunks/SimulatorEngine-DM1F9nCO.js.map +1 -0
  218. package/build/server/chunks/StateValue-BBjWox8f.js +105 -0
  219. package/build/server/chunks/StateValue-BBjWox8f.js.map +1 -0
  220. package/build/server/chunks/{TagDotStrip-B1XQ0m0Y.js → TagDotStrip-0rn-IJVE.js} +4 -4
  221. package/build/server/chunks/TagDotStrip-0rn-IJVE.js.map +1 -0
  222. package/build/server/chunks/{TagFilterSelect-DbO0Qduh.js → TagFilterSelect-Dbu-7Dg4.js} +5 -5
  223. package/build/server/chunks/{TagFilterSelect-DbO0Qduh.js.map → TagFilterSelect-Dbu-7Dg4.js.map} +1 -1
  224. package/build/server/chunks/{TagPalette-CtMNYCmu.js → TagPalette-CpdTiC_7.js} +101 -9
  225. package/build/server/chunks/TagPalette-CpdTiC_7.js.map +1 -0
  226. package/build/server/chunks/TransitionCatalog-CYXUANy6.js +271 -0
  227. package/build/server/chunks/TransitionCatalog-CYXUANy6.js.map +1 -0
  228. package/build/server/chunks/_layout.svelte-pSSG85WT.js +1342 -0
  229. package/build/server/chunks/_layout.svelte-pSSG85WT.js.map +1 -0
  230. package/build/server/chunks/{_page.svelte-BKTveFAj.js → _page.svelte-BNH3szkk.js} +22 -17
  231. package/build/server/chunks/{_page.svelte-BKTveFAj.js.map → _page.svelte-BNH3szkk.js.map} +1 -1
  232. package/build/server/chunks/_page.svelte-BcuGvUt1.js +37 -0
  233. package/build/server/chunks/{_page.svelte-B7hT3P8E.js.map → _page.svelte-BcuGvUt1.js.map} +1 -1
  234. package/build/server/chunks/_page.svelte-BoOMG5Y0.js +37 -0
  235. package/build/server/chunks/{_page.svelte-De508ek8.js.map → _page.svelte-BoOMG5Y0.js.map} +1 -1
  236. package/build/server/chunks/{_page.svelte-BqSC-1vK.js → _page.svelte-C4PRh_wP.js} +104 -54
  237. package/build/server/chunks/_page.svelte-C4PRh_wP.js.map +1 -0
  238. package/build/server/chunks/_page.svelte-Cqn34NXy.js +74 -0
  239. package/build/server/chunks/_page.svelte-Cqn34NXy.js.map +1 -0
  240. package/build/server/chunks/{_page.svelte-B1s7jxaQ.js → _page.svelte-DSCeOGv7.js} +15 -10
  241. package/build/server/chunks/_page.svelte-DSCeOGv7.js.map +1 -0
  242. package/build/server/chunks/_page.svelte-DqWdGt48.js +182 -0
  243. package/build/server/chunks/_page.svelte-DqWdGt48.js.map +1 -0
  244. package/build/server/chunks/_page.svelte-DsQHSEl4.js +49 -0
  245. package/build/server/chunks/_page.svelte-DsQHSEl4.js.map +1 -0
  246. package/build/server/chunks/{_page.svelte-BKKCa9H5.js → _page.svelte-Uioz8hsG.js} +18 -11
  247. package/build/server/chunks/{_page.svelte-BKKCa9H5.js.map → _page.svelte-Uioz8hsG.js.map} +1 -1
  248. package/build/server/chunks/{_page.svelte-Zf9H4KOP.js → _page.svelte-p38jot9e.js} +81 -478
  249. package/build/server/chunks/_page.svelte-p38jot9e.js.map +1 -0
  250. package/build/server/chunks/{_page.svelte-BtI2zZ_Z.js → _page.svelte-yN5kzgJ9.js} +251 -447
  251. package/build/server/chunks/_page.svelte-yN5kzgJ9.js.map +1 -0
  252. package/build/server/chunks/{_server.ts-DsbbVoOn.js → _server.ts-1CtrHhte.js} +4 -4
  253. package/build/server/chunks/{_server.ts-DsbbVoOn.js.map → _server.ts-1CtrHhte.js.map} +1 -1
  254. package/build/server/chunks/{_server.ts-CWvU15tL.js → _server.ts-71Qx1lQb.js} +4 -4
  255. package/build/server/chunks/{_server.ts-CWvU15tL.js.map → _server.ts-71Qx1lQb.js.map} +1 -1
  256. package/build/server/chunks/_server.ts-BAyekGHB.js +961 -0
  257. package/build/server/chunks/_server.ts-BAyekGHB.js.map +1 -0
  258. package/build/server/chunks/{_server.ts-BihpbxOW.js → _server.ts-BLWhU22T.js} +4 -4
  259. package/build/server/chunks/{_server.ts-BihpbxOW.js.map → _server.ts-BLWhU22T.js.map} +1 -1
  260. package/build/server/chunks/{_server.ts-YnfXkeMJ.js → _server.ts-C7EVZVxv.js} +22 -13
  261. package/build/server/chunks/_server.ts-C7EVZVxv.js.map +1 -0
  262. package/build/server/chunks/{_server.ts-vcaqdwxS.js → _server.ts-CGjYuLmo.js} +12 -7
  263. package/build/server/chunks/_server.ts-CGjYuLmo.js.map +1 -0
  264. package/build/server/chunks/{_server.ts-Dy5zQHe2.js → _server.ts-CX6H8fSE.js} +8 -31
  265. package/build/server/chunks/_server.ts-CX6H8fSE.js.map +1 -0
  266. package/build/server/chunks/{_server.ts-BuoQ02BW.js → _server.ts-CyEdTCLr.js} +4 -4
  267. package/build/server/chunks/{_server.ts-BuoQ02BW.js.map → _server.ts-CyEdTCLr.js.map} +1 -1
  268. package/build/server/chunks/_server.ts-DKVTM9Pj.js +77 -0
  269. package/build/server/chunks/_server.ts-DKVTM9Pj.js.map +1 -0
  270. package/build/server/chunks/{_server.ts-0uNTZKwF.js → _server.ts-Dip65hLJ.js} +15 -9
  271. package/build/server/chunks/_server.ts-Dip65hLJ.js.map +1 -0
  272. package/build/server/chunks/{_server.ts-D4EO0VHu.js → _server.ts-Dm0tCs2i.js} +5 -5
  273. package/build/server/chunks/{_server.ts-D4EO0VHu.js.map → _server.ts-Dm0tCs2i.js.map} +1 -1
  274. package/build/server/chunks/{_server.ts-BIBWjQI-.js → _server.ts-DsYwK_uW.js} +4 -4
  275. package/build/server/chunks/{_server.ts-BIBWjQI-.js.map → _server.ts-DsYwK_uW.js.map} +1 -1
  276. package/build/server/chunks/{_server.ts-DDa0Nk_S.js → _server.ts-RCEgegYU.js} +4 -4
  277. package/build/server/chunks/{_server.ts-DDa0Nk_S.js.map → _server.ts-RCEgegYU.js.map} +1 -1
  278. package/build/server/chunks/_server.ts-XOLAT4dd.js +146 -0
  279. package/build/server/chunks/_server.ts-XOLAT4dd.js.map +1 -0
  280. package/build/server/chunks/_server.ts-afh_zLVi.js +69 -0
  281. package/build/server/chunks/_server.ts-afh_zLVi.js.map +1 -0
  282. package/build/server/chunks/{browserContainer-CNX7ANld.js → browserContainer-BdldtueJ.js} +71 -1378
  283. package/build/server/chunks/browserContainer-BdldtueJ.js.map +1 -0
  284. package/build/server/chunks/buildSearchDocs-Cyfrnw9G.js +337 -0
  285. package/build/server/chunks/buildSearchDocs-Cyfrnw9G.js.map +1 -0
  286. package/build/server/chunks/{builderModeStore.svelte-ihupr-3p.js → builderModeStore.svelte-BEZMQEqn.js} +223 -11
  287. package/build/server/chunks/builderModeStore.svelte-BEZMQEqn.js.map +1 -0
  288. package/build/server/chunks/client-C9Cat4DK.js +51 -0
  289. package/build/server/chunks/{client-DfpLcAZ9.js.map → client-C9Cat4DK.js.map} +1 -1
  290. package/build/server/chunks/{error.svelte-C35KOpru.js → error.svelte-CzVR_A6P.js} +5 -5
  291. package/build/server/chunks/{error.svelte-C35KOpru.js.map → error.svelte-CzVR_A6P.js.map} +1 -1
  292. package/build/server/chunks/featureQueueContext-DuXpyTdC.js +32 -0
  293. package/build/server/chunks/featureQueueContext-DuXpyTdC.js.map +1 -0
  294. package/build/server/chunks/featureStore.svelte-DHZf88gu.js +162 -0
  295. package/build/server/chunks/featureStore.svelte-DHZf88gu.js.map +1 -0
  296. package/build/server/chunks/{projectsStore.svelte-QDz5PchX.js → featuresStore.svelte-bUyQBg1-.js} +95 -3
  297. package/build/server/chunks/featuresStore.svelte-bUyQBg1-.js.map +1 -0
  298. package/build/server/chunks/{hooks.server-Rv301GTB.js → hooks.server-y3jdg_sB.js} +6 -2
  299. package/build/server/chunks/hooks.server-y3jdg_sB.js.map +1 -0
  300. package/build/server/chunks/humanize-CkCPfeWi.js +53 -0
  301. package/build/server/chunks/humanize-CkCPfeWi.js.map +1 -0
  302. package/build/server/chunks/{index-server-7H0jzj0M.js → index-server-DvBux_Gf.js} +47 -2
  303. package/build/server/chunks/{index-server-7H0jzj0M.js.map → index-server-DvBux_Gf.js.map} +1 -1
  304. package/build/server/chunks/{internal-BPKrFkK1.js → internal-BFt8yDlf.js} +5 -5
  305. package/build/server/chunks/{internal-BPKrFkK1.js.map → internal-BFt8yDlf.js.map} +1 -1
  306. package/build/server/chunks/projectBundleClient-BtvWPh87.js +168 -0
  307. package/build/server/chunks/projectBundleClient-BtvWPh87.js.map +1 -0
  308. package/build/server/chunks/projectContextStore.svelte-jRJGJZ42.js +141 -0
  309. package/build/server/chunks/projectContextStore.svelte-jRJGJZ42.js.map +1 -0
  310. package/build/server/chunks/projectFeaturesStore.svelte-BwNEtDIL.js +87 -0
  311. package/build/server/chunks/projectFeaturesStore.svelte-BwNEtDIL.js.map +1 -0
  312. package/build/server/chunks/projectStore.svelte-BNuLNxk_.js +230 -0
  313. package/build/server/chunks/projectStore.svelte-BNuLNxk_.js.map +1 -0
  314. package/build/server/chunks/{reconcile-Dv7jS3C8.js → reconcile-CVG2LSlW.js} +54 -267
  315. package/build/server/chunks/reconcile-CVG2LSlW.js.map +1 -0
  316. package/build/server/chunks/registry-DqAn_hVE.js +21 -0
  317. package/build/server/chunks/registry-DqAn_hVE.js.map +1 -0
  318. package/build/server/chunks/{snapshotRepository-BPXCjX92.js → snapshotRepository-8f-2wTrb.js} +30 -5
  319. package/build/server/chunks/snapshotRepository-8f-2wTrb.js.map +1 -0
  320. package/build/server/chunks/{state-CpLVNZq7.js → state-CZZtjXLE.js} +3 -3
  321. package/build/server/chunks/{state-CpLVNZq7.js.map → state-CZZtjXLE.js.map} +1 -1
  322. package/build/server/chunks/{sync-DZ3dn761.js → sync-Bn6eSUhC.js} +3 -3
  323. package/build/server/chunks/{sync-DZ3dn761.js.map → sync-Bn6eSUhC.js.map} +1 -1
  324. package/build/server/chunks/{syncBridge-BwXzPdjJ.js → syncAwareRepositories-DvUjq5Q6.js} +27 -3
  325. package/build/server/chunks/syncAwareRepositories-DvUjq5Q6.js.map +1 -0
  326. package/build/server/chunks/{tagPaletteStore.svelte-DfZOBvgY.js → tagPaletteStore.svelte-C71bdzDl.js} +4 -4
  327. package/build/server/chunks/{tagPaletteStore.svelte-DfZOBvgY.js.map → tagPaletteStore.svelte-C71bdzDl.js.map} +1 -1
  328. package/build/server/index.js +2 -2
  329. package/build/server/index.js.map +1 -1
  330. package/build/server/manifest.js +74 -29
  331. package/build/server/manifest.js.map +1 -1
  332. package/cli/README.md +70 -2
  333. package/cli/commands/check.ts +190 -0
  334. package/cli/commands/ci.ts +71 -0
  335. package/cli/commands/coverage-ingest.ts +112 -0
  336. package/cli/commands/dashboard.ts +14 -0
  337. package/cli/commands/init.ts +26 -0
  338. package/cli/commands/scenarios-adapter.ts +96 -0
  339. package/cli/commands/theme.ts +62 -0
  340. package/cli/scenarios/adapter-scaffold.ts +99 -0
  341. package/cli/scenarios/codegen.ts +7 -1
  342. package/cli/scenarios/results.ts +85 -0
  343. package/cli/skills/unspa-audit/SKILL.md +19 -0
  344. package/cli/skills/unspa-edit/SKILL.md +20 -3
  345. package/cli/skills/unspa-implement/SKILL.md +28 -0
  346. package/cli/unspa.ts +136 -2
  347. package/cli/util/context-files.ts +18 -2
  348. package/cli/util/theme.ts +34 -0
  349. package/mcp-server/bin.ts +104 -104
  350. package/mcp-server/migrate-defaults.ts +164 -164
  351. package/mcp-server/repo-link.ts +142 -134
  352. package/mcp-server/resources/guide.ts +24 -4
  353. package/mcp-server/resources/operations.ts +3 -0
  354. package/mcp-server/seed-snapshots.ts +22 -22
  355. package/mcp-server/server.ts +8 -4
  356. package/mcp-server/sync-aware-repos.ts +79 -79
  357. package/mcp-server/sync-notifier.ts +180 -127
  358. package/mcp-server/tools/_codegen.ts +115 -115
  359. package/mcp-server/tools/_entity_builders.ts +30 -0
  360. package/mcp-server/tools/_shared.ts +210 -210
  361. package/mcp-server/tools/action.ts +210 -210
  362. package/mcp-server/tools/batch.ts +29 -5
  363. package/mcp-server/tools/effect.ts +139 -135
  364. package/mcp-server/tools/entity.ts +132 -132
  365. package/mcp-server/tools/entityField.ts +132 -132
  366. package/mcp-server/tools/event.ts +116 -116
  367. package/mcp-server/tools/feature.ts +264 -264
  368. package/mcp-server/tools/invariant.ts +275 -275
  369. package/mcp-server/tools/persona.ts +141 -141
  370. package/mcp-server/tools/project.ts +500 -391
  371. package/mcp-server/tools/reachabilityGoal.ts +97 -0
  372. package/mcp-server/tools/read.ts +526 -483
  373. package/mcp-server/tools/reorder.ts +114 -114
  374. package/mcp-server/tools/resource.ts +194 -194
  375. package/mcp-server/tools/rule.ts +302 -302
  376. package/mcp-server/tools/scenario.ts +4 -1
  377. package/mcp-server/tools/specGaps.ts +221 -221
  378. package/mcp-server/tools/state.ts +10 -2
  379. package/mcp-server/tools/surface.ts +102 -102
  380. package/mcp-server/tools/transition.ts +96 -96
  381. package/mcp-server/tools/verification.ts +131 -0
  382. package/package.json +15 -2
  383. package/src/app.css +208 -9
  384. package/src/app.html +15 -1
  385. package/src/features/behavior-model/application/ports/FeatureRepository.ts +16 -16
  386. package/src/features/behavior-model/application/use-cases/CreateFeature.ts +24 -24
  387. package/src/features/behavior-model/application/use-cases/DeleteFeature.ts +8 -8
  388. package/src/features/behavior-model/application/use-cases/GetFeature.ts +9 -9
  389. package/src/features/behavior-model/application/use-cases/ListFeatures.ts +10 -10
  390. package/src/features/behavior-model/application/use-cases/MutateFeature.ts +90 -90
  391. package/src/features/behavior-model/application/use-cases/SaveFeature.ts +31 -31
  392. package/src/features/behavior-model/domain/entities/Entity.ts +45 -45
  393. package/src/features/behavior-model/domain/entities/EventDefinition.ts +35 -35
  394. package/src/features/behavior-model/domain/entities/Feature.ts +10 -0
  395. package/src/features/behavior-model/domain/entities/Persona.ts +33 -33
  396. package/src/features/behavior-model/domain/entities/ReachabilityGoal.ts +39 -0
  397. package/src/features/behavior-model/domain/entities/Resource.ts +54 -54
  398. package/src/features/behavior-model/domain/entities/Scenario.ts +15 -0
  399. package/src/features/behavior-model/domain/entities/StateDefinition.ts +13 -0
  400. package/src/features/behavior-model/domain/entities/Surface.ts +75 -75
  401. package/src/features/behavior-model/domain/entities/index.ts +9 -9
  402. package/src/features/behavior-model/domain/services/BehaviorGraphModel.ts +556 -0
  403. package/src/features/behavior-model/domain/services/DerivedState.ts +67 -0
  404. package/src/features/behavior-model/domain/services/EffectApplier.ts +112 -3
  405. package/src/features/behavior-model/domain/services/EffectiveEntities.ts +166 -166
  406. package/src/features/behavior-model/domain/services/EntityDeducer.ts +83 -83
  407. package/src/features/behavior-model/domain/services/EventCatalog.ts +141 -141
  408. package/src/features/behavior-model/domain/services/FeatureExpressionNormalizer.ts +43 -5
  409. package/src/features/behavior-model/domain/services/FeatureSharedStateNormalizer.ts +24 -3
  410. package/src/features/behavior-model/domain/services/FeatureTransforms.ts +33 -0
  411. package/src/features/behavior-model/domain/services/FeatureValidator.ts +124 -16
  412. package/src/features/behavior-model/domain/services/PersonaApplier.ts +39 -39
  413. package/src/features/behavior-model/domain/services/ResourceDeducer.ts +64 -64
  414. package/src/features/behavior-model/domain/services/ResourceUsage.ts +79 -79
  415. package/src/features/behavior-model/domain/services/ScenarioApplier.ts +40 -40
  416. package/src/features/behavior-model/domain/services/SharedStateDefinitions.ts +32 -32
  417. package/src/features/behavior-model/domain/services/StatePathReferences.ts +249 -217
  418. package/src/features/behavior-model/domain/services/TransitionCatalog.ts +173 -173
  419. package/src/features/behavior-model/domain/value-objects/Effect.ts +100 -3
  420. package/src/features/behavior-model/domain/value-objects/EntityFieldType.ts +57 -57
  421. package/src/features/behavior-model/domain/value-objects/Expression.ts +22 -2
  422. package/src/features/behavior-model/domain/value-objects/ParameterType.ts +57 -57
  423. package/src/features/behavior-model/domain/value-objects/Resource.ts +210 -210
  424. package/src/features/behavior-model/domain/value-objects/RuleCategory.ts +57 -57
  425. package/src/features/behavior-model/domain/value-objects/RuleCondition.ts +52 -1
  426. package/src/features/behavior-model/domain/value-objects/SimulationClock.ts +35 -0
  427. package/src/features/behavior-model/domain/value-objects/ids.ts +2 -0
  428. package/src/features/behavior-model/infrastructure/io/FeatureJson.ts +89 -89
  429. package/src/features/behavior-model/infrastructure/persistence/HttpFeatureRepository.ts +43 -43
  430. package/src/features/behavior-model/infrastructure/persistence/JsonFolderFeatureRepository.ts +10 -0
  431. package/src/features/behavior-model/infrastructure/persistence/snapshot-discovery.ts +76 -76
  432. package/src/features/behavior-model/infrastructure/seed/seedStorefront.ts +967 -967
  433. package/src/features/behavior-model/presentation/adapters/VisBehaviorGraphRenderer.ts +501 -0
  434. package/src/features/behavior-model/presentation/components/ActionEditor.svelte +683 -682
  435. package/src/features/behavior-model/presentation/components/ActionsEditor.svelte +232 -232
  436. package/src/features/behavior-model/presentation/components/BehaviorGraph.svelte +568 -0
  437. package/src/features/behavior-model/presentation/components/EffectEditor.svelte +168 -168
  438. package/src/features/behavior-model/presentation/components/EntityEditor.svelte +241 -248
  439. package/src/features/behavior-model/presentation/components/EntityFieldRow.svelte +180 -181
  440. package/src/features/behavior-model/presentation/components/EntityManager.svelte +252 -251
  441. package/src/features/behavior-model/presentation/components/EventsManager.svelte +373 -372
  442. package/src/features/behavior-model/presentation/components/FeatureEditor.svelte +396 -348
  443. package/src/features/behavior-model/presentation/components/FeatureHeader.svelte +165 -148
  444. package/src/features/behavior-model/presentation/components/FeatureHealthStrip.svelte +110 -110
  445. package/src/features/behavior-model/presentation/components/HistoryPanel.svelte +154 -154
  446. package/src/features/behavior-model/presentation/components/NewFeatureForm.svelte +66 -66
  447. package/src/features/behavior-model/presentation/components/ParameterNameSelect.svelte +84 -84
  448. package/src/features/behavior-model/presentation/components/ParametersEditor.svelte +411 -411
  449. package/src/features/behavior-model/presentation/components/PersonaEditor.svelte +244 -244
  450. package/src/features/behavior-model/presentation/components/PersonasManager.svelte +130 -130
  451. package/src/features/behavior-model/presentation/components/ReachabilityGoalEditor.svelte +230 -0
  452. package/src/features/behavior-model/presentation/components/ReachabilityGoalsEditor.svelte +86 -0
  453. package/src/features/behavior-model/presentation/components/ResourcesManager.svelte +291 -290
  454. package/src/features/behavior-model/presentation/components/ScenariosEditor.svelte +496 -496
  455. package/src/features/behavior-model/presentation/components/StateDefinitionsEditor.svelte +356 -356
  456. package/src/features/behavior-model/presentation/components/SurfaceEntitiesView.svelte +88 -88
  457. package/src/features/behavior-model/presentation/components/SurfaceInvariantsEditor.svelte +76 -76
  458. package/src/features/behavior-model/presentation/components/SurfaceList.svelte +300 -300
  459. package/src/features/behavior-model/presentation/components/SurfaceMetaEditor.svelte +158 -156
  460. package/src/features/behavior-model/presentation/components/SurfacePanel.svelte +198 -198
  461. package/src/features/behavior-model/presentation/components/SurfacePersonasView.svelte +122 -122
  462. package/src/features/behavior-model/presentation/components/SurfaceResourcesView.svelte +113 -113
  463. package/src/features/behavior-model/presentation/components/SurfaceRulesEditor.svelte +69 -69
  464. package/src/features/behavior-model/presentation/components/TransitionsManager.svelte +322 -321
  465. package/src/features/behavior-model/presentation/context/featureQueueContext.ts +78 -0
  466. package/src/features/behavior-model/presentation/stores/editorStore.svelte.ts +132 -131
  467. package/src/features/behavior-model/presentation/stores/featureStore.svelte.ts +177 -177
  468. package/src/features/behavior-model/presentation/stores/featuresStore.svelte.ts +98 -98
  469. package/src/features/behavior-model/presentation/view-models/BehaviorGraphTheme.ts +44 -0
  470. package/src/features/behavior-model/presentation/view-models/factories.ts +181 -132
  471. package/src/features/builder-mode/domain/BuilderModeDashboard.ts +7 -1
  472. package/src/features/builder-mode/presentation/components/BuilderModeDashboard.svelte +78 -16
  473. package/src/features/builder-mode/presentation/components/BuilderTagChips.svelte +25 -0
  474. package/src/features/builder-mode/presentation/stores/builderModeStore.svelte.ts +247 -3
  475. package/src/features/domains/infrastructure/persistence/JsonFolderDomainRepository.ts +9 -0
  476. package/src/features/global-search/application/use-cases/LoadSearchIndex.ts +70 -0
  477. package/src/features/global-search/domain/SearchDoc.ts +111 -0
  478. package/src/features/global-search/domain/buildSearchDocs.ts +483 -0
  479. package/src/features/global-search/domain/searchNav.ts +58 -0
  480. package/src/features/global-search/domain/searchScoring.ts +81 -0
  481. package/src/features/global-search/infrastructure/adapters/defaultSearchHost.ts +28 -0
  482. package/src/features/global-search/presentation/components/GlobalSearch.svelte +262 -0
  483. package/src/features/global-search/presentation/ports/SearchHostPorts.ts +41 -0
  484. package/src/features/global-search/presentation/searchKindMeta.ts +108 -0
  485. package/src/features/global-search/presentation/stores/globalSearchStore.svelte.ts +171 -0
  486. package/src/features/implementation-queue/presentation/components/FloatingQueueWidget.svelte +264 -0
  487. package/src/features/implementation-queue/presentation/stores/globalQueueStore.svelte.ts +172 -0
  488. package/src/features/implementation-status/application/ports/ImplementationStatusRepository.ts +8 -8
  489. package/src/features/implementation-status/application/use-cases/GetImplementationStatus.ts +8 -8
  490. package/src/features/implementation-status/domain/ApplyCapturedToSpec.ts +323 -322
  491. package/src/features/implementation-status/domain/FieldDiff.ts +238 -236
  492. package/src/features/implementation-status/infrastructure/persistence/InMemoryImplementationStatusRepository.ts +21 -21
  493. package/src/features/implementation-status/presentation/components/ImplementationStatusPanel.svelte +831 -831
  494. package/src/features/implementation-status/presentation/stores/implementationStatusStore.svelte.ts +97 -97
  495. package/src/features/library/application/use-cases/ApplyBlueprintsToFeature.ts +33 -33
  496. package/src/features/library/domain/services/BlueprintApplier.ts +94 -94
  497. package/src/features/library/infrastructure/blueprints/auth/ResetPasswordBlueprint.ts +332 -332
  498. package/src/features/library/infrastructure/blueprints/auth/SignInBlueprint.ts +281 -281
  499. package/src/features/library/infrastructure/blueprints/auth/SignUpBlueprint.ts +299 -299
  500. package/src/features/library/infrastructure/blueprints/auth/VerifyEmailBlueprint.ts +288 -288
  501. package/src/features/library/infrastructure/blueprints/auth/shared.ts +146 -146
  502. package/src/features/library/infrastructure/blueprints/commerce/CartBlueprint.ts +222 -222
  503. package/src/features/library/infrastructure/blueprints/commerce/CatalogBlueprint.ts +190 -190
  504. package/src/features/library/infrastructure/blueprints/commerce/CheckoutBlueprint.ts +322 -322
  505. package/src/features/library/infrastructure/blueprints/commerce/OrderConfirmationBlueprint.ts +172 -172
  506. package/src/features/library/infrastructure/blueprints/commerce/ProductDetailsBlueprint.ts +290 -290
  507. package/src/features/library/infrastructure/blueprints/content/ReviewsBlueprint.ts +392 -392
  508. package/src/features/library/infrastructure/blueprints/onboarding/OnboardingWizardBlueprint.ts +344 -344
  509. package/src/features/library/infrastructure/blueprints/utility/CanvasBlueprint.ts +419 -419
  510. package/src/features/library/infrastructure/blueprints/utility/CookieConsentBlueprint.ts +195 -195
  511. package/src/features/library/infrastructure/blueprints/utility/NotFoundBlueprint.ts +86 -86
  512. package/src/features/library/infrastructure/blueprints/utility/SearchPaletteBlueprint.ts +192 -192
  513. package/src/features/library/infrastructure/blueprints/utility/StoreLocatorBlueprint.ts +221 -221
  514. package/src/features/library/infrastructure/blueprints/utility/TaskBoardBlueprint.ts +196 -196
  515. package/src/features/maturity/application/use-cases/ScoreFeature.ts +7 -7
  516. package/src/features/maturity/domain/MaturityReport.ts +70 -70
  517. package/src/features/maturity/domain/MaturityScorer.ts +1001 -985
  518. package/src/features/maturity/presentation/components/MaturityPanel.svelte +376 -372
  519. package/src/features/mcp-tools/application/tools/dryRunSimulate.ts +24 -24
  520. package/src/features/mcp-tools/application/tools/findStateReferences.ts +19 -19
  521. package/src/features/mcp-tools/application/tools/generateTypes.ts +0 -1
  522. package/src/features/mcp-tools/application/tools/getAction.ts +165 -165
  523. package/src/features/mcp-tools/application/tools/getFeature.ts +5 -5
  524. package/src/features/mcp-tools/application/tools/getFeatureIndex.ts +79 -79
  525. package/src/features/mcp-tools/application/tools/getNeighborhood.ts +319 -319
  526. package/src/features/mcp-tools/application/tools/getSurface.ts +86 -86
  527. package/src/features/mcp-tools/application/tools/index.ts +56 -56
  528. package/src/features/mcp-tools/application/tools/listActions.ts +49 -49
  529. package/src/features/mcp-tools/application/tools/listFeatures.ts +7 -7
  530. package/src/features/mcp-tools/application/tools/scoreFeature.ts +153 -153
  531. package/src/features/projects/application/ports/ProjectRepository.ts +14 -14
  532. package/src/features/projects/application/use-cases/AddFeatureToProject.ts +23 -23
  533. package/src/features/projects/application/use-cases/CreateProject.ts +16 -16
  534. package/src/features/projects/application/use-cases/FindProjectContainingFeature.ts +23 -23
  535. package/src/features/projects/application/use-cases/GetProjectAggregate.ts +131 -131
  536. package/src/features/projects/application/use-cases/ImportProjectBundle.ts +45 -0
  537. package/src/features/projects/application/use-cases/MoveFeatureInProject.ts +36 -36
  538. package/src/features/projects/application/use-cases/RemoveFeatureFromProject.ts +23 -23
  539. package/src/features/projects/domain/entities/Project.ts +12 -0
  540. package/src/features/projects/domain/services/InheritedFromProject.ts +130 -130
  541. package/src/features/projects/infrastructure/persistence/JsonFolderProjectRepository.ts +9 -0
  542. package/src/features/projects/presentation/components/ProjectCard.svelte +27 -8
  543. package/src/features/projects/presentation/components/ProjectEditor.svelte +23 -19
  544. package/src/features/projects/presentation/components/ProjectFeaturesPanel.svelte +433 -433
  545. package/src/features/projects/presentation/components/ProjectsIndex.svelte +54 -10
  546. package/src/features/projects/presentation/stores/projectContextStore.svelte.ts +170 -170
  547. package/src/features/projects/presentation/stores/projectFeaturesStore.svelte.ts +114 -114
  548. package/src/features/projects/presentation/stores/projectStore.svelte.ts +265 -266
  549. package/src/features/projects/presentation/stores/projectsStore.svelte.ts +134 -134
  550. package/src/features/simulator/application/use-cases/RunScenarios.ts +27 -1
  551. package/src/features/simulator/application/use-cases/SimulateAction.ts +47 -47
  552. package/src/features/simulator/domain/SimulationResult.ts +79 -79
  553. package/src/features/simulator/domain/SimulatorEngine.ts +43 -9
  554. package/src/features/simulator/domain/StateExplorer.ts +369 -0
  555. package/src/features/simulator/domain/SurfaceReachability.ts +130 -0
  556. package/src/features/simulator/presentation/components/ParameterInputs.svelte +277 -277
  557. package/src/features/simulator/presentation/components/PersonaPicker.svelte +52 -52
  558. package/src/features/simulator/presentation/components/ScenarioPicker.svelte +42 -45
  559. package/src/features/simulator/presentation/components/SidePanel.svelte +170 -170
  560. package/src/features/simulator/presentation/components/SimulationResultView.svelte +394 -394
  561. package/src/features/simulator/presentation/components/SimulatorPanel.svelte +293 -293
  562. package/src/features/simulator/presentation/components/StateInspector.svelte +101 -101
  563. package/src/features/simulator/presentation/stores/simulatorStore.svelte.ts +268 -268
  564. package/src/features/tutorial/presentation/components/CodeBlock.svelte +5 -1
  565. package/src/features/verification/application/ports/BehavioralIndexReader.ts +12 -0
  566. package/src/features/verification/application/use-cases/VerifyFeatures.ts +151 -0
  567. package/src/features/verification/domain/DriftReport.ts +37 -0
  568. package/src/features/verification/domain/EventCoherenceReport.ts +27 -0
  569. package/src/features/verification/domain/IndexedImplementation.ts +27 -0
  570. package/src/features/verification/domain/VerificationReport.ts +59 -0
  571. package/src/features/verification/domain/VerificationThresholds.ts +52 -0
  572. package/src/features/verification/domain/VerificationVerdict.ts +43 -0
  573. package/src/features/verification/domain/aggregateVerdict.ts +244 -0
  574. package/src/features/verification/domain/analyzeEventCoherence.ts +43 -0
  575. package/src/features/verification/domain/detectDrift.ts +166 -0
  576. package/src/features/verification/domain/verifiedCoverage.ts +37 -0
  577. package/src/features/verification/infrastructure/persistence/FileBehavioralIndexReader.ts +81 -0
  578. package/src/features/verification/infrastructure/persistence/StaticBehavioralIndexReader.ts +15 -0
  579. package/src/features/verification/presentation/components/VerifyPanel.svelte +74 -0
  580. package/src/features/verification/presentation/stores/verificationStore.svelte.ts +64 -0
  581. package/src/hooks.server.ts +11 -1
  582. package/src/lib/server/openLocalDirectory.ts +40 -0
  583. package/src/lib/server/searchIndex.ts +161 -0
  584. package/src/lib/server/snapshotRepository.ts +37 -37
  585. package/src/lib/server/sync/YDocManager.ts +391 -391
  586. package/src/lib/server/sync/historyStore.ts +276 -276
  587. package/src/lib/server/sync/wsServer.ts +1 -1
  588. package/src/lib/sync/protocol.ts +147 -147
  589. package/src/lib/sync/roomId.ts +33 -33
  590. package/src/lib/theme/registry.ts +77 -0
  591. package/src/lib/theme/themeStore.svelte.ts +64 -0
  592. package/src/routes/+layout.svelte +288 -30
  593. package/src/routes/api/domains/[id]/+server.ts +7 -3
  594. package/src/routes/api/projects/[id]/+server.ts +14 -4
  595. package/src/routes/api/projects/import/+server.ts +16 -38
  596. package/src/routes/api/search-index/+server.ts +16 -0
  597. package/src/routes/api/snapshots/[id]/+server.ts +56 -44
  598. package/src/routes/api/snapshots/[id]/implementation-status/+server.ts +13 -13
  599. package/src/routes/api/snapshots/[id]/verify/+server.ts +37 -0
  600. package/src/routes/api/sync/reload/+server.ts +157 -157
  601. package/src/routes/api/system/hub-directory/+server.ts +24 -0
  602. package/src/routes/features/+page.svelte +484 -484
  603. package/src/routes/features/[id]/+page.svelte +55 -49
  604. package/src/routes/features/[id]/graph/+page.svelte +39 -0
  605. package/src/routes/features/[id]/verify/+page.svelte +89 -0
  606. package/src/routes/mcp/+page.svelte +16 -1
  607. package/src/routes/projects/[id]/+page.svelte +70 -70
  608. package/src/routes/projects/[id]/graph/+page.svelte +79 -0
  609. package/src/routes/tutorial/+page.svelte +3 -2
  610. package/src/shared/infrastructure/browserContainer.ts +61 -61
  611. package/src/shared/presentation/components/KebabMenu.svelte +95 -0
  612. package/src/shared/presentation/components/MenuItem.svelte +29 -0
  613. package/src/shared/presentation/components/ProgressBar.svelte +1 -1
  614. package/src/shared/presentation/toast/SyncToast.svelte +14 -3
  615. package/src/shared/presentation/toast/viewLinkResolver.ts +32 -0
  616. package/static/lyriks_logo.svg +148 -0
  617. package/vite.config.ts +47 -47
  618. package/build/client/_app/immutable/assets/0.DFMDYAU9.css +0 -1
  619. package/build/client/_app/immutable/assets/0.DFMDYAU9.css.br +0 -0
  620. package/build/client/_app/immutable/assets/0.DFMDYAU9.css.gz +0 -0
  621. package/build/client/_app/immutable/assets/9.nv0I59TU.css.gz +0 -0
  622. package/build/client/_app/immutable/chunks/BO66rBOa2.js +0 -1
  623. package/build/client/_app/immutable/chunks/BO66rBOa2.js.br +0 -0
  624. package/build/client/_app/immutable/chunks/BO66rBOa2.js.gz +0 -0
  625. package/build/client/_app/immutable/chunks/BOrLmFwJ.js.br +0 -0
  626. package/build/client/_app/immutable/chunks/BOrLmFwJ.js.gz +0 -0
  627. package/build/client/_app/immutable/chunks/BfMYiIUi.js.br +0 -0
  628. package/build/client/_app/immutable/chunks/BfMYiIUi.js.gz +0 -0
  629. package/build/client/_app/immutable/chunks/Bp2_Vghh.js +0 -1
  630. package/build/client/_app/immutable/chunks/Bp2_Vghh.js.br +0 -0
  631. package/build/client/_app/immutable/chunks/Bp2_Vghh.js.gz +0 -0
  632. package/build/client/_app/immutable/chunks/Bp8HpEPe2.js +0 -4
  633. package/build/client/_app/immutable/chunks/Bp8HpEPe2.js.br +0 -0
  634. package/build/client/_app/immutable/chunks/Bp8HpEPe2.js.gz +0 -0
  635. package/build/client/_app/immutable/chunks/C8rRKIXT.js +0 -1
  636. package/build/client/_app/immutable/chunks/C8rRKIXT.js.br +0 -0
  637. package/build/client/_app/immutable/chunks/C8rRKIXT.js.gz +0 -0
  638. package/build/client/_app/immutable/chunks/CJjJLwzv2.js +0 -1
  639. package/build/client/_app/immutable/chunks/CJjJLwzv2.js.br +0 -0
  640. package/build/client/_app/immutable/chunks/CJjJLwzv2.js.gz +0 -0
  641. package/build/client/_app/immutable/chunks/CxyLMlpt2.js.br +0 -0
  642. package/build/client/_app/immutable/chunks/CxyLMlpt2.js.gz +0 -0
  643. package/build/client/_app/immutable/chunks/D6jhrpTg.js +0 -1
  644. package/build/client/_app/immutable/chunks/D6jhrpTg.js.br +0 -0
  645. package/build/client/_app/immutable/chunks/D6jhrpTg.js.gz +0 -0
  646. package/build/client/_app/immutable/chunks/D8YEa1po.js +0 -1
  647. package/build/client/_app/immutable/chunks/D8YEa1po.js.br +0 -0
  648. package/build/client/_app/immutable/chunks/D8YEa1po.js.gz +0 -0
  649. package/build/client/_app/immutable/chunks/D9dKmajw.js +0 -1
  650. package/build/client/_app/immutable/chunks/D9dKmajw.js.br +0 -0
  651. package/build/client/_app/immutable/chunks/D9dKmajw.js.gz +0 -0
  652. package/build/client/_app/immutable/chunks/DBJWcC6Y.js +0 -1
  653. package/build/client/_app/immutable/chunks/DBJWcC6Y.js.br +0 -0
  654. package/build/client/_app/immutable/chunks/DBJWcC6Y.js.gz +0 -0
  655. package/build/client/_app/immutable/chunks/DHoA038D.js +0 -1
  656. package/build/client/_app/immutable/chunks/DHoA038D.js.br +0 -2
  657. package/build/client/_app/immutable/chunks/DHoA038D.js.gz +0 -0
  658. package/build/client/_app/immutable/chunks/DKgYpi6_.js +0 -1
  659. package/build/client/_app/immutable/chunks/DKgYpi6_.js.br +0 -0
  660. package/build/client/_app/immutable/chunks/DKgYpi6_.js.gz +0 -0
  661. package/build/client/_app/immutable/chunks/DatGSObE.js +0 -1
  662. package/build/client/_app/immutable/chunks/DatGSObE.js.br +0 -0
  663. package/build/client/_app/immutable/chunks/DatGSObE.js.gz +0 -0
  664. package/build/client/_app/immutable/chunks/Dg0acPpT.js +0 -1
  665. package/build/client/_app/immutable/chunks/Dg0acPpT.js.br +0 -0
  666. package/build/client/_app/immutable/chunks/Dg0acPpT.js.gz +0 -0
  667. package/build/client/_app/immutable/chunks/DjWKKtqp.js +0 -1
  668. package/build/client/_app/immutable/chunks/DjWKKtqp.js.br +0 -1
  669. package/build/client/_app/immutable/chunks/DjWKKtqp.js.gz +0 -0
  670. package/build/client/_app/immutable/chunks/Dq0DUAz1.js +0 -1
  671. package/build/client/_app/immutable/chunks/Dq0DUAz1.js.br +0 -0
  672. package/build/client/_app/immutable/chunks/Dq0DUAz1.js.gz +0 -0
  673. package/build/client/_app/immutable/chunks/HKLi1Yz3.js +0 -1
  674. package/build/client/_app/immutable/chunks/HKLi1Yz3.js.br +0 -0
  675. package/build/client/_app/immutable/chunks/HKLi1Yz3.js.gz +0 -0
  676. package/build/client/_app/immutable/chunks/N7PXjlRH.js +0 -1
  677. package/build/client/_app/immutable/chunks/N7PXjlRH.js.br +0 -0
  678. package/build/client/_app/immutable/chunks/N7PXjlRH.js.gz +0 -0
  679. package/build/client/_app/immutable/chunks/hpWJNn0t2.js +0 -2
  680. package/build/client/_app/immutable/chunks/hpWJNn0t2.js.br +0 -0
  681. package/build/client/_app/immutable/chunks/hpWJNn0t2.js.gz +0 -0
  682. package/build/client/_app/immutable/chunks/iQu0D9Ux.js +0 -1
  683. package/build/client/_app/immutable/chunks/iQu0D9Ux.js.br +0 -0
  684. package/build/client/_app/immutable/chunks/iQu0D9Ux.js.gz +0 -0
  685. package/build/client/_app/immutable/entry/app.CLgh6Mx_.js +0 -2
  686. package/build/client/_app/immutable/entry/app.CLgh6Mx_.js.br +0 -0
  687. package/build/client/_app/immutable/entry/app.CLgh6Mx_.js.gz +0 -0
  688. package/build/client/_app/immutable/entry/start.D5GPCQZD.js +0 -1
  689. package/build/client/_app/immutable/entry/start.D5GPCQZD.js.br +0 -0
  690. package/build/client/_app/immutable/entry/start.D5GPCQZD.js.gz +0 -0
  691. package/build/client/_app/immutable/nodes/0.BOoI-hsu.js +0 -4
  692. package/build/client/_app/immutable/nodes/0.BOoI-hsu.js.br +0 -0
  693. package/build/client/_app/immutable/nodes/0.BOoI-hsu.js.gz +0 -0
  694. package/build/client/_app/immutable/nodes/1.KYdA6ppX.js.br +0 -2
  695. package/build/client/_app/immutable/nodes/1.KYdA6ppX.js.gz +0 -0
  696. package/build/client/_app/immutable/nodes/2.DBz20KgG.js.br +0 -0
  697. package/build/client/_app/immutable/nodes/2.DBz20KgG.js.gz +0 -0
  698. package/build/client/_app/immutable/nodes/3.19DIoFtw.js +0 -1
  699. package/build/client/_app/immutable/nodes/3.19DIoFtw.js.br +0 -0
  700. package/build/client/_app/immutable/nodes/3.19DIoFtw.js.gz +0 -0
  701. package/build/client/_app/immutable/nodes/4.BvMzqBJj.js +0 -3
  702. package/build/client/_app/immutable/nodes/4.BvMzqBJj.js.br +0 -0
  703. package/build/client/_app/immutable/nodes/4.BvMzqBJj.js.gz +0 -0
  704. package/build/client/_app/immutable/nodes/5.Dq6obSGG.js +0 -42
  705. package/build/client/_app/immutable/nodes/5.Dq6obSGG.js.br +0 -0
  706. package/build/client/_app/immutable/nodes/5.Dq6obSGG.js.gz +0 -0
  707. package/build/client/_app/immutable/nodes/6.BOHISqs-.js +0 -5
  708. package/build/client/_app/immutable/nodes/6.BOHISqs-.js.br +0 -0
  709. package/build/client/_app/immutable/nodes/6.BOHISqs-.js.gz +0 -0
  710. package/build/client/_app/immutable/nodes/7.CemgNJfw.js.br +0 -0
  711. package/build/client/_app/immutable/nodes/7.CemgNJfw.js.gz +0 -0
  712. package/build/client/_app/immutable/nodes/8.DejSfIYh.js +0 -5
  713. package/build/client/_app/immutable/nodes/8.DejSfIYh.js.br +0 -0
  714. package/build/client/_app/immutable/nodes/8.DejSfIYh.js.gz +0 -0
  715. package/build/client/_app/immutable/nodes/9.CMW6a2Lg.js.br +0 -0
  716. package/build/client/_app/immutable/nodes/9.CMW6a2Lg.js.gz +0 -0
  717. package/build/server/chunks/0-C_o0oz-N.js +0 -15
  718. package/build/server/chunks/0-C_o0oz-N.js.map +0 -1
  719. package/build/server/chunks/1-DPpKAKXV.js +0 -9
  720. package/build/server/chunks/2-AlfFqtL1.js +0 -9
  721. package/build/server/chunks/2-AlfFqtL1.js.map +0 -1
  722. package/build/server/chunks/3-vbjUt_51.js +0 -16
  723. package/build/server/chunks/3-vbjUt_51.js.map +0 -1
  724. package/build/server/chunks/4-BNow4x6D.js +0 -16
  725. package/build/server/chunks/4-BNow4x6D.js.map +0 -1
  726. package/build/server/chunks/5-D7OCJpxD.js +0 -9
  727. package/build/server/chunks/5-D7OCJpxD.js.map +0 -1
  728. package/build/server/chunks/6-QQ7r8Rd5.js +0 -9
  729. package/build/server/chunks/7-CbPLGaIG.js +0 -9
  730. package/build/server/chunks/7-CbPLGaIG.js.map +0 -1
  731. package/build/server/chunks/8-CVO-E-sf.js +0 -9
  732. package/build/server/chunks/8-CVO-E-sf.js.map +0 -1
  733. package/build/server/chunks/9-DxT1baO5.js +0 -9
  734. package/build/server/chunks/9-DxT1baO5.js.map +0 -1
  735. package/build/server/chunks/FeatureTransforms-UWDHmWEg.js.map +0 -1
  736. package/build/server/chunks/FeatureValidator-B8qEjAUW.js.map +0 -1
  737. package/build/server/chunks/ManageTagsDialog-DBxA3tM2.js.map +0 -1
  738. package/build/server/chunks/ProgressBar-CfhccQ83.js.map +0 -1
  739. package/build/server/chunks/ProjectsIndex-CoDrvRya.js.map +0 -1
  740. package/build/server/chunks/RenameTag-BuWLMl1m.js.map +0 -1
  741. package/build/server/chunks/TagDotStrip-B1XQ0m0Y.js.map +0 -1
  742. package/build/server/chunks/TagPalette-CtMNYCmu.js.map +0 -1
  743. package/build/server/chunks/_layout.svelte-BREws55o.js +0 -616
  744. package/build/server/chunks/_layout.svelte-BREws55o.js.map +0 -1
  745. package/build/server/chunks/_page.svelte-B1s7jxaQ.js.map +0 -1
  746. package/build/server/chunks/_page.svelte-B7hT3P8E.js +0 -29
  747. package/build/server/chunks/_page.svelte-BqSC-1vK.js.map +0 -1
  748. package/build/server/chunks/_page.svelte-BtI2zZ_Z.js.map +0 -1
  749. package/build/server/chunks/_page.svelte-De508ek8.js +0 -29
  750. package/build/server/chunks/_page.svelte-Zf9H4KOP.js.map +0 -1
  751. package/build/server/chunks/_server.ts-0uNTZKwF.js.map +0 -1
  752. package/build/server/chunks/_server.ts-DcZPhyhK.js +0 -59
  753. package/build/server/chunks/_server.ts-DcZPhyhK.js.map +0 -1
  754. package/build/server/chunks/_server.ts-Dy5zQHe2.js.map +0 -1
  755. package/build/server/chunks/_server.ts-YnfXkeMJ.js.map +0 -1
  756. package/build/server/chunks/_server.ts-vcaqdwxS.js.map +0 -1
  757. package/build/server/chunks/browserContainer-CNX7ANld.js.map +0 -1
  758. package/build/server/chunks/builderModeStore.svelte-ihupr-3p.js.map +0 -1
  759. package/build/server/chunks/client-DfpLcAZ9.js +0 -24
  760. package/build/server/chunks/featuresStore.svelte-DR1gYZyu.js +0 -98
  761. package/build/server/chunks/featuresStore.svelte-DR1gYZyu.js.map +0 -1
  762. package/build/server/chunks/hooks.server-Rv301GTB.js.map +0 -1
  763. package/build/server/chunks/identityStore.svelte-IIvW2_3b.js +0 -59
  764. package/build/server/chunks/identityStore.svelte-IIvW2_3b.js.map +0 -1
  765. package/build/server/chunks/projectsStore.svelte-QDz5PchX.js.map +0 -1
  766. package/build/server/chunks/reconcile-Dv7jS3C8.js.map +0 -1
  767. package/build/server/chunks/snapshotRepository-BPXCjX92.js.map +0 -1
  768. package/build/server/chunks/syncBridge-BwXzPdjJ.js.map +0 -1
  769. package/src/features/implementation-queue/presentation/components/QueuePanel.svelte +0 -204
  770. package/src/features/implementation-queue/presentation/stores/queueStore.svelte.ts +0 -143
  771. /package/build/client/_app/immutable/assets/{9.nv0I59TU.css → 12.nv0I59TU.css} +0 -0
  772. /package/build/client/_app/immutable/assets/{9.nv0I59TU.css.br → 12.nv0I59TU.css.br} +0 -0
@@ -1,349 +1,397 @@
1
- <script lang="ts">
2
- import { onMount, untrack } from 'svelte';
3
- import { page } from '$app/state';
4
- import { goto } from '$app/navigation';
5
- import type { Feature } from '$features/behavior-model/domain/entities/Feature';
6
- import { asSurfaceId } from '$features/behavior-model/domain/value-objects/ids';
7
- import { featureStore } from '$features/behavior-model/presentation/stores/featureStore.svelte';
8
- import { editorStore } from '$features/behavior-model/presentation/stores/editorStore.svelte';
9
- import { getEffectiveEntities } from '$features/behavior-model/domain/services/EffectiveEntities';
10
- import { withSharedStateDefinitions } from '$features/behavior-model/domain/services/SharedStateDefinitions';
11
- import type { SurfacePanelTab } from '$features/maturity/domain/MaturityReport';
12
- import FeatureHeader from './FeatureHeader.svelte';
13
- import FeatureHealthStrip from './FeatureHealthStrip.svelte';
14
- import HistoryPanel from './HistoryPanel.svelte';
15
- import SurfaceList from './SurfaceList.svelte';
16
- import SurfacePanel from './SurfacePanel.svelte';
17
- import SidePanel from '$features/simulator/presentation/components/SidePanel.svelte';
18
- import ResourcesManager from './ResourcesManager.svelte';
19
- import EntityManager from './EntityManager.svelte';
20
- import EventsManager from './EventsManager.svelte';
21
- import FeatureInvariantsEditor from './FeatureInvariantsEditor.svelte';
22
- import TransitionsManager from './TransitionsManager.svelte';
23
- import { buildEventCatalog } from '$features/behavior-model/domain/services/EventCatalog';
24
- import { buildTransitionCatalog } from '$features/behavior-model/domain/services/TransitionCatalog';
25
- import { implementationStatusStore } from '$features/implementation-status/presentation/stores/implementationStatusStore.svelte';
26
- import { fade } from 'svelte/transition';
27
- import { cubicOut } from 'svelte/easing';
28
-
29
- const VALID_TOP_TABS = new Set([
30
- 'build',
31
- 'resources',
32
- 'data',
33
- 'events',
34
- 'transitions',
35
- 'invariants'
36
- ]);
37
- const VALID_PANEL_TABS = new Set([
38
- 'actions',
39
- 'state',
40
- 'rules',
41
- 'invariants',
42
- 'data',
43
- 'resources',
44
- 'personas'
45
- ]);
46
-
47
- type Props = { feature: Feature };
48
- let { feature }: Props = $props();
49
-
50
- type TopTab =
51
- | 'build'
52
- | 'resources'
53
- | 'data'
54
- | 'events'
55
- | 'transitions'
56
- | 'invariants';
57
- // Top-level tab is now in the editor store so deep-link navigation can
58
- // jump back to "Build" when fixing an issue from elsewhere.
59
- const activeTab = $derived<TopTab>(editorStore.topLevelTab);
60
-
61
- const selectedSurface = $derived(
62
- feature.surfaces.find((s) => s.id === editorStore.selectedSurfaceId) ?? null
63
- );
64
- const selectedSurfaceForUse = $derived(
65
- selectedSurface ? withSharedStateDefinitions(feature, selectedSurface) : null
66
- );
67
-
68
- onMount(() => {
69
- if (!editorStore.selectedSurfaceId && feature.surfaces.length > 0) {
70
- const first = feature.surfaces[0];
71
- if (first) editorStore.selectSurface(first.id);
72
- }
73
- implementationStatusStore.load(feature.id);
74
- });
75
-
76
- $effect(() => {
77
- if (
78
- editorStore.selectedSurfaceId &&
79
- !feature.surfaces.some((s) => s.id === editorStore.selectedSurfaceId)
80
- ) {
81
- const first = feature.surfaces[0];
82
- editorStore.selectSurface(first ? first.id : null);
83
- }
84
- });
85
-
1
+ <script lang="ts">
2
+ import { onMount, untrack } from 'svelte';
3
+ import { page } from '$app/state';
4
+ import { goto } from '$app/navigation';
5
+ import type { Feature } from '$features/behavior-model/domain/entities/Feature';
6
+ import { asActionId, asSurfaceId } from '$features/behavior-model/domain/value-objects/ids';
7
+ import { featureStore } from '$features/behavior-model/presentation/stores/featureStore.svelte';
8
+ import { editorStore } from '$features/behavior-model/presentation/stores/editorStore.svelte';
9
+ import { getEffectiveEntities } from '$features/behavior-model/domain/services/EffectiveEntities';
10
+ import { withSharedStateDefinitions } from '$features/behavior-model/domain/services/SharedStateDefinitions';
11
+ import type { SurfacePanelTab } from '$features/maturity/domain/MaturityReport';
12
+ import FeatureHeader from './FeatureHeader.svelte';
13
+ import FeatureHealthStrip from './FeatureHealthStrip.svelte';
14
+ import HistoryPanel from './HistoryPanel.svelte';
15
+ import SurfaceList from './SurfaceList.svelte';
16
+ import SurfacePanel from './SurfacePanel.svelte';
17
+ import SidePanel from '$features/simulator/presentation/components/SidePanel.svelte';
18
+ import ResourcesManager from './ResourcesManager.svelte';
19
+ import EntityManager from './EntityManager.svelte';
20
+ import EventsManager from './EventsManager.svelte';
21
+ import FeatureInvariantsEditor from './FeatureInvariantsEditor.svelte';
22
+ import ReachabilityGoalsEditor from './ReachabilityGoalsEditor.svelte';
23
+ import TransitionsManager from './TransitionsManager.svelte';
24
+ import { buildEventCatalog } from '$features/behavior-model/domain/services/EventCatalog';
25
+ import { buildTransitionCatalog } from '$features/behavior-model/domain/services/TransitionCatalog';
26
+ import { implementationStatusStore } from '$features/implementation-status/presentation/stores/implementationStatusStore.svelte';
27
+ import { fade } from 'svelte/transition';
28
+ import { cubicOut } from 'svelte/easing';
29
+
30
+ const VALID_TOP_TABS = new Set([
31
+ 'build',
32
+ 'resources',
33
+ 'data',
34
+ 'events',
35
+ 'transitions',
36
+ 'invariants',
37
+ 'goals'
38
+ ]);
39
+ const VALID_PANEL_TABS = new Set([
40
+ 'actions',
41
+ 'state',
42
+ 'rules',
43
+ 'invariants',
44
+ 'data',
45
+ 'resources',
46
+ 'personas'
47
+ ]);
48
+
49
+ type Props = { feature: Feature };
50
+ let { feature }: Props = $props();
51
+
52
+ type TopTab =
53
+ | 'build'
54
+ | 'resources'
55
+ | 'data'
56
+ | 'events'
57
+ | 'transitions'
58
+ | 'invariants'
59
+ | 'goals';
60
+ // Top-level tab is now in the editor store so deep-link navigation can
61
+ // jump back to "Build" when fixing an issue from elsewhere.
62
+ const activeTab = $derived<TopTab>(editorStore.topLevelTab);
63
+
64
+ const selectedSurface = $derived(
65
+ feature.surfaces.find((s) => s.id === editorStore.selectedSurfaceId) ?? null
66
+ );
67
+ const selectedSurfaceForUse = $derived(
68
+ selectedSurface ? withSharedStateDefinitions(feature, selectedSurface) : null
69
+ );
70
+
71
+ onMount(() => {
72
+ if (!editorStore.selectedSurfaceId && feature.surfaces.length > 0) {
73
+ const first = feature.surfaces[0];
74
+ if (first) editorStore.selectSurface(first.id);
75
+ }
76
+ implementationStatusStore.load(feature.id);
77
+ });
78
+
79
+ $effect(() => {
80
+ if (
81
+ editorStore.selectedSurfaceId &&
82
+ !feature.surfaces.some((s) => s.id === editorStore.selectedSurfaceId)
83
+ ) {
84
+ const first = feature.surfaces[0];
85
+ editorStore.selectSurface(first ? first.id : null);
86
+ }
87
+ });
88
+
86
89
  // Focus observer: when the editor asks to focus a target (e.g. via the
87
- // maturity panel's "Fix →" anchor), wait a tick for the surface/tab/cap
88
- // selection to settle, then scroll the matching DOM element into view and
89
- // briefly pulse it so the user can see exactly what to act on.
90
- $effect(() => {
91
- editorStore.focusToken; // re-fire each navigation
92
- const target = editorStore.focusTarget;
93
- if (!target) return;
94
- let cancelled = false;
95
- const timers: ReturnType<typeof setTimeout>[] = [];
96
- const tryFocus = (attempt = 0) => {
97
- if (cancelled) return;
98
- const el = document.querySelector(`[data-focus-target="${CSS.escape(target)}"]`);
99
- if (el) {
100
- el.scrollIntoView({ behavior: 'smooth', block: 'center' });
101
- el.classList.add('focus-flash');
102
- timers.push(setTimeout(() => el.classList.remove('focus-flash'), 1700));
103
- return;
104
- }
105
- // The element may not be in the DOM yet (tab switching, action
106
- // expanding). Retry a handful of times before giving up.
107
- if (attempt < 5) {
108
- timers.push(setTimeout(() => tryFocus(attempt + 1), 80));
109
- }
110
- };
111
- timers.push(setTimeout(() => tryFocus(), 60));
112
- return () => {
113
- cancelled = true;
114
- for (const t of timers) clearTimeout(t);
115
- };
116
- });
117
-
118
- // ───────── URL editorStore sync ────────────────────────────────────
119
- //
120
- // The browser URL is the source of truth for navigation: top-level tab,
121
- // selected surface, surface-panel tab. Two effects keep them in lockstep:
122
- // • URL → store: only re-runs when the URL changes (back/forward, deep
123
- // links). Store reads are wrapped in `untrack` so the effect cannot
124
- // re-fire when its own writes propagate.
125
- // • store URL: only re-runs when the store changes. URL reads happen
126
- // inside `untrack` for the same reason. Without this, a click on a
127
- // surface mutates the store, the other effect immediately fires reading
128
- // the still-stale URL, and reverts the click.
129
-
130
- $effect(() => {
131
- const url = page.url;
132
- const tabParam = url.searchParams.get('tab');
133
- const surfaceParam = url.searchParams.get('surface');
134
- const panelParam = url.searchParams.get('panel');
135
-
136
- untrack(() => {
137
- const tab =
138
- tabParam && VALID_TOP_TABS.has(tabParam)
139
- ? (tabParam as typeof editorStore.topLevelTab)
140
- : 'build';
141
- if (editorStore.topLevelTab !== tab) {
142
- editorStore.setTopLevelTab(tab);
143
- }
144
-
145
- const surfaceId = surfaceParam ? asSurfaceId(surfaceParam) : null;
146
- if (editorStore.selectedSurfaceId !== surfaceId) {
147
- editorStore.selectSurface(surfaceId);
148
- }
149
-
150
- const panel: SurfacePanelTab =
151
- panelParam && VALID_PANEL_TABS.has(panelParam)
152
- ? (panelParam as SurfacePanelTab)
153
- : 'actions';
154
- if (editorStore.surfacePanelTab !== panel) {
155
- editorStore.setSurfacePanelTab(panel);
156
- }
157
- });
158
- });
159
-
160
- $effect(() => {
161
- const tab = editorStore.topLevelTab;
162
- const surfaceId = editorStore.selectedSurfaceId;
163
- const panel = editorStore.surfacePanelTab;
164
-
165
- untrack(() => {
166
- const params = new URLSearchParams();
167
- if (tab !== 'build') params.set('tab', tab);
168
- if (surfaceId) params.set('surface', surfaceId);
169
- if (panel !== 'actions') params.set('panel', panel);
170
- const qs = params.toString();
171
- const desired = qs ? `?${qs}` : '';
172
- const current = page.url.search;
173
- if (desired === current) return;
174
- void goto(`${page.url.pathname}${desired}`, {
175
- keepFocus: true,
176
- noScroll: true,
177
- replaceState: false
178
- });
179
- });
180
- });
181
-
182
- // Effective data = every namespace touched by the model (deduced + declared).
183
- // Counter must reflect what the Entity tab actually shows, not just stored
184
- // overrides.
185
- const effectiveDataCount = $derived(getEffectiveEntities(feature).length);
186
- const eventsCount = $derived(buildEventCatalog(feature).length);
187
- const transitionsCount = $derived(buildTransitionCatalog(feature).length);
188
-
189
- const tabs: ReadonlyArray<{ key: TopTab; label: string; count?: number }> = $derived([
190
- { key: 'build', label: 'Build', count: feature.surfaces.length },
191
- { key: 'resources', label: 'Resources', count: feature.resources.length },
192
- { key: 'data', label: 'Entity', count: effectiveDataCount },
193
- { key: 'events', label: 'Events', count: eventsCount },
194
- { key: 'transitions', label: 'Transitions', count: transitionsCount },
195
- {
196
- key: 'invariants',
197
- label: 'Invariants',
198
- count: feature.featureInvariants?.length ?? 0
199
- }
200
- ]);
201
-
202
- // Global undo/redo shortcuts. We deliberately ignore the event when focus
203
- // is in a text editor. Native input/textarea undo handles per-keystroke
204
- // text edits, and our store-level undo only exists for committed mutations
205
- // (mutate() calls), not in-progress text drafts.
206
- $effect(() => {
207
- const isEditable = (el: EventTarget | null): boolean => {
208
- if (!(el instanceof HTMLElement)) return false;
209
- const tag = el.tagName;
210
- if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return true;
211
- return el.isContentEditable;
212
- };
213
- const onKeydown = (event: KeyboardEvent) => {
214
- const mod = event.ctrlKey || event.metaKey;
215
- if (!mod) return;
216
- const key = event.key.toLowerCase();
217
- const isUndo = key === 'z' && !event.shiftKey;
218
- const isRedo = (key === 'z' && event.shiftKey) || key === 'y';
219
- if (!isUndo && !isRedo) return;
220
- if (isEditable(event.target)) return;
221
- event.preventDefault();
222
- if (isUndo) featureStore.undo();
223
- else featureStore.redo();
224
- };
225
- window.addEventListener('keydown', onKeydown);
226
- return () => window.removeEventListener('keydown', onKeydown);
227
- });
228
-
229
- // Detect when the tab nav is pinned to the top of the viewport. A 1px
230
- // sentinel sits just above the nav; when it scrolls out of view the nav has
231
- // crossed top: 0 and we add a shadow to lift it off the content scrolling
232
- // behind it.
233
- let navStuck = $state(false);
234
- let stuckSentinel = $state<HTMLDivElement | null>(null);
235
- let historyOpen = $state(false);
236
-
237
- $effect(() => {
238
- const el = stuckSentinel;
239
- if (!el) return;
240
- const observer = new IntersectionObserver(
241
- (entries) => {
242
- const entry = entries[0];
243
- if (entry) navStuck = !entry.isIntersecting;
244
- },
245
- { threshold: 0 }
246
- );
247
- observer.observe(el);
248
- return () => observer.disconnect();
249
- });
250
- </script>
251
-
252
- <div class="relative flex">
253
- <div class="mx-auto flex max-w-400 flex-1 flex-col gap-4 px-4 py-6 sm:px-6">
254
- <FeatureHeader
255
- {feature}
256
- saving={featureStore.saving}
257
- {historyOpen}
258
- onToggleHistory={() => (historyOpen = !historyOpen)}
259
- />
260
-
261
- <FeatureHealthStrip {feature} />
262
-
263
- <div bind:this={stuckSentinel} aria-hidden="true" class="h-px"></div>
264
-
265
- <nav
266
- class="sticky top-16 z-20 -mx-4 flex flex-wrap gap-1 border-b border-hairline bg-canvas/95 px-4 backdrop-blur transition-shadow {navStuck
267
- ? 'shadow-[0_4px_8px_-2px_rgba(15,23,42,0.08)]'
268
- : ''}"
269
- >
270
- {#each tabs as tab (tab.key)}
271
- <button
272
- type="button"
273
- class="-mb-px border-b-2 px-4 py-2 text-sm font-medium transition {activeTab === tab.key
274
- ? 'border-brand-700 text-brand-800'
275
- : 'border-transparent text-slate-600 hover:text-slate-900'}"
276
- onclick={() => editorStore.setTopLevelTab(tab.key)}
277
- >
278
- {tab.label}{tab.count !== undefined ? ` (${tab.count})` : ''}
279
- </button>
280
- {/each}
281
- </nav>
282
-
283
- {#key activeTab}
284
- <div in:fade={{ duration: 140, easing: cubicOut }} class="motion-reduce:animate-none! motion-reduce:opacity-100!">
285
- {#if activeTab === 'build'}
286
- <div class="flex flex-col gap-4 lg:flex-row lg:items-start">
287
- <aside
288
- class="w-full shrink-0 lg:sticky lg:top-32 lg:max-h-[calc(100vh-8rem)] lg:w-[16rem] lg:overflow-y-auto xl:w-[18rem]"
289
- >
290
- <SurfaceList
291
- {feature}
292
- selectedId={editorStore.selectedSurfaceId}
293
- onSelect={(id) => editorStore.selectSurface(id)}
294
- />
295
- </aside>
296
- <section class="min-w-0 flex-1">
297
- {#if selectedSurface}
298
- <SurfacePanel
299
- {feature}
300
- surface={selectedSurface}
301
- resources={feature.resources}
302
- personas={feature.personas}
303
- />
304
- {:else}
305
- <div
306
- class="rounded-lg border border-dashed border-hairline bg-white p-8 text-center text-sm text-slate-500"
307
- >
308
- Add a surface to get started.
309
- </div>
310
- {/if}
311
- </section>
312
- <aside
313
- class="w-full shrink-0 lg:sticky lg:top-32 lg:max-h-[calc(100vh-8rem)] lg:overflow-y-auto {editorStore.railCollapsed
314
- ? 'lg:w-12'
315
- : 'lg:w-88 xl:w-104'}"
316
- >
317
- <SidePanel {feature} surface={selectedSurfaceForUse} />
318
- </aside>
319
- </div>
320
- {:else if activeTab === 'resources'}
321
- <section class="rounded-lg border border-hairline bg-white p-4">
322
- <ResourcesManager {feature} />
323
- </section>
324
- {:else if activeTab === 'data'}
325
- <section class="rounded-lg border border-hairline bg-white p-4">
326
- <EntityManager {feature} />
327
- </section>
328
- {:else if activeTab === 'events'}
329
- <section class="rounded-lg border border-hairline bg-white p-4">
330
- <EventsManager {feature} />
331
- </section>
332
- {:else if activeTab === 'invariants'}
333
- <section class="rounded-lg border border-hairline bg-white p-4">
334
- <FeatureInvariantsEditor {feature} />
335
- </section>
336
- {:else}
337
- <section class="rounded-lg border border-hairline bg-white p-4">
338
- <TransitionsManager {feature} />
339
- </section>
340
- {/if}
341
- </div>
342
- {/key}
343
- </div>
344
- {#if historyOpen}
345
- <div class="sticky top-0 z-30 h-screen self-start">
346
- <HistoryPanel bind:open={historyOpen} />
347
- </div>
348
- {/if}
349
- </div>
90
+ // maturity panel's "Fix →" anchor or a global-search result), wait a tick for
91
+ // the surface/tab/capability selection to settle, then scroll the matching
92
+ // DOM element into view and pulse it so the user can see exactly what they
93
+ // searched for. The pulse holds for ~3s (FOCUS_FLASH_MS) long enough to
94
+ // catch the eye after the scroll lands.
95
+ const FOCUS_FLASH_MS = 3000;
96
+ $effect(() => {
97
+ editorStore.focusToken; // re-fire each navigation
98
+ const target = editorStore.focusTarget;
99
+ if (!target) return;
100
+ let cancelled = false;
101
+ let flashed: Element | null = null;
102
+ const timers: ReturnType<typeof setTimeout>[] = [];
103
+ // Clear any leftover highlight from a previous navigation so re-searching
104
+ // never leaves two elements glowing at once.
105
+ document
106
+ .querySelectorAll('.focus-flash')
107
+ .forEach((el) => el.classList.remove('focus-flash'));
108
+ const tryFocus = (attempt = 0) => {
109
+ if (cancelled) return;
110
+ const el = document.querySelector(`[data-focus-target="${CSS.escape(target)}"]`);
111
+ if (el) {
112
+ el.scrollIntoView({ behavior: 'smooth', block: 'center' });
113
+ // Restart the CSS animation cleanly even if the class lingered.
114
+ el.classList.remove('focus-flash');
115
+ void (el as HTMLElement).offsetWidth; // reflow so the animation replays
116
+ el.classList.add('focus-flash');
117
+ flashed = el;
118
+ timers.push(setTimeout(() => el.classList.remove('focus-flash'), FOCUS_FLASH_MS + 200));
119
+ return;
120
+ }
121
+ // The element may not be in the DOM yet (tab switching, action
122
+ // expanding). Retry a handful of times before giving up.
123
+ if (attempt < 6) {
124
+ timers.push(setTimeout(() => tryFocus(attempt + 1), 80));
125
+ }
126
+ };
127
+ timers.push(setTimeout(() => tryFocus(), 60));
128
+ return () => {
129
+ cancelled = true;
130
+ for (const t of timers) clearTimeout(t);
131
+ // Drop the highlight if we navigate away mid-pulse.
132
+ flashed?.classList.remove('focus-flash');
133
+ };
134
+ });
135
+
136
+ // ───────── URL ⇄ editorStore sync ────────────────────────────────────
137
+ //
138
+ // The browser URL is the source of truth for navigation: top-level tab,
139
+ // selected surface, surface-panel tab. Two effects keep them in lockstep:
140
+ // • URL → store: only re-runs when the URL changes (back/forward, deep
141
+ // links). Store reads are wrapped in `untrack` so the effect cannot
142
+ // re-fire when its own writes propagate.
143
+ // • store → URL: only re-runs when the store changes. URL reads happen
144
+ // inside `untrack` for the same reason. Without this, a click on a
145
+ // surface mutates the store, the other effect immediately fires reading
146
+ // the still-stale URL, and reverts the click.
147
+
148
+ $effect(() => {
149
+ const url = page.url;
150
+ const tabParam = url.searchParams.get('tab');
151
+ const surfaceParam = url.searchParams.get('surface');
152
+ const panelParam = url.searchParams.get('panel');
153
+ // Optional one-shot deep-link focus (e.g. from global search): the value of
154
+ // a `data-focus-target` attribute the focus observer below scrolls to and
155
+ // pulses. Read here so it survives a fresh page load; the store→URL effect
156
+ // strips it from the URL afterward, which is fine — it's a one-time pulse.
157
+ const focusParam = url.searchParams.get('focus');
158
+
159
+ untrack(() => {
160
+ const tab =
161
+ tabParam && VALID_TOP_TABS.has(tabParam)
162
+ ? (tabParam as typeof editorStore.topLevelTab)
163
+ : 'build';
164
+ if (editorStore.topLevelTab !== tab) {
165
+ editorStore.setTopLevelTab(tab);
166
+ }
167
+
168
+ const surfaceId = surfaceParam ? asSurfaceId(surfaceParam) : null;
169
+ if (editorStore.selectedSurfaceId !== surfaceId) {
170
+ editorStore.selectSurface(surfaceId);
171
+ }
172
+
173
+ const panel: SurfacePanelTab =
174
+ panelParam && VALID_PANEL_TABS.has(panelParam)
175
+ ? (panelParam as SurfacePanelTab)
176
+ : 'actions';
177
+ if (editorStore.surfacePanelTab !== panel) {
178
+ editorStore.setSurfacePanelTab(panel);
179
+ }
180
+
181
+ if (focusParam) {
182
+ // Open the dropdown for the exact target so the user sees the searched
183
+ // item itself, not a collapsed header. An `action:<id>` focus selects
184
+ // that capability, which expands its card (ActionsEditor renders the
185
+ // selected action expanded). Runs AFTER selectSurface above, which
186
+ // would otherwise reset the selected capability to null.
187
+ const actionMatch = /^action:(.+)$/.exec(focusParam);
188
+ if (actionMatch?.[1]) {
189
+ editorStore.selectCapability(asActionId(actionMatch[1]));
190
+ }
191
+ // Bump the token so re-navigating to the same target still re-fires the
192
+ // focus observer; writes propagate even from inside untrack.
193
+ editorStore.focusTarget = focusParam;
194
+ editorStore.focusToken += 1;
195
+ }
196
+ });
197
+ });
198
+
199
+ $effect(() => {
200
+ const tab = editorStore.topLevelTab;
201
+ const surfaceId = editorStore.selectedSurfaceId;
202
+ const panel = editorStore.surfacePanelTab;
203
+
204
+ untrack(() => {
205
+ const params = new URLSearchParams();
206
+ if (tab !== 'build') params.set('tab', tab);
207
+ if (surfaceId) params.set('surface', surfaceId);
208
+ if (panel !== 'actions') params.set('panel', panel);
209
+ const qs = params.toString();
210
+ const desired = qs ? `?${qs}` : '';
211
+ const current = page.url.search;
212
+ if (desired === current) return;
213
+ void goto(`${page.url.pathname}${desired}`, {
214
+ keepFocus: true,
215
+ noScroll: true,
216
+ replaceState: false
217
+ });
218
+ });
219
+ });
220
+
221
+ // Effective data = every namespace touched by the model (deduced + declared).
222
+ // Counter must reflect what the Entity tab actually shows, not just stored
223
+ // overrides.
224
+ const effectiveDataCount = $derived(getEffectiveEntities(feature).length);
225
+ const eventsCount = $derived(buildEventCatalog(feature).length);
226
+ const transitionsCount = $derived(buildTransitionCatalog(feature).length);
227
+
228
+ const tabs: ReadonlyArray<{ key: TopTab; label: string; count?: number }> = $derived([
229
+ { key: 'build', label: 'Build', count: feature.surfaces.length },
230
+ { key: 'resources', label: 'Resources', count: feature.resources.length },
231
+ { key: 'data', label: 'Entity', count: effectiveDataCount },
232
+ { key: 'events', label: 'Events', count: eventsCount },
233
+ { key: 'transitions', label: 'Transitions', count: transitionsCount },
234
+ {
235
+ key: 'invariants',
236
+ label: 'Invariants',
237
+ count: feature.featureInvariants?.length ?? 0
238
+ },
239
+ {
240
+ key: 'goals',
241
+ label: 'Reachability goals',
242
+ count: feature.reachabilityGoals?.length ?? 0
243
+ }
244
+ ]);
245
+
246
+ // Global undo/redo shortcuts. We deliberately ignore the event when focus
247
+ // is in a text editor. Native input/textarea undo handles per-keystroke
248
+ // text edits, and our store-level undo only exists for committed mutations
249
+ // (mutate() calls), not in-progress text drafts.
250
+ $effect(() => {
251
+ const isEditable = (el: EventTarget | null): boolean => {
252
+ if (!(el instanceof HTMLElement)) return false;
253
+ const tag = el.tagName;
254
+ if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return true;
255
+ return el.isContentEditable;
256
+ };
257
+ const onKeydown = (event: KeyboardEvent) => {
258
+ const mod = event.ctrlKey || event.metaKey;
259
+ if (!mod) return;
260
+ const key = event.key.toLowerCase();
261
+ const isUndo = key === 'z' && !event.shiftKey;
262
+ const isRedo = (key === 'z' && event.shiftKey) || key === 'y';
263
+ if (!isUndo && !isRedo) return;
264
+ if (isEditable(event.target)) return;
265
+ event.preventDefault();
266
+ if (isUndo) featureStore.undo();
267
+ else featureStore.redo();
268
+ };
269
+ window.addEventListener('keydown', onKeydown);
270
+ return () => window.removeEventListener('keydown', onKeydown);
271
+ });
272
+
273
+ // Detect when the tab nav is pinned to the top of the viewport. A 1px
274
+ // sentinel sits just above the nav; when it scrolls out of view the nav has
275
+ // crossed top: 0 and we add a shadow to lift it off the content scrolling
276
+ // behind it.
277
+ let navStuck = $state(false);
278
+ let stuckSentinel = $state<HTMLDivElement | null>(null);
279
+ let historyOpen = $state(false);
280
+
281
+ $effect(() => {
282
+ const el = stuckSentinel;
283
+ if (!el) return;
284
+ const observer = new IntersectionObserver(
285
+ (entries) => {
286
+ const entry = entries[0];
287
+ if (entry) navStuck = !entry.isIntersecting;
288
+ },
289
+ { threshold: 0 }
290
+ );
291
+ observer.observe(el);
292
+ return () => observer.disconnect();
293
+ });
294
+ </script>
295
+
296
+ <div class="relative flex">
297
+ <div class="mx-auto flex max-w-400 flex-1 flex-col gap-4 px-4 py-6 sm:px-6">
298
+ <FeatureHeader
299
+ {feature}
300
+ saving={featureStore.saving}
301
+ {historyOpen}
302
+ onToggleHistory={() => (historyOpen = !historyOpen)}
303
+ />
304
+
305
+ <FeatureHealthStrip {feature} />
306
+
307
+ <div bind:this={stuckSentinel} aria-hidden="true" class="h-px"></div>
308
+
309
+ <nav
310
+ class="sticky top-16 z-20 -mx-4 flex flex-wrap gap-1 border-b border-hairline bg-canvas/95 px-4 backdrop-blur transition-shadow {navStuck
311
+ ? 'shadow-[0_4px_8px_-2px_rgba(15,23,42,0.08)]'
312
+ : ''}"
313
+ >
314
+ {#each tabs as tab (tab.key)}
315
+ <button
316
+ type="button"
317
+ class="-mb-px border-b-2 px-4 py-2 text-sm font-medium transition {activeTab === tab.key
318
+ ? 'border-brand-700 text-brand-800'
319
+ : 'border-transparent text-slate-600 hover:text-slate-900'}"
320
+ onclick={() => editorStore.setTopLevelTab(tab.key)}
321
+ >
322
+ {tab.label}{tab.count !== undefined ? ` (${tab.count})` : ''}
323
+ </button>
324
+ {/each}
325
+ </nav>
326
+
327
+ {#key activeTab}
328
+ <div in:fade={{ duration: 140, easing: cubicOut }} class="motion-reduce:animate-none! motion-reduce:opacity-100!">
329
+ {#if activeTab === 'build'}
330
+ <div class="flex flex-col gap-4 lg:flex-row lg:items-start">
331
+ <aside
332
+ class="w-full shrink-0 lg:sticky lg:top-32 lg:max-h-[calc(100vh-8rem)] lg:w-[16rem] lg:overflow-y-auto xl:w-[18rem]"
333
+ >
334
+ <SurfaceList
335
+ {feature}
336
+ selectedId={editorStore.selectedSurfaceId}
337
+ onSelect={(id) => editorStore.selectSurface(id)}
338
+ />
339
+ </aside>
340
+ <section class="min-w-0 flex-1">
341
+ {#if selectedSurface}
342
+ <SurfacePanel
343
+ {feature}
344
+ surface={selectedSurface}
345
+ resources={feature.resources}
346
+ personas={feature.personas}
347
+ />
348
+ {:else}
349
+ <div
350
+ class="rounded-lg border border-dashed border-hairline bg-white p-8 text-center text-sm text-slate-500"
351
+ >
352
+ Add a surface to get started.
353
+ </div>
354
+ {/if}
355
+ </section>
356
+ <aside
357
+ class="w-full shrink-0 lg:sticky lg:top-32 lg:max-h-[calc(100vh-8rem)] lg:overflow-y-auto {editorStore.railCollapsed
358
+ ? 'lg:w-12'
359
+ : 'lg:w-88 xl:w-104'}"
360
+ >
361
+ <SidePanel {feature} surface={selectedSurfaceForUse} />
362
+ </aside>
363
+ </div>
364
+ {:else if activeTab === 'resources'}
365
+ <section class="rounded-lg border border-hairline bg-white p-4">
366
+ <ResourcesManager {feature} />
367
+ </section>
368
+ {:else if activeTab === 'data'}
369
+ <section class="rounded-lg border border-hairline bg-white p-4">
370
+ <EntityManager {feature} />
371
+ </section>
372
+ {:else if activeTab === 'events'}
373
+ <section class="rounded-lg border border-hairline bg-white p-4">
374
+ <EventsManager {feature} />
375
+ </section>
376
+ {:else if activeTab === 'invariants'}
377
+ <section class="rounded-lg border border-hairline bg-white p-4">
378
+ <FeatureInvariantsEditor {feature} />
379
+ </section>
380
+ {:else if activeTab === 'goals'}
381
+ <section class="rounded-lg border border-hairline bg-white p-4">
382
+ <ReachabilityGoalsEditor {feature} />
383
+ </section>
384
+ {:else}
385
+ <section class="rounded-lg border border-hairline bg-white p-4">
386
+ <TransitionsManager {feature} />
387
+ </section>
388
+ {/if}
389
+ </div>
390
+ {/key}
391
+ </div>
392
+ {#if historyOpen}
393
+ <div class="sticky top-0 z-30 h-screen self-start">
394
+ <HistoryPanel bind:open={historyOpen} />
395
+ </div>
396
+ {/if}
397
+ </div>