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
@@ -7,21 +7,23 @@ function __memo(fn) {
7
7
  return {
8
8
  appDir: "_app",
9
9
  appPath: "_app",
10
- assets: new Set(["unspaghettit_logo.png"]),
11
- mimeTypes: {".png":"image/png"},
10
+ assets: new Set(["lyriks_logo.svg","unspaghettit_logo.png"]),
11
+ mimeTypes: {".svg":"image/svg+xml",".png":"image/png"},
12
12
  _: {
13
- client: {start:"_app/immutable/entry/start.D5GPCQZD.js",app:"_app/immutable/entry/app.CLgh6Mx_.js",imports:["_app/immutable/entry/start.D5GPCQZD.js","_app/immutable/chunks/DatGSObE.js","_app/immutable/chunks/BPl9BITm.js","_app/immutable/entry/app.CLgh6Mx_.js","_app/immutable/chunks/BPl9BITm.js","_app/immutable/chunks/kNaey6uv.js","_app/immutable/chunks/xihTtKlq.js"],stylesheets:[],fonts:[],uses_env_dynamic_public:true},
13
+ client: {start:"_app/immutable/entry/start.C3xXQVkq.js",app:"_app/immutable/entry/app.Cd4S3giu.js",imports:["_app/immutable/entry/start.C3xXQVkq.js","_app/immutable/chunks/OJscNS3T.js","_app/immutable/chunks/BPl9BITm.js","_app/immutable/entry/app.Cd4S3giu.js","_app/immutable/chunks/BPl9BITm.js","_app/immutable/chunks/kNaey6uv.js","_app/immutable/chunks/xihTtKlq.js"],stylesheets:[],fonts:[],uses_env_dynamic_public:true},
14
14
  nodes: [
15
- __memo(() => import('./chunks/0-C_o0oz-N.js')),
16
- __memo(() => import('./chunks/1-DPpKAKXV.js')),
17
- __memo(() => import('./chunks/2-AlfFqtL1.js')),
18
- __memo(() => import('./chunks/3-vbjUt_51.js')),
19
- __memo(() => import('./chunks/4-BNow4x6D.js')),
20
- __memo(() => import('./chunks/5-D7OCJpxD.js')),
21
- __memo(() => import('./chunks/6-QQ7r8Rd5.js')),
22
- __memo(() => import('./chunks/7-CbPLGaIG.js')),
23
- __memo(() => import('./chunks/8-CVO-E-sf.js')),
24
- __memo(() => import('./chunks/9-DxT1baO5.js'))
15
+ __memo(() => import('./chunks/0-Co8kcANG.js')),
16
+ __memo(() => import('./chunks/1-BSUItTig.js')),
17
+ __memo(() => import('./chunks/2-BQT3m1vc.js')),
18
+ __memo(() => import('./chunks/3-DPZ9BquJ.js')),
19
+ __memo(() => import('./chunks/4-DHo47YX6.js')),
20
+ __memo(() => import('./chunks/5-Cp9evBAG.js')),
21
+ __memo(() => import('./chunks/6-DiBq3bOV.js')),
22
+ __memo(() => import('./chunks/7-C4hmS0dG.js')),
23
+ __memo(() => import('./chunks/8-CFFuDzBC.js')),
24
+ __memo(() => import('./chunks/9-nhhKZJrs.js')),
25
+ __memo(() => import('./chunks/10-BygvxrZp.js')),
26
+ __memo(() => import('./chunks/11-DRx0tRx2.js'))
25
27
  ],
26
28
  remotes: {
27
29
 
@@ -146,32 +148,46 @@ return {
146
148
  page: { layouts: [0,], errors: [1,], leaf: 5 },
147
149
  endpoint: null
148
150
  },
151
+ {
152
+ id: "/features/[id]/graph",
153
+ pattern: /^\/features\/([^/]+?)\/graph\/?$/,
154
+ params: [{"name":"id","optional":false,"rest":false,"chained":false}],
155
+ page: { layouts: [0,], errors: [1,], leaf: 6 },
156
+ endpoint: null
157
+ },
149
158
  {
150
159
  id: "/mcp",
151
160
  pattern: /^\/mcp\/?$/,
152
161
  params: [],
153
- page: { layouts: [0,], errors: [1,], leaf: 6 },
162
+ page: { layouts: [0,], errors: [1,], leaf: 7 },
154
163
  endpoint: null
155
164
  },
156
165
  {
157
166
  id: "/projects",
158
167
  pattern: /^\/projects\/?$/,
159
168
  params: [],
160
- page: { layouts: [0,], errors: [1,], leaf: 7 },
169
+ page: { layouts: [0,], errors: [1,], leaf: 8 },
161
170
  endpoint: null
162
171
  },
163
172
  {
164
173
  id: "/projects/[id]",
165
174
  pattern: /^\/projects\/([^/]+?)\/?$/,
166
175
  params: [{"name":"id","optional":false,"rest":false,"chained":false}],
167
- page: { layouts: [0,], errors: [1,], leaf: 8 },
176
+ page: { layouts: [0,], errors: [1,], leaf: 9 },
177
+ endpoint: null
178
+ },
179
+ {
180
+ id: "/projects/[id]/graph",
181
+ pattern: /^\/projects\/([^/]+?)\/graph\/?$/,
182
+ params: [{"name":"id","optional":false,"rest":false,"chained":false}],
183
+ page: { layouts: [0,], errors: [1,], leaf: 10 },
168
184
  endpoint: null
169
185
  },
170
186
  {
171
187
  id: "/tutorial",
172
188
  pattern: /^\/tutorial\/?$/,
173
189
  params: [],
174
- page: { layouts: [0,], errors: [1,], leaf: 9 },
190
+ page: { layouts: [0,], errors: [1,], leaf: 11 },
175
191
  endpoint: null
176
192
  }
177
193
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sources":["../../.svelte-kit/adapter-node/manifest.js"],"sourcesContent":["export const manifest = (() => {\nfunction __memo(fn) {\n\tlet value;\n\treturn () => value ??= (value = fn());\n}\n\nreturn {\n\tappDir: \"_app\",\n\tappPath: \"_app\",\n\tassets: new Set([\"unspaghettit_logo.png\"]),\n\tmimeTypes: {\".png\":\"image/png\"},\n\t_: {\n\t\tclient: {start:\"_app/immutable/entry/start.D5GPCQZD.js\",app:\"_app/immutable/entry/app.CLgh6Mx_.js\",imports:[\"_app/immutable/entry/start.D5GPCQZD.js\",\"_app/immutable/chunks/DatGSObE.js\",\"_app/immutable/chunks/BPl9BITm.js\",\"_app/immutable/entry/app.CLgh6Mx_.js\",\"_app/immutable/chunks/BPl9BITm.js\",\"_app/immutable/chunks/kNaey6uv.js\",\"_app/immutable/chunks/xihTtKlq.js\"],stylesheets:[],fonts:[],uses_env_dynamic_public:true},\n\t\tnodes: [\n\t\t\t__memo(() => import('./nodes/0.js')),\n\t\t\t__memo(() => import('./nodes/1.js')),\n\t\t\t__memo(() => import('./nodes/2.js')),\n\t\t\t__memo(() => import('./nodes/3.js')),\n\t\t\t__memo(() => import('./nodes/4.js')),\n\t\t\t__memo(() => import('./nodes/5.js')),\n\t\t\t__memo(() => import('./nodes/6.js')),\n\t\t\t__memo(() => import('./nodes/7.js')),\n\t\t\t__memo(() => import('./nodes/8.js')),\n\t\t\t__memo(() => import('./nodes/9.js'))\n\t\t],\n\t\tremotes: {\n\t\t\t\n\t\t},\n\t\troutes: [\n\t\t\t{\n\t\t\t\tid: \"/\",\n\t\t\t\tpattern: /^\\/$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 2 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/domains\",\n\t\t\t\tpattern: /^\\/api\\/domains\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/domains/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/domains/[id]\",\n\t\t\t\tpattern: /^\\/api\\/domains\\/([^/]+?)\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/domains/_id_/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/projects\",\n\t\t\t\tpattern: /^\\/api\\/projects\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/projects/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/projects/import\",\n\t\t\t\tpattern: /^\\/api\\/projects\\/import\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/projects/import/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/projects/[id]\",\n\t\t\t\tpattern: /^\\/api\\/projects\\/([^/]+?)\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/projects/_id_/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/projects/[id]/bundle\",\n\t\t\t\tpattern: /^\\/api\\/projects\\/([^/]+?)\\/bundle\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/projects/_id_/bundle/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/snapshots\",\n\t\t\t\tpattern: /^\\/api\\/snapshots\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/snapshots/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/snapshots/[id]\",\n\t\t\t\tpattern: /^\\/api\\/snapshots\\/([^/]+?)\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/snapshots/_id_/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/snapshots/[id]/implementation-status\",\n\t\t\t\tpattern: /^\\/api\\/snapshots\\/([^/]+?)\\/implementation-status\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/snapshots/_id_/implementation-status/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/sync/events\",\n\t\t\t\tpattern: /^\\/api\\/sync\\/events\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/sync/events/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/sync/reload\",\n\t\t\t\tpattern: /^\\/api\\/sync\\/reload\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/sync/reload/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/tag-palette\",\n\t\t\t\tpattern: /^\\/api\\/tag-palette\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/tag-palette/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/tag-palette/rename\",\n\t\t\t\tpattern: /^\\/api\\/tag-palette\\/rename\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/tag-palette/rename/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/builder-mode\",\n\t\t\t\tpattern: /^\\/builder-mode\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 3 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/features\",\n\t\t\t\tpattern: /^\\/features\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 4 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/features/[id]\",\n\t\t\t\tpattern: /^\\/features\\/([^/]+?)\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 5 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/mcp\",\n\t\t\t\tpattern: /^\\/mcp\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 6 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/projects\",\n\t\t\t\tpattern: /^\\/projects\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 7 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/projects/[id]\",\n\t\t\t\tpattern: /^\\/projects\\/([^/]+?)\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 8 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/tutorial\",\n\t\t\t\tpattern: /^\\/tutorial\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 9 },\n\t\t\t\tendpoint: null\n\t\t\t}\n\t\t],\n\t\tprerendered_routes: new Set([]),\n\t\tmatchers: async () => {\n\t\t\t\n\t\t\treturn { };\n\t\t},\n\t\tserver_assets: {}\n\t}\n}\n})();\n\nexport const prerendered = new Set([]);\n\nexport const base = \"\";"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manifest.js","sources":["../../.svelte-kit/adapter-node/manifest.js"],"sourcesContent":["export const manifest = (() => {\nfunction __memo(fn) {\n\tlet value;\n\treturn () => value ??= (value = fn());\n}\n\nreturn {\n\tappDir: \"_app\",\n\tappPath: \"_app\",\n\tassets: new Set([\"lyriks_logo.svg\",\"unspaghettit_logo.png\"]),\n\tmimeTypes: {\".svg\":\"image/svg+xml\",\".png\":\"image/png\"},\n\t_: {\n\t\tclient: {start:\"_app/immutable/entry/start.C3xXQVkq.js\",app:\"_app/immutable/entry/app.Cd4S3giu.js\",imports:[\"_app/immutable/entry/start.C3xXQVkq.js\",\"_app/immutable/chunks/OJscNS3T.js\",\"_app/immutable/chunks/BPl9BITm.js\",\"_app/immutable/entry/app.Cd4S3giu.js\",\"_app/immutable/chunks/BPl9BITm.js\",\"_app/immutable/chunks/kNaey6uv.js\",\"_app/immutable/chunks/xihTtKlq.js\"],stylesheets:[],fonts:[],uses_env_dynamic_public:true},\n\t\tnodes: [\n\t\t\t__memo(() => import('./nodes/0.js')),\n\t\t\t__memo(() => import('./nodes/1.js')),\n\t\t\t__memo(() => import('./nodes/2.js')),\n\t\t\t__memo(() => import('./nodes/3.js')),\n\t\t\t__memo(() => import('./nodes/4.js')),\n\t\t\t__memo(() => import('./nodes/5.js')),\n\t\t\t__memo(() => import('./nodes/6.js')),\n\t\t\t__memo(() => import('./nodes/7.js')),\n\t\t\t__memo(() => import('./nodes/8.js')),\n\t\t\t__memo(() => import('./nodes/9.js')),\n\t\t\t__memo(() => import('./nodes/10.js')),\n\t\t\t__memo(() => import('./nodes/11.js'))\n\t\t],\n\t\tremotes: {\n\t\t\t\n\t\t},\n\t\troutes: [\n\t\t\t{\n\t\t\t\tid: \"/\",\n\t\t\t\tpattern: /^\\/$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 2 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/domains\",\n\t\t\t\tpattern: /^\\/api\\/domains\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/domains/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/domains/[id]\",\n\t\t\t\tpattern: /^\\/api\\/domains\\/([^/]+?)\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/domains/_id_/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/projects\",\n\t\t\t\tpattern: /^\\/api\\/projects\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/projects/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/projects/import\",\n\t\t\t\tpattern: /^\\/api\\/projects\\/import\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/projects/import/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/projects/[id]\",\n\t\t\t\tpattern: /^\\/api\\/projects\\/([^/]+?)\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/projects/_id_/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/projects/[id]/bundle\",\n\t\t\t\tpattern: /^\\/api\\/projects\\/([^/]+?)\\/bundle\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/projects/_id_/bundle/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/snapshots\",\n\t\t\t\tpattern: /^\\/api\\/snapshots\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/snapshots/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/snapshots/[id]\",\n\t\t\t\tpattern: /^\\/api\\/snapshots\\/([^/]+?)\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/snapshots/_id_/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/snapshots/[id]/implementation-status\",\n\t\t\t\tpattern: /^\\/api\\/snapshots\\/([^/]+?)\\/implementation-status\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/snapshots/_id_/implementation-status/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/sync/events\",\n\t\t\t\tpattern: /^\\/api\\/sync\\/events\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/sync/events/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/sync/reload\",\n\t\t\t\tpattern: /^\\/api\\/sync\\/reload\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/sync/reload/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/tag-palette\",\n\t\t\t\tpattern: /^\\/api\\/tag-palette\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/tag-palette/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/api/tag-palette/rename\",\n\t\t\t\tpattern: /^\\/api\\/tag-palette\\/rename\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: null,\n\t\t\t\tendpoint: __memo(() => import('./entries/endpoints/api/tag-palette/rename/_server.ts.js'))\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/builder-mode\",\n\t\t\t\tpattern: /^\\/builder-mode\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 3 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/features\",\n\t\t\t\tpattern: /^\\/features\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 4 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/features/[id]\",\n\t\t\t\tpattern: /^\\/features\\/([^/]+?)\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 5 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/features/[id]/graph\",\n\t\t\t\tpattern: /^\\/features\\/([^/]+?)\\/graph\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 6 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/mcp\",\n\t\t\t\tpattern: /^\\/mcp\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 7 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/projects\",\n\t\t\t\tpattern: /^\\/projects\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 8 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/projects/[id]\",\n\t\t\t\tpattern: /^\\/projects\\/([^/]+?)\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 9 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/projects/[id]/graph\",\n\t\t\t\tpattern: /^\\/projects\\/([^/]+?)\\/graph\\/?$/,\n\t\t\t\tparams: [{\"name\":\"id\",\"optional\":false,\"rest\":false,\"chained\":false}],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 10 },\n\t\t\t\tendpoint: null\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"/tutorial\",\n\t\t\t\tpattern: /^\\/tutorial\\/?$/,\n\t\t\t\tparams: [],\n\t\t\t\tpage: { layouts: [0,], errors: [1,], leaf: 11 },\n\t\t\t\tendpoint: null\n\t\t\t}\n\t\t],\n\t\tprerendered_routes: new Set([]),\n\t\tmatchers: async () => {\n\t\t\t\n\t\t\treturn { };\n\t\t},\n\t\tserver_assets: {}\n\t}\n}\n})();\n\nexport const prerendered = new Set([]);\n\nexport const base = \"\";"],"names":[],"mappings":"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"}
@@ -3,7 +3,9 @@ import { existsSync } from 'node:fs';
3
3
  import { dirname, resolve } from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
5
5
  import { discoverSnapshotDirectory } from '../../src/features/behavior-model/infrastructure/persistence/snapshot-discovery';
6
+ import { parseThemeId } from '../../src/lib/theme/registry';
6
7
  import { readEnabledViews } from '../util/views';
8
+ import { readSelectedTheme } from '../util/theme';
7
9
  import { log } from '../util/log';
8
10
 
9
11
  const __filename = fileURLToPath(import.meta.url);
@@ -45,6 +47,7 @@ export const runDashboardCommand = async (
45
47
  readonly host?: string;
46
48
  readonly snapshots?: string;
47
49
  readonly views?: string;
50
+ readonly theme?: string;
48
51
  }
49
52
  ): Promise<number> => {
50
53
  const repoRoot = resolve(__dirname, '..', '..');
@@ -126,6 +129,17 @@ export const runDashboardCommand = async (
126
129
  log.dim(`Views: expert + ${views.join(', ')}`);
127
130
  }
128
131
 
132
+ // Colour theme (cosmetic). A `--theme` flag overrides the persisted choice
133
+ // (`unspa theme set`) for this run; both feed the app as PUBLIC_UNSPA_THEME,
134
+ // which seeds the no-flash server-rendered <html data-theme>. The in-app
135
+ // switcher can still change it live in the browser. Unknown ids fall back to
136
+ // the default, so a typo never blanks the UI.
137
+ const theme = parseThemeId(args.theme ?? readSelectedTheme(directory));
138
+ if (theme !== 'default') {
139
+ env.PUBLIC_UNSPA_THEME = theme;
140
+ log.dim(`Theme: ${theme}`);
141
+ }
142
+
129
143
  return await new Promise<number>((resolvePromise) => {
130
144
  const child = spawn(process.execPath, [serverShim], {
131
145
  stdio: 'inherit',
@@ -7,12 +7,14 @@ import { ALL_CLIENTS, clientById, SERVER_NAME, type ClientAdapter } from '../cli
7
7
  import { buildUnspaMcpEntry } from '../clients/claude-code';
8
8
  import type { ApplyResult, ConfigScope, McpServerEntry } from '../clients/types';
9
9
  import { isOptionalViewId, optionalViews } from '../../src/lib/views/registry';
10
+ import { isThemeId, parseThemeId } from '../../src/lib/theme/registry';
10
11
  import { ask } from '../util/ask';
11
12
  import { writeUnspaContextBlocks } from '../util/context-files';
12
13
  import { upsertGitignoreBlock } from '../util/gitignore';
13
14
  import { log } from '../util/log';
14
15
  import { installUnspaSkills } from '../util/skills';
15
16
  import { readEnabledViews, writeEnabledViews } from '../util/views';
17
+ import { writeSelectedTheme } from '../util/theme';
16
18
 
17
19
  /**
18
20
  * Expand a user-supplied hub path: tilde-expansion, relative→absolute (resolved
@@ -119,6 +121,13 @@ export type InitOptions = {
119
121
  * always on regardless.
120
122
  */
121
123
  readonly withViews?: string;
124
+ /**
125
+ * Dashboard colour theme to persist at setup (e.g. "lyriks"). Cosmetic only;
126
+ * written to `<snapshots>/theme.json`, same as `unspa theme set`, so
127
+ * `unspa dashboard` boots with it. The in-app header switcher can change it
128
+ * live later. Unknown ids fall back to the default with a warning.
129
+ */
130
+ readonly theme?: string;
122
131
  };
123
132
 
124
133
  const resolveClientsArg = async (
@@ -338,6 +347,23 @@ export const runInitCommand = async (options: InitOptions = {}): Promise<number>
338
347
  log.dim('Shows as a view switcher in `unspa dashboard`. Turn off later with `unspa view remove <id>`.');
339
348
  }
340
349
 
350
+ // 1c. Optional colour theme. Cosmetic only — persists the chosen skin into
351
+ // `<snapshots>/theme.json` so `unspa dashboard` boots with it. An unknown
352
+ // id is a no-op (keeps the default) with a warning rather than a hard
353
+ // fail. Switchable later via `unspa theme set` or the in-app switcher.
354
+ if (options.theme !== undefined) {
355
+ const raw = options.theme.trim().toLowerCase();
356
+ if (raw && raw !== 'default' && !isThemeId(raw)) {
357
+ log.warn(`Unknown theme "${raw}" — keeping the default theme.`);
358
+ }
359
+ const id = parseThemeId(options.theme);
360
+ writeSelectedTheme(target.dir, id);
361
+ if (id !== 'default') {
362
+ log.ok(`Dashboard theme set to ${pc.cyan(id)}.`);
363
+ log.dim('Cosmetic skin. Change it with `unspa theme set <id>` or the dashboard header switcher.');
364
+ }
365
+ }
366
+
341
367
  // 2. Pick clients, write MCP server entry. `mergeMcpServerEntry` compares
342
368
  // before writing so re-runs are a no-op when nothing changed. Detection
343
369
  // is scoped to this cwd/home so the pre-selection (interactive) and the
@@ -0,0 +1,62 @@
1
+ import pc from 'picocolors';
2
+ import { discoverSnapshotDirectory } from '../../src/features/behavior-model/infrastructure/persistence/snapshot-discovery';
3
+ import { ALL_THEMES, isThemeId, parseThemeId } from '../../src/lib/theme/registry';
4
+ import { readSelectedTheme, writeSelectedTheme } from '../util/theme';
5
+ import { log } from '../util/log';
6
+
7
+ export type ThemeCommandOptions = {
8
+ readonly action: 'list' | 'set' | 'reset';
9
+ readonly id?: string;
10
+ readonly cwd?: string;
11
+ readonly snapshots?: string;
12
+ };
13
+
14
+ const known = (): string => ALL_THEMES.map((t) => t.id).join(', ');
15
+
16
+ /**
17
+ * Pick the dashboard's colour theme. Purely cosmetic: it only changes which
18
+ * skin the design system renders with, never a feature. The selection persists
19
+ * in `<snapshots>/theme.json` so `unspa dashboard` boots with it; the in-app
20
+ * header switcher can flip it live in the browser without touching this file.
21
+ */
22
+ export const runThemeCommand = async (options: ThemeCommandOptions): Promise<number> => {
23
+ const cwd = options.cwd ?? process.cwd();
24
+ const { directory, source } = discoverSnapshotDirectory({ cwd, override: options.snapshots });
25
+ const active = parseThemeId(readSelectedTheme(directory));
26
+
27
+ if (options.action === 'list') {
28
+ log.step(`Themes for ${pc.cyan(directory)} (${source})`);
29
+ log.dim(`Active default: ${pc.cyan(active)}`);
30
+ for (const theme of ALL_THEMES) {
31
+ const on = active === theme.id;
32
+ const marker = on ? pc.green('● active') : pc.dim('○ ');
33
+ process.stdout.write(`${marker} ${pc.cyan(theme.label)} ${pc.dim(`(${theme.id})`)} — ${theme.description}\n`);
34
+ }
35
+ log.blank();
36
+ log.dim('Set with `unspa theme set <id>`, revert with `unspa theme reset`.');
37
+ log.dim('Or flip it live from the dashboard header (the palette button).');
38
+ return 0;
39
+ }
40
+
41
+ if (options.action === 'reset') {
42
+ writeSelectedTheme(directory, 'default');
43
+ log.ok('Theme reset to default.');
44
+ log.dim('Restart `unspa dashboard` to apply (or use the in-app switcher).');
45
+ return 0;
46
+ }
47
+
48
+ // set
49
+ const id = (options.id ?? '').trim().toLowerCase();
50
+ if (!id) {
51
+ log.err(`Missing theme id. Known themes: ${known()}.`);
52
+ return 1;
53
+ }
54
+ if (!isThemeId(id)) {
55
+ log.err(`Unknown theme "${id}". Known themes: ${known()}.`);
56
+ return 1;
57
+ }
58
+ const next = writeSelectedTheme(directory, id);
59
+ log.ok(`Theme set to ${pc.cyan(next)}.`);
60
+ log.dim('Restart `unspa dashboard` to apply, or switch live via the dashboard header.');
61
+ return 0;
62
+ };
package/cli/unspa.ts CHANGED
@@ -6,6 +6,7 @@ import { runLinkCommand } from './commands/link';
6
6
  import { runListCommand } from './commands/list';
7
7
  import { runScenariosExportCommand } from './commands/scenarios-export';
8
8
  import { runServeCommand } from './commands/serve';
9
+ import { runThemeCommand } from './commands/theme';
9
10
  import { runUninstallCommand } from './commands/uninstall';
10
11
  import { runViewCommand } from './commands/view';
11
12
  import { log } from './util/log';
@@ -68,6 +69,7 @@ program
68
69
  .option('--no-skills', 'Skip installing the bundled unspa skills under .claude/skills/.')
69
70
  .option('--fun', 'Pre-check the opt-in narrative skills (worldbuild + worldplay) in the skill picker. Also implicitly on when the CLI is invoked as `unspaghettit`.')
70
71
  .option('--with <views>', 'Comma list of opt-in dashboard views to enable (e.g. "builder"). Expert is always on. Without it, interactive init offers the Builder view.')
72
+ .option('--theme <id>', 'Set the dashboard colour theme at install (e.g. "lyriks"). Cosmetic only; persists so `unspa dashboard` boots with it. Switchable later via `unspa theme set` or the in-app header switcher.')
71
73
  .option('-y, --yes', 'Accept defaults. Non-interactive (CI / scripts).')
72
74
  .action(async (opts) => {
73
75
  if (opts.scope !== 'project' && opts.scope !== 'global') {
@@ -87,7 +89,8 @@ program
87
89
  local: opts.local === true,
88
90
  custom: opts.custom === true,
89
91
  fun: opts.fun === true || FUN_MODE_BY_INVOCATION,
90
- withViews: opts.with
92
+ withViews: opts.with,
93
+ theme: opts.theme
91
94
  });
92
95
  process.exit(code);
93
96
  });
@@ -108,8 +111,9 @@ program
108
111
  .option('-h, --host <host>', 'Host to bind (default: 127.0.0.1). Pass 0.0.0.0 to expose on the LAN; the dashboard has no auth, so do this only on trusted networks.')
109
112
  .option('-s, --snapshots <dir>', 'Point the dashboard at a specific snapshots folder (sets UNSPA_SNAPSHOTS for this run). Handy for a one-off look at a custom hub or another repo.')
110
113
  .option('--view <ids>', 'Comma list of optional views to enable beyond Expert (e.g. "builder"). Expert is always on and is the default; with no extra views the header shows no switcher.')
114
+ .option('--theme <id>', 'Colour theme to boot with (e.g. "lyriks"). Cosmetic only; overrides the persisted `unspa theme set` choice for this run. The in-app header switcher can still change it live.')
111
115
  .action(async (opts) => {
112
- const code = await runDashboardCommand({ port: opts.port, host: opts.host, snapshots: opts.snapshots, views: opts.view });
116
+ const code = await runDashboardCommand({ port: opts.port, host: opts.host, snapshots: opts.snapshots, views: opts.view, theme: opts.theme });
113
117
  process.exit(code);
114
118
  });
115
119
 
@@ -192,6 +196,38 @@ view
192
196
  process.exit(await runViewCommand({ action: 'remove', id, snapshots: opts.snapshots }));
193
197
  });
194
198
 
199
+ // `theme list|set|reset` — pick the dashboard's colour skin. Purely cosmetic
200
+ // (it never changes which features exist), persisted next to the model in
201
+ // `<snapshots>/theme.json` so `unspa dashboard` boots with it. The in-app
202
+ // header switcher flips it live in the browser without touching this file.
203
+ const theme = program
204
+ .command('theme')
205
+ .description('Pick the dashboard colour theme (cosmetic). The in-app header switcher can also flip it live.');
206
+
207
+ theme
208
+ .command('list')
209
+ .description('Show the available themes and which one is the persisted default.')
210
+ .option('-s, --snapshots <dir>', 'Target a specific snapshots folder (defaults to walk-up, then the shared hub).')
211
+ .action(async (opts) => {
212
+ process.exit(await runThemeCommand({ action: 'list', snapshots: opts.snapshots }));
213
+ });
214
+
215
+ theme
216
+ .command('set <id>')
217
+ .description('Set the dashboard theme (e.g. "lyriks"). Persists so `unspa dashboard` uses it.')
218
+ .option('-s, --snapshots <dir>', 'Target a specific snapshots folder.')
219
+ .action(async (id, opts) => {
220
+ process.exit(await runThemeCommand({ action: 'set', id, snapshots: opts.snapshots }));
221
+ });
222
+
223
+ theme
224
+ .command('reset')
225
+ .description('Revert to the default theme.')
226
+ .option('-s, --snapshots <dir>', 'Target a specific snapshots folder.')
227
+ .action(async (opts) => {
228
+ process.exit(await runThemeCommand({ action: 'reset', snapshots: opts.snapshots }));
229
+ });
230
+
195
231
  // `scenarios export <featureId>` — generates a Vitest spec from the feature's
196
232
  // scenarios, using the deterministic simulator as the assertion oracle. The
197
233
  // user writes a thin adapter that calls their real implementation; the
@@ -27,6 +27,11 @@ per-repo install (\`unspa init --local\`). Open the dashboard with
27
27
  \`unspa dashboard\` (http://localhost:3000) to see surfaces, actions, simulator,
28
28
  maturity, and implementation coverage.
29
29
 
30
+ When using the CLI hub, treat \`~/.unspa-hub/unspa\` as the source of truth.
31
+ Dashboard localhost ports are only views over that folder and may change per
32
+ run. Do not inspect Docker containers, unrelated app integrations, or another
33
+ product's embedded Unspa data unless the user explicitly asks for that source.
34
+
30
35
  ### Editing the model. Use the MCP, don't re-emit JSON
31
36
 
32
37
  The Unspaghettit **MCP server** is registered for this repo. Prefer its tools over
@@ -0,0 +1,34 @@
1
+ import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+
4
+ /**
5
+ * Persisted dashboard-theme selection, stored next to the model the dashboard
6
+ * shows (`<snapshots>/theme.json`). Purely cosmetic — picks the colour skin the
7
+ * UI renders with. `unspa dashboard` reads it and exposes it to the app as
8
+ * `PUBLIC_UNSPA_THEME`; the in-app header switcher can still override it live
9
+ * in the browser. A missing/malformed file means the default theme.
10
+ */
11
+ const FILE_NAME = 'theme.json';
12
+
13
+ type ThemeConfig = { readonly theme?: unknown };
14
+
15
+ export const themeConfigPath = (snapshotsDir: string): string => join(snapshotsDir, FILE_NAME);
16
+
17
+ /** Read the selected theme id; tolerant of a missing/malformed file. */
18
+ export const readSelectedTheme = (snapshotsDir: string): string => {
19
+ try {
20
+ const parsed = JSON.parse(readFileSync(themeConfigPath(snapshotsDir), 'utf8')) as ThemeConfig;
21
+ return typeof parsed.theme === 'string' ? parsed.theme.trim().toLowerCase() : 'default';
22
+ } catch {
23
+ return 'default';
24
+ }
25
+ };
26
+
27
+ /** Persist the selected theme id (normalized: trimmed, lowercased). */
28
+ export const writeSelectedTheme = (snapshotsDir: string, theme: string): string => {
29
+ const next = theme.trim().toLowerCase() || 'default';
30
+ const path = themeConfigPath(snapshotsDir);
31
+ mkdirSync(dirname(path), { recursive: true });
32
+ writeFileSync(path, `${JSON.stringify({ theme: next }, null, 2)}\n`, 'utf8');
33
+ return next;
34
+ };
@@ -6,10 +6,12 @@
6
6
  * disk we POST {kind,id} to /api/sync/reload so any open editor sees the
7
7
  * change without a refresh.
8
8
  *
9
- * Default is :3000, the port `unspa dashboard` (adapter-node production
10
- * build) listens on. Devs running `vite dev` (:5173) should set
11
- * `UNSPA_SYNC_URL=http://localhost:5173` in the MCP entry env so list
12
- * views auto-refresh during development too.
9
+ * With no override we probe 127.0.0.1:3000 (the port `unspa dashboard`
10
+ * the adapter-node production build listens on), then both the IPv4 and
11
+ * IPv6 literals on :5173 (Vite dev binds `localhost`, which resolves to ::1
12
+ * first on Windows/Node 20+). So both `unspa dashboard` and `npm run dev`
13
+ * get live refresh + toasts with zero config. Set `UNSPA_SYNC_URL` to a
14
+ * single loopback URL to pin a non-default port and skip the probe.
13
15
  *
14
16
  * Failures are swallowed: MCP must work even when no SvelteKit server is up.
15
17
  * A 300 ms timeout caps the cost when the server is unreachable.
@@ -30,7 +32,20 @@ export type SyncKind = 'feature' | 'project' | 'implementation-status';
30
32
  // 300 ms timeout fires before Node falls back to IPv4 — every notify
31
33
  // silently times out and the 5 s cooldown below skips the rest. Using
32
34
  // the literal IPv4 the dashboard listens on avoids the whole DNS path.
33
- const DEFAULT_SYNC_URL = 'http://127.0.0.1:3000';
35
+ // Candidate dashboard base URLs to probe when no UNSPA_SYNC_URL is set, in
36
+ // order. Covers both ways a local dashboard runs:
37
+ // - `unspa dashboard` (adapter-node prod build) binds 127.0.0.1:3000.
38
+ // - `npm run dev` (Vite) binds `localhost` on :5173 — which on Windows /
39
+ // Node 20+ resolves to ::1 (IPv6) first, so we probe BOTH the IPv4 and
40
+ // IPv6 literals on the dev port (a server bound to one family refuses the
41
+ // other). The prod server is IPv4-only, hence no ::1 variant there.
42
+ // Literal addresses (not the `localhost` name) so we never pay the
43
+ // resolve-wrong-family-then-time-out cost the name form incurs.
44
+ const DEFAULT_SYNC_URLS = [
45
+ 'http://127.0.0.1:3000',
46
+ 'http://127.0.0.1:5173',
47
+ 'http://[::1]:5173'
48
+ ];
34
49
 
35
50
  const isLoopbackUrl = (raw: string): boolean => {
36
51
  try {
@@ -51,28 +66,39 @@ const isLoopbackUrl = (raw: string): boolean => {
51
66
 
52
67
  let warnedOnce = false;
53
68
 
54
- const baseUrl = (): string => {
69
+ // Ordered list of dashboard base URLs to try for one notify. An explicit
70
+ // (loopback) UNSPA_SYNC_URL wins outright — the caller knows their port. With
71
+ // no override we probe the production port first, then the Vite dev port, so a
72
+ // single write reaches whichever dashboard is actually up without the user
73
+ // configuring anything. A non-loopback override is rejected (see module
74
+ // header) and falls back to probing both defaults.
75
+ const candidateUrls = (): readonly string[] => {
55
76
  const override = process.env.UNSPA_SYNC_URL?.replace(/\/$/, '');
56
- if (!override) return DEFAULT_SYNC_URL;
57
- if (isLoopbackUrl(override)) return override;
58
- if (!warnedOnce) {
59
- warnedOnce = true;
60
- process.stderr.write(
61
- `[unspa-mcp] UNSPA_SYNC_URL must be a loopback URL (got ${override}). Falling back to ${DEFAULT_SYNC_URL}.\n`
62
- );
77
+ if (override) {
78
+ if (isLoopbackUrl(override)) return [override];
79
+ if (!warnedOnce) {
80
+ warnedOnce = true;
81
+ process.stderr.write(
82
+ `[unspa-mcp] UNSPA_SYNC_URL must be a loopback URL (got ${override}). Probing ${DEFAULT_SYNC_URLS.join(', ')} instead.\n`
83
+ );
84
+ }
63
85
  }
64
- return DEFAULT_SYNC_URL;
86
+ return DEFAULT_SYNC_URLS;
65
87
  };
66
88
 
89
+ // Sticky last-known-good URL. Once a candidate answers we try it first on
90
+ // every later notify, so we never pay the dead-port timeout twice in a row.
91
+ let preferredUrl: string | null = null;
92
+
67
93
  let lastFailureAt = 0;
68
94
  let failureLogged = false;
69
95
  const COOLDOWN_MS = 5_000;
70
96
 
71
- const logFailureOnce = (url: string, reason: string): void => {
97
+ const logFailureOnce = (urls: readonly string[]): void => {
72
98
  if (failureLogged) return;
73
99
  failureLogged = true;
74
100
  process.stderr.write(
75
- `[unspa-mcp] sync notify to ${url} failed (${reason}). Dashboard will need manual refresh until reachable. Set UNSPA_SYNC_URL in the MCP entry env if the dashboard is on a non-default port.\n`
101
+ `[unspa-mcp] sync notify failed (tried ${urls.join(', ')}). Dashboard will need manual refresh until reachable. Set UNSPA_SYNC_URL in the MCP entry env if the dashboard is on a non-default port.\n`
76
102
  );
77
103
  };
78
104
 
@@ -87,16 +113,40 @@ export type NotifyExtras = {
87
113
  readonly op?: 'save' | 'delete';
88
114
  };
89
115
 
116
+ /** POST one reload to a single base URL. Returns true on a 2xx, false on any
117
+ * HTTP error, network failure, or the per-attempt timeout. Never throws — the
118
+ * caller decides whether to fall through to the next candidate. */
119
+ const postReload = async (
120
+ baseUrl: string,
121
+ body: string,
122
+ headers: Record<string, string>
123
+ ): Promise<boolean> => {
124
+ const ctrl = new AbortController();
125
+ const timer = setTimeout(() => ctrl.abort(), TIMEOUT_MS);
126
+ try {
127
+ const res = await fetch(`${baseUrl}/api/sync/reload`, {
128
+ method: 'POST',
129
+ headers,
130
+ body,
131
+ signal: ctrl.signal
132
+ });
133
+ return res.ok;
134
+ } catch {
135
+ return false;
136
+ } finally {
137
+ clearTimeout(timer);
138
+ }
139
+ };
140
+
90
141
  export const notifySyncReload = async (
91
142
  kind: SyncKind,
92
143
  id: string,
93
144
  extras: NotifyExtras = {}
94
145
  ): Promise<void> => {
95
- // If the last attempt failed recently, skip. The server isn't running.
146
+ // If the last full sweep failed recently, skip. No dashboard is reachable.
96
147
  if (Date.now() - lastFailureAt < COOLDOWN_MS) return;
97
148
  if (typeof fetch !== 'function') return;
98
149
 
99
- const url = `${baseUrl()}/api/sync/reload`;
100
150
  // When the dashboard is gated by UNSPA_AUTH_TOKEN, the MCP server is
101
151
  // a server-to-server caller and uses the header form. Configured via
102
152
  // the same env var name as the dashboard so a single shared secret
@@ -105,23 +155,26 @@ export const notifySyncReload = async (
105
155
  const token = process.env.UNSPA_AUTH_TOKEN?.trim();
106
156
  const headers: Record<string, string> = { 'Content-Type': 'application/json' };
107
157
  if (token && token.length > 0) headers.Authorization = `Bearer ${token}`;
108
- const ctrl = new AbortController();
109
- const timer = setTimeout(() => ctrl.abort(), TIMEOUT_MS);
110
- try {
111
- const res = await fetch(url, {
112
- method: 'POST',
113
- headers,
114
- body: JSON.stringify({ kind, id, ...extras }),
115
- signal: ctrl.signal
116
- });
117
- if (!res.ok) {
118
- lastFailureAt = Date.now();
119
- logFailureOnce(url, `HTTP ${res.status}`);
158
+ const body = JSON.stringify({ kind, id, ...extras });
159
+
160
+ // Try the last-known-good URL first, then the rest. One running dashboard
161
+ // is the norm, so the sticky hit means the steady state is a single POST.
162
+ const candidates = candidateUrls();
163
+ const ordered =
164
+ preferredUrl && candidates.includes(preferredUrl)
165
+ ? [preferredUrl, ...candidates.filter((u) => u !== preferredUrl)]
166
+ : candidates;
167
+
168
+ for (const url of ordered) {
169
+ if (await postReload(url, body, headers)) {
170
+ preferredUrl = url;
171
+ failureLogged = false; // a fresh success re-arms the failure log
172
+ return;
120
173
  }
121
- } catch (e) {
122
- lastFailureAt = Date.now();
123
- logFailureOnce(url, (e as Error).message);
124
- } finally {
125
- clearTimeout(timer);
126
174
  }
175
+
176
+ // Every candidate failed — back off and log once until one answers again.
177
+ lastFailureAt = Date.now();
178
+ preferredUrl = null;
179
+ logFailureOnce(ordered);
127
180
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unspaghettit",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "description": "Executable specifications for AI-assisted software development. Local-first and MCP-native.",
6
6
  "author": {
@@ -107,6 +107,7 @@
107
107
  "picocolors": "^1.1.1",
108
108
  "prompts": "^2.4.2",
109
109
  "tsx": "^4.21.0",
110
+ "vis-network": "^10.1.0",
110
111
  "write-file-atomic": "^7.0.1",
111
112
  "ws": "^8.20.1",
112
113
  "y-protocols": "^1.0.7",