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,20 +1,20 @@
1
- import type { Feature } from '$features/behavior-model/domain/entities/Feature';
2
- import {
3
- asActionId,
4
- asEffectId,
5
- asFeatureId,
6
- asInvariantId,
7
- asParameterId,
8
- asRuleId,
9
- asStateDefinitionId,
10
- asSurfaceId
11
- } from '$features/behavior-model/domain/value-objects/ids';
12
- import { asEventName } from '$features/behavior-model/domain/value-objects/EventName';
13
- import { asStatePath } from '$features/behavior-model/domain/value-objects/StatePath';
14
-
15
- const now = '2026-05-08T12:00:00.000Z';
16
-
17
- const CATALOG_ID = asSurfaceId('seed-shop-catalog');
1
+ import type { Feature } from '$features/behavior-model/domain/entities/Feature';
2
+ import {
3
+ asActionId,
4
+ asEffectId,
5
+ asFeatureId,
6
+ asInvariantId,
7
+ asParameterId,
8
+ asRuleId,
9
+ asStateDefinitionId,
10
+ asSurfaceId
11
+ } from '$features/behavior-model/domain/value-objects/ids';
12
+ import { asEventName } from '$features/behavior-model/domain/value-objects/EventName';
13
+ import { asStatePath } from '$features/behavior-model/domain/value-objects/StatePath';
14
+
15
+ const now = '2026-05-08T12:00:00.000Z';
16
+
17
+ const CATALOG_ID = asSurfaceId('seed-shop-catalog');
18
18
  const CART_ID = asSurfaceId('seed-shop-cart');
19
19
  const CHECKOUT_ID = asSurfaceId('seed-shop-checkout');
20
20
  const ORDER_ID = asSurfaceId('seed-shop-order');
@@ -131,956 +131,956 @@ const withRequiredDescriptions = (feature: Feature): Feature =>
131
131
  );
132
132
 
133
133
  const storefrontFeatureData: Feature = {
134
- id: asFeatureId('seed-shop'),
135
- name: 'E-commerce storefront',
136
- description:
137
- 'Amazon-like online store. Demonstrates a full multi-surface flow with catalog, cart, checkout, and order confirmation. Covers stock validation, authentication gates, coupon logic, free-shipping thresholds, fraud limits, cancellation policy, and surface transitions.',
138
- createdAt: now,
139
- updatedAt: now,
140
- personas: [],
141
- resources: [],
142
- entities: [],
143
- surfaces: [
144
- // ── Catalog ────────────────────────────────────────────────────────────
145
- {
146
- id: CATALOG_ID,
147
- name: 'Catalog',
148
- type: 'screen',
149
- description: 'Browse and search products. Add items directly to the cart.',
150
- stateDefinitions: [
151
- {
152
- id: asStateDefinitionId('seed-shop-catalog-state-query'),
153
- path: asStatePath('search.query'),
154
- type: 'string',
155
- defaultValue: '',
156
- description: 'Active search query.'
157
- },
158
- {
159
- id: asStateDefinitionId('seed-shop-catalog-state-results'),
160
- path: asStatePath('search.resultCount'),
161
- type: 'number',
162
- defaultValue: 0,
163
- description: 'Number of products returned by the current query.'
164
- },
165
- {
166
- id: asStateDefinitionId('seed-shop-catalog-state-stock'),
167
- path: asStatePath('product.stock'),
168
- type: 'number',
169
- defaultValue: 12,
170
- description: 'Available stock for the focused product.'
171
- },
172
- {
173
- id: asStateDefinitionId('seed-shop-catalog-state-price'),
174
- path: asStatePath('product.price'),
175
- type: 'number',
176
- defaultValue: 1999,
177
- description: 'Unit price of the focused product, in cents.'
178
- },
179
- {
180
- id: asStateDefinitionId('seed-shop-catalog-state-cart-count'),
181
- path: asStatePath('cart.itemCount'),
182
- type: 'number',
183
- defaultValue: 0
184
- },
185
- {
186
- id: asStateDefinitionId('seed-shop-catalog-state-cart-subtotal'),
187
- path: asStatePath('cart.subtotal'),
188
- type: 'number',
189
- defaultValue: 0,
190
- description: 'Cart subtotal in cents.'
191
- }
192
- ],
193
- rules: [],
194
- invariants: [
195
- {
196
- id: asInvariantId('seed-shop-catalog-invariant-stock-non-negative'),
197
- name: 'product.stock is non-negative',
198
- condition: {
199
- left: asStatePath('product.stock'),
200
- operator: 'greater_than',
201
- right: -1
202
- },
203
- message: 'Stock must never go below zero.'
204
- }
205
- ],
206
- transitions: [
207
- {
208
- id: asEffectId('seed-shop-catalog-transition-cart') as never,
209
- target: CART_ID,
210
- label: 'View cart'
211
- }
212
- ],
213
- actions: [
214
- {
215
- id: asActionId('seed-shop-cap-search'),
216
- name: 'Search products',
217
- intent: 'Run a keyword search and update the visible result list.',
218
- parameters: [
219
- {
220
- id: asParameterId('seed-shop-param-query'),
221
- name: 'query',
222
- type: 'string',
223
- required: true,
224
- description: 'The search keywords typed by the user.'
225
- }
226
- ],
227
- requiredStates: [],
228
- rules: [],
229
- invariants: [],
230
- effects: [
231
- {
232
- id: asEffectId('seed-shop-effect-set-query'),
233
- type: 'set_state',
234
- path: asStatePath('search.query'),
235
- value: 'placeholder'
236
- },
237
- {
238
- id: asEffectId('seed-shop-effect-emit-search'),
239
- type: 'emit_event',
240
- event: asEventName('catalog.search.executed')
241
- }
242
- ],
243
- emittedEvents: [asEventName('catalog.search.executed')],
244
- transitions: []
245
- },
246
- {
247
- id: asActionId('seed-shop-cap-add-to-cart'),
248
- name: 'Add to cart',
249
- intent:
250
- 'Add the focused product to the cart, validating stock and updating cart counters.',
251
- parameters: [
252
- {
253
- id: asParameterId('seed-shop-param-quantity'),
254
- name: 'quantity',
255
- type: 'number',
256
- required: true,
257
- defaultValue: 1,
258
- description: 'Number of units to add (1–10).'
259
- }
260
- ],
261
- requiredStates: [
262
- asStatePath('product.stock'),
263
- asStatePath('cart.itemCount'),
264
- asStatePath('cart.subtotal')
265
- ],
266
- rules: [
267
- {
268
- id: asRuleId('seed-shop-rule-out-of-stock'),
269
- category: 'business',
270
- condition: {
271
- left: asStatePath('product.stock'),
272
- operator: 'lower_than',
273
- right: 1
274
- },
275
- effect: {
276
- id: asEffectId('seed-shop-effect-out-of-stock'),
277
- type: 'block_action',
278
- reason: 'Out of stock'
279
- }
280
- },
281
- {
282
- id: asRuleId('seed-shop-rule-quantity-bound'),
283
- category: 'validation',
284
- condition: {
285
- left: asStatePath('product.stock'),
286
- operator: 'lower_than',
287
- right: 1
288
- },
289
- effect: {
290
- id: asEffectId('seed-shop-effect-quantity-bound'),
291
- type: 'show_message',
292
- message: 'Cannot add more than the available stock.',
293
- tone: 'warning'
294
- },
295
- description:
296
- 'In a real system the quantity would be compared to product.stock. This rule keeps it simple.'
297
- }
298
- ],
299
- invariants: [],
300
- effects: [
301
- {
302
- id: asEffectId('seed-shop-effect-inc-cart-count'),
303
- type: 'set_state',
304
- path: asStatePath('cart.itemCount'),
305
- value: 1
306
- },
307
- {
308
- id: asEffectId('seed-shop-effect-decrement-stock'),
309
- type: 'set_state',
310
- path: asStatePath('product.stock'),
311
- value: 11
312
- },
313
- {
314
- id: asEffectId('seed-shop-effect-add-subtotal'),
315
- type: 'set_state',
316
- path: asStatePath('cart.subtotal'),
317
- value: 1999
318
- },
319
- {
320
- id: asEffectId('seed-shop-effect-emit-added'),
321
- type: 'emit_event',
322
- event: asEventName('cart.item.added')
323
- },
324
- {
325
- id: asEffectId('seed-shop-effect-message-added'),
326
- type: 'show_message',
327
- message: 'Added to cart',
328
- tone: 'success'
329
- }
330
- ],
331
- emittedEvents: [asEventName('cart.item.added')],
332
- transitions: []
333
- },
334
- {
335
- id: asActionId('seed-shop-cap-go-to-cart'),
336
- name: 'Go to cart',
337
- intent: 'Navigate from the catalog to the cart surface.',
338
- parameters: [],
339
- requiredStates: [],
340
- rules: [
341
- {
342
- id: asRuleId('seed-shop-rule-empty-cart-block-nav'),
343
- category: 'ux_feedback',
344
- condition: {
345
- left: asStatePath('cart.itemCount'),
346
- operator: 'equals',
347
- right: 0
348
- },
349
- effect: {
350
- id: asEffectId('seed-shop-effect-empty-cart-block'),
351
- type: 'block_action',
352
- reason: 'Your cart is empty'
353
- }
354
- }
355
- ],
356
- invariants: [],
357
- effects: [
358
- {
359
- id: asEffectId('seed-shop-effect-transition-cart'),
360
- type: 'transition_surface',
361
- target: CART_ID
362
- }
363
- ],
364
- emittedEvents: [asEventName('navigation.cart.opened')],
365
- transitions: [
366
- {
367
- id: asEffectId('seed-shop-catalog-trans-2') as never,
368
- target: CART_ID
369
- }
370
- ]
371
- }
372
- ]
373
- },
374
-
375
- // ── Cart ───────────────────────────────────────────────────────────────
376
- {
377
- id: CART_ID,
378
- name: 'Cart',
379
- type: 'screen',
380
- description: 'Review items, change quantities, apply a coupon, and proceed to checkout.',
381
- stateDefinitions: [
382
- {
383
- id: asStateDefinitionId('seed-shop-cart-state-count'),
384
- path: asStatePath('cart.itemCount'),
385
- type: 'number',
386
- defaultValue: 2
387
- },
388
- {
389
- id: asStateDefinitionId('seed-shop-cart-state-subtotal'),
390
- path: asStatePath('cart.subtotal'),
391
- type: 'number',
392
- defaultValue: 4598,
393
- description: 'Subtotal in cents.'
394
- },
395
- {
396
- id: asStateDefinitionId('seed-shop-cart-state-shipping'),
397
- path: asStatePath('cart.shipping'),
398
- type: 'number',
399
- defaultValue: 599
400
- },
401
- {
402
- id: asStateDefinitionId('seed-shop-cart-state-total'),
403
- path: asStatePath('cart.total'),
404
- type: 'number',
405
- defaultValue: 5197
406
- },
407
- {
408
- id: asStateDefinitionId('seed-shop-cart-state-coupon'),
409
- path: asStatePath('coupon.code'),
410
- type: 'string',
411
- defaultValue: '',
412
- description: 'Applied coupon code, empty when none.'
413
- },
414
- {
415
- id: asStateDefinitionId('seed-shop-cart-state-coupon-valid'),
416
- path: asStatePath('coupon.applied'),
417
- type: 'boolean',
418
- defaultValue: false
419
- },
420
- {
421
- id: asStateDefinitionId('seed-shop-cart-state-user-auth'),
422
- path: asStatePath('user.authenticated'),
423
- type: 'boolean',
424
- defaultValue: false
425
- }
426
- ],
427
- rules: [],
428
- invariants: [
429
- {
430
- id: asInvariantId('seed-shop-cart-invariant-count-non-negative'),
431
- name: 'cart.itemCount is non-negative',
432
- condition: {
433
- left: asStatePath('cart.itemCount'),
434
- operator: 'greater_than',
435
- right: -1
436
- },
437
- message: 'Cart count must be ≥ 0.'
438
- },
439
- {
440
- id: asInvariantId('seed-shop-cart-invariant-subtotal-non-negative'),
441
- name: 'cart.subtotal is non-negative',
442
- condition: {
443
- left: asStatePath('cart.subtotal'),
444
- operator: 'greater_than',
445
- right: -1
446
- },
447
- message: 'Subtotal must be ≥ 0.'
448
- }
449
- ],
450
- transitions: [
451
- { id: asEffectId('seed-shop-cart-trans-back') as never, target: CATALOG_ID, label: 'Back to catalog' },
452
- { id: asEffectId('seed-shop-cart-trans-checkout') as never, target: CHECKOUT_ID, label: 'Checkout' }
453
- ],
454
- actions: [
455
- {
456
- id: asActionId('seed-shop-cap-remove-item'),
457
- name: 'Remove item',
458
- intent: 'Remove an item from the cart and update totals.',
459
- parameters: [],
460
- requiredStates: [asStatePath('cart.itemCount')],
461
- rules: [
462
- {
463
- id: asRuleId('seed-shop-rule-empty-remove'),
464
- category: 'ux_feedback',
465
- condition: {
466
- left: asStatePath('cart.itemCount'),
467
- operator: 'equals',
468
- right: 0
469
- },
470
- effect: {
471
- id: asEffectId('seed-shop-effect-empty-remove'),
472
- type: 'block_action',
473
- reason: 'Cart is already empty'
474
- }
475
- }
476
- ],
477
- invariants: [],
478
- effects: [
479
- {
480
- id: asEffectId('seed-shop-effect-dec-count'),
481
- type: 'set_state',
482
- path: asStatePath('cart.itemCount'),
483
- value: 1
484
- },
485
- {
486
- id: asEffectId('seed-shop-effect-dec-subtotal'),
487
- type: 'set_state',
488
- path: asStatePath('cart.subtotal'),
489
- value: 2299
490
- },
491
- {
492
- id: asEffectId('seed-shop-effect-emit-removed'),
493
- type: 'emit_event',
494
- event: asEventName('cart.item.removed')
495
- }
496
- ],
497
- emittedEvents: [asEventName('cart.item.removed')],
498
- transitions: []
499
- },
500
- {
501
- id: asActionId('seed-shop-cap-apply-coupon'),
502
- name: 'Apply coupon',
503
- intent: 'Validate and apply a discount coupon to the cart.',
504
- parameters: [
505
- {
506
- id: asParameterId('seed-shop-param-coupon'),
507
- name: 'code',
508
- type: 'string',
509
- required: true,
510
- description: 'Coupon code to validate.'
511
- }
512
- ],
513
- requiredStates: [asStatePath('coupon.applied'), asStatePath('cart.subtotal')],
514
- rules: [
515
- {
516
- id: asRuleId('seed-shop-rule-coupon-already-applied'),
517
- category: 'business',
518
- condition: {
519
- left: asStatePath('coupon.applied'),
520
- operator: 'is_true'
521
- },
522
- effect: {
523
- id: asEffectId('seed-shop-effect-coupon-already-applied'),
524
- type: 'block_action',
525
- reason: 'A coupon is already applied. Remove it first.'
526
- }
527
- },
528
- {
529
- id: asRuleId('seed-shop-rule-coupon-min-cart'),
530
- category: 'business',
531
- condition: {
532
- left: asStatePath('cart.subtotal'),
533
- operator: 'lower_than',
534
- right: 1500
535
- },
536
- effect: {
537
- id: asEffectId('seed-shop-effect-coupon-min-cart'),
538
- type: 'block_action',
539
- reason: 'Coupons require a $15 minimum cart total.'
540
- }
541
- }
542
- ],
543
- invariants: [],
544
- effects: [
545
- {
546
- id: asEffectId('seed-shop-effect-set-coupon'),
547
- type: 'set_state',
548
- path: asStatePath('coupon.code'),
549
- value: 'SAVE10'
550
- },
551
- {
552
- id: asEffectId('seed-shop-effect-mark-coupon-applied'),
553
- type: 'set_state',
554
- path: asStatePath('coupon.applied'),
555
- value: true
556
- },
557
- {
558
- id: asEffectId('seed-shop-effect-emit-coupon'),
559
- type: 'emit_event',
560
- event: asEventName('cart.coupon.applied')
561
- },
562
- {
563
- id: asEffectId('seed-shop-effect-coupon-message'),
564
- type: 'show_message',
565
- message: 'Coupon applied. 10% off',
566
- tone: 'success'
567
- }
568
- ],
569
- emittedEvents: [asEventName('cart.coupon.applied')],
570
- transitions: []
571
- },
572
- {
573
- id: asActionId('seed-shop-cap-checkout'),
574
- name: 'Proceed to checkout',
575
- intent: 'Move from the cart to the checkout flow.',
576
- parameters: [],
577
- requiredStates: [
578
- asStatePath('cart.itemCount'),
579
- asStatePath('user.authenticated')
580
- ],
581
- rules: [
582
- {
583
- id: asRuleId('seed-shop-rule-empty-cart-checkout'),
584
- category: 'business',
585
- condition: {
586
- left: asStatePath('cart.itemCount'),
587
- operator: 'equals',
588
- right: 0
589
- },
590
- effect: {
591
- id: asEffectId('seed-shop-effect-empty-cart-checkout'),
592
- type: 'block_action',
593
- reason: 'Add something to your cart before checking out.'
594
- }
595
- },
596
- {
597
- id: asRuleId('seed-shop-rule-not-authenticated'),
598
- category: 'permissions',
599
- condition: {
600
- left: asStatePath('user.authenticated'),
601
- operator: 'is_false'
602
- },
603
- effect: {
604
- id: asEffectId('seed-shop-effect-must-login'),
605
- type: 'block_action',
606
- reason: 'Sign in to continue to checkout.'
607
- }
608
- },
609
- {
610
- id: asRuleId('seed-shop-rule-free-shipping'),
611
- category: 'ux_feedback',
612
- condition: {
613
- left: asStatePath('cart.subtotal'),
614
- operator: 'greater_than',
615
- right: 3499
616
- },
617
- effect: {
618
- id: asEffectId('seed-shop-effect-free-shipping'),
619
- type: 'show_message',
620
- message: 'You qualify for free shipping.',
621
- tone: 'info'
622
- }
623
- }
624
- ],
625
- invariants: [],
626
- effects: [
627
- {
628
- id: asEffectId('seed-shop-effect-transition-checkout'),
629
- type: 'transition_surface',
630
- target: CHECKOUT_ID
631
- },
632
- {
633
- id: asEffectId('seed-shop-effect-emit-checkout-started'),
634
- type: 'emit_event',
635
- event: asEventName('checkout.started')
636
- }
637
- ],
638
- emittedEvents: [asEventName('checkout.started')],
639
- transitions: []
640
- }
641
- ]
642
- },
643
-
644
- // ── Checkout ───────────────────────────────────────────────────────────
645
- {
646
- id: CHECKOUT_ID,
647
- name: 'Checkout',
648
- type: 'workflow',
649
- description: 'Multi-step checkout: shipping address → payment method → place order.',
650
- stateDefinitions: [
651
- {
652
- id: asStateDefinitionId('seed-shop-checkout-state-step'),
653
- path: asStatePath('checkout.step'),
654
- type: 'enum',
655
- enumValues: ['address', 'payment', 'review'],
656
- defaultValue: 'address'
657
- },
658
- {
659
- id: asStateDefinitionId('seed-shop-checkout-state-address'),
660
- path: asStatePath('shipping.addressProvided'),
661
- type: 'boolean',
662
- defaultValue: false
663
- },
664
- {
665
- id: asStateDefinitionId('seed-shop-checkout-state-payment'),
666
- path: asStatePath('payment.method'),
667
- type: 'enum',
668
- enumValues: ['none', 'card', 'paypal', 'gift_card'],
669
- defaultValue: 'none'
670
- },
671
- {
672
- id: asStateDefinitionId('seed-shop-checkout-state-amount'),
673
- path: asStatePath('order.amount'),
674
- type: 'number',
675
- defaultValue: 5197,
676
- description: 'Final order amount in cents.'
677
- },
678
- {
679
- id: asStateDefinitionId('seed-shop-checkout-state-fraud-flag'),
680
- path: asStatePath('fraud.flagged'),
681
- type: 'boolean',
682
- defaultValue: false
683
- },
684
- {
685
- id: asStateDefinitionId('seed-shop-checkout-state-user-auth'),
686
- path: asStatePath('user.authenticated'),
687
- type: 'boolean',
688
- defaultValue: true
689
- }
690
- ],
691
- // Surface-level guard: must be authenticated to do anything in checkout.
692
- rules: [
693
- {
694
- id: asRuleId('seed-shop-checkout-surface-rule-auth'),
695
- category: 'security',
696
- condition: {
697
- left: asStatePath('user.authenticated'),
698
- operator: 'is_false'
699
- },
700
- effect: {
701
- id: asEffectId('seed-shop-checkout-effect-must-auth'),
702
- type: 'block_action',
703
- reason: 'Sign in required to access checkout.'
704
- },
705
- description: 'Cross-cutting: every action on this surface requires an authenticated user.'
706
- }
707
- ],
708
- invariants: [
709
- {
710
- id: asInvariantId('seed-shop-checkout-invariant-amount-positive'),
711
- name: 'order.amount is positive',
712
- condition: {
713
- left: asStatePath('order.amount'),
714
- operator: 'greater_than',
715
- right: 0
716
- },
717
- message: 'Order amount must be > 0.'
718
- }
719
- ],
720
- transitions: [
721
- { id: asEffectId('seed-shop-checkout-trans-back') as never, target: CART_ID, label: 'Back to cart' },
722
- { id: asEffectId('seed-shop-checkout-trans-order') as never, target: ORDER_ID, label: 'Order confirmation' }
723
- ],
724
- actions: [
725
- {
726
- id: asActionId('seed-shop-cap-confirm-address'),
727
- name: 'Confirm shipping address',
728
- intent: 'Persist the shipping address and advance to payment.',
729
- parameters: [
730
- {
731
- id: asParameterId('seed-shop-param-postal-code'),
732
- name: 'postalCode',
733
- type: 'string',
734
- required: true
735
- }
736
- ],
737
- requiredStates: [asStatePath('checkout.step')],
738
- rules: [
739
- {
740
- id: asRuleId('seed-shop-rule-wrong-step-address'),
741
- category: 'business',
742
- condition: {
743
- left: asStatePath('checkout.step'),
744
- operator: 'not_equals',
745
- right: 'address'
746
- },
747
- effect: {
748
- id: asEffectId('seed-shop-effect-wrong-step-address'),
749
- type: 'block_action',
750
- reason: 'You already passed the address step.'
751
- }
752
- }
753
- ],
754
- invariants: [],
755
- effects: [
756
- {
757
- id: asEffectId('seed-shop-effect-mark-address-provided'),
758
- type: 'set_state',
759
- path: asStatePath('shipping.addressProvided'),
760
- value: true
761
- },
762
- {
763
- id: asEffectId('seed-shop-effect-advance-payment'),
764
- type: 'set_state',
765
- path: asStatePath('checkout.step'),
766
- value: 'payment'
767
- },
768
- {
769
- id: asEffectId('seed-shop-effect-emit-address'),
770
- type: 'emit_event',
771
- event: asEventName('checkout.address.confirmed')
772
- }
773
- ],
774
- emittedEvents: [asEventName('checkout.address.confirmed')],
775
- transitions: []
776
- },
777
- {
778
- id: asActionId('seed-shop-cap-select-payment'),
779
- name: 'Select payment method',
780
- intent: 'Pick a payment method and advance to the review step.',
781
- parameters: [
782
- {
783
- id: asParameterId('seed-shop-param-payment'),
784
- name: 'method',
785
- type: 'enum',
786
- required: true,
787
- enumValues: ['card', 'paypal', 'gift_card']
788
- }
789
- ],
790
- requiredStates: [
791
- asStatePath('checkout.step'),
792
- asStatePath('shipping.addressProvided')
793
- ],
794
- rules: [
795
- {
796
- id: asRuleId('seed-shop-rule-no-address'),
797
- category: 'business',
798
- condition: {
799
- left: asStatePath('shipping.addressProvided'),
800
- operator: 'is_false'
801
- },
802
- effect: {
803
- id: asEffectId('seed-shop-effect-no-address'),
804
- type: 'block_action',
805
- reason: 'Confirm a shipping address first.'
806
- }
807
- },
808
- {
809
- id: asRuleId('seed-shop-rule-wrong-step-payment'),
810
- category: 'business',
811
- condition: {
812
- left: asStatePath('checkout.step'),
813
- operator: 'not_equals',
814
- right: 'payment'
815
- },
816
- effect: {
817
- id: asEffectId('seed-shop-effect-wrong-step-payment'),
818
- type: 'block_action',
819
- reason: 'You are not on the payment step.'
820
- }
821
- }
822
- ],
823
- invariants: [],
824
- effects: [
825
- {
826
- id: asEffectId('seed-shop-effect-set-payment'),
827
- type: 'set_state',
828
- path: asStatePath('payment.method'),
829
- value: 'card'
830
- },
831
- {
832
- id: asEffectId('seed-shop-effect-advance-review'),
833
- type: 'set_state',
834
- path: asStatePath('checkout.step'),
835
- value: 'review'
836
- },
837
- {
838
- id: asEffectId('seed-shop-effect-emit-payment'),
839
- type: 'emit_event',
840
- event: asEventName('checkout.payment.selected')
841
- }
842
- ],
843
- emittedEvents: [asEventName('checkout.payment.selected')],
844
- transitions: []
845
- },
846
- {
847
- id: asActionId('seed-shop-cap-place-order'),
848
- name: 'Place order',
849
- intent:
850
- 'Finalize the order, run fraud checks, and transition to the confirmation surface.',
851
- parameters: [],
852
- requiredStates: [
853
- asStatePath('checkout.step'),
854
- asStatePath('payment.method'),
855
- asStatePath('order.amount')
856
- ],
857
- rules: [
858
- {
859
- id: asRuleId('seed-shop-rule-not-on-review'),
860
- category: 'business',
861
- condition: {
862
- left: asStatePath('checkout.step'),
863
- operator: 'not_equals',
864
- right: 'review'
865
- },
866
- effect: {
867
- id: asEffectId('seed-shop-effect-not-on-review'),
868
- type: 'block_action',
869
- reason: 'Complete the previous steps first.'
870
- }
871
- },
872
- {
873
- id: asRuleId('seed-shop-rule-no-payment'),
874
- category: 'validation',
875
- condition: {
876
- left: asStatePath('payment.method'),
877
- operator: 'equals',
878
- right: 'none'
879
- },
880
- effect: {
881
- id: asEffectId('seed-shop-effect-no-payment'),
882
- type: 'block_action',
883
- reason: 'Select a payment method before placing the order.'
884
- }
885
- },
886
- {
887
- id: asRuleId('seed-shop-rule-fraud-amount'),
888
- category: 'compliance',
889
- condition: {
890
- left: asStatePath('order.amount'),
891
- operator: 'greater_than',
892
- right: 100000
893
- },
894
- effect: {
895
- id: asEffectId('seed-shop-effect-fraud-flag'),
896
- type: 'block_action',
897
- reason: 'Orders over $1,000 require manual review.'
898
- },
899
- description: 'Compliance gate triggered for high-value orders.'
900
- },
901
- {
902
- id: asRuleId('seed-shop-rule-fraud-flagged'),
903
- category: 'security',
904
- condition: {
905
- left: asStatePath('fraud.flagged'),
906
- operator: 'is_true'
907
- },
908
- effect: {
909
- id: asEffectId('seed-shop-effect-fraud-flagged'),
910
- type: 'block_action',
911
- reason: 'Account flagged for fraud review.'
912
- }
913
- }
914
- ],
915
- invariants: [],
916
- effects: [
917
- {
918
- id: asEffectId('seed-shop-effect-emit-placed'),
919
- type: 'emit_event',
920
- event: asEventName('order.placed')
921
- },
922
- {
923
- id: asEffectId('seed-shop-effect-message-placed'),
924
- type: 'show_message',
925
- message: 'Order placed!',
926
- tone: 'success'
927
- },
928
- {
929
- id: asEffectId('seed-shop-effect-transition-order'),
930
- type: 'transition_surface',
931
- target: ORDER_ID
932
- }
933
- ],
934
- emittedEvents: [asEventName('order.placed')],
935
- transitions: []
936
- }
937
- ]
938
- },
939
-
940
- // ── Order ──────────────────────────────────────────────────────────────
941
- {
942
- id: ORDER_ID,
943
- name: 'Order confirmation',
944
- type: 'screen',
945
- description:
946
- 'Post-purchase view. Order can be cancelled while in preparation, but not after shipping.',
947
- stateDefinitions: [
948
- {
949
- id: asStateDefinitionId('seed-shop-order-state-status'),
950
- path: asStatePath('order.status'),
951
- type: 'enum',
952
- enumValues: ['placed', 'preparing', 'shipped', 'delivered', 'cancelled'],
953
- defaultValue: 'preparing'
954
- },
955
- {
956
- id: asStateDefinitionId('seed-shop-order-state-id'),
957
- path: asStatePath('order.id'),
958
- type: 'string',
959
- defaultValue: 'ORD-1042'
960
- },
961
- {
962
- id: asStateDefinitionId('seed-shop-order-state-amount'),
963
- path: asStatePath('order.amount'),
964
- type: 'number',
965
- defaultValue: 5197
966
- }
967
- ],
968
- rules: [],
969
- invariants: [],
970
- transitions: [
971
- { id: asEffectId('seed-shop-order-trans-back') as never, target: CATALOG_ID, label: 'Continue shopping' }
972
- ],
973
- actions: [
974
- {
975
- id: asActionId('seed-shop-cap-cancel-order'),
976
- name: 'Cancel order',
977
- intent: 'Cancel an order before it ships.',
978
- parameters: [],
979
- requiredStates: [asStatePath('order.status')],
980
- rules: [
981
- {
982
- id: asRuleId('seed-shop-rule-cancel-shipped'),
983
- category: 'business',
984
- condition: {
985
- left: asStatePath('order.status'),
986
- operator: 'equals',
987
- right: 'shipped'
988
- },
989
- effect: {
990
- id: asEffectId('seed-shop-effect-cancel-shipped'),
991
- type: 'block_action',
992
- reason: 'Cannot cancel. Already shipped.'
993
- }
994
- },
995
- {
996
- id: asRuleId('seed-shop-rule-cancel-delivered'),
997
- category: 'business',
998
- condition: {
999
- left: asStatePath('order.status'),
1000
- operator: 'equals',
1001
- right: 'delivered'
1002
- },
1003
- effect: {
1004
- id: asEffectId('seed-shop-effect-cancel-delivered'),
1005
- type: 'block_action',
1006
- reason: 'Order already delivered. Use the return flow instead.'
1007
- }
1008
- },
1009
- {
1010
- id: asRuleId('seed-shop-rule-cancel-already-cancelled'),
1011
- category: 'business',
1012
- condition: {
1013
- left: asStatePath('order.status'),
1014
- operator: 'equals',
1015
- right: 'cancelled'
1016
- },
1017
- effect: {
1018
- id: asEffectId('seed-shop-effect-cancel-already-cancelled'),
1019
- type: 'block_action',
1020
- reason: 'Order is already cancelled.'
1021
- }
1022
- }
1023
- ],
1024
- invariants: [],
1025
- effects: [
1026
- {
1027
- id: asEffectId('seed-shop-effect-set-cancelled'),
1028
- type: 'set_state',
1029
- path: asStatePath('order.status'),
1030
- value: 'cancelled'
1031
- },
1032
- {
1033
- id: asEffectId('seed-shop-effect-emit-cancelled'),
1034
- type: 'emit_event',
1035
- event: asEventName('order.cancelled')
1036
- },
1037
- {
1038
- id: asEffectId('seed-shop-effect-cancel-message'),
1039
- type: 'show_message',
1040
- message: 'Order cancelled. Refund is on its way.',
1041
- tone: 'success'
1042
- }
1043
- ],
1044
- emittedEvents: [asEventName('order.cancelled')],
1045
- transitions: []
1046
- },
1047
- {
1048
- id: asActionId('seed-shop-cap-track-order'),
1049
- name: 'Track shipment',
1050
- intent: 'Open the shipment tracker (no-op in MVP).',
1051
- parameters: [],
1052
- requiredStates: [asStatePath('order.status')],
1053
- rules: [
1054
- {
1055
- id: asRuleId('seed-shop-rule-track-not-shippable'),
1056
- category: 'ux_feedback',
1057
- condition: {
1058
- left: asStatePath('order.status'),
1059
- operator: 'equals',
1060
- right: 'preparing'
1061
- },
1062
- effect: {
1063
- id: asEffectId('seed-shop-effect-track-not-shippable'),
1064
- type: 'show_message',
1065
- message: 'Tracking not yet available. Order still being prepared.',
1066
- tone: 'info'
1067
- }
1068
- }
1069
- ],
1070
- invariants: [],
1071
- effects: [
1072
- {
1073
- id: asEffectId('seed-shop-effect-emit-track'),
1074
- type: 'emit_event',
1075
- event: asEventName('order.track.opened')
1076
- }
1077
- ],
1078
- emittedEvents: [asEventName('order.track.opened')],
1079
- transitions: []
1080
- }
1081
- ]
1082
- }
1083
- ]
134
+ id: asFeatureId('seed-shop'),
135
+ name: 'E-commerce storefront',
136
+ description:
137
+ 'Amazon-like online store. Demonstrates a full multi-surface flow with catalog, cart, checkout, and order confirmation. Covers stock validation, authentication gates, coupon logic, free-shipping thresholds, fraud limits, cancellation policy, and surface transitions.',
138
+ createdAt: now,
139
+ updatedAt: now,
140
+ personas: [],
141
+ resources: [],
142
+ entities: [],
143
+ surfaces: [
144
+ // ── Catalog ────────────────────────────────────────────────────────────
145
+ {
146
+ id: CATALOG_ID,
147
+ name: 'Catalog',
148
+ type: 'screen',
149
+ description: 'Browse and search products. Add items directly to the cart.',
150
+ stateDefinitions: [
151
+ {
152
+ id: asStateDefinitionId('seed-shop-catalog-state-query'),
153
+ path: asStatePath('search.query'),
154
+ type: 'string',
155
+ defaultValue: '',
156
+ description: 'Active search query.'
157
+ },
158
+ {
159
+ id: asStateDefinitionId('seed-shop-catalog-state-results'),
160
+ path: asStatePath('search.resultCount'),
161
+ type: 'number',
162
+ defaultValue: 0,
163
+ description: 'Number of products returned by the current query.'
164
+ },
165
+ {
166
+ id: asStateDefinitionId('seed-shop-catalog-state-stock'),
167
+ path: asStatePath('product.stock'),
168
+ type: 'number',
169
+ defaultValue: 12,
170
+ description: 'Available stock for the focused product.'
171
+ },
172
+ {
173
+ id: asStateDefinitionId('seed-shop-catalog-state-price'),
174
+ path: asStatePath('product.price'),
175
+ type: 'number',
176
+ defaultValue: 1999,
177
+ description: 'Unit price of the focused product, in cents.'
178
+ },
179
+ {
180
+ id: asStateDefinitionId('seed-shop-catalog-state-cart-count'),
181
+ path: asStatePath('cart.itemCount'),
182
+ type: 'number',
183
+ defaultValue: 0
184
+ },
185
+ {
186
+ id: asStateDefinitionId('seed-shop-catalog-state-cart-subtotal'),
187
+ path: asStatePath('cart.subtotal'),
188
+ type: 'number',
189
+ defaultValue: 0,
190
+ description: 'Cart subtotal in cents.'
191
+ }
192
+ ],
193
+ rules: [],
194
+ invariants: [
195
+ {
196
+ id: asInvariantId('seed-shop-catalog-invariant-stock-non-negative'),
197
+ name: 'product.stock is non-negative',
198
+ condition: {
199
+ left: asStatePath('product.stock'),
200
+ operator: 'greater_than',
201
+ right: -1
202
+ },
203
+ message: 'Stock must never go below zero.'
204
+ }
205
+ ],
206
+ transitions: [
207
+ {
208
+ id: asEffectId('seed-shop-catalog-transition-cart') as never,
209
+ target: CART_ID,
210
+ label: 'View cart'
211
+ }
212
+ ],
213
+ actions: [
214
+ {
215
+ id: asActionId('seed-shop-cap-search'),
216
+ name: 'Search products',
217
+ intent: 'Run a keyword search and update the visible result list.',
218
+ parameters: [
219
+ {
220
+ id: asParameterId('seed-shop-param-query'),
221
+ name: 'query',
222
+ type: 'string',
223
+ required: true,
224
+ description: 'The search keywords typed by the user.'
225
+ }
226
+ ],
227
+ requiredStates: [],
228
+ rules: [],
229
+ invariants: [],
230
+ effects: [
231
+ {
232
+ id: asEffectId('seed-shop-effect-set-query'),
233
+ type: 'set_state',
234
+ path: asStatePath('search.query'),
235
+ value: 'placeholder'
236
+ },
237
+ {
238
+ id: asEffectId('seed-shop-effect-emit-search'),
239
+ type: 'emit_event',
240
+ event: asEventName('catalog.search.executed')
241
+ }
242
+ ],
243
+ emittedEvents: [asEventName('catalog.search.executed')],
244
+ transitions: []
245
+ },
246
+ {
247
+ id: asActionId('seed-shop-cap-add-to-cart'),
248
+ name: 'Add to cart',
249
+ intent:
250
+ 'Add the focused product to the cart, validating stock and updating cart counters.',
251
+ parameters: [
252
+ {
253
+ id: asParameterId('seed-shop-param-quantity'),
254
+ name: 'quantity',
255
+ type: 'number',
256
+ required: true,
257
+ defaultValue: 1,
258
+ description: 'Number of units to add (1–10).'
259
+ }
260
+ ],
261
+ requiredStates: [
262
+ asStatePath('product.stock'),
263
+ asStatePath('cart.itemCount'),
264
+ asStatePath('cart.subtotal')
265
+ ],
266
+ rules: [
267
+ {
268
+ id: asRuleId('seed-shop-rule-out-of-stock'),
269
+ category: 'business',
270
+ condition: {
271
+ left: asStatePath('product.stock'),
272
+ operator: 'lower_than',
273
+ right: 1
274
+ },
275
+ effect: {
276
+ id: asEffectId('seed-shop-effect-out-of-stock'),
277
+ type: 'block_action',
278
+ reason: 'Out of stock'
279
+ }
280
+ },
281
+ {
282
+ id: asRuleId('seed-shop-rule-quantity-bound'),
283
+ category: 'validation',
284
+ condition: {
285
+ left: asStatePath('product.stock'),
286
+ operator: 'lower_than',
287
+ right: 1
288
+ },
289
+ effect: {
290
+ id: asEffectId('seed-shop-effect-quantity-bound'),
291
+ type: 'show_message',
292
+ message: 'Cannot add more than the available stock.',
293
+ tone: 'warning'
294
+ },
295
+ description:
296
+ 'In a real system the quantity would be compared to product.stock. This rule keeps it simple.'
297
+ }
298
+ ],
299
+ invariants: [],
300
+ effects: [
301
+ {
302
+ id: asEffectId('seed-shop-effect-inc-cart-count'),
303
+ type: 'set_state',
304
+ path: asStatePath('cart.itemCount'),
305
+ value: 1
306
+ },
307
+ {
308
+ id: asEffectId('seed-shop-effect-decrement-stock'),
309
+ type: 'set_state',
310
+ path: asStatePath('product.stock'),
311
+ value: 11
312
+ },
313
+ {
314
+ id: asEffectId('seed-shop-effect-add-subtotal'),
315
+ type: 'set_state',
316
+ path: asStatePath('cart.subtotal'),
317
+ value: 1999
318
+ },
319
+ {
320
+ id: asEffectId('seed-shop-effect-emit-added'),
321
+ type: 'emit_event',
322
+ event: asEventName('cart.item.added')
323
+ },
324
+ {
325
+ id: asEffectId('seed-shop-effect-message-added'),
326
+ type: 'show_message',
327
+ message: 'Added to cart',
328
+ tone: 'success'
329
+ }
330
+ ],
331
+ emittedEvents: [asEventName('cart.item.added')],
332
+ transitions: []
333
+ },
334
+ {
335
+ id: asActionId('seed-shop-cap-go-to-cart'),
336
+ name: 'Go to cart',
337
+ intent: 'Navigate from the catalog to the cart surface.',
338
+ parameters: [],
339
+ requiredStates: [],
340
+ rules: [
341
+ {
342
+ id: asRuleId('seed-shop-rule-empty-cart-block-nav'),
343
+ category: 'ux_feedback',
344
+ condition: {
345
+ left: asStatePath('cart.itemCount'),
346
+ operator: 'equals',
347
+ right: 0
348
+ },
349
+ effect: {
350
+ id: asEffectId('seed-shop-effect-empty-cart-block'),
351
+ type: 'block_action',
352
+ reason: 'Your cart is empty'
353
+ }
354
+ }
355
+ ],
356
+ invariants: [],
357
+ effects: [
358
+ {
359
+ id: asEffectId('seed-shop-effect-transition-cart'),
360
+ type: 'transition_surface',
361
+ target: CART_ID
362
+ }
363
+ ],
364
+ emittedEvents: [asEventName('navigation.cart.opened')],
365
+ transitions: [
366
+ {
367
+ id: asEffectId('seed-shop-catalog-trans-2') as never,
368
+ target: CART_ID
369
+ }
370
+ ]
371
+ }
372
+ ]
373
+ },
374
+
375
+ // ── Cart ───────────────────────────────────────────────────────────────
376
+ {
377
+ id: CART_ID,
378
+ name: 'Cart',
379
+ type: 'screen',
380
+ description: 'Review items, change quantities, apply a coupon, and proceed to checkout.',
381
+ stateDefinitions: [
382
+ {
383
+ id: asStateDefinitionId('seed-shop-cart-state-count'),
384
+ path: asStatePath('cart.itemCount'),
385
+ type: 'number',
386
+ defaultValue: 2
387
+ },
388
+ {
389
+ id: asStateDefinitionId('seed-shop-cart-state-subtotal'),
390
+ path: asStatePath('cart.subtotal'),
391
+ type: 'number',
392
+ defaultValue: 4598,
393
+ description: 'Subtotal in cents.'
394
+ },
395
+ {
396
+ id: asStateDefinitionId('seed-shop-cart-state-shipping'),
397
+ path: asStatePath('cart.shipping'),
398
+ type: 'number',
399
+ defaultValue: 599
400
+ },
401
+ {
402
+ id: asStateDefinitionId('seed-shop-cart-state-total'),
403
+ path: asStatePath('cart.total'),
404
+ type: 'number',
405
+ defaultValue: 5197
406
+ },
407
+ {
408
+ id: asStateDefinitionId('seed-shop-cart-state-coupon'),
409
+ path: asStatePath('coupon.code'),
410
+ type: 'string',
411
+ defaultValue: '',
412
+ description: 'Applied coupon code, empty when none.'
413
+ },
414
+ {
415
+ id: asStateDefinitionId('seed-shop-cart-state-coupon-valid'),
416
+ path: asStatePath('coupon.applied'),
417
+ type: 'boolean',
418
+ defaultValue: false
419
+ },
420
+ {
421
+ id: asStateDefinitionId('seed-shop-cart-state-user-auth'),
422
+ path: asStatePath('user.authenticated'),
423
+ type: 'boolean',
424
+ defaultValue: false
425
+ }
426
+ ],
427
+ rules: [],
428
+ invariants: [
429
+ {
430
+ id: asInvariantId('seed-shop-cart-invariant-count-non-negative'),
431
+ name: 'cart.itemCount is non-negative',
432
+ condition: {
433
+ left: asStatePath('cart.itemCount'),
434
+ operator: 'greater_than',
435
+ right: -1
436
+ },
437
+ message: 'Cart count must be ≥ 0.'
438
+ },
439
+ {
440
+ id: asInvariantId('seed-shop-cart-invariant-subtotal-non-negative'),
441
+ name: 'cart.subtotal is non-negative',
442
+ condition: {
443
+ left: asStatePath('cart.subtotal'),
444
+ operator: 'greater_than',
445
+ right: -1
446
+ },
447
+ message: 'Subtotal must be ≥ 0.'
448
+ }
449
+ ],
450
+ transitions: [
451
+ { id: asEffectId('seed-shop-cart-trans-back') as never, target: CATALOG_ID, label: 'Back to catalog' },
452
+ { id: asEffectId('seed-shop-cart-trans-checkout') as never, target: CHECKOUT_ID, label: 'Checkout' }
453
+ ],
454
+ actions: [
455
+ {
456
+ id: asActionId('seed-shop-cap-remove-item'),
457
+ name: 'Remove item',
458
+ intent: 'Remove an item from the cart and update totals.',
459
+ parameters: [],
460
+ requiredStates: [asStatePath('cart.itemCount')],
461
+ rules: [
462
+ {
463
+ id: asRuleId('seed-shop-rule-empty-remove'),
464
+ category: 'ux_feedback',
465
+ condition: {
466
+ left: asStatePath('cart.itemCount'),
467
+ operator: 'equals',
468
+ right: 0
469
+ },
470
+ effect: {
471
+ id: asEffectId('seed-shop-effect-empty-remove'),
472
+ type: 'block_action',
473
+ reason: 'Cart is already empty'
474
+ }
475
+ }
476
+ ],
477
+ invariants: [],
478
+ effects: [
479
+ {
480
+ id: asEffectId('seed-shop-effect-dec-count'),
481
+ type: 'set_state',
482
+ path: asStatePath('cart.itemCount'),
483
+ value: 1
484
+ },
485
+ {
486
+ id: asEffectId('seed-shop-effect-dec-subtotal'),
487
+ type: 'set_state',
488
+ path: asStatePath('cart.subtotal'),
489
+ value: 2299
490
+ },
491
+ {
492
+ id: asEffectId('seed-shop-effect-emit-removed'),
493
+ type: 'emit_event',
494
+ event: asEventName('cart.item.removed')
495
+ }
496
+ ],
497
+ emittedEvents: [asEventName('cart.item.removed')],
498
+ transitions: []
499
+ },
500
+ {
501
+ id: asActionId('seed-shop-cap-apply-coupon'),
502
+ name: 'Apply coupon',
503
+ intent: 'Validate and apply a discount coupon to the cart.',
504
+ parameters: [
505
+ {
506
+ id: asParameterId('seed-shop-param-coupon'),
507
+ name: 'code',
508
+ type: 'string',
509
+ required: true,
510
+ description: 'Coupon code to validate.'
511
+ }
512
+ ],
513
+ requiredStates: [asStatePath('coupon.applied'), asStatePath('cart.subtotal')],
514
+ rules: [
515
+ {
516
+ id: asRuleId('seed-shop-rule-coupon-already-applied'),
517
+ category: 'business',
518
+ condition: {
519
+ left: asStatePath('coupon.applied'),
520
+ operator: 'is_true'
521
+ },
522
+ effect: {
523
+ id: asEffectId('seed-shop-effect-coupon-already-applied'),
524
+ type: 'block_action',
525
+ reason: 'A coupon is already applied. Remove it first.'
526
+ }
527
+ },
528
+ {
529
+ id: asRuleId('seed-shop-rule-coupon-min-cart'),
530
+ category: 'business',
531
+ condition: {
532
+ left: asStatePath('cart.subtotal'),
533
+ operator: 'lower_than',
534
+ right: 1500
535
+ },
536
+ effect: {
537
+ id: asEffectId('seed-shop-effect-coupon-min-cart'),
538
+ type: 'block_action',
539
+ reason: 'Coupons require a $15 minimum cart total.'
540
+ }
541
+ }
542
+ ],
543
+ invariants: [],
544
+ effects: [
545
+ {
546
+ id: asEffectId('seed-shop-effect-set-coupon'),
547
+ type: 'set_state',
548
+ path: asStatePath('coupon.code'),
549
+ value: 'SAVE10'
550
+ },
551
+ {
552
+ id: asEffectId('seed-shop-effect-mark-coupon-applied'),
553
+ type: 'set_state',
554
+ path: asStatePath('coupon.applied'),
555
+ value: true
556
+ },
557
+ {
558
+ id: asEffectId('seed-shop-effect-emit-coupon'),
559
+ type: 'emit_event',
560
+ event: asEventName('cart.coupon.applied')
561
+ },
562
+ {
563
+ id: asEffectId('seed-shop-effect-coupon-message'),
564
+ type: 'show_message',
565
+ message: 'Coupon applied. 10% off',
566
+ tone: 'success'
567
+ }
568
+ ],
569
+ emittedEvents: [asEventName('cart.coupon.applied')],
570
+ transitions: []
571
+ },
572
+ {
573
+ id: asActionId('seed-shop-cap-checkout'),
574
+ name: 'Proceed to checkout',
575
+ intent: 'Move from the cart to the checkout flow.',
576
+ parameters: [],
577
+ requiredStates: [
578
+ asStatePath('cart.itemCount'),
579
+ asStatePath('user.authenticated')
580
+ ],
581
+ rules: [
582
+ {
583
+ id: asRuleId('seed-shop-rule-empty-cart-checkout'),
584
+ category: 'business',
585
+ condition: {
586
+ left: asStatePath('cart.itemCount'),
587
+ operator: 'equals',
588
+ right: 0
589
+ },
590
+ effect: {
591
+ id: asEffectId('seed-shop-effect-empty-cart-checkout'),
592
+ type: 'block_action',
593
+ reason: 'Add something to your cart before checking out.'
594
+ }
595
+ },
596
+ {
597
+ id: asRuleId('seed-shop-rule-not-authenticated'),
598
+ category: 'permissions',
599
+ condition: {
600
+ left: asStatePath('user.authenticated'),
601
+ operator: 'is_false'
602
+ },
603
+ effect: {
604
+ id: asEffectId('seed-shop-effect-must-login'),
605
+ type: 'block_action',
606
+ reason: 'Sign in to continue to checkout.'
607
+ }
608
+ },
609
+ {
610
+ id: asRuleId('seed-shop-rule-free-shipping'),
611
+ category: 'ux_feedback',
612
+ condition: {
613
+ left: asStatePath('cart.subtotal'),
614
+ operator: 'greater_than',
615
+ right: 3499
616
+ },
617
+ effect: {
618
+ id: asEffectId('seed-shop-effect-free-shipping'),
619
+ type: 'show_message',
620
+ message: 'You qualify for free shipping.',
621
+ tone: 'info'
622
+ }
623
+ }
624
+ ],
625
+ invariants: [],
626
+ effects: [
627
+ {
628
+ id: asEffectId('seed-shop-effect-transition-checkout'),
629
+ type: 'transition_surface',
630
+ target: CHECKOUT_ID
631
+ },
632
+ {
633
+ id: asEffectId('seed-shop-effect-emit-checkout-started'),
634
+ type: 'emit_event',
635
+ event: asEventName('checkout.started')
636
+ }
637
+ ],
638
+ emittedEvents: [asEventName('checkout.started')],
639
+ transitions: []
640
+ }
641
+ ]
642
+ },
643
+
644
+ // ── Checkout ───────────────────────────────────────────────────────────
645
+ {
646
+ id: CHECKOUT_ID,
647
+ name: 'Checkout',
648
+ type: 'workflow',
649
+ description: 'Multi-step checkout: shipping address → payment method → place order.',
650
+ stateDefinitions: [
651
+ {
652
+ id: asStateDefinitionId('seed-shop-checkout-state-step'),
653
+ path: asStatePath('checkout.step'),
654
+ type: 'enum',
655
+ enumValues: ['address', 'payment', 'review'],
656
+ defaultValue: 'address'
657
+ },
658
+ {
659
+ id: asStateDefinitionId('seed-shop-checkout-state-address'),
660
+ path: asStatePath('shipping.addressProvided'),
661
+ type: 'boolean',
662
+ defaultValue: false
663
+ },
664
+ {
665
+ id: asStateDefinitionId('seed-shop-checkout-state-payment'),
666
+ path: asStatePath('payment.method'),
667
+ type: 'enum',
668
+ enumValues: ['none', 'card', 'paypal', 'gift_card'],
669
+ defaultValue: 'none'
670
+ },
671
+ {
672
+ id: asStateDefinitionId('seed-shop-checkout-state-amount'),
673
+ path: asStatePath('order.amount'),
674
+ type: 'number',
675
+ defaultValue: 5197,
676
+ description: 'Final order amount in cents.'
677
+ },
678
+ {
679
+ id: asStateDefinitionId('seed-shop-checkout-state-fraud-flag'),
680
+ path: asStatePath('fraud.flagged'),
681
+ type: 'boolean',
682
+ defaultValue: false
683
+ },
684
+ {
685
+ id: asStateDefinitionId('seed-shop-checkout-state-user-auth'),
686
+ path: asStatePath('user.authenticated'),
687
+ type: 'boolean',
688
+ defaultValue: true
689
+ }
690
+ ],
691
+ // Surface-level guard: must be authenticated to do anything in checkout.
692
+ rules: [
693
+ {
694
+ id: asRuleId('seed-shop-checkout-surface-rule-auth'),
695
+ category: 'security',
696
+ condition: {
697
+ left: asStatePath('user.authenticated'),
698
+ operator: 'is_false'
699
+ },
700
+ effect: {
701
+ id: asEffectId('seed-shop-checkout-effect-must-auth'),
702
+ type: 'block_action',
703
+ reason: 'Sign in required to access checkout.'
704
+ },
705
+ description: 'Cross-cutting: every action on this surface requires an authenticated user.'
706
+ }
707
+ ],
708
+ invariants: [
709
+ {
710
+ id: asInvariantId('seed-shop-checkout-invariant-amount-positive'),
711
+ name: 'order.amount is positive',
712
+ condition: {
713
+ left: asStatePath('order.amount'),
714
+ operator: 'greater_than',
715
+ right: 0
716
+ },
717
+ message: 'Order amount must be > 0.'
718
+ }
719
+ ],
720
+ transitions: [
721
+ { id: asEffectId('seed-shop-checkout-trans-back') as never, target: CART_ID, label: 'Back to cart' },
722
+ { id: asEffectId('seed-shop-checkout-trans-order') as never, target: ORDER_ID, label: 'Order confirmation' }
723
+ ],
724
+ actions: [
725
+ {
726
+ id: asActionId('seed-shop-cap-confirm-address'),
727
+ name: 'Confirm shipping address',
728
+ intent: 'Persist the shipping address and advance to payment.',
729
+ parameters: [
730
+ {
731
+ id: asParameterId('seed-shop-param-postal-code'),
732
+ name: 'postalCode',
733
+ type: 'string',
734
+ required: true
735
+ }
736
+ ],
737
+ requiredStates: [asStatePath('checkout.step')],
738
+ rules: [
739
+ {
740
+ id: asRuleId('seed-shop-rule-wrong-step-address'),
741
+ category: 'business',
742
+ condition: {
743
+ left: asStatePath('checkout.step'),
744
+ operator: 'not_equals',
745
+ right: 'address'
746
+ },
747
+ effect: {
748
+ id: asEffectId('seed-shop-effect-wrong-step-address'),
749
+ type: 'block_action',
750
+ reason: 'You already passed the address step.'
751
+ }
752
+ }
753
+ ],
754
+ invariants: [],
755
+ effects: [
756
+ {
757
+ id: asEffectId('seed-shop-effect-mark-address-provided'),
758
+ type: 'set_state',
759
+ path: asStatePath('shipping.addressProvided'),
760
+ value: true
761
+ },
762
+ {
763
+ id: asEffectId('seed-shop-effect-advance-payment'),
764
+ type: 'set_state',
765
+ path: asStatePath('checkout.step'),
766
+ value: 'payment'
767
+ },
768
+ {
769
+ id: asEffectId('seed-shop-effect-emit-address'),
770
+ type: 'emit_event',
771
+ event: asEventName('checkout.address.confirmed')
772
+ }
773
+ ],
774
+ emittedEvents: [asEventName('checkout.address.confirmed')],
775
+ transitions: []
776
+ },
777
+ {
778
+ id: asActionId('seed-shop-cap-select-payment'),
779
+ name: 'Select payment method',
780
+ intent: 'Pick a payment method and advance to the review step.',
781
+ parameters: [
782
+ {
783
+ id: asParameterId('seed-shop-param-payment'),
784
+ name: 'method',
785
+ type: 'enum',
786
+ required: true,
787
+ enumValues: ['card', 'paypal', 'gift_card']
788
+ }
789
+ ],
790
+ requiredStates: [
791
+ asStatePath('checkout.step'),
792
+ asStatePath('shipping.addressProvided')
793
+ ],
794
+ rules: [
795
+ {
796
+ id: asRuleId('seed-shop-rule-no-address'),
797
+ category: 'business',
798
+ condition: {
799
+ left: asStatePath('shipping.addressProvided'),
800
+ operator: 'is_false'
801
+ },
802
+ effect: {
803
+ id: asEffectId('seed-shop-effect-no-address'),
804
+ type: 'block_action',
805
+ reason: 'Confirm a shipping address first.'
806
+ }
807
+ },
808
+ {
809
+ id: asRuleId('seed-shop-rule-wrong-step-payment'),
810
+ category: 'business',
811
+ condition: {
812
+ left: asStatePath('checkout.step'),
813
+ operator: 'not_equals',
814
+ right: 'payment'
815
+ },
816
+ effect: {
817
+ id: asEffectId('seed-shop-effect-wrong-step-payment'),
818
+ type: 'block_action',
819
+ reason: 'You are not on the payment step.'
820
+ }
821
+ }
822
+ ],
823
+ invariants: [],
824
+ effects: [
825
+ {
826
+ id: asEffectId('seed-shop-effect-set-payment'),
827
+ type: 'set_state',
828
+ path: asStatePath('payment.method'),
829
+ value: 'card'
830
+ },
831
+ {
832
+ id: asEffectId('seed-shop-effect-advance-review'),
833
+ type: 'set_state',
834
+ path: asStatePath('checkout.step'),
835
+ value: 'review'
836
+ },
837
+ {
838
+ id: asEffectId('seed-shop-effect-emit-payment'),
839
+ type: 'emit_event',
840
+ event: asEventName('checkout.payment.selected')
841
+ }
842
+ ],
843
+ emittedEvents: [asEventName('checkout.payment.selected')],
844
+ transitions: []
845
+ },
846
+ {
847
+ id: asActionId('seed-shop-cap-place-order'),
848
+ name: 'Place order',
849
+ intent:
850
+ 'Finalize the order, run fraud checks, and transition to the confirmation surface.',
851
+ parameters: [],
852
+ requiredStates: [
853
+ asStatePath('checkout.step'),
854
+ asStatePath('payment.method'),
855
+ asStatePath('order.amount')
856
+ ],
857
+ rules: [
858
+ {
859
+ id: asRuleId('seed-shop-rule-not-on-review'),
860
+ category: 'business',
861
+ condition: {
862
+ left: asStatePath('checkout.step'),
863
+ operator: 'not_equals',
864
+ right: 'review'
865
+ },
866
+ effect: {
867
+ id: asEffectId('seed-shop-effect-not-on-review'),
868
+ type: 'block_action',
869
+ reason: 'Complete the previous steps first.'
870
+ }
871
+ },
872
+ {
873
+ id: asRuleId('seed-shop-rule-no-payment'),
874
+ category: 'validation',
875
+ condition: {
876
+ left: asStatePath('payment.method'),
877
+ operator: 'equals',
878
+ right: 'none'
879
+ },
880
+ effect: {
881
+ id: asEffectId('seed-shop-effect-no-payment'),
882
+ type: 'block_action',
883
+ reason: 'Select a payment method before placing the order.'
884
+ }
885
+ },
886
+ {
887
+ id: asRuleId('seed-shop-rule-fraud-amount'),
888
+ category: 'compliance',
889
+ condition: {
890
+ left: asStatePath('order.amount'),
891
+ operator: 'greater_than',
892
+ right: 100000
893
+ },
894
+ effect: {
895
+ id: asEffectId('seed-shop-effect-fraud-flag'),
896
+ type: 'block_action',
897
+ reason: 'Orders over $1,000 require manual review.'
898
+ },
899
+ description: 'Compliance gate triggered for high-value orders.'
900
+ },
901
+ {
902
+ id: asRuleId('seed-shop-rule-fraud-flagged'),
903
+ category: 'security',
904
+ condition: {
905
+ left: asStatePath('fraud.flagged'),
906
+ operator: 'is_true'
907
+ },
908
+ effect: {
909
+ id: asEffectId('seed-shop-effect-fraud-flagged'),
910
+ type: 'block_action',
911
+ reason: 'Account flagged for fraud review.'
912
+ }
913
+ }
914
+ ],
915
+ invariants: [],
916
+ effects: [
917
+ {
918
+ id: asEffectId('seed-shop-effect-emit-placed'),
919
+ type: 'emit_event',
920
+ event: asEventName('order.placed')
921
+ },
922
+ {
923
+ id: asEffectId('seed-shop-effect-message-placed'),
924
+ type: 'show_message',
925
+ message: 'Order placed!',
926
+ tone: 'success'
927
+ },
928
+ {
929
+ id: asEffectId('seed-shop-effect-transition-order'),
930
+ type: 'transition_surface',
931
+ target: ORDER_ID
932
+ }
933
+ ],
934
+ emittedEvents: [asEventName('order.placed')],
935
+ transitions: []
936
+ }
937
+ ]
938
+ },
939
+
940
+ // ── Order ──────────────────────────────────────────────────────────────
941
+ {
942
+ id: ORDER_ID,
943
+ name: 'Order confirmation',
944
+ type: 'screen',
945
+ description:
946
+ 'Post-purchase view. Order can be cancelled while in preparation, but not after shipping.',
947
+ stateDefinitions: [
948
+ {
949
+ id: asStateDefinitionId('seed-shop-order-state-status'),
950
+ path: asStatePath('order.status'),
951
+ type: 'enum',
952
+ enumValues: ['placed', 'preparing', 'shipped', 'delivered', 'cancelled'],
953
+ defaultValue: 'preparing'
954
+ },
955
+ {
956
+ id: asStateDefinitionId('seed-shop-order-state-id'),
957
+ path: asStatePath('order.id'),
958
+ type: 'string',
959
+ defaultValue: 'ORD-1042'
960
+ },
961
+ {
962
+ id: asStateDefinitionId('seed-shop-order-state-amount'),
963
+ path: asStatePath('order.amount'),
964
+ type: 'number',
965
+ defaultValue: 5197
966
+ }
967
+ ],
968
+ rules: [],
969
+ invariants: [],
970
+ transitions: [
971
+ { id: asEffectId('seed-shop-order-trans-back') as never, target: CATALOG_ID, label: 'Continue shopping' }
972
+ ],
973
+ actions: [
974
+ {
975
+ id: asActionId('seed-shop-cap-cancel-order'),
976
+ name: 'Cancel order',
977
+ intent: 'Cancel an order before it ships.',
978
+ parameters: [],
979
+ requiredStates: [asStatePath('order.status')],
980
+ rules: [
981
+ {
982
+ id: asRuleId('seed-shop-rule-cancel-shipped'),
983
+ category: 'business',
984
+ condition: {
985
+ left: asStatePath('order.status'),
986
+ operator: 'equals',
987
+ right: 'shipped'
988
+ },
989
+ effect: {
990
+ id: asEffectId('seed-shop-effect-cancel-shipped'),
991
+ type: 'block_action',
992
+ reason: 'Cannot cancel. Already shipped.'
993
+ }
994
+ },
995
+ {
996
+ id: asRuleId('seed-shop-rule-cancel-delivered'),
997
+ category: 'business',
998
+ condition: {
999
+ left: asStatePath('order.status'),
1000
+ operator: 'equals',
1001
+ right: 'delivered'
1002
+ },
1003
+ effect: {
1004
+ id: asEffectId('seed-shop-effect-cancel-delivered'),
1005
+ type: 'block_action',
1006
+ reason: 'Order already delivered. Use the return flow instead.'
1007
+ }
1008
+ },
1009
+ {
1010
+ id: asRuleId('seed-shop-rule-cancel-already-cancelled'),
1011
+ category: 'business',
1012
+ condition: {
1013
+ left: asStatePath('order.status'),
1014
+ operator: 'equals',
1015
+ right: 'cancelled'
1016
+ },
1017
+ effect: {
1018
+ id: asEffectId('seed-shop-effect-cancel-already-cancelled'),
1019
+ type: 'block_action',
1020
+ reason: 'Order is already cancelled.'
1021
+ }
1022
+ }
1023
+ ],
1024
+ invariants: [],
1025
+ effects: [
1026
+ {
1027
+ id: asEffectId('seed-shop-effect-set-cancelled'),
1028
+ type: 'set_state',
1029
+ path: asStatePath('order.status'),
1030
+ value: 'cancelled'
1031
+ },
1032
+ {
1033
+ id: asEffectId('seed-shop-effect-emit-cancelled'),
1034
+ type: 'emit_event',
1035
+ event: asEventName('order.cancelled')
1036
+ },
1037
+ {
1038
+ id: asEffectId('seed-shop-effect-cancel-message'),
1039
+ type: 'show_message',
1040
+ message: 'Order cancelled. Refund is on its way.',
1041
+ tone: 'success'
1042
+ }
1043
+ ],
1044
+ emittedEvents: [asEventName('order.cancelled')],
1045
+ transitions: []
1046
+ },
1047
+ {
1048
+ id: asActionId('seed-shop-cap-track-order'),
1049
+ name: 'Track shipment',
1050
+ intent: 'Open the shipment tracker (no-op in MVP).',
1051
+ parameters: [],
1052
+ requiredStates: [asStatePath('order.status')],
1053
+ rules: [
1054
+ {
1055
+ id: asRuleId('seed-shop-rule-track-not-shippable'),
1056
+ category: 'ux_feedback',
1057
+ condition: {
1058
+ left: asStatePath('order.status'),
1059
+ operator: 'equals',
1060
+ right: 'preparing'
1061
+ },
1062
+ effect: {
1063
+ id: asEffectId('seed-shop-effect-track-not-shippable'),
1064
+ type: 'show_message',
1065
+ message: 'Tracking not yet available. Order still being prepared.',
1066
+ tone: 'info'
1067
+ }
1068
+ }
1069
+ ],
1070
+ invariants: [],
1071
+ effects: [
1072
+ {
1073
+ id: asEffectId('seed-shop-effect-emit-track'),
1074
+ type: 'emit_event',
1075
+ event: asEventName('order.track.opened')
1076
+ }
1077
+ ],
1078
+ emittedEvents: [asEventName('order.track.opened')],
1079
+ transitions: []
1080
+ }
1081
+ ]
1082
+ }
1083
+ ]
1084
1084
  };
1085
1085
 
1086
1086
  export const storefrontFeature: Feature = withRequiredDescriptions(storefrontFeatureData);