unspaghettit 0.2.0 → 0.3.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 (270) hide show
  1. package/build/client/_app/immutable/assets/0.DSctqr5I.css +1 -0
  2. package/build/client/_app/immutable/assets/0.DSctqr5I.css.br +0 -0
  3. package/build/client/_app/immutable/assets/0.DSctqr5I.css.gz +0 -0
  4. package/build/client/_app/immutable/assets/BehaviorGraph.Bk0xQRZk.css +1 -0
  5. package/build/client/_app/immutable/assets/BehaviorGraph.Bk0xQRZk.css.br +0 -0
  6. package/build/client/_app/immutable/assets/BehaviorGraph.Bk0xQRZk.css.gz +0 -0
  7. package/build/client/_app/immutable/chunks/9nXQ5qrY2.js +1 -0
  8. package/build/client/_app/immutable/chunks/9nXQ5qrY2.js.br +0 -0
  9. package/build/client/_app/immutable/chunks/9nXQ5qrY2.js.gz +0 -0
  10. package/build/client/_app/immutable/chunks/B439_FLv.js +1 -0
  11. package/build/client/_app/immutable/chunks/B439_FLv.js.br +0 -0
  12. package/build/client/_app/immutable/chunks/B439_FLv.js.gz +0 -0
  13. package/build/client/_app/immutable/chunks/BCEY79Dw.js +1 -0
  14. package/build/client/_app/immutable/chunks/BCEY79Dw.js.br +2 -0
  15. package/build/client/_app/immutable/chunks/BCEY79Dw.js.gz +0 -0
  16. package/build/client/_app/immutable/chunks/{DBJWcC6Y.js → BYIrIC5L.js} +1 -1
  17. package/build/client/_app/immutable/chunks/BYIrIC5L.js.br +0 -0
  18. package/build/client/_app/immutable/chunks/BYIrIC5L.js.gz +0 -0
  19. package/build/client/_app/immutable/chunks/B_9TWPrx2.js +1 -0
  20. package/build/client/_app/immutable/chunks/B_9TWPrx2.js.br +0 -0
  21. package/build/client/_app/immutable/chunks/B_9TWPrx2.js.gz +0 -0
  22. package/build/client/_app/immutable/chunks/BvOhVtZg.js +1 -0
  23. package/build/client/_app/immutable/chunks/BvOhVtZg.js.br +1 -0
  24. package/build/client/_app/immutable/chunks/BvOhVtZg.js.gz +0 -0
  25. package/build/client/_app/immutable/chunks/CY3em1ma2.js +1 -0
  26. package/build/client/_app/immutable/chunks/CY3em1ma2.js.br +0 -0
  27. package/build/client/_app/immutable/chunks/CY3em1ma2.js.gz +0 -0
  28. package/build/client/_app/immutable/chunks/CgdRZPgI.js +1 -0
  29. package/build/client/_app/immutable/chunks/CgdRZPgI.js.br +0 -0
  30. package/build/client/_app/immutable/chunks/CgdRZPgI.js.gz +0 -0
  31. package/build/client/_app/immutable/chunks/D5speDV82.js +908 -0
  32. package/build/client/_app/immutable/chunks/D5speDV82.js.br +0 -0
  33. package/build/client/_app/immutable/chunks/D5speDV82.js.gz +0 -0
  34. package/build/client/_app/immutable/chunks/DkxwAIfJ2.js +1 -0
  35. package/build/client/_app/immutable/chunks/DkxwAIfJ2.js.br +0 -0
  36. package/build/client/_app/immutable/chunks/DkxwAIfJ2.js.gz +0 -0
  37. package/build/client/_app/immutable/chunks/{DatGSObE.js → OJscNS3T.js} +1 -1
  38. package/build/client/_app/immutable/chunks/OJscNS3T.js.br +0 -0
  39. package/build/client/_app/immutable/chunks/OJscNS3T.js.gz +0 -0
  40. package/build/client/_app/immutable/chunks/U9p9CtKG2.js +2 -0
  41. package/build/client/_app/immutable/chunks/U9p9CtKG2.js.br +0 -0
  42. package/build/client/_app/immutable/chunks/U9p9CtKG2.js.gz +0 -0
  43. package/build/client/_app/immutable/entry/app.Cd4S3giu.js +2 -0
  44. package/build/client/_app/immutable/entry/app.Cd4S3giu.js.br +0 -0
  45. package/build/client/_app/immutable/entry/app.Cd4S3giu.js.gz +0 -0
  46. package/build/client/_app/immutable/entry/start.C3xXQVkq.js +1 -0
  47. package/build/client/_app/immutable/entry/start.C3xXQVkq.js.br +0 -0
  48. package/build/client/_app/immutable/entry/start.C3xXQVkq.js.gz +0 -0
  49. package/build/client/_app/immutable/nodes/0.dIOlQ-0y.js +4 -0
  50. package/build/client/_app/immutable/nodes/0.dIOlQ-0y.js.br +0 -0
  51. package/build/client/_app/immutable/nodes/0.dIOlQ-0y.js.gz +0 -0
  52. package/build/client/_app/immutable/nodes/{1.KYdA6ppX.js → 1.Dyte3Ggf.js} +1 -1
  53. package/build/client/_app/immutable/nodes/1.Dyte3Ggf.js.br +2 -0
  54. package/build/client/_app/immutable/nodes/1.Dyte3Ggf.js.gz +0 -0
  55. package/build/client/_app/immutable/nodes/10.ivxAosDg.js +2 -0
  56. package/build/client/_app/immutable/nodes/10.ivxAosDg.js.br +0 -0
  57. package/build/client/_app/immutable/nodes/10.ivxAosDg.js.gz +0 -0
  58. package/build/client/_app/immutable/nodes/{9.CMW6a2Lg.js → 11.wvMfJKC2.js} +1 -1
  59. package/build/client/_app/immutable/nodes/11.wvMfJKC2.js.br +0 -0
  60. package/build/client/_app/immutable/nodes/11.wvMfJKC2.js.gz +0 -0
  61. package/build/client/_app/immutable/nodes/{2.DBz20KgG.js → 2.CmPPom9Z.js} +1 -1
  62. package/build/client/_app/immutable/nodes/2.CmPPom9Z.js.br +0 -0
  63. package/build/client/_app/immutable/nodes/2.CmPPom9Z.js.gz +0 -0
  64. package/build/client/_app/immutable/nodes/3.D-iCGCEx.js +1 -0
  65. package/build/client/_app/immutable/nodes/3.D-iCGCEx.js.br +0 -0
  66. package/build/client/_app/immutable/nodes/3.D-iCGCEx.js.gz +0 -0
  67. package/build/client/_app/immutable/nodes/{4.BvMzqBJj.js → 4.DbfAvO8Z.js} +1 -1
  68. package/build/client/_app/immutable/nodes/4.DbfAvO8Z.js.br +0 -0
  69. package/build/client/_app/immutable/nodes/4.DbfAvO8Z.js.gz +0 -0
  70. package/build/client/_app/immutable/nodes/5.CC5Q7lVw.js +42 -0
  71. package/build/client/_app/immutable/nodes/5.CC5Q7lVw.js.br +0 -0
  72. package/build/client/_app/immutable/nodes/5.CC5Q7lVw.js.gz +0 -0
  73. package/build/client/_app/immutable/nodes/6.CHIjlzpO.js +1 -0
  74. package/build/client/_app/immutable/nodes/6.CHIjlzpO.js.br +0 -0
  75. package/build/client/_app/immutable/nodes/6.CHIjlzpO.js.gz +0 -0
  76. package/build/client/_app/immutable/nodes/{6.BOHISqs-.js → 7.Ejs18ZUc.js} +1 -1
  77. package/build/client/_app/immutable/nodes/7.Ejs18ZUc.js.br +0 -0
  78. package/build/client/_app/immutable/nodes/7.Ejs18ZUc.js.gz +0 -0
  79. package/build/client/_app/immutable/nodes/{7.CemgNJfw.js → 8.B-HweAc8.js} +1 -1
  80. package/build/client/_app/immutable/nodes/8.B-HweAc8.js.br +0 -0
  81. package/build/client/_app/immutable/nodes/8.B-HweAc8.js.gz +0 -0
  82. package/build/client/_app/immutable/nodes/9.CKPeM6tx.js +5 -0
  83. package/build/client/_app/immutable/nodes/9.CKPeM6tx.js.br +0 -0
  84. package/build/client/_app/immutable/nodes/9.CKPeM6tx.js.gz +0 -0
  85. package/build/client/_app/version.json +1 -1
  86. package/build/client/_app/version.json.br +0 -0
  87. package/build/client/_app/version.json.gz +0 -0
  88. package/build/client/lyriks_logo.svg +148 -0
  89. package/build/client/lyriks_logo.svg.br +0 -0
  90. package/build/client/lyriks_logo.svg.gz +0 -0
  91. package/build/server/chunks/{0-C_o0oz-N.js → 0-Co8kcANG.js} +4 -4
  92. package/build/server/chunks/{0-C_o0oz-N.js.map → 0-Co8kcANG.js.map} +1 -1
  93. package/build/server/chunks/1-BSUItTig.js +9 -0
  94. package/build/server/chunks/{1-DPpKAKXV.js.map → 1-BSUItTig.js.map} +1 -1
  95. package/build/server/chunks/10-BygvxrZp.js +9 -0
  96. package/build/server/chunks/10-BygvxrZp.js.map +1 -0
  97. package/build/server/chunks/11-DRx0tRx2.js +9 -0
  98. package/build/server/chunks/11-DRx0tRx2.js.map +1 -0
  99. package/build/server/chunks/{2-AlfFqtL1.js → 2-BQT3m1vc.js} +3 -3
  100. package/build/server/chunks/{2-AlfFqtL1.js.map → 2-BQT3m1vc.js.map} +1 -1
  101. package/build/server/chunks/{3-vbjUt_51.js → 3-DPZ9BquJ.js} +3 -3
  102. package/build/server/chunks/{3-vbjUt_51.js.map → 3-DPZ9BquJ.js.map} +1 -1
  103. package/build/server/chunks/{4-BNow4x6D.js → 4-DHo47YX6.js} +3 -3
  104. package/build/server/chunks/{4-BNow4x6D.js.map → 4-DHo47YX6.js.map} +1 -1
  105. package/build/server/chunks/5-Cp9evBAG.js +9 -0
  106. package/build/server/chunks/5-Cp9evBAG.js.map +1 -0
  107. package/build/server/chunks/6-DiBq3bOV.js +9 -0
  108. package/build/server/chunks/6-DiBq3bOV.js.map +1 -0
  109. package/build/server/chunks/{6-QQ7r8Rd5.js → 7-C4hmS0dG.js} +3 -3
  110. package/build/server/chunks/{6-QQ7r8Rd5.js.map → 7-C4hmS0dG.js.map} +1 -1
  111. package/build/server/chunks/{7-CbPLGaIG.js → 8-CFFuDzBC.js} +4 -4
  112. package/build/server/chunks/{7-CbPLGaIG.js.map → 8-CFFuDzBC.js.map} +1 -1
  113. package/build/server/chunks/9-nhhKZJrs.js +9 -0
  114. package/build/server/chunks/9-nhhKZJrs.js.map +1 -0
  115. package/build/server/chunks/BehaviorGraph-m5kYj5HH.js +757 -0
  116. package/build/server/chunks/BehaviorGraph-m5kYj5HH.js.map +1 -0
  117. package/build/server/chunks/{FeatureCard-BQOY6gJQ.js → FeatureCard-CfbXNYe8.js} +2 -2
  118. package/build/server/chunks/{FeatureCard-BQOY6gJQ.js.map → FeatureCard-CfbXNYe8.js.map} +1 -1
  119. package/build/server/chunks/{ProgressBar-CfhccQ83.js → ProgressBar-DDoQJ_C9.js} +2 -2
  120. package/build/server/chunks/ProgressBar-DDoQJ_C9.js.map +1 -0
  121. package/build/server/chunks/{ProjectsIndex-CoDrvRya.js → ProjectsIndex-DUVJ3hyL.js} +2 -2
  122. package/build/server/chunks/{ProjectsIndex-CoDrvRya.js.map → ProjectsIndex-DUVJ3hyL.js.map} +1 -1
  123. package/build/server/chunks/TransitionCatalog-B8zHs-2E.js +271 -0
  124. package/build/server/chunks/TransitionCatalog-B8zHs-2E.js.map +1 -0
  125. package/build/server/chunks/{_layout.svelte-BREws55o.js → _layout.svelte-CLTmk0xU.js} +66 -15
  126. package/build/server/chunks/_layout.svelte-CLTmk0xU.js.map +1 -0
  127. package/build/server/chunks/{_page.svelte-De508ek8.js → _page.svelte-B1nG3PKn.js} +4 -4
  128. package/build/server/chunks/{_page.svelte-De508ek8.js.map → _page.svelte-B1nG3PKn.js.map} +1 -1
  129. package/build/server/chunks/{_page.svelte-Zf9H4KOP.js → _page.svelte-BW_nbAAH.js} +11 -315
  130. package/build/server/chunks/_page.svelte-BW_nbAAH.js.map +1 -0
  131. package/build/server/chunks/{_page.svelte-BqSC-1vK.js → _page.svelte-Caq7J0jU.js} +91 -47
  132. package/build/server/chunks/_page.svelte-Caq7J0jU.js.map +1 -0
  133. package/build/server/chunks/{_page.svelte-B7hT3P8E.js → _page.svelte-Cham-dsM.js} +4 -4
  134. package/build/server/chunks/{_page.svelte-B7hT3P8E.js.map → _page.svelte-Cham-dsM.js.map} +1 -1
  135. package/build/server/chunks/_page.svelte-Dhwjwph_.js +41 -0
  136. package/build/server/chunks/_page.svelte-Dhwjwph_.js.map +1 -0
  137. package/build/server/chunks/{_page.svelte-BKKCa9H5.js → _page.svelte-DlFVT40-.js} +3 -3
  138. package/build/server/chunks/{_page.svelte-BKKCa9H5.js.map → _page.svelte-DlFVT40-.js.map} +1 -1
  139. package/build/server/chunks/{_page.svelte-BtI2zZ_Z.js → _page.svelte-NVT2dzpG.js} +176 -327
  140. package/build/server/chunks/_page.svelte-NVT2dzpG.js.map +1 -0
  141. package/build/server/chunks/{_page.svelte-BKTveFAj.js → _page.svelte-Oj-W7G5s.js} +5 -5
  142. package/build/server/chunks/{_page.svelte-BKTveFAj.js.map → _page.svelte-Oj-W7G5s.js.map} +1 -1
  143. package/build/server/chunks/_page.svelte-Z_kK2lHY.js +68 -0
  144. package/build/server/chunks/_page.svelte-Z_kK2lHY.js.map +1 -0
  145. package/build/server/chunks/{builderModeStore.svelte-ihupr-3p.js → builderModeStore.svelte-BpRIU_zP.js} +217 -6
  146. package/build/server/chunks/builderModeStore.svelte-BpRIU_zP.js.map +1 -0
  147. package/build/server/chunks/client-DeX3TC3s.js +51 -0
  148. package/build/server/chunks/{client-DfpLcAZ9.js.map → client-DeX3TC3s.js.map} +1 -1
  149. package/build/server/chunks/{error.svelte-C35KOpru.js → error.svelte-Cdjeq3L2.js} +4 -4
  150. package/build/server/chunks/{error.svelte-C35KOpru.js.map → error.svelte-Cdjeq3L2.js.map} +1 -1
  151. package/build/server/chunks/featureStore.svelte-DIYgPBVm.js +161 -0
  152. package/build/server/chunks/featureStore.svelte-DIYgPBVm.js.map +1 -0
  153. package/build/server/chunks/{hooks.server-Rv301GTB.js → hooks.server-y3jdg_sB.js} +6 -2
  154. package/build/server/chunks/hooks.server-y3jdg_sB.js.map +1 -0
  155. package/build/server/chunks/{internal-BPKrFkK1.js → internal-KYK0WpL7.js} +4 -4
  156. package/build/server/chunks/{internal-BPKrFkK1.js.map → internal-KYK0WpL7.js.map} +1 -1
  157. package/build/server/chunks/projectFeaturesStore.svelte-2o-72_vr.js +313 -0
  158. package/build/server/chunks/projectFeaturesStore.svelte-2o-72_vr.js.map +1 -0
  159. package/build/server/chunks/{reconcile-Dv7jS3C8.js → reconcile-B5xqb6-s.js} +3 -272
  160. package/build/server/chunks/reconcile-B5xqb6-s.js.map +1 -0
  161. package/build/server/chunks/registry-DqAn_hVE.js +21 -0
  162. package/build/server/chunks/registry-DqAn_hVE.js.map +1 -0
  163. package/build/server/chunks/{state-CpLVNZq7.js → state-DBjl9lhV.js} +2 -2
  164. package/build/server/chunks/{state-CpLVNZq7.js.map → state-DBjl9lhV.js.map} +1 -1
  165. package/build/server/index.js +1 -1
  166. package/build/server/index.js.map +1 -1
  167. package/build/server/manifest.js +33 -17
  168. package/build/server/manifest.js.map +1 -1
  169. package/cli/commands/dashboard.ts +14 -0
  170. package/cli/commands/init.ts +26 -0
  171. package/cli/commands/theme.ts +62 -0
  172. package/cli/unspa.ts +38 -2
  173. package/cli/util/context-files.ts +5 -0
  174. package/cli/util/theme.ts +34 -0
  175. package/mcp-server/sync-notifier.ts +88 -35
  176. package/package.json +2 -1
  177. package/src/app.css +187 -0
  178. package/src/app.html +15 -1
  179. package/src/features/behavior-model/domain/services/BehaviorGraphModel.ts +531 -0
  180. package/src/features/behavior-model/presentation/adapters/VisBehaviorGraphRenderer.ts +492 -0
  181. package/src/features/behavior-model/presentation/components/BehaviorGraph.svelte +370 -0
  182. package/src/features/behavior-model/presentation/components/FeatureHeader.svelte +13 -5
  183. package/src/features/behavior-model/presentation/view-models/BehaviorGraphTheme.ts +43 -0
  184. package/src/features/builder-mode/domain/BuilderModeDashboard.ts +7 -1
  185. package/src/features/builder-mode/presentation/components/BuilderModeDashboard.svelte +78 -16
  186. package/src/features/builder-mode/presentation/components/BuilderTagChips.svelte +25 -0
  187. package/src/features/builder-mode/presentation/stores/builderModeStore.svelte.ts +247 -3
  188. package/src/features/projects/presentation/components/ProjectEditor.svelte +7 -0
  189. package/src/features/simulator/application/use-cases/RunScenarios.ts +15 -1
  190. package/src/hooks.server.ts +11 -1
  191. package/src/lib/theme/registry.ts +77 -0
  192. package/src/lib/theme/themeStore.svelte.ts +64 -0
  193. package/src/routes/+layout.svelte +184 -30
  194. package/src/routes/features/[id]/graph/+page.svelte +34 -0
  195. package/src/routes/projects/[id]/graph/+page.svelte +79 -0
  196. package/src/shared/presentation/components/ProgressBar.svelte +1 -1
  197. package/src/shared/presentation/toast/SyncToast.svelte +14 -3
  198. package/src/shared/presentation/toast/viewLinkResolver.ts +32 -0
  199. package/static/lyriks_logo.svg +148 -0
  200. package/build/client/_app/immutable/assets/0.DFMDYAU9.css +0 -1
  201. package/build/client/_app/immutable/assets/0.DFMDYAU9.css.br +0 -0
  202. package/build/client/_app/immutable/assets/0.DFMDYAU9.css.gz +0 -0
  203. package/build/client/_app/immutable/chunks/BO66rBOa2.js +0 -1
  204. package/build/client/_app/immutable/chunks/BO66rBOa2.js.br +0 -0
  205. package/build/client/_app/immutable/chunks/BO66rBOa2.js.gz +0 -0
  206. package/build/client/_app/immutable/chunks/DBJWcC6Y.js.br +0 -0
  207. package/build/client/_app/immutable/chunks/DBJWcC6Y.js.gz +0 -0
  208. package/build/client/_app/immutable/chunks/DHoA038D.js +0 -1
  209. package/build/client/_app/immutable/chunks/DHoA038D.js.br +0 -2
  210. package/build/client/_app/immutable/chunks/DHoA038D.js.gz +0 -0
  211. package/build/client/_app/immutable/chunks/DatGSObE.js.br +0 -0
  212. package/build/client/_app/immutable/chunks/DatGSObE.js.gz +0 -0
  213. package/build/client/_app/immutable/chunks/DjWKKtqp.js +0 -1
  214. package/build/client/_app/immutable/chunks/DjWKKtqp.js.br +0 -1
  215. package/build/client/_app/immutable/chunks/DjWKKtqp.js.gz +0 -0
  216. package/build/client/_app/immutable/chunks/Dq0DUAz1.js +0 -1
  217. package/build/client/_app/immutable/chunks/Dq0DUAz1.js.br +0 -0
  218. package/build/client/_app/immutable/chunks/Dq0DUAz1.js.gz +0 -0
  219. package/build/client/_app/immutable/chunks/iQu0D9Ux.js +0 -1
  220. package/build/client/_app/immutable/chunks/iQu0D9Ux.js.br +0 -0
  221. package/build/client/_app/immutable/chunks/iQu0D9Ux.js.gz +0 -0
  222. package/build/client/_app/immutable/entry/app.CLgh6Mx_.js +0 -2
  223. package/build/client/_app/immutable/entry/app.CLgh6Mx_.js.br +0 -0
  224. package/build/client/_app/immutable/entry/app.CLgh6Mx_.js.gz +0 -0
  225. package/build/client/_app/immutable/entry/start.D5GPCQZD.js +0 -1
  226. package/build/client/_app/immutable/entry/start.D5GPCQZD.js.br +0 -0
  227. package/build/client/_app/immutable/entry/start.D5GPCQZD.js.gz +0 -0
  228. package/build/client/_app/immutable/nodes/0.BOoI-hsu.js +0 -4
  229. package/build/client/_app/immutable/nodes/0.BOoI-hsu.js.br +0 -0
  230. package/build/client/_app/immutable/nodes/0.BOoI-hsu.js.gz +0 -0
  231. package/build/client/_app/immutable/nodes/1.KYdA6ppX.js.br +0 -2
  232. package/build/client/_app/immutable/nodes/1.KYdA6ppX.js.gz +0 -0
  233. package/build/client/_app/immutable/nodes/2.DBz20KgG.js.br +0 -0
  234. package/build/client/_app/immutable/nodes/2.DBz20KgG.js.gz +0 -0
  235. package/build/client/_app/immutable/nodes/3.19DIoFtw.js +0 -1
  236. package/build/client/_app/immutable/nodes/3.19DIoFtw.js.br +0 -0
  237. package/build/client/_app/immutable/nodes/3.19DIoFtw.js.gz +0 -0
  238. package/build/client/_app/immutable/nodes/4.BvMzqBJj.js.br +0 -0
  239. package/build/client/_app/immutable/nodes/4.BvMzqBJj.js.gz +0 -0
  240. package/build/client/_app/immutable/nodes/5.Dq6obSGG.js +0 -42
  241. package/build/client/_app/immutable/nodes/5.Dq6obSGG.js.br +0 -0
  242. package/build/client/_app/immutable/nodes/5.Dq6obSGG.js.gz +0 -0
  243. package/build/client/_app/immutable/nodes/6.BOHISqs-.js.br +0 -0
  244. package/build/client/_app/immutable/nodes/6.BOHISqs-.js.gz +0 -0
  245. package/build/client/_app/immutable/nodes/7.CemgNJfw.js.br +0 -0
  246. package/build/client/_app/immutable/nodes/7.CemgNJfw.js.gz +0 -0
  247. package/build/client/_app/immutable/nodes/8.DejSfIYh.js +0 -5
  248. package/build/client/_app/immutable/nodes/8.DejSfIYh.js.br +0 -0
  249. package/build/client/_app/immutable/nodes/8.DejSfIYh.js.gz +0 -0
  250. package/build/client/_app/immutable/nodes/9.CMW6a2Lg.js.br +0 -0
  251. package/build/client/_app/immutable/nodes/9.CMW6a2Lg.js.gz +0 -0
  252. package/build/server/chunks/1-DPpKAKXV.js +0 -9
  253. package/build/server/chunks/5-D7OCJpxD.js +0 -9
  254. package/build/server/chunks/5-D7OCJpxD.js.map +0 -1
  255. package/build/server/chunks/8-CVO-E-sf.js +0 -9
  256. package/build/server/chunks/8-CVO-E-sf.js.map +0 -1
  257. package/build/server/chunks/9-DxT1baO5.js +0 -9
  258. package/build/server/chunks/9-DxT1baO5.js.map +0 -1
  259. package/build/server/chunks/ProgressBar-CfhccQ83.js.map +0 -1
  260. package/build/server/chunks/_layout.svelte-BREws55o.js.map +0 -1
  261. package/build/server/chunks/_page.svelte-BqSC-1vK.js.map +0 -1
  262. package/build/server/chunks/_page.svelte-BtI2zZ_Z.js.map +0 -1
  263. package/build/server/chunks/_page.svelte-Zf9H4KOP.js.map +0 -1
  264. package/build/server/chunks/builderModeStore.svelte-ihupr-3p.js.map +0 -1
  265. package/build/server/chunks/client-DfpLcAZ9.js +0 -24
  266. package/build/server/chunks/hooks.server-Rv301GTB.js.map +0 -1
  267. package/build/server/chunks/reconcile-Dv7jS3C8.js.map +0 -1
  268. /package/build/client/_app/immutable/assets/{9.nv0I59TU.css → 11.nv0I59TU.css} +0 -0
  269. /package/build/client/_app/immutable/assets/{9.nv0I59TU.css.br → 11.nv0I59TU.css.br} +0 -0
  270. /package/build/client/_app/immutable/assets/{9.nv0I59TU.css.gz → 11.nv0I59TU.css.gz} +0 -0
@@ -2,21 +2,21 @@ import { A as head, t as escape_html, g as attr, r as ensure_array_like, q as de
2
2
  import { x as humanizeTagText, X as tagKey } from './TagPalette-CtMNYCmu.js';
3
3
  import { a as asProjectId } from './ids-t7Gjdj0M.js';
4
4
  import { e as confirmDialog } from './browserContainer-CNX7ANld.js';
5
- import './client-DfpLcAZ9.js';
5
+ import './client-DeX3TC3s.js';
6
6
  import { p as projectsStore } from './projectsStore.svelte-QDz5PchX.js';
7
7
  import { f as featuresStore } from './featuresStore.svelte-DR1gYZyu.js';
8
8
  import { T as TagFilterSelect } from './TagFilterSelect-DbO0Qduh.js';
9
9
  import { M as ManageTagsDialog } from './ManageTagsDialog-DBxA3tM2.js';
10
- import { F as FeatureCard } from './FeatureCard-BQOY6gJQ.js';
10
+ import { F as FeatureCard } from './FeatureCard-CfbXNYe8.js';
11
11
  import './FeatureValidator-B8qEjAUW.js';
12
12
  import './RenameTag-BuWLMl1m.js';
13
- import './internal-BPKrFkK1.js';
13
+ import './internal-KYK0WpL7.js';
14
14
  import './index-DBqjc0Yf.js';
15
15
  import './eventBus-B9k-Vzso.js';
16
16
  import './FeatureJson-Bv-qiOSf.js';
17
17
  import './tagPaletteStore.svelte-DfZOBvgY.js';
18
18
  import './TagDotStrip-B1XQ0m0Y.js';
19
- import './ProgressBar-CfhccQ83.js';
19
+ import './ProgressBar-DDoQJ_C9.js';
20
20
 
21
21
  //#region src/routes/features/+page.svelte
22
22
  function _page($$renderer, $$props) {
@@ -194,4 +194,4 @@ function _page($$renderer, $$props) {
194
194
  }
195
195
 
196
196
  export { _page as default };
197
- //# sourceMappingURL=_page.svelte-BKTveFAj.js.map
197
+ //# sourceMappingURL=_page.svelte-Oj-W7G5s.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"_page.svelte-BKTveFAj.js","sources":["../../../.svelte-kit/adapter-node/entries/pages/features/_page.svelte.js"],"sourcesContent":["import { G as attr, d as head, l as derived, q as escape_html, u as ensure_array_like } from \"../../../chunks/index-server.js\";\nimport { Z as tagKey, q as humanizeTagText } from \"../../../chunks/TagPalette.js\";\nimport { t as asProjectId } from \"../../../chunks/ids.js\";\nimport { y as confirmDialog } from \"../../../chunks/browserContainer.js\";\nimport \"../../../chunks/navigation.js\";\nimport { t as projectsStore } from \"../../../chunks/projectsStore.svelte.js\";\nimport \"../../../chunks/tagPaletteStore.svelte.js\";\nimport { t as featuresStore } from \"../../../chunks/featuresStore.svelte.js\";\nimport { t as TagFilterSelect } from \"../../../chunks/TagFilterSelect.js\";\nimport { t as ManageTagsDialog } from \"../../../chunks/ManageTagsDialog.js\";\nimport { t as FeatureCard } from \"../../../chunks/FeatureCard.js\";\n//#region src/routes/features/+page.svelte\nfunction _page($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\tasync function handleDelete(id) {\n\t\t\tif (!await confirmDialog({\n\t\t\t\ttitle: `Delete \"${featuresStore.summaries.find((s) => String(s.id) === String(id))?.name ?? \"this feature\"}\"?`,\n\t\t\t\tmessage: \"Its surfaces, actions, rules, and scenarios will be removed. Any project that references it keeps the link, but the feature itself is gone. This cannot be undone.\",\n\t\t\t\tconfirmLabel: \"Delete feature\",\n\t\t\t\ttone: \"danger\"\n\t\t\t})) return;\n\t\t\tawait featuresStore.remove(id);\n\t\t}\n\t\tlet loadingSamples = false;\n\t\tlet search = \"\";\n\t\tlet moreOpen = false;\n\t\tlet sortBy = \"updated\";\n\t\tlet projectFilter = \"all\";\n\t\tlet tagFilter = \"all\";\n\t\tlet manageTagsOpen = false;\n\t\tlet projectMembership = /* @__PURE__ */ new Map();\n\t\tconst totalSurfaces = derived(() => featuresStore.summaries.reduce((total, summary) => total + summary.surfaceCount, 0));\n\t\tconst totalCapabilities = derived(() => featuresStore.summaries.reduce((total, summary) => total + summary.actionCount, 0));\n\t\tconst averageMaturity = derived(() => featuresStore.summaries.length === 0 ? 0 : Math.round(featuresStore.summaries.reduce((total, summary) => total + summary.maturityPercentage, 0) / featuresStore.summaries.length));\n\t\tconst allTagsFlat = derived(() => {\n\t\t\tconst out = [];\n\t\t\tfor (const summary of featuresStore.summaries) for (const tag of summary.tags ?? []) out.push(tag);\n\t\t\treturn out;\n\t\t});\n\t\tconst tagTypeOptions = derived(() => [...new Set(allTagsFlat().map((tag) => humanizeTagText(tag.type)))].sort((a, b) => a.localeCompare(b)));\n\t\tconst filtered = derived(() => {\n\t\t\tconst q = search.trim().toLowerCase();\n\t\t\tconst bySearch = (summary) => q.length === 0 || summary.name.toLowerCase().includes(q) || (summary.description ?? \"\").toLowerCase().includes(q);\n\t\t\tconst byProject = (id) => {\n\t\t\t\tif (projectFilter === \"all\") return true;\n\t\t\t\tif (projectFilter === \"unassigned\") {\n\t\t\t\t\tfor (const members of projectMembership.values()) if (members.has(id)) return false;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn projectMembership.get(projectFilter)?.has(id) ?? false;\n\t\t\t};\n\t\t\treturn featuresStore.summaries.filter((summary) => bySearch(summary) && byProject(String(summary.id)) && byTag(summary, tagFilter)).sort((a, b) => {\n\t\t\t\treturn new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime();\n\t\t\t});\n\t\t});\n\t\tfunction byTag(summary, filter) {\n\t\t\tconst tags = summary.tags ?? [];\n\t\t\tif (filter === \"all\") return true;\n\t\t\tif (filter === \"untagged\") return tags.length === 0;\n\t\t\tconst key = tagKey(filter);\n\t\t\treturn tags.some((t) => tagKey(t) === key);\n\t\t}\n\t\tfunction tagFilterCount(filter) {\n\t\t\treturn featuresStore.summaries.filter((s) => byTag(s, filter)).length;\n\t\t}\n\t\thead(\"1d0dgro\", $$renderer, ($$renderer) => {\n\t\t\t$$renderer.title(($$renderer) => {\n\t\t\t\t$$renderer.push(`<title>Features / Unspaghettit</title>`);\n\t\t\t});\n\t\t});\n\t\t$$renderer.push(`<div class=\"mx-auto max-w-7xl px-4 py-8 sm:px-6\"><header class=\"mb-6 border-b border-slate-200 pb-6\"><div class=\"grid gap-6 lg:grid-cols-[minmax(0,1fr)_auto] lg:items-end\"><div class=\"max-w-3xl\"><div><p class=\"text-xs font-semibold uppercase tracking-wide text-brand-700\">Behavior models</p> <h1 class=\"mt-2 text-4xl font-semibold tracking-tight text-slate-950\">Features</h1> <p class=\"mt-2 max-w-2xl text-sm leading-6 text-slate-600\">Describe what software does as surfaces, actions, states, rules, effects, and events.</p></div></div> <div class=\"grid grid-cols-2 gap-3 sm:grid-cols-4 lg:w-[42rem]\"><div class=\"rounded-xl border border-slate-200 bg-white p-4 shadow-sm shadow-slate-950/5\"><p class=\"text-xs font-medium uppercase tracking-wide text-brand-700\">Models</p> <p class=\"mt-2 text-2xl font-semibold text-slate-950\">${escape_html(filtered().length)}</p> <p class=\"mt-1 text-xs text-slate-500\">${escape_html(featuresStore.summaries.length)} total</p></div> <div class=\"rounded-xl border border-slate-200 bg-white p-4 shadow-sm shadow-slate-950/5\"><p class=\"text-xs font-medium uppercase tracking-wide text-violet-700\">Surfaces</p> <p class=\"mt-2 text-2xl font-semibold text-slate-950\">${escape_html(totalSurfaces())}</p> <p class=\"mt-1 text-xs text-slate-500\">Across models</p></div> <div class=\"rounded-xl border border-slate-200 bg-white p-4 shadow-sm shadow-slate-950/5\"><p class=\"text-xs font-medium uppercase tracking-wide text-amber-700\">Actions</p> <p class=\"mt-2 text-2xl font-semibold text-slate-950\">${escape_html(totalCapabilities())}</p> <p class=\"mt-1 text-xs text-slate-500\">Actions</p></div> <div class=\"rounded-xl border border-slate-200 bg-white p-4 shadow-sm shadow-slate-950/5\"><p class=\"text-xs font-medium uppercase tracking-wide text-emerald-700\">Maturity</p> <p class=\"mt-2 text-2xl font-semibold text-slate-950\">${escape_html(averageMaturity())}%</p> <p class=\"mt-1 text-xs text-slate-500\">Average</p></div></div></div> <div class=\"mt-6 flex flex-col gap-3 rounded-xl border border-slate-200 bg-white p-3 shadow-sm shadow-slate-950/5 lg:flex-row lg:items-center lg:justify-between\"><div class=\"flex min-w-0 items-center rounded-lg border border-hairline bg-white p-1 lg:flex-1\"><label for=\"feature-search\" class=\"sr-only\">Search features</label> <input id=\"feature-search\" type=\"search\" placeholder=\"Search features...\"${attr(\"value\", search)} class=\"h-9 w-full min-w-0 rounded-md border-0 bg-transparent px-3 text-sm outline-none placeholder:text-slate-400\"/> `);\n\t\tif (search.trim().length > 0) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<button type=\"button\" class=\"h-8 rounded-md px-2 text-xs font-medium text-slate-500 hover:bg-slate-50 hover:text-slate-900\">Clear</button>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--></div> <div class=\"flex flex-col gap-2 sm:flex-row sm:items-center\"><label class=\"flex h-10 items-center gap-2 rounded-lg border border-hairline bg-white px-3 text-sm text-slate-600\"><span class=\"text-xs font-medium\">Project</span> `);\n\t\t$$renderer.select({\n\t\t\tvalue: projectFilter,\n\t\t\tonchange: (event) => {\n\t\t\t\tconst v = event.currentTarget.value;\n\t\t\t\tprojectFilter = v === \"all\" || v === \"unassigned\" ? v : asProjectId(v);\n\t\t\t},\n\t\t\tclass: \"bg-transparent text-sm font-medium text-slate-800 outline-none\"\n\t\t}, ($$renderer) => {\n\t\t\t$$renderer.option({ value: \"all\" }, ($$renderer) => {\n\t\t\t\t$$renderer.push(`All`);\n\t\t\t});\n\t\t\t$$renderer.option({ value: \"unassigned\" }, ($$renderer) => {\n\t\t\t\t$$renderer.push(`Unassigned`);\n\t\t\t});\n\t\t\t$$renderer.push(`<!--[-->`);\n\t\t\tconst each_array = ensure_array_like(projectsStore.summaries);\n\t\t\tfor (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {\n\t\t\t\tlet project = each_array[$$index];\n\t\t\t\t$$renderer.option({ value: project.id }, ($$renderer) => {\n\t\t\t\t\t$$renderer.push(`${escape_html(project.name)}`);\n\t\t\t\t});\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]-->`);\n\t\t});\n\t\t$$renderer.push(`</label> `);\n\t\tTagFilterSelect($$renderer, {\n\t\t\ttags: allTagsFlat(),\n\t\t\tvalue: tagFilter,\n\t\t\tonChange: (next) => tagFilter = next,\n\t\t\tonManage: () => manageTagsOpen = true,\n\t\t\tcountLabel: tagFilterCount\n\t\t});\n\t\t$$renderer.push(`<!----> <label class=\"flex h-10 items-center gap-2 rounded-lg border border-hairline bg-white px-3 text-sm text-slate-600\"><span class=\"text-xs font-medium\">Sort</span> `);\n\t\t$$renderer.select({\n\t\t\tvalue: sortBy,\n\t\t\tclass: \"bg-transparent text-sm font-medium text-slate-800 outline-none\"\n\t\t}, ($$renderer) => {\n\t\t\t$$renderer.option({ value: \"updated\" }, ($$renderer) => {\n\t\t\t\t$$renderer.push(`Updated`);\n\t\t\t});\n\t\t\t$$renderer.option({ value: \"name\" }, ($$renderer) => {\n\t\t\t\t$$renderer.push(`Name`);\n\t\t\t});\n\t\t\t$$renderer.option({ value: \"maturity\" }, ($$renderer) => {\n\t\t\t\t$$renderer.push(`Maturity`);\n\t\t\t});\n\t\t});\n\t\t$$renderer.push(`</label> <div class=\"relative\"><button type=\"button\" class=\"inline-flex h-10 items-center gap-2 rounded-lg border border-hairline bg-white px-3 text-sm font-medium text-slate-700 hover:bg-slate-50\"${attr(\"aria-expanded\", moreOpen)}>More <span class=\"text-xs text-slate-400\" aria-hidden=\"true\">v</span></button> `);\n\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--></div> <a href=\"/projects\" class=\"inline-flex h-10 items-center justify-center gap-2 rounded-md bg-slate-900 px-4 text-sm font-medium text-white hover:bg-slate-800\" title=\"New features are created from a project\"><span class=\"text-base leading-none\" aria-hidden=\"true\">+</span> New feature</a></div></div></header> <section aria-labelledby=\"features-list-title\"><div class=\"mb-3 flex flex-col gap-1 sm:flex-row sm:items-end sm:justify-between\"><div><h2 id=\"features-list-title\" class=\"text-base font-semibold text-slate-950\">Behavior models</h2> <p class=\"text-sm text-slate-500\">Open an feature to edit surfaces, rules, effects, and scenarios.</p></div> <p class=\"text-xs text-slate-500\">${escape_html(filtered().length)} shown</p></div> `);\n\t\tif (featuresStore.loading) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"rounded-lg border border-dashed border-hairline bg-white p-8 text-center text-sm text-slate-500\">Loading features...</div>`);\n\t\t} else if (featuresStore.error) {\n\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t$$renderer.push(`<div class=\"rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-700\">${escape_html(featuresStore.error)}</div>`);\n\t\t} else if (filtered().length === 0) {\n\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t$$renderer.push(`<div class=\"rounded-lg border border-dashed border-hairline bg-white p-8 text-center text-sm text-slate-500\">`);\n\t\t\tif (featuresStore.summaries.length === 0) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<div class=\"space-y-3\"><p>No features yet.</p> <p class=\"text-xs\">Features live inside projects. Start by opening or creating a project.</p> <div class=\"flex flex-wrap justify-center gap-2\"><a href=\"/projects\" class=\"rounded-md bg-slate-900 px-4 py-2 text-sm font-medium text-white\">Go to projects</a> <button type=\"button\" class=\"rounded-md border border-slate-300 bg-white px-4 py-2 text-sm font-medium text-slate-700\"${attr(\"disabled\", loadingSamples, true)}>${escape_html(\"Load sample project\")}</button></div></div>`);\n\t\t\t} else {\n\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`No features match your search.`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]--></div>`);\n\t\t} else {\n\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<ul class=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\"><!--[-->`);\n\t\t\tconst each_array_1 = ensure_array_like(filtered());\n\t\t\tfor (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {\n\t\t\t\tlet summary = each_array_1[$$index_1];\n\t\t\t\t$$renderer.push(`<li>`);\n\t\t\t\tFeatureCard($$renderer, {\n\t\t\t\t\tsummary,\n\t\t\t\t\ttagTypeOptions: tagTypeOptions(),\n\t\t\t\t\tonAddTag: (type, value) => featuresStore.addTag(String(summary.id), {\n\t\t\t\t\t\ttype,\n\t\t\t\t\t\tvalue\n\t\t\t\t\t}),\n\t\t\t\t\tonRemoveTag: async (type, value) => {\n\t\t\t\t\t\tawait featuresStore.removeTag(String(summary.id), {\n\t\t\t\t\t\t\ttype,\n\t\t\t\t\t\t\tvalue\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (tagFilter !== \"all\" && tagFilter !== \"untagged\" && tagKey(tagFilter) === tagKey({\n\t\t\t\t\t\t\ttype,\n\t\t\t\t\t\t\tvalue\n\t\t\t\t\t\t})) tagFilter = \"all\";\n\t\t\t\t\t},\n\t\t\t\t\tonDelete: () => handleDelete(summary.id)\n\t\t\t\t});\n\t\t\t\t$$renderer.push(`<!----></li>`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]--></ul>`);\n\t\t}\n\t\t$$renderer.push(`<!--]--></section></div> `);\n\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tManageTagsDialog($$renderer, {\n\t\t\topen: manageTagsOpen,\n\t\t\ttags: allTagsFlat(),\n\t\t\tonClose: () => manageTagsOpen = false,\n\t\t\tonRenamed: () => featuresStore.refreshSilent()\n\t\t});\n\t\t$$renderer.push(`<!---->`);\n\t});\n}\n//#endregion\nexport { _page as default };\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"_page.svelte-Oj-W7G5s.js","sources":["../../../.svelte-kit/adapter-node/entries/pages/features/_page.svelte.js"],"sourcesContent":["import { G as attr, d as head, l as derived, q as escape_html, u as ensure_array_like } from \"../../../chunks/index-server.js\";\nimport { Z as tagKey, q as humanizeTagText } from \"../../../chunks/TagPalette.js\";\nimport { t as asProjectId } from \"../../../chunks/ids.js\";\nimport { y as confirmDialog } from \"../../../chunks/browserContainer.js\";\nimport \"../../../chunks/navigation.js\";\nimport { t as projectsStore } from \"../../../chunks/projectsStore.svelte.js\";\nimport \"../../../chunks/tagPaletteStore.svelte.js\";\nimport { t as featuresStore } from \"../../../chunks/featuresStore.svelte.js\";\nimport { t as TagFilterSelect } from \"../../../chunks/TagFilterSelect.js\";\nimport { t as ManageTagsDialog } from \"../../../chunks/ManageTagsDialog.js\";\nimport { t as FeatureCard } from \"../../../chunks/FeatureCard.js\";\n//#region src/routes/features/+page.svelte\nfunction _page($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\tasync function handleDelete(id) {\n\t\t\tif (!await confirmDialog({\n\t\t\t\ttitle: `Delete \"${featuresStore.summaries.find((s) => String(s.id) === String(id))?.name ?? \"this feature\"}\"?`,\n\t\t\t\tmessage: \"Its surfaces, actions, rules, and scenarios will be removed. Any project that references it keeps the link, but the feature itself is gone. This cannot be undone.\",\n\t\t\t\tconfirmLabel: \"Delete feature\",\n\t\t\t\ttone: \"danger\"\n\t\t\t})) return;\n\t\t\tawait featuresStore.remove(id);\n\t\t}\n\t\tlet loadingSamples = false;\n\t\tlet search = \"\";\n\t\tlet moreOpen = false;\n\t\tlet sortBy = \"updated\";\n\t\tlet projectFilter = \"all\";\n\t\tlet tagFilter = \"all\";\n\t\tlet manageTagsOpen = false;\n\t\tlet projectMembership = /* @__PURE__ */ new Map();\n\t\tconst totalSurfaces = derived(() => featuresStore.summaries.reduce((total, summary) => total + summary.surfaceCount, 0));\n\t\tconst totalCapabilities = derived(() => featuresStore.summaries.reduce((total, summary) => total + summary.actionCount, 0));\n\t\tconst averageMaturity = derived(() => featuresStore.summaries.length === 0 ? 0 : Math.round(featuresStore.summaries.reduce((total, summary) => total + summary.maturityPercentage, 0) / featuresStore.summaries.length));\n\t\tconst allTagsFlat = derived(() => {\n\t\t\tconst out = [];\n\t\t\tfor (const summary of featuresStore.summaries) for (const tag of summary.tags ?? []) out.push(tag);\n\t\t\treturn out;\n\t\t});\n\t\tconst tagTypeOptions = derived(() => [...new Set(allTagsFlat().map((tag) => humanizeTagText(tag.type)))].sort((a, b) => a.localeCompare(b)));\n\t\tconst filtered = derived(() => {\n\t\t\tconst q = search.trim().toLowerCase();\n\t\t\tconst bySearch = (summary) => q.length === 0 || summary.name.toLowerCase().includes(q) || (summary.description ?? \"\").toLowerCase().includes(q);\n\t\t\tconst byProject = (id) => {\n\t\t\t\tif (projectFilter === \"all\") return true;\n\t\t\t\tif (projectFilter === \"unassigned\") {\n\t\t\t\t\tfor (const members of projectMembership.values()) if (members.has(id)) return false;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn projectMembership.get(projectFilter)?.has(id) ?? false;\n\t\t\t};\n\t\t\treturn featuresStore.summaries.filter((summary) => bySearch(summary) && byProject(String(summary.id)) && byTag(summary, tagFilter)).sort((a, b) => {\n\t\t\t\treturn new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime();\n\t\t\t});\n\t\t});\n\t\tfunction byTag(summary, filter) {\n\t\t\tconst tags = summary.tags ?? [];\n\t\t\tif (filter === \"all\") return true;\n\t\t\tif (filter === \"untagged\") return tags.length === 0;\n\t\t\tconst key = tagKey(filter);\n\t\t\treturn tags.some((t) => tagKey(t) === key);\n\t\t}\n\t\tfunction tagFilterCount(filter) {\n\t\t\treturn featuresStore.summaries.filter((s) => byTag(s, filter)).length;\n\t\t}\n\t\thead(\"1d0dgro\", $$renderer, ($$renderer) => {\n\t\t\t$$renderer.title(($$renderer) => {\n\t\t\t\t$$renderer.push(`<title>Features / Unspaghettit</title>`);\n\t\t\t});\n\t\t});\n\t\t$$renderer.push(`<div class=\"mx-auto max-w-7xl px-4 py-8 sm:px-6\"><header class=\"mb-6 border-b border-slate-200 pb-6\"><div class=\"grid gap-6 lg:grid-cols-[minmax(0,1fr)_auto] lg:items-end\"><div class=\"max-w-3xl\"><div><p class=\"text-xs font-semibold uppercase tracking-wide text-brand-700\">Behavior models</p> <h1 class=\"mt-2 text-4xl font-semibold tracking-tight text-slate-950\">Features</h1> <p class=\"mt-2 max-w-2xl text-sm leading-6 text-slate-600\">Describe what software does as surfaces, actions, states, rules, effects, and events.</p></div></div> <div class=\"grid grid-cols-2 gap-3 sm:grid-cols-4 lg:w-[42rem]\"><div class=\"rounded-xl border border-slate-200 bg-white p-4 shadow-sm shadow-slate-950/5\"><p class=\"text-xs font-medium uppercase tracking-wide text-brand-700\">Models</p> <p class=\"mt-2 text-2xl font-semibold text-slate-950\">${escape_html(filtered().length)}</p> <p class=\"mt-1 text-xs text-slate-500\">${escape_html(featuresStore.summaries.length)} total</p></div> <div class=\"rounded-xl border border-slate-200 bg-white p-4 shadow-sm shadow-slate-950/5\"><p class=\"text-xs font-medium uppercase tracking-wide text-violet-700\">Surfaces</p> <p class=\"mt-2 text-2xl font-semibold text-slate-950\">${escape_html(totalSurfaces())}</p> <p class=\"mt-1 text-xs text-slate-500\">Across models</p></div> <div class=\"rounded-xl border border-slate-200 bg-white p-4 shadow-sm shadow-slate-950/5\"><p class=\"text-xs font-medium uppercase tracking-wide text-amber-700\">Actions</p> <p class=\"mt-2 text-2xl font-semibold text-slate-950\">${escape_html(totalCapabilities())}</p> <p class=\"mt-1 text-xs text-slate-500\">Actions</p></div> <div class=\"rounded-xl border border-slate-200 bg-white p-4 shadow-sm shadow-slate-950/5\"><p class=\"text-xs font-medium uppercase tracking-wide text-emerald-700\">Maturity</p> <p class=\"mt-2 text-2xl font-semibold text-slate-950\">${escape_html(averageMaturity())}%</p> <p class=\"mt-1 text-xs text-slate-500\">Average</p></div></div></div> <div class=\"mt-6 flex flex-col gap-3 rounded-xl border border-slate-200 bg-white p-3 shadow-sm shadow-slate-950/5 lg:flex-row lg:items-center lg:justify-between\"><div class=\"flex min-w-0 items-center rounded-lg border border-hairline bg-white p-1 lg:flex-1\"><label for=\"feature-search\" class=\"sr-only\">Search features</label> <input id=\"feature-search\" type=\"search\" placeholder=\"Search features...\"${attr(\"value\", search)} class=\"h-9 w-full min-w-0 rounded-md border-0 bg-transparent px-3 text-sm outline-none placeholder:text-slate-400\"/> `);\n\t\tif (search.trim().length > 0) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<button type=\"button\" class=\"h-8 rounded-md px-2 text-xs font-medium text-slate-500 hover:bg-slate-50 hover:text-slate-900\">Clear</button>`);\n\t\t} else $$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--></div> <div class=\"flex flex-col gap-2 sm:flex-row sm:items-center\"><label class=\"flex h-10 items-center gap-2 rounded-lg border border-hairline bg-white px-3 text-sm text-slate-600\"><span class=\"text-xs font-medium\">Project</span> `);\n\t\t$$renderer.select({\n\t\t\tvalue: projectFilter,\n\t\t\tonchange: (event) => {\n\t\t\t\tconst v = event.currentTarget.value;\n\t\t\t\tprojectFilter = v === \"all\" || v === \"unassigned\" ? v : asProjectId(v);\n\t\t\t},\n\t\t\tclass: \"bg-transparent text-sm font-medium text-slate-800 outline-none\"\n\t\t}, ($$renderer) => {\n\t\t\t$$renderer.option({ value: \"all\" }, ($$renderer) => {\n\t\t\t\t$$renderer.push(`All`);\n\t\t\t});\n\t\t\t$$renderer.option({ value: \"unassigned\" }, ($$renderer) => {\n\t\t\t\t$$renderer.push(`Unassigned`);\n\t\t\t});\n\t\t\t$$renderer.push(`<!--[-->`);\n\t\t\tconst each_array = ensure_array_like(projectsStore.summaries);\n\t\t\tfor (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {\n\t\t\t\tlet project = each_array[$$index];\n\t\t\t\t$$renderer.option({ value: project.id }, ($$renderer) => {\n\t\t\t\t\t$$renderer.push(`${escape_html(project.name)}`);\n\t\t\t\t});\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]-->`);\n\t\t});\n\t\t$$renderer.push(`</label> `);\n\t\tTagFilterSelect($$renderer, {\n\t\t\ttags: allTagsFlat(),\n\t\t\tvalue: tagFilter,\n\t\t\tonChange: (next) => tagFilter = next,\n\t\t\tonManage: () => manageTagsOpen = true,\n\t\t\tcountLabel: tagFilterCount\n\t\t});\n\t\t$$renderer.push(`<!----> <label class=\"flex h-10 items-center gap-2 rounded-lg border border-hairline bg-white px-3 text-sm text-slate-600\"><span class=\"text-xs font-medium\">Sort</span> `);\n\t\t$$renderer.select({\n\t\t\tvalue: sortBy,\n\t\t\tclass: \"bg-transparent text-sm font-medium text-slate-800 outline-none\"\n\t\t}, ($$renderer) => {\n\t\t\t$$renderer.option({ value: \"updated\" }, ($$renderer) => {\n\t\t\t\t$$renderer.push(`Updated`);\n\t\t\t});\n\t\t\t$$renderer.option({ value: \"name\" }, ($$renderer) => {\n\t\t\t\t$$renderer.push(`Name`);\n\t\t\t});\n\t\t\t$$renderer.option({ value: \"maturity\" }, ($$renderer) => {\n\t\t\t\t$$renderer.push(`Maturity`);\n\t\t\t});\n\t\t});\n\t\t$$renderer.push(`</label> <div class=\"relative\"><button type=\"button\" class=\"inline-flex h-10 items-center gap-2 rounded-lg border border-hairline bg-white px-3 text-sm font-medium text-slate-700 hover:bg-slate-50\"${attr(\"aria-expanded\", moreOpen)}>More <span class=\"text-xs text-slate-400\" aria-hidden=\"true\">v</span></button> `);\n\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--></div> <a href=\"/projects\" class=\"inline-flex h-10 items-center justify-center gap-2 rounded-md bg-slate-900 px-4 text-sm font-medium text-white hover:bg-slate-800\" title=\"New features are created from a project\"><span class=\"text-base leading-none\" aria-hidden=\"true\">+</span> New feature</a></div></div></header> <section aria-labelledby=\"features-list-title\"><div class=\"mb-3 flex flex-col gap-1 sm:flex-row sm:items-end sm:justify-between\"><div><h2 id=\"features-list-title\" class=\"text-base font-semibold text-slate-950\">Behavior models</h2> <p class=\"text-sm text-slate-500\">Open an feature to edit surfaces, rules, effects, and scenarios.</p></div> <p class=\"text-xs text-slate-500\">${escape_html(filtered().length)} shown</p></div> `);\n\t\tif (featuresStore.loading) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<div class=\"rounded-lg border border-dashed border-hairline bg-white p-8 text-center text-sm text-slate-500\">Loading features...</div>`);\n\t\t} else if (featuresStore.error) {\n\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t$$renderer.push(`<div class=\"rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-700\">${escape_html(featuresStore.error)}</div>`);\n\t\t} else if (filtered().length === 0) {\n\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t$$renderer.push(`<div class=\"rounded-lg border border-dashed border-hairline bg-white p-8 text-center text-sm text-slate-500\">`);\n\t\t\tif (featuresStore.summaries.length === 0) {\n\t\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t\t$$renderer.push(`<div class=\"space-y-3\"><p>No features yet.</p> <p class=\"text-xs\">Features live inside projects. Start by opening or creating a project.</p> <div class=\"flex flex-wrap justify-center gap-2\"><a href=\"/projects\" class=\"rounded-md bg-slate-900 px-4 py-2 text-sm font-medium text-white\">Go to projects</a> <button type=\"button\" class=\"rounded-md border border-slate-300 bg-white px-4 py-2 text-sm font-medium text-slate-700\"${attr(\"disabled\", loadingSamples, true)}>${escape_html(\"Load sample project\")}</button></div></div>`);\n\t\t\t} else {\n\t\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t\t$$renderer.push(`No features match your search.`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]--></div>`);\n\t\t} else {\n\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<ul class=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\"><!--[-->`);\n\t\t\tconst each_array_1 = ensure_array_like(filtered());\n\t\t\tfor (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {\n\t\t\t\tlet summary = each_array_1[$$index_1];\n\t\t\t\t$$renderer.push(`<li>`);\n\t\t\t\tFeatureCard($$renderer, {\n\t\t\t\t\tsummary,\n\t\t\t\t\ttagTypeOptions: tagTypeOptions(),\n\t\t\t\t\tonAddTag: (type, value) => featuresStore.addTag(String(summary.id), {\n\t\t\t\t\t\ttype,\n\t\t\t\t\t\tvalue\n\t\t\t\t\t}),\n\t\t\t\t\tonRemoveTag: async (type, value) => {\n\t\t\t\t\t\tawait featuresStore.removeTag(String(summary.id), {\n\t\t\t\t\t\t\ttype,\n\t\t\t\t\t\t\tvalue\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (tagFilter !== \"all\" && tagFilter !== \"untagged\" && tagKey(tagFilter) === tagKey({\n\t\t\t\t\t\t\ttype,\n\t\t\t\t\t\t\tvalue\n\t\t\t\t\t\t})) tagFilter = \"all\";\n\t\t\t\t\t},\n\t\t\t\t\tonDelete: () => handleDelete(summary.id)\n\t\t\t\t});\n\t\t\t\t$$renderer.push(`<!----></li>`);\n\t\t\t}\n\t\t\t$$renderer.push(`<!--]--></ul>`);\n\t\t}\n\t\t$$renderer.push(`<!--]--></section></div> `);\n\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t$$renderer.push(`<!--]--> `);\n\t\tManageTagsDialog($$renderer, {\n\t\t\topen: manageTagsOpen,\n\t\t\ttags: allTagsFlat(),\n\t\t\tonClose: () => manageTagsOpen = false,\n\t\t\tonRenamed: () => featuresStore.refreshSilent()\n\t\t});\n\t\t$$renderer.push(`<!---->`);\n\t});\n}\n//#endregion\nexport { _page as default };\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import { W as onDestroy, A as head, t as escape_html } from './index-server-7H0jzj0M.js';
2
+ import './TagPalette-CtMNYCmu.js';
3
+ import './browserContainer-CNX7ANld.js';
4
+ import './client-DeX3TC3s.js';
5
+ import { B as BehaviorGraph } from './BehaviorGraph-m5kYj5HH.js';
6
+ import { a as projectStore, p as projectFeaturesStore } from './projectFeaturesStore.svelte-2o-72_vr.js';
7
+ import './FeatureValidator-B8qEjAUW.js';
8
+ import './ids-t7Gjdj0M.js';
9
+ import './RenameTag-BuWLMl1m.js';
10
+ import './internal-KYK0WpL7.js';
11
+ import './index-DBqjc0Yf.js';
12
+ import './eventBus-B9k-Vzso.js';
13
+ import './reconcile-B5xqb6-s.js';
14
+ import './protocol-3LlFyPP_.js';
15
+ import './identityStore.svelte-IIvW2_3b.js';
16
+ import 'yjs';
17
+
18
+ //#region src/routes/projects/[id]/graph/+page.svelte
19
+ function _page($$renderer, $$props) {
20
+ $$renderer.component(($$renderer) => {
21
+ let unsubscribeSync = null;
22
+ let graphDataReady = false;
23
+ onDestroy(() => {
24
+ unsubscribeSync?.();
25
+ unsubscribeSync = null;
26
+ graphDataReady = false;
27
+ projectStore.reset();
28
+ projectFeaturesStore.reset();
29
+ });
30
+ head("106h624", $$renderer, ($$renderer) => {
31
+ $$renderer.title(($$renderer) => {
32
+ $$renderer.push(`<title>Project Graph / Unspaghettit</title>`);
33
+ });
34
+ });
35
+ if (projectStore.loading) {
36
+ $$renderer.push("<!--[0-->");
37
+ $$renderer.push(`<p class="mx-auto max-w-7xl px-4 py-10 text-sm text-neutral-500">Loading project...</p>`);
38
+ } else if (projectStore.error) {
39
+ $$renderer.push("<!--[1-->");
40
+ $$renderer.push(`<p class="mx-auto max-w-7xl px-4 py-10 text-sm text-red-600">${escape_html(projectStore.error)}</p>`);
41
+ } else if (!projectStore.project) {
42
+ $$renderer.push("<!--[2-->");
43
+ $$renderer.push(`<p class="mx-auto max-w-7xl px-4 py-10 text-sm text-neutral-500">Project not found. <a href="/projects" class="text-brand-700 hover:underline">Back to projects</a></p>`);
44
+ } else if (projectFeaturesStore.loading || !graphDataReady) {
45
+ $$renderer.push("<!--[3-->");
46
+ $$renderer.push(`<p class="mx-auto max-w-7xl px-4 py-10 text-sm text-neutral-500">Loading project features...</p>`);
47
+ } else if (projectFeaturesStore.error) {
48
+ $$renderer.push("<!--[4-->");
49
+ $$renderer.push(`<p class="mx-auto max-w-7xl px-4 py-10 text-sm text-red-600">${escape_html(projectFeaturesStore.error)}</p>`);
50
+ } else if (projectStore.project.featureIds.length > 0 && projectFeaturesStore.features.length === 0) {
51
+ $$renderer.push("<!--[5-->");
52
+ $$renderer.push(`<div class="mx-auto max-w-7xl px-4 py-10"><p class="text-sm font-medium text-slate-900">No feature snapshots loaded for this project.</p> <p class="mt-2 text-sm text-slate-600">The project lists ${escape_html(projectStore.project.featureIds.length)} feature${escape_html(projectStore.project.featureIds.length === 1 ? "" : "s")},
53
+ but the graph could not load their behavior models from the shared hub.</p></div>`);
54
+ } else {
55
+ $$renderer.push("<!--[-1-->");
56
+ $$renderer.push(`<main class="mx-auto max-w-[1800px] px-4 py-6">`);
57
+ BehaviorGraph($$renderer, {
58
+ project: projectStore.project,
59
+ features: projectFeaturesStore.features
60
+ });
61
+ $$renderer.push(`<!----></main>`);
62
+ }
63
+ $$renderer.push(`<!--]-->`);
64
+ });
65
+ }
66
+
67
+ export { _page as default };
68
+ //# sourceMappingURL=_page.svelte-Z_kK2lHY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_page.svelte-Z_kK2lHY.js","sources":["../../../.svelte-kit/adapter-node/entries/pages/projects/_id_/graph/_page.svelte.js"],"sourcesContent":["import { d as head, h as unsubscribe_stores, n as onDestroy, q as escape_html } from \"../../../../../chunks/index-server.js\";\nimport \"../../../../../chunks/TagPalette.js\";\nimport \"../../../../../chunks/ids.js\";\nimport \"../../../../../chunks/syncEvents.js\";\nimport \"../../../../../chunks/stores.js\";\nimport { t as BehaviorGraph } from \"../../../../../chunks/BehaviorGraph.js\";\nimport { n as projectStore, t as projectFeaturesStore } from \"../../../../../chunks/projectFeaturesStore.svelte.js\";\n//#region src/routes/projects/[id]/graph/+page.svelte\nfunction _page($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\tvar $$store_subs;\n\t\tlet unsubscribeSync = null;\n\t\tlet graphDataReady = false;\n\t\tonDestroy(() => {\n\t\t\tunsubscribeSync?.();\n\t\t\tunsubscribeSync = null;\n\t\t\tgraphDataReady = false;\n\t\t\tprojectStore.reset();\n\t\t\tprojectFeaturesStore.reset();\n\t\t});\n\t\thead(\"106h624\", $$renderer, ($$renderer) => {\n\t\t\t$$renderer.title(($$renderer) => {\n\t\t\t\t$$renderer.push(`<title>Project Graph / Unspaghettit</title>`);\n\t\t\t});\n\t\t});\n\t\tif (projectStore.loading) {\n\t\t\t$$renderer.push(\"<!--[0-->\");\n\t\t\t$$renderer.push(`<p class=\"mx-auto max-w-7xl px-4 py-10 text-sm text-neutral-500\">Loading project...</p>`);\n\t\t} else if (projectStore.error) {\n\t\t\t$$renderer.push(\"<!--[1-->\");\n\t\t\t$$renderer.push(`<p class=\"mx-auto max-w-7xl px-4 py-10 text-sm text-red-600\">${escape_html(projectStore.error)}</p>`);\n\t\t} else if (!projectStore.project) {\n\t\t\t$$renderer.push(\"<!--[2-->\");\n\t\t\t$$renderer.push(`<p class=\"mx-auto max-w-7xl px-4 py-10 text-sm text-neutral-500\">Project not found. <a href=\"/projects\" class=\"text-brand-700 hover:underline\">Back to projects</a></p>`);\n\t\t} else if (projectFeaturesStore.loading || !graphDataReady) {\n\t\t\t$$renderer.push(\"<!--[3-->\");\n\t\t\t$$renderer.push(`<p class=\"mx-auto max-w-7xl px-4 py-10 text-sm text-neutral-500\">Loading project features...</p>`);\n\t\t} else if (projectFeaturesStore.error) {\n\t\t\t$$renderer.push(\"<!--[4-->\");\n\t\t\t$$renderer.push(`<p class=\"mx-auto max-w-7xl px-4 py-10 text-sm text-red-600\">${escape_html(projectFeaturesStore.error)}</p>`);\n\t\t} else if (projectStore.project.featureIds.length > 0 && projectFeaturesStore.features.length === 0) {\n\t\t\t$$renderer.push(\"<!--[5-->\");\n\t\t\t$$renderer.push(`<div class=\"mx-auto max-w-7xl px-4 py-10\"><p class=\"text-sm font-medium text-slate-900\">No feature snapshots loaded for this project.</p> <p class=\"mt-2 text-sm text-slate-600\">The project lists ${escape_html(projectStore.project.featureIds.length)} feature${escape_html(projectStore.project.featureIds.length === 1 ? \"\" : \"s\")},\n but the graph could not load their behavior models from the shared hub.</p></div>`);\n\t\t} else {\n\t\t\t$$renderer.push(\"<!--[-1-->\");\n\t\t\t$$renderer.push(`<main class=\"mx-auto max-w-[1800px] px-4 py-6\">`);\n\t\t\tBehaviorGraph($$renderer, {\n\t\t\t\tproject: projectStore.project,\n\t\t\t\tfeatures: projectFeaturesStore.features\n\t\t\t});\n\t\t\t$$renderer.push(`<!----></main>`);\n\t\t}\n\t\t$$renderer.push(`<!--]-->`);\n\t\tif ($$store_subs) unsubscribe_stores($$store_subs);\n\t});\n}\n//#endregion\nexport { _page as default };\n"],"names":[],"mappings":"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"}
@@ -9,6 +9,9 @@ var subscribeSyncEvents = (fn) => {
9
9
  return () => {};
10
10
  };
11
11
 
12
+ /** In-view link for the changed entity, or null to use the default route. */
13
+ var resolveViewLink = (kind, id) => null;
14
+ //#endregion
12
15
  //#region src/features/builder-mode/domain/BuilderModeDashboard.ts
13
16
  var fallbackDescription = "No description yet.";
14
17
  var average = (values) => values.length === 0 ? 0 : Math.round(values.reduce((total, value) => total + value, 0) / values.length);
@@ -55,7 +58,9 @@ var buildBuilderModeDashboard = (inputs) => ({ projects: inputs.map(({ project,
55
58
  description: action.intent || fallbackDescription,
56
59
  maturityPercentage: actionReport?.percentage ?? 0,
57
60
  implementationPercentage,
58
- suggestions: []
61
+ suggestions: [],
62
+ surfaceId: String(surface.id),
63
+ surfaceName: surface.name
59
64
  };
60
65
  }));
61
66
  const coreImplementationPercentage = implementation.expectedCount === 0 ? null : implementation.percentage;
@@ -160,6 +165,22 @@ var BuilderModeStore = class {
160
165
  }
161
166
  loading = true;
162
167
  dashboard = { projects: [] };
168
+ fullyLoaded = false;
169
+ totalProjectCount = 0;
170
+ #projectCount = derived(() => Math.max(this.totalProjectCount, this.dashboard.projects.length));
171
+ get projectCount() {
172
+ return this.#projectCount();
173
+ }
174
+ set projectCount($$value) {
175
+ return this.#projectCount($$value);
176
+ }
177
+ #pendingProjectCount = derived(() => this.fullyLoaded ? 0 : Math.max(0, this.totalProjectCount - this.dashboard.projects.length));
178
+ get pendingProjectCount() {
179
+ return this.#pendingProjectCount();
180
+ }
181
+ set pendingProjectCount($$value) {
182
+ return this.#pendingProjectCount($$value);
183
+ }
163
184
  selectedProjectId = null;
164
185
  selectedCoreFeatureId = null;
165
186
  search = "";
@@ -385,6 +406,35 @@ var BuilderModeStore = class {
385
406
  set visibleSelectedFeatures($$value) {
386
407
  return this.#visibleSelectedFeatures($$value);
387
408
  }
409
+ #visibleSelectedSurfaces = derived(() => {
410
+ const coreFeature = this.selectedCoreFeature;
411
+ if (!coreFeature) return [];
412
+ const q = this.searchQuery;
413
+ const showAll = !q || this.matchesText(q, coreFeature.name, coreFeature.description);
414
+ const groups = [];
415
+ const byId = /* @__PURE__ */ new Map();
416
+ for (const feature of coreFeature.features) {
417
+ if (!showAll && this.featureScore(feature, q) === 0) continue;
418
+ let group = byId.get(feature.surfaceId);
419
+ if (!group) {
420
+ group = {
421
+ surfaceId: feature.surfaceId,
422
+ surfaceName: feature.surfaceName,
423
+ features: []
424
+ };
425
+ byId.set(feature.surfaceId, group);
426
+ groups.push(group);
427
+ }
428
+ group.features.push(feature);
429
+ }
430
+ return groups;
431
+ });
432
+ get visibleSelectedSurfaces() {
433
+ return this.#visibleSelectedSurfaces();
434
+ }
435
+ set visibleSelectedSurfaces($$value) {
436
+ return this.#visibleSelectedSurfaces($$value);
437
+ }
388
438
  setSearch(query) {
389
439
  this.search = query;
390
440
  }
@@ -415,10 +465,53 @@ var BuilderModeStore = class {
415
465
  projectScore(project, query) {
416
466
  return Math.max(this.textScore(query, project.name, 120), this.textScore(query, project.description, 40), this.tagScore(project.tags, query, 70), ...project.coreFeatures.map((coreFeature) => this.coreFeatureScore(coreFeature, query) * .8));
417
467
  }
468
+ /**
469
+ * Load the full project list PROGRESSIVELY: read the cheap project list
470
+ * first, then load + score each project independently and stream it into the
471
+ * dashboard as it resolves — so cards appear one-by-one instead of the whole
472
+ * grid blocking on the slowest project. Cards are ordered by the project
473
+ * list regardless of which finishes first. The skeleton shows until the
474
+ * first card is ready (so the empty-state never flashes mid-load).
475
+ */
418
476
  async refresh() {
419
477
  this.loading = true;
420
- await this.refreshSilent();
421
- this.loading = false;
478
+ this.error = null;
479
+ try {
480
+ const container = await this.host.data.getContainer();
481
+ const summaries = await container.useCases.listProjects();
482
+ this.totalProjectCount = summaries.length;
483
+ if (summaries.length === 0) {
484
+ this.dashboard = { projects: [] };
485
+ this.fullyLoaded = true;
486
+ this.loading = false;
487
+ return;
488
+ }
489
+ const order = new Map(summaries.map((summary, index) => [String(summary.id), index]));
490
+ const loadProject = getBuilderModeProjectUseCase({
491
+ projects: container.projectRepository,
492
+ features: container.repository,
493
+ statuses: container.statusRepository
494
+ });
495
+ const loaded = [];
496
+ await Promise.all(summaries.map(async (summary) => {
497
+ const project = await loadProject(asProjectId(String(summary.id)));
498
+ if (!project) return;
499
+ loaded.push(project);
500
+ loaded.sort((a, b) => (order.get(a.id) ?? 0) - (order.get(b.id) ?? 0));
501
+ this.dashboard = { projects: [...loaded] };
502
+ this.loading = false;
503
+ }));
504
+ this.fullyLoaded = true;
505
+ this.loading = false;
506
+ if (this.selectedProjectId && !this.dashboard.projects.some((project) => project.id === this.selectedProjectId)) {
507
+ this.selectedProjectId = null;
508
+ this.selectedCoreFeatureId = null;
509
+ }
510
+ await this.refreshQueue();
511
+ } catch (e) {
512
+ this.error = e.message;
513
+ this.loading = false;
514
+ }
422
515
  }
423
516
  async refreshSilent() {
424
517
  try {
@@ -429,6 +522,8 @@ var BuilderModeStore = class {
429
522
  statuses: container.statusRepository
430
523
  });
431
524
  this.dashboard = await loadDashboard();
525
+ this.fullyLoaded = true;
526
+ this.totalProjectCount = this.dashboard.projects.length;
432
527
  if (this.selectedProjectId && !this.dashboard.projects.some((project) => project.id === this.selectedProjectId)) {
433
528
  this.selectedProjectId = null;
434
529
  this.selectedCoreFeatureId = null;
@@ -439,21 +534,88 @@ var BuilderModeStore = class {
439
534
  this.error = e.message;
440
535
  }
441
536
  }
537
+ /**
538
+ * Load ONLY the given project (its features, scores, queue) into the
539
+ * dashboard — used on a deep-linked open so we don't read and score every
540
+ * project in the hub just to show one. The rest of the list stays unloaded
541
+ * (`fullyLoaded=false`) until `ensureFullyLoaded` runs. Falls back to a full
542
+ * read when the id can't be resolved alone, so an unknown/stale link still
543
+ * lands the user on a usable list.
544
+ */
545
+ async loadProjectOnly(projectId) {
546
+ this.loading = true;
547
+ this.refreshProjectCount();
548
+ try {
549
+ const container = await this.host.data.getContainer();
550
+ const project = await getBuilderModeProjectUseCase({
551
+ projects: container.projectRepository,
552
+ features: container.repository,
553
+ statuses: container.statusRepository
554
+ })(asProjectId(projectId));
555
+ if (!project) await this.refreshSilent();
556
+ else {
557
+ this.dashboard = { projects: [project] };
558
+ this.fullyLoaded = false;
559
+ this.error = null;
560
+ await this.refreshQueue();
561
+ }
562
+ } catch (e) {
563
+ this.error = e.message;
564
+ } finally {
565
+ this.loading = false;
566
+ }
567
+ }
568
+ /** Ensure the whole project list is loaded (for the all-projects view). A
569
+ * no-op once any full read has happened, so returning from a deep-linked
570
+ * project triggers exactly one full load. */
571
+ async ensureFullyLoaded() {
572
+ if (this.fullyLoaded) return;
573
+ await this.refresh();
574
+ }
575
+ /** Fetch the true total project count (cheap — project docs only, no feature
576
+ * scoring) so the "All projects (N)" label is correct even when a single
577
+ * project was deep-loaded. Decorative: failures are ignored. */
578
+ async refreshProjectCount() {
579
+ try {
580
+ const container = await this.host.data.getContainer();
581
+ this.totalProjectCount = (await container.useCases.listProjects()).length;
582
+ } catch {}
583
+ }
442
584
  selectProject(id) {
443
585
  this.selectedProjectId = id;
444
586
  this.selectedCoreFeatureId = null;
445
587
  this.refreshQueue();
446
588
  }
447
- /** Cancel the project filter. */
589
+ /** Cancel the project filter. Returning to the all-projects view fills the
590
+ * list if a deep-linked open only loaded one project. */
448
591
  deselectProject() {
449
592
  this.selectedProjectId = null;
450
593
  this.selectedCoreFeatureId = null;
451
594
  this.queue = [];
595
+ this.ensureFullyLoaded();
452
596
  }
453
597
  /** Toggle a core feature filter (click the selected one again to clear). */
454
598
  selectCoreFeature(id) {
455
599
  this.selectedCoreFeatureId = this.selectedCoreFeatureId === id ? null : id;
456
600
  }
601
+ /**
602
+ * Set the full project + core-feature selection in ONE synchronous pass.
603
+ * Used when restoring from the URL (deep-link / refresh-persist, and the
604
+ * activity-toast "View" links that target the Builder while it's already
605
+ * open). Doing both at once avoids the project change transiently clearing
606
+ * the core and the URL writer racing to drop the `core` param before it's
607
+ * applied. Idempotent and order-independent for the URL ↔ store sync.
608
+ */
609
+ applySelection(projectId, coreFeatureId) {
610
+ if (this.selectedProjectId !== projectId) {
611
+ this.selectedProjectId = projectId;
612
+ this.selectedCoreFeatureId = null;
613
+ this.queue = [];
614
+ this.refreshQueue();
615
+ if (!projectId) this.ensureFullyLoaded();
616
+ }
617
+ this.selectedCoreFeatureId = coreFeatureId;
618
+ }
457
619
  deselectCoreFeature() {
458
620
  this.selectedCoreFeatureId = null;
459
621
  }
@@ -655,6 +817,55 @@ var BuilderModeStore = class {
655
817
  async refreshSelectedProject() {
656
818
  if (this.selectedProjectId) await this.refreshProject(this.selectedProjectId);
657
819
  }
820
+ hasProject(projectId) {
821
+ return this.dashboard.projects.some((project) => project.id === projectId);
822
+ }
823
+ /** The project whose core features include `featureId`, or null. A model
824
+ * Feature maps to one Builder "core feature", so a feature/status event
825
+ * touches exactly one project's card. */
826
+ projectIdOwningFeature(featureId) {
827
+ for (const project of this.dashboard.projects) if (project.coreFeatures.some((coreFeature) => coreFeature.id === featureId)) return project.id;
828
+ return null;
829
+ }
830
+ /**
831
+ * Apply one out-of-band sync event (MCP write) with the SMALLEST refresh
832
+ * that keeps the view correct — the Builder's mirror of the Expert view's
833
+ * refetchOne/syncWith. A `project` event rebuilds just that project's card
834
+ * in place; a `feature`/`implementation-status` event rebuilds only the
835
+ * owning project. Both reuse the keyed lists, so scroll, selection, queue
836
+ * widget, and expanded descriptions survive instead of the whole dashboard
837
+ * blanking and re-running its entrance animations. We fall back to a full
838
+ * silent refresh ONLY when the event names something we don't have yet (a
839
+ * brand-new project, or a feature not attached to any loaded project) —
840
+ * that's the one case a scoped rebuild can't surface.
841
+ */
842
+ async applySyncEvent(event) {
843
+ if (event.kind === "project") {
844
+ if (this.hasProject(event.id)) {
845
+ await this.refreshProject(event.id);
846
+ if (event.id === this.selectedProjectId) await this.refreshQueue();
847
+ } else await this.refreshSilent();
848
+ return;
849
+ }
850
+ const projectId = this.projectIdOwningFeature(event.id);
851
+ if (projectId) {
852
+ await this.refreshProject(projectId);
853
+ if (projectId === this.selectedProjectId) await this.refreshQueue();
854
+ } else await this.refreshSilent();
855
+ }
856
+ /**
857
+ * A Builder deep-link for an entity touched by a sync event, or null when it
858
+ * isn't shown in the Builder (so the activity-toast falls back to the Expert
859
+ * route). A `project` event targets the project card; `feature` /
860
+ * `implementation-status` (both carry a feature id) target that feature's
861
+ * core card via `?project=&core=`.
862
+ */
863
+ deepLinkFor(kind, id) {
864
+ if (kind === "project") return this.hasProject(id) ? `/builder-mode?project=${encodeURIComponent(id)}` : null;
865
+ const projectId = this.projectIdOwningFeature(id);
866
+ if (!projectId) return null;
867
+ return `/builder-mode?project=${encodeURIComponent(projectId)}&core=${encodeURIComponent(id)}`;
868
+ }
658
869
  /** Drag-and-drop reorder: drop `itemId` at absolute position `targetIndex`. */
659
870
  async moveQueueTo(itemId, targetIndex) {
660
871
  const projectId = this.selectedProjectId;
@@ -677,5 +888,5 @@ var BuilderModeStore = class {
677
888
  };
678
889
  var builderModeStore = new BuilderModeStore(defaultBuilderHost);
679
890
 
680
- export { builderModeStore as b, subscribeSyncEvents as s };
681
- //# sourceMappingURL=builderModeStore.svelte-ihupr-3p.js.map
891
+ export { builderModeStore as b, resolveViewLink as r, subscribeSyncEvents as s };
892
+ //# sourceMappingURL=builderModeStore.svelte-BpRIU_zP.js.map