@cryptiklemur/lattice 4.0.2 → 5.0.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 (394) hide show
  1. package/bin/lattice +1 -9
  2. package/dist/client/assets/{angular-html-N8PCEquT.js → angular-html-DKTL-XDO.js} +1 -1
  3. package/dist/client/assets/{angular-ts-CJ8RJIPD.js → angular-ts-tvBzOwQR.js} +1 -1
  4. package/dist/client/assets/{apl-BD6tCLWN.js → apl-CCzl5qFl.js} +1 -1
  5. package/dist/client/assets/{astro-CpIIfBs6.js → astro-DNQTpO2Y.js} +1 -1
  6. package/dist/client/assets/{blade-D3qgnjiV.js → blade-CyJoIMeJ.js} +1 -1
  7. package/dist/client/assets/{c-Dr6ADN_t.js → c-OEwk5KN8.js} +1 -1
  8. package/dist/client/assets/{cobol-BIfDE0Hr.js → cobol-DpHyJzz2.js} +1 -1
  9. package/dist/client/assets/{coffee-DHQ57vfY.js → coffee-BX5dbDzZ.js} +1 -1
  10. package/dist/client/assets/{cpp-CEBY6JOp.js → cpp-BTBjNg2U.js} +1 -1
  11. package/dist/client/assets/{crystal-D125CSmP.js → crystal-CNzZd6DW.js} +1 -1
  12. package/dist/client/assets/{css-CBmrkYSr.js → css-BuKsNmms.js} +1 -1
  13. package/dist/client/assets/{dist-A_mCRD1f.js → dist-CKpDHMy6.js} +2 -2
  14. package/dist/client/assets/{edge-Ccsz7cJW.js → edge-DzhnGgJE.js} +1 -1
  15. package/dist/client/assets/{elixir-Do6gk14X.js → elixir-Dqs0waqF.js} +1 -1
  16. package/dist/client/assets/{elm-Db22zT4C.js → elm-BtWwjxWn.js} +1 -1
  17. package/dist/client/assets/{erb-MXVqAAJD.js → erb-iPD89b4v.js} +1 -1
  18. package/dist/client/assets/{git-rebase-B-LLWBOA.js → git-rebase-BxVNXJL4.js} +1 -1
  19. package/dist/client/assets/{glimmer-js-eWszRU73.js → glimmer-js-BlyCupwF.js} +1 -1
  20. package/dist/client/assets/{glimmer-ts-VQmwGqUp.js → glimmer-ts-DjIxWOS9.js} +1 -1
  21. package/dist/client/assets/{glsl-B8ilOfAl.js → glsl-CGIL-65r.js} +1 -1
  22. package/dist/client/assets/{graphql-DnTqxeOc.js → graphql-DeOn6mNV.js} +1 -1
  23. package/dist/client/assets/{hack-XJsHYSQb.js → hack-DVppeCmS.js} +1 -1
  24. package/dist/client/assets/{haml-CQ7Vqzwp.js → haml-WDhua0Mp.js} +1 -1
  25. package/dist/client/assets/{handlebars-C4szooBf.js → handlebars-i2Fu_9HI.js} +1 -1
  26. package/dist/client/assets/{html-B6EgAiSd.js → html-B1e6oxzK.js} +1 -1
  27. package/dist/client/assets/{html-derivative-DdinogQX.js → html-derivative-MofKXIVd.js} +1 -1
  28. package/dist/client/assets/{http-BSLxCgRq.js → http-Dk6S5pRD.js} +1 -1
  29. package/dist/client/assets/{hurl-pOsTwNfp.js → hurl-CroFYYJG.js} +1 -1
  30. package/dist/client/assets/{index-BHQ_8mvl.js → index-CVu-S6Yk.js} +2 -2
  31. package/dist/client/assets/{java-DRQLiiST.js → java-B89FYjqS.js} +1 -1
  32. package/dist/client/assets/{javascript-DvEK2-47.js → javascript-m6CO1Uiy.js} +1 -1
  33. package/dist/client/assets/{jinja-D2NYJ25y.js → jinja-DC9Wi41X.js} +1 -1
  34. package/dist/client/assets/{jison-DDZaLNAp.js → jison-6xiegwDk.js} +1 -1
  35. package/dist/client/assets/{json-TGR0NIWd.js → json-HA-96-qr.js} +1 -1
  36. package/dist/client/assets/{jsx-BjUoPYga.js → jsx-Wt1a8i8U.js} +1 -1
  37. package/dist/client/assets/{julia-C4gjSpFu.js → julia-7M93VBON.js} +1 -1
  38. package/dist/client/assets/{just-H351x5u_.js → just-CjfDLYLv.js} +1 -1
  39. package/dist/client/assets/{latex-BiTmf6gf.js → latex-CitsJ46x.js} +1 -1
  40. package/dist/client/assets/{liquid-86ufjRy-.js → liquid-C8VIFin8.js} +1 -1
  41. package/dist/client/assets/{lua-BNxR0F_8.js → lua-Ba2N7esc.js} +1 -1
  42. package/dist/client/assets/{marko-CvRxpRjM.js → marko-lTLvb2wu.js} +1 -1
  43. package/dist/client/assets/{mdc-CYbAIy2C.js → mdc-D6IV-8FD.js} +1 -1
  44. package/dist/client/assets/{nginx-egdgMq-F.js → nginx-Ch5AjE6S.js} +1 -1
  45. package/dist/client/assets/{nim-CXBJVz_w.js → nim-WmDDC6LW.js} +1 -1
  46. package/dist/client/assets/{perl-XRfMobzg.js → perl-CQv0gYuq.js} +1 -1
  47. package/dist/client/assets/{php-Br7a8uil.js → php-BJmH0qOB.js} +1 -1
  48. package/dist/client/assets/{pug-BVbbUVvy.js → pug-CsHPkzc9.js} +1 -1
  49. package/dist/client/assets/{qml-ByKvrL1j.js → qml-B36ecArG.js} +1 -1
  50. package/dist/client/assets/{r-mVoV0Ni6.js → r-D5Yi5Z4y.js} +1 -1
  51. package/dist/client/assets/{razor-T5O-9UJL.js → razor-CHAxVq4R.js} +1 -1
  52. package/dist/client/assets/{regexp-CioRuhuN.js → regexp-gfs--3M7.js} +1 -1
  53. package/dist/client/assets/{rst-V__uTudD.js → rst-ugdlp-hl.js} +1 -1
  54. package/dist/client/assets/{ruby-C_PuKPTI.js → ruby-CDRRW37j.js} +1 -1
  55. package/dist/client/assets/{sas-D_DqqQH4.js → sas-DZaNQaIP.js} +1 -1
  56. package/dist/client/assets/{scss-D-TjzZ4c.js → scss-CzWQEplj.js} +1 -1
  57. package/dist/client/assets/{shellscript-E5759VHu.js → shellscript-fgYvpu9N.js} +1 -1
  58. package/dist/client/assets/{shellsession-AESTM-Pv.js → shellsession-BoAohHh7.js} +1 -1
  59. package/dist/client/assets/{soy-QrbrrcDv.js → soy-DBzVgv9x.js} +1 -1
  60. package/dist/client/assets/{sql-0M8VcDHD.js → sql-BYXpAYTs.js} +1 -1
  61. package/dist/client/assets/{stata-CgeIpGtc.js → stata-I71MMY3p.js} +1 -1
  62. package/dist/client/assets/{surrealql-DBGwnZbw.js → surrealql-C9U8_1VO.js} +1 -1
  63. package/dist/client/assets/{svelte-Cv0PvUc_.js → svelte-VOFrPnWT.js} +1 -1
  64. package/dist/client/assets/{templ-B9t7xRE4.js → templ-BIaxAEtC.js} +1 -1
  65. package/dist/client/assets/{tex-DhZZ8dr2.js → tex-D1dwnBE5.js} +1 -1
  66. package/dist/client/assets/{ts-tags-BFv8sbnd.js → ts-tags-C0L2Q0r5.js} +1 -1
  67. package/dist/client/assets/{tsx-CXC9KSbY.js → tsx-BqcycEv1.js} +1 -1
  68. package/dist/client/assets/{twig-CM_OO66r.js → twig-vyWqOhpM.js} +1 -1
  69. package/dist/client/assets/{typescript-BdgOTaoD.js → typescript-B2YbovqG.js} +1 -1
  70. package/dist/client/assets/{vue-BnQhjnCm.js → vue-CbXxGdjo.js} +1 -1
  71. package/dist/client/assets/{vue-html-CNnGecRI.js → vue-html-DDX4KXW7.js} +1 -1
  72. package/dist/client/assets/{vue-vine-DCuMkRhK.js → vue-vine-DsyY1LR5.js} +1 -1
  73. package/dist/client/assets/{xml-CbTD7cB8.js → xml-Ddi0-r0D.js} +1 -1
  74. package/dist/client/assets/{xsl-uOqqo7cf.js → xsl-CsFcZHFS.js} +1 -1
  75. package/dist/client/assets/{yaml-BNrLoH59.js → yaml-tGJWoH6Y.js} +1 -1
  76. package/dist/client/index.html +1 -1
  77. package/dist/client/sw.js +1 -1
  78. package/dist/server/analytics/engine.js +832 -0
  79. package/dist/server/assets.js +39 -0
  80. package/dist/server/auth/passphrase.js +70 -0
  81. package/dist/server/config.js +47 -0
  82. package/dist/server/daemon.js +535 -0
  83. package/dist/server/features/ralph-loop.js +138 -0
  84. package/dist/server/features/scheduler.js +260 -0
  85. package/dist/server/features/sticky-notes.js +99 -0
  86. package/dist/server/handlers/analytics.js +28 -0
  87. package/dist/server/handlers/attachment.js +158 -0
  88. package/dist/server/handlers/bookmarks.js +41 -0
  89. package/dist/server/handlers/chat.js +350 -0
  90. package/dist/server/handlers/editor.js +72 -0
  91. package/dist/server/handlers/fs.js +234 -0
  92. package/dist/server/handlers/loop.js +33 -0
  93. package/dist/server/handlers/memory.js +181 -0
  94. package/dist/server/handlers/mesh.js +322 -0
  95. package/dist/server/handlers/notes.js +36 -0
  96. package/dist/server/handlers/plugins.js +593 -0
  97. package/dist/server/handlers/project-settings.js +166 -0
  98. package/dist/server/handlers/scheduler.js +52 -0
  99. package/dist/server/handlers/session.js +194 -0
  100. package/dist/server/handlers/settings.js +148 -0
  101. package/dist/server/handlers/skills.js +360 -0
  102. package/dist/server/handlers/terminal.js +75 -0
  103. package/dist/server/handlers/themes.js +102 -0
  104. package/dist/server/handlers/update.js +124 -0
  105. package/dist/server/identity.js +45 -0
  106. package/dist/server/index.js +435 -0
  107. package/dist/server/logger.js +20 -0
  108. package/dist/server/mesh/connector.js +355 -0
  109. package/dist/server/mesh/crypto.js +88 -0
  110. package/dist/server/mesh/discovery.js +95 -0
  111. package/dist/server/mesh/pairing.js +104 -0
  112. package/dist/server/mesh/peers.js +54 -0
  113. package/dist/server/mesh/proxy.js +86 -0
  114. package/dist/server/mesh/session-sync.js +85 -0
  115. package/dist/server/project/bookmarks.js +77 -0
  116. package/dist/server/project/context-breakdown.js +279 -0
  117. package/dist/server/project/file-browser.js +97 -0
  118. package/dist/server/project/project-files.js +274 -0
  119. package/dist/server/project/registry.js +51 -0
  120. package/dist/server/project/sdk-bridge.js +960 -0
  121. package/dist/server/project/session.js +696 -0
  122. package/dist/server/project/terminal.js +87 -0
  123. package/dist/server/project/warmup.js +242 -0
  124. package/dist/server/push.js +87 -0
  125. package/dist/server/tls.js +50 -0
  126. package/dist/server/tui.js +83 -0
  127. package/dist/server/update-checker.js +119 -0
  128. package/dist/server/ws/broadcast.js +50 -0
  129. package/dist/server/ws/router.js +105 -0
  130. package/dist/server/ws/server.js +2 -0
  131. package/dist/shared/analytics.js +1 -0
  132. package/dist/shared/messages.js +1 -0
  133. package/dist/shared/models.js +1 -0
  134. package/dist/shared/project-settings.js +1 -0
  135. package/package.json +5 -8
  136. package/themes/alabaster.json +9 -0
  137. package/themes/amoled.json +20 -0
  138. package/themes/ayu-light.json +9 -0
  139. package/themes/catppuccin-latte.json +9 -0
  140. package/themes/catppuccin-mocha.json +9 -0
  141. package/themes/clay-light.json +10 -0
  142. package/themes/clay.json +10 -0
  143. package/themes/dracula.json +9 -0
  144. package/themes/everforest-light.json +9 -0
  145. package/themes/everforest.json +9 -0
  146. package/themes/github-light.json +9 -0
  147. package/themes/gruvbox-dark.json +9 -0
  148. package/themes/gruvbox-light.json +9 -0
  149. package/themes/horizon-light.json +9 -0
  150. package/themes/kanagawa-lotus.json +9 -0
  151. package/themes/kanagawa.json +9 -0
  152. package/themes/modus-operandi.json +9 -0
  153. package/themes/monokai.json +9 -0
  154. package/themes/nightfox.json +9 -0
  155. package/themes/nord-light.json +9 -0
  156. package/themes/nord.json +9 -0
  157. package/themes/one-dark.json +9 -0
  158. package/themes/one-light.json +9 -0
  159. package/themes/palenight.json +9 -0
  160. package/themes/paper.json +9 -0
  161. package/themes/penumbra-light.json +9 -0
  162. package/themes/poimandres.json +9 -0
  163. package/themes/quiet-light.json +9 -0
  164. package/themes/rose-pine-dawn.json +9 -0
  165. package/themes/rose-pine.json +9 -0
  166. package/themes/solarized-dark.json +9 -0
  167. package/themes/solarized-light.json +9 -0
  168. package/themes/synthwave84.json +9 -0
  169. package/themes/tokyo-night-light.json +9 -0
  170. package/themes/tokyo-night.json +9 -0
  171. package/themes/vesper.json +9 -0
  172. package/index.html +0 -20
  173. package/public/icons/icon-192.svg +0 -11
  174. package/public/icons/icon-512.svg +0 -11
  175. package/public/sw-push.js +0 -53
  176. package/src/client/App.tsx +0 -42
  177. package/src/client/commands.ts +0 -36
  178. package/src/client/components/analytics/AnalyticsView.tsx +0 -244
  179. package/src/client/components/analytics/ChartCard.tsx +0 -194
  180. package/src/client/components/analytics/PeriodSelector.tsx +0 -42
  181. package/src/client/components/analytics/QuickStats.tsx +0 -122
  182. package/src/client/components/analytics/chartTokens.ts +0 -188
  183. package/src/client/components/analytics/charts/ActivityCalendar.tsx +0 -204
  184. package/src/client/components/analytics/charts/CacheEfficiencyChart.tsx +0 -56
  185. package/src/client/components/analytics/charts/ContextUtilizationChart.tsx +0 -106
  186. package/src/client/components/analytics/charts/CostAreaChart.tsx +0 -79
  187. package/src/client/components/analytics/charts/CostDistributionChart.tsx +0 -59
  188. package/src/client/components/analytics/charts/CostDonutChart.tsx +0 -84
  189. package/src/client/components/analytics/charts/CumulativeCostChart.tsx +0 -59
  190. package/src/client/components/analytics/charts/DailySummaryCards.tsx +0 -86
  191. package/src/client/components/analytics/charts/HourlyHeatmap.tsx +0 -133
  192. package/src/client/components/analytics/charts/NodeFleetOverview.tsx +0 -89
  193. package/src/client/components/analytics/charts/PermissionBreakdown.tsx +0 -98
  194. package/src/client/components/analytics/charts/ProjectRadar.tsx +0 -126
  195. package/src/client/components/analytics/charts/ResponseTimeScatter.tsx +0 -96
  196. package/src/client/components/analytics/charts/SessionBubbleChart.tsx +0 -114
  197. package/src/client/components/analytics/charts/SessionComplexityList.tsx +0 -65
  198. package/src/client/components/analytics/charts/SessionTimeline.tsx +0 -107
  199. package/src/client/components/analytics/charts/TokenFlowChart.tsx +0 -78
  200. package/src/client/components/analytics/charts/TokenSankeyChart.tsx +0 -93
  201. package/src/client/components/analytics/charts/ToolSunburst.tsx +0 -123
  202. package/src/client/components/analytics/charts/ToolTreemap.tsx +0 -110
  203. package/src/client/components/auth/PassphrasePrompt.tsx +0 -70
  204. package/src/client/components/chat/AttachmentChips.tsx +0 -116
  205. package/src/client/components/chat/ChatInput.tsx +0 -533
  206. package/src/client/components/chat/ChatView.tsx +0 -1076
  207. package/src/client/components/chat/CommandPalette.tsx +0 -162
  208. package/src/client/components/chat/ElicitationCard.tsx +0 -238
  209. package/src/client/components/chat/Message.tsx +0 -825
  210. package/src/client/components/chat/ModelSelector.tsx +0 -108
  211. package/src/client/components/chat/PermissionModeSelector.tsx +0 -41
  212. package/src/client/components/chat/PromptQuestion.tsx +0 -271
  213. package/src/client/components/chat/StatusBar.tsx +0 -50
  214. package/src/client/components/chat/TodoCard.tsx +0 -57
  215. package/src/client/components/chat/ToolGroup.tsx +0 -129
  216. package/src/client/components/chat/ToolResultRenderer.tsx +0 -348
  217. package/src/client/components/chat/VoiceRecorder.tsx +0 -85
  218. package/src/client/components/chat/toolSummary.ts +0 -41
  219. package/src/client/components/dashboard/DashboardView.tsx +0 -200
  220. package/src/client/components/dashboard/ProjectDashboardView.tsx +0 -179
  221. package/src/client/components/mesh/NodeBadge.tsx +0 -24
  222. package/src/client/components/mesh/PairingDialog.tsx +0 -340
  223. package/src/client/components/project-settings/ProjectClaude.tsx +0 -318
  224. package/src/client/components/project-settings/ProjectEnvironment.tsx +0 -235
  225. package/src/client/components/project-settings/ProjectGeneral.tsx +0 -76
  226. package/src/client/components/project-settings/ProjectMcp.tsx +0 -232
  227. package/src/client/components/project-settings/ProjectMemory.tsx +0 -488
  228. package/src/client/components/project-settings/ProjectNotifications.tsx +0 -48
  229. package/src/client/components/project-settings/ProjectPermissions.tsx +0 -209
  230. package/src/client/components/project-settings/ProjectPlugins.tsx +0 -117
  231. package/src/client/components/project-settings/ProjectRules.tsx +0 -286
  232. package/src/client/components/project-settings/ProjectSettingsView.tsx +0 -117
  233. package/src/client/components/project-settings/ProjectSkills.tsx +0 -91
  234. package/src/client/components/settings/Appearance.tsx +0 -275
  235. package/src/client/components/settings/BudgetSettings.tsx +0 -165
  236. package/src/client/components/settings/ClaudeSettings.tsx +0 -175
  237. package/src/client/components/settings/Editor.tsx +0 -123
  238. package/src/client/components/settings/Environment.tsx +0 -185
  239. package/src/client/components/settings/GlobalMcp.tsx +0 -216
  240. package/src/client/components/settings/GlobalMemory.tsx +0 -19
  241. package/src/client/components/settings/GlobalPlugins.tsx +0 -806
  242. package/src/client/components/settings/GlobalRules.tsx +0 -149
  243. package/src/client/components/settings/GlobalSkills.tsx +0 -140
  244. package/src/client/components/settings/MeshStatus.tsx +0 -183
  245. package/src/client/components/settings/Notifications.tsx +0 -123
  246. package/src/client/components/settings/SettingsView.tsx +0 -75
  247. package/src/client/components/settings/SkillMarketplace.tsx +0 -175
  248. package/src/client/components/settings/ThemePreview.tsx +0 -140
  249. package/src/client/components/settings/ThemeWizard.tsx +0 -405
  250. package/src/client/components/settings/mcp-shared.tsx +0 -194
  251. package/src/client/components/settings/skill-shared.tsx +0 -186
  252. package/src/client/components/setup/SetupWizard.tsx +0 -755
  253. package/src/client/components/sidebar/AddProjectModal.tsx +0 -438
  254. package/src/client/components/sidebar/NodeSettingsModal.tsx +0 -206
  255. package/src/client/components/sidebar/ProjectDropdown.tsx +0 -211
  256. package/src/client/components/sidebar/ProjectRail.tsx +0 -353
  257. package/src/client/components/sidebar/SearchFilter.tsx +0 -52
  258. package/src/client/components/sidebar/SessionList.tsx +0 -599
  259. package/src/client/components/sidebar/SettingsSidebar.tsx +0 -139
  260. package/src/client/components/sidebar/Sidebar.tsx +0 -469
  261. package/src/client/components/sidebar/UserIsland.tsx +0 -282
  262. package/src/client/components/sidebar/UserMenu.tsx +0 -107
  263. package/src/client/components/ui/CommandPalette.tsx +0 -321
  264. package/src/client/components/ui/ContextMenu.tsx +0 -153
  265. package/src/client/components/ui/ErrorBoundary.tsx +0 -56
  266. package/src/client/components/ui/IconPicker.tsx +0 -184
  267. package/src/client/components/ui/KeyboardShortcuts.tsx +0 -129
  268. package/src/client/components/ui/LatticeLogomark.tsx +0 -19
  269. package/src/client/components/ui/NodeDisconnectedOverlay.tsx +0 -35
  270. package/src/client/components/ui/PopupMenu.tsx +0 -120
  271. package/src/client/components/ui/SaveFooter.tsx +0 -63
  272. package/src/client/components/ui/Toast.tsx +0 -132
  273. package/src/client/components/ui/UpdateBanner.tsx +0 -110
  274. package/src/client/components/ui/UpdatePrompt.tsx +0 -47
  275. package/src/client/components/workspace/BookmarksView.tsx +0 -156
  276. package/src/client/components/workspace/FileBrowser.tsx +0 -174
  277. package/src/client/components/workspace/FileTree.tsx +0 -129
  278. package/src/client/components/workspace/FileViewer.tsx +0 -211
  279. package/src/client/components/workspace/NoteCard.tsx +0 -120
  280. package/src/client/components/workspace/NotesView.tsx +0 -102
  281. package/src/client/components/workspace/ScheduledTasksView.tsx +0 -117
  282. package/src/client/components/workspace/SplitPane.tsx +0 -81
  283. package/src/client/components/workspace/TabBar.tsx +0 -170
  284. package/src/client/components/workspace/TaskCard.tsx +0 -159
  285. package/src/client/components/workspace/TaskEditModal.tsx +0 -129
  286. package/src/client/components/workspace/TerminalInstance.tsx +0 -171
  287. package/src/client/components/workspace/TerminalView.tsx +0 -110
  288. package/src/client/components/workspace/WorkspaceView.tsx +0 -141
  289. package/src/client/hooks/useAnalytics.ts +0 -84
  290. package/src/client/hooks/useAttachments.ts +0 -313
  291. package/src/client/hooks/useBookmarks.ts +0 -57
  292. package/src/client/hooks/useEditorConfig.ts +0 -28
  293. package/src/client/hooks/useFocusTrap.ts +0 -74
  294. package/src/client/hooks/useIdleDetection.ts +0 -50
  295. package/src/client/hooks/useInstallPrompt.ts +0 -53
  296. package/src/client/hooks/useMesh.ts +0 -89
  297. package/src/client/hooks/useNotifications.ts +0 -54
  298. package/src/client/hooks/useOnline.ts +0 -6
  299. package/src/client/hooks/useProjectSettings.ts +0 -56
  300. package/src/client/hooks/useProjects.ts +0 -98
  301. package/src/client/hooks/usePushNotifications.ts +0 -92
  302. package/src/client/hooks/useSaveState.ts +0 -65
  303. package/src/client/hooks/useSession.ts +0 -580
  304. package/src/client/hooks/useSidebar.ts +0 -90
  305. package/src/client/hooks/useSkills.ts +0 -30
  306. package/src/client/hooks/useSpinnerVerb.ts +0 -36
  307. package/src/client/hooks/useSwipeDrawer.ts +0 -299
  308. package/src/client/hooks/useTheme.ts +0 -114
  309. package/src/client/hooks/useTimeTick.ts +0 -35
  310. package/src/client/hooks/useVoiceRecorder.ts +0 -169
  311. package/src/client/hooks/useWebSocket.ts +0 -27
  312. package/src/client/hooks/useWorkspace.ts +0 -57
  313. package/src/client/lib/theme-derive.ts +0 -196
  314. package/src/client/lib/workspace-url.ts +0 -219
  315. package/src/client/main.tsx +0 -10
  316. package/src/client/providers/WebSocketProvider.tsx +0 -186
  317. package/src/client/router.tsx +0 -578
  318. package/src/client/stores/analytics.ts +0 -68
  319. package/src/client/stores/bookmarks.ts +0 -45
  320. package/src/client/stores/mesh.ts +0 -78
  321. package/src/client/stores/session.ts +0 -569
  322. package/src/client/stores/sidebar.ts +0 -530
  323. package/src/client/stores/theme.ts +0 -44
  324. package/src/client/stores/workspace.ts +0 -518
  325. package/src/client/styles/global.css +0 -391
  326. package/src/client/styles/theme-vars.css +0 -18
  327. package/src/client/themes/index.ts +0 -105
  328. package/src/client/utils/editorUrl.ts +0 -55
  329. package/src/client/utils/findDuplicateKeys.ts +0 -12
  330. package/src/client/utils/formatSessionTitle.ts +0 -17
  331. package/src/client/vite-env.d.ts +0 -6
  332. package/src/server/analytics/engine.ts +0 -920
  333. package/src/server/assets.ts +0 -45
  334. package/src/server/auth/passphrase.ts +0 -78
  335. package/src/server/config.ts +0 -55
  336. package/src/server/daemon.ts +0 -567
  337. package/src/server/features/ralph-loop.ts +0 -173
  338. package/src/server/features/scheduler.ts +0 -304
  339. package/src/server/features/sticky-notes.ts +0 -104
  340. package/src/server/handlers/analytics.ts +0 -39
  341. package/src/server/handlers/attachment.ts +0 -189
  342. package/src/server/handlers/bookmarks.ts +0 -50
  343. package/src/server/handlers/chat.ts +0 -381
  344. package/src/server/handlers/editor.ts +0 -76
  345. package/src/server/handlers/fs.ts +0 -251
  346. package/src/server/handlers/loop.ts +0 -37
  347. package/src/server/handlers/memory.ts +0 -182
  348. package/src/server/handlers/mesh.ts +0 -362
  349. package/src/server/handlers/notes.ts +0 -47
  350. package/src/server/handlers/plugins.ts +0 -655
  351. package/src/server/handlers/project-settings.ts +0 -180
  352. package/src/server/handlers/scheduler.ts +0 -64
  353. package/src/server/handlers/session.ts +0 -226
  354. package/src/server/handlers/settings.ts +0 -157
  355. package/src/server/handlers/skills.ts +0 -378
  356. package/src/server/handlers/terminal.ts +0 -88
  357. package/src/server/handlers/themes.ts +0 -121
  358. package/src/server/handlers/update.ts +0 -133
  359. package/src/server/identity.ts +0 -56
  360. package/src/server/index.ts +0 -457
  361. package/src/server/logger.ts +0 -21
  362. package/src/server/mesh/connector.ts +0 -419
  363. package/src/server/mesh/crypto.ts +0 -106
  364. package/src/server/mesh/discovery.ts +0 -126
  365. package/src/server/mesh/pairing.ts +0 -123
  366. package/src/server/mesh/peers.ts +0 -60
  367. package/src/server/mesh/proxy.ts +0 -106
  368. package/src/server/mesh/session-sync.ts +0 -107
  369. package/src/server/project/bookmarks.ts +0 -83
  370. package/src/server/project/context-breakdown.ts +0 -307
  371. package/src/server/project/file-browser.ts +0 -106
  372. package/src/server/project/project-files.ts +0 -267
  373. package/src/server/project/pty-worker.cjs +0 -83
  374. package/src/server/project/registry.ts +0 -57
  375. package/src/server/project/sdk-bridge.ts +0 -1100
  376. package/src/server/project/session.ts +0 -723
  377. package/src/server/project/terminal.ts +0 -111
  378. package/src/server/project/warmup.ts +0 -285
  379. package/src/server/push.ts +0 -121
  380. package/src/server/tls.ts +0 -65
  381. package/src/server/tui.ts +0 -103
  382. package/src/server/update-checker.ts +0 -147
  383. package/src/server/ws/broadcast.ts +0 -61
  384. package/src/server/ws/router.ts +0 -123
  385. package/src/server/ws/server.ts +0 -2
  386. package/src/shared/analytics.ts +0 -40
  387. package/src/shared/messages.ts +0 -1302
  388. package/src/shared/models.ts +0 -255
  389. package/src/shared/project-settings.ts +0 -45
  390. package/tsconfig.json +0 -25
  391. package/vite.config.ts +0 -71
  392. /package/{src/server/runtime.ts → dist/server/runtime.js} +0 -0
  393. /package/{src/shared/constants.ts → dist/shared/constants.js} +0 -0
  394. /package/{src/shared/index.ts → dist/shared/index.js} +0 -0
@@ -1,184 +0,0 @@
1
- import { useState, useMemo } from "react";
2
- import { icons } from "lucide-react";
3
- import type { ProjectIcon } from "#shared";
4
-
5
- type Tab = "lucide" | "text" | "upload";
6
-
7
- interface IconPickerProps {
8
- value?: ProjectIcon;
9
- onChange: (icon: ProjectIcon) => void;
10
- }
11
-
12
- function renderPreview(value?: ProjectIcon) {
13
- if (!value) {
14
- return (
15
- <div className="w-8 h-8 rounded-lg bg-base-300 border border-base-content/15 flex items-center justify-center text-base-content/30 text-[11px]">
16
- ?
17
- </div>
18
- );
19
- }
20
-
21
- if (value.type === "lucide") {
22
- var LucideIcon = icons[value.name as keyof typeof icons];
23
- if (!LucideIcon) return null;
24
- return (
25
- <div className="w-8 h-8 rounded-lg bg-base-300 border border-base-content/15 flex items-center justify-center text-base-content">
26
- <LucideIcon size={18} />
27
- </div>
28
- );
29
- }
30
-
31
- if (value.type === "text") {
32
- return (
33
- <div
34
- className="w-8 h-8 rounded-lg bg-base-300 border border-base-content/15 flex items-center justify-center text-[14px] font-bold"
35
- style={value.color ? { color: value.color } : undefined}
36
- >
37
- {value.value}
38
- </div>
39
- );
40
- }
41
-
42
- if (value.type === "image") {
43
- return (
44
- <img src={value.path} alt="icon" className="w-8 h-8 rounded-lg object-cover border border-base-content/15" loading="lazy" />
45
- );
46
- }
47
-
48
- return null;
49
- }
50
-
51
- export function IconPicker({ value, onChange }: IconPickerProps) {
52
- var normalizedValue = value && (value as { type: string }).type === "emoji" ? undefined : value;
53
- var [tab, setTab] = useState<Tab>(normalizedValue?.type === "text" ? "text" : normalizedValue?.type === "image" ? "upload" : "lucide");
54
- var [search, setSearch] = useState("");
55
- var [textValue, setTextValue] = useState(normalizedValue?.type === "text" ? normalizedValue.value : "");
56
- var [textColor, setTextColor] = useState(normalizedValue?.type === "text" ? (normalizedValue.color || "#ffffff") : "#ffffff");
57
-
58
- var iconNames = useMemo(function () {
59
- var allNames = Object.keys(icons);
60
- if (!search.trim()) return allNames.slice(0, 60);
61
- var term = search.toLowerCase();
62
- return allNames.filter(function (name) {
63
- return name.toLowerCase().includes(term);
64
- }).slice(0, 60);
65
- }, [search]);
66
-
67
- var tabs: { id: Tab; label: string }[] = [
68
- { id: "lucide", label: "Lucide" },
69
- { id: "text", label: "Text" },
70
- { id: "upload", label: "Upload" },
71
- ];
72
-
73
- function handleFileChange(e: React.ChangeEvent<HTMLInputElement>) {
74
- var file = e.target.files?.[0];
75
- if (!file) return;
76
- var reader = new FileReader();
77
- reader.onload = function (ev) {
78
- var dataUrl = ev.target?.result as string;
79
- onChange({ type: "image", path: dataUrl });
80
- };
81
- reader.readAsDataURL(file);
82
- }
83
-
84
- return (
85
- <div className="space-y-3">
86
- <div className="flex items-center gap-3">
87
- {renderPreview(normalizedValue)}
88
- <span className="text-[11px] text-base-content/40">Current icon</span>
89
- </div>
90
-
91
- <div className="flex gap-1">
92
- {tabs.map(function (t) {
93
- return (
94
- <button
95
- key={t.id}
96
- type="button"
97
- onClick={function () { setTab(t.id); }}
98
- className={"btn btn-xs " + (tab === t.id ? "btn-primary" : "btn-ghost")}
99
- >
100
- {t.label}
101
- </button>
102
- );
103
- })}
104
- </div>
105
-
106
- {tab === "lucide" && (
107
- <div className="space-y-2">
108
- <input
109
- type="text"
110
- value={search}
111
- onChange={function (e) { setSearch(e.target.value); }}
112
- placeholder="Search icons..."
113
- aria-label="Search icons"
114
- className="w-full h-8 px-3 bg-base-300 border border-base-content/15 rounded-xl text-base-content text-[12px] focus:border-primary focus-visible:outline-none transition-colors duration-[120ms]"
115
- />
116
- <div className="grid grid-cols-10 gap-1 max-h-48 overflow-y-auto">
117
- {iconNames.map(function (name) {
118
- var Icon = icons[name as keyof typeof icons];
119
- var selected = normalizedValue?.type === "lucide" && normalizedValue.name === name;
120
- return (
121
- <button
122
- key={name}
123
- type="button"
124
- title={name}
125
- onClick={function () { onChange({ type: "lucide", name: name }); }}
126
- className={
127
- "w-8 h-8 flex items-center justify-center rounded-lg text-base-content transition-colors duration-75 " +
128
- (selected ? "border border-primary bg-base-300" : "hover:bg-base-300")
129
- }
130
- >
131
- <Icon size={16} />
132
- </button>
133
- );
134
- })}
135
- </div>
136
- </div>
137
- )}
138
-
139
- {tab === "text" && (
140
- <div className="flex gap-2">
141
- <input
142
- type="text"
143
- value={textValue}
144
- maxLength={2}
145
- onChange={function (e) {
146
- setTextValue(e.target.value);
147
- if (e.target.value) {
148
- onChange({ type: "text", value: e.target.value, color: textColor });
149
- }
150
- }}
151
- placeholder="1-2 chars"
152
- aria-label="Icon text"
153
- className="flex-1 h-9 px-3 bg-base-300 border border-base-content/15 rounded-xl text-base-content text-[13px] focus:border-primary focus-visible:outline-none transition-colors duration-[120ms]"
154
- />
155
- <input
156
- type="color"
157
- value={textColor}
158
- onChange={function (e) {
159
- setTextColor(e.target.value);
160
- if (textValue) {
161
- onChange({ type: "text", value: textValue, color: e.target.value });
162
- }
163
- }}
164
- className="w-9 h-9 rounded-xl border border-base-content/15 bg-base-300 cursor-pointer"
165
- />
166
- </div>
167
- )}
168
-
169
- {tab === "upload" && (
170
- <div className="space-y-2">
171
- <input
172
- type="file"
173
- accept="image/*"
174
- onChange={handleFileChange}
175
- className="w-full text-[12px] text-base-content/60 file:mr-3 file:py-1.5 file:px-3 file:rounded-lg file:border-0 file:text-[12px] file:bg-base-300 file:text-base-content/60 file:cursor-pointer"
176
- />
177
- {normalizedValue?.type === "image" && (
178
- <img src={normalizedValue.path} alt="preview" className="w-16 h-16 rounded-xl object-cover border border-base-content/15" loading="lazy" />
179
- )}
180
- </div>
181
- )}
182
- </div>
183
- );
184
- }
@@ -1,129 +0,0 @@
1
- import { useEffect, useState } from "react";
2
- import { X } from "lucide-react";
3
-
4
- interface ShortcutEntry {
5
- keys: string[];
6
- description: string;
7
- }
8
-
9
- interface ShortcutCategory {
10
- name: string;
11
- shortcuts: ShortcutEntry[];
12
- }
13
-
14
- var isMac = typeof navigator !== "undefined" && navigator.platform.indexOf("Mac") !== -1;
15
- var modKey = isMac ? "\u2318" : "Ctrl";
16
-
17
- var categories: ShortcutCategory[] = [
18
- {
19
- name: "Chat",
20
- shortcuts: [
21
- { keys: ["Enter"], description: "Send message" },
22
- { keys: ["Shift", "Enter"], description: "New line" },
23
- { keys: ["\u2191"], description: "Previous input history" },
24
- { keys: ["\u2193"], description: "Next input history" },
25
- { keys: ["/"], description: "Slash commands" },
26
- { keys: ["Escape"], description: "Close autocomplete" },
27
- ],
28
- },
29
- {
30
- name: "Navigation",
31
- shortcuts: [
32
- { keys: [modKey, "K"], description: "Command palette" },
33
- { keys: ["?"], description: "Keyboard shortcuts" },
34
- { keys: ["Escape"], description: "Close modal / exit settings" },
35
- ],
36
- },
37
- {
38
- name: "Session",
39
- shortcuts: [
40
- { keys: ["/clear"], description: "New session" },
41
- { keys: ["/copy"], description: "Copy last response" },
42
- { keys: ["/export"], description: "Export conversation" },
43
- { keys: ["/rename"], description: "Rename session" },
44
- ],
45
- },
46
- ];
47
-
48
- function Kbd(props: { children: string }) {
49
- return (
50
- <kbd className="bg-base-300 border border-base-content/20 rounded px-1.5 py-0.5 text-[11px] font-mono text-base-content/70 leading-none inline-flex items-center justify-center min-w-[22px]">
51
- {props.children}
52
- </kbd>
53
- );
54
- }
55
-
56
- export function KeyboardShortcuts() {
57
- var [open, setOpen] = useState(false);
58
-
59
- useEffect(function () {
60
- function handleKeyDown(e: KeyboardEvent) {
61
- if (e.key === "?" && !e.ctrlKey && !e.metaKey && !e.altKey) {
62
- var tag = (e.target as HTMLElement).tagName;
63
- if (tag === "INPUT" || tag === "TEXTAREA" || (e.target as HTMLElement).isContentEditable) return;
64
- e.preventDefault();
65
- setOpen(true);
66
- }
67
- if (e.key === "Escape" && open) {
68
- setOpen(false);
69
- }
70
- }
71
- document.addEventListener("keydown", handleKeyDown);
72
- return function () { document.removeEventListener("keydown", handleKeyDown); };
73
- }, [open]);
74
-
75
- if (!open) return null;
76
-
77
- return (
78
- <div className="fixed inset-0 z-[9998] flex items-center justify-center" onClick={function () { setOpen(false); }}>
79
- <div className="absolute inset-0 bg-base-content/50" />
80
- <div
81
- className="relative w-full max-w-[540px] mx-4 bg-base-200 border border-base-content/15 rounded-2xl shadow-xl overflow-hidden"
82
- onClick={function (e) { e.stopPropagation(); }}
83
- >
84
- <div className="flex items-center justify-between px-5 py-3.5 border-b border-base-content/10">
85
- <h2 className="text-[14px] font-mono font-bold text-base-content tracking-tight">Keyboard Shortcuts</h2>
86
- <button
87
- onClick={function () { setOpen(false); }}
88
- className="w-6 h-6 rounded flex items-center justify-center text-base-content/30 hover:text-base-content/60 transition-colors"
89
- >
90
- <X size={14} />
91
- </button>
92
- </div>
93
- <div className="px-5 py-4 max-h-[70vh] overflow-y-auto">
94
- <div className="flex flex-col gap-5">
95
- {categories.map(function (cat) {
96
- return (
97
- <div key={cat.name}>
98
- <div className="text-[9px] uppercase tracking-widest text-base-content/30 font-mono font-bold mb-2">{cat.name}</div>
99
- <div className="flex flex-col gap-1">
100
- {cat.shortcuts.map(function (shortcut, i) {
101
- return (
102
- <div key={i} className="flex items-center justify-between py-1.5 px-2 rounded hover:bg-base-content/5 transition-colors">
103
- <span className="text-[13px] text-base-content/60">{shortcut.description}</span>
104
- <div className="flex items-center gap-1 flex-shrink-0 ml-4">
105
- {shortcut.keys.map(function (key, ki) {
106
- return (
107
- <span key={ki} className="flex items-center gap-1">
108
- {ki > 0 && <span className="text-[10px] text-base-content/20">+</span>}
109
- <Kbd>{key}</Kbd>
110
- </span>
111
- );
112
- })}
113
- </div>
114
- </div>
115
- );
116
- })}
117
- </div>
118
- </div>
119
- );
120
- })}
121
- </div>
122
- </div>
123
- <div className="px-5 py-2.5 border-t border-base-content/10 flex justify-end">
124
- <span className="text-[10px] font-mono text-base-content/20">Press <Kbd>Esc</Kbd> to close</span>
125
- </div>
126
- </div>
127
- </div>
128
- );
129
- }
@@ -1,19 +0,0 @@
1
- interface LatticeLogomarkProps {
2
- size: number;
3
- }
4
-
5
- export function LatticeLogomark(props: LatticeLogomarkProps) {
6
- var s = props.size;
7
- return (
8
- <svg width={s} height={s} viewBox="0 0 48 48" fill="none" aria-hidden="true">
9
- <rect x="4" y="4" width="18" height="18" rx="3" fill="currentColor" />
10
- <rect x="26" y="4" width="18" height="18" rx="3" fill="currentColor" opacity="0.55" />
11
- <rect x="4" y="26" width="18" height="18" rx="3" fill="currentColor" opacity="0.55" />
12
- <rect x="26" y="26" width="18" height="18" rx="3" fill="currentColor" opacity="0.25" />
13
- <line x1="13" y1="22" x2="13" y2="26" stroke="currentColor" strokeWidth="1.5" opacity="0.8" />
14
- <line x1="35" y1="22" x2="35" y2="26" stroke="currentColor" strokeWidth="1.5" opacity="0.5" />
15
- <line x1="22" y1="13" x2="26" y2="13" stroke="currentColor" strokeWidth="1.5" opacity="0.8" />
16
- <line x1="22" y1="35" x2="26" y2="35" stroke="currentColor" strokeWidth="1.5" opacity="0.5" />
17
- </svg>
18
- );
19
- }
@@ -1,35 +0,0 @@
1
- import { WifiOff, Loader2 } from "lucide-react";
2
- import { useProjects } from "../../hooks/useProjects";
3
- import { useMesh } from "../../hooks/useMesh";
4
- import { useSidebar } from "../../hooks/useSidebar";
5
-
6
- export function NodeDisconnectedOverlay() {
7
- var { activeProject } = useProjects();
8
- var { nodes } = useMesh();
9
- var sidebar = useSidebar();
10
-
11
- if (!activeProject || !activeProject.isRemote) return null;
12
- if (sidebar.activeView.type !== "chat") return null;
13
-
14
- var remoteNode = nodes.find(function (n) { return n.id === activeProject!.nodeId; });
15
- if (!remoteNode || remoteNode.online) return null;
16
-
17
- return (
18
- <div className="absolute inset-0 z-40 flex items-center justify-center bg-base-100/80 backdrop-blur-sm">
19
- <div className="bg-base-300 border border-base-content/15 rounded-2xl shadow-2xl px-8 py-6 max-w-sm text-center">
20
- <WifiOff size={28} className="text-warning mx-auto mb-3" />
21
- <h3 className="text-[15px] font-mono font-bold text-base-content mb-1">Node Disconnected</h3>
22
- <p className="text-[13px] text-base-content/50 mb-3">
23
- <span className="font-semibold text-base-content/70">{remoteNode.name}</span> is unreachable.
24
- </p>
25
- <div className="flex items-center justify-center gap-2 text-[12px] text-base-content/40">
26
- <Loader2 size={12} className="animate-spin" />
27
- Attempting to reconnect...
28
- </div>
29
- <p className="text-[11px] text-base-content/25 mt-3">
30
- Session state preserved. Operations will resume on reconnect.
31
- </p>
32
- </div>
33
- </div>
34
- );
35
- }
@@ -1,120 +0,0 @@
1
- import { useEffect, useRef } from "react";
2
- import { createPortal } from "react-dom";
3
-
4
- export interface PopupMenuItem {
5
- id: string;
6
- label: string;
7
- icon?: React.ReactNode;
8
- danger?: boolean;
9
- separator?: boolean;
10
- }
11
-
12
- interface PopupMenuProps {
13
- items: PopupMenuItem[];
14
- onSelect: (id: string) => void;
15
- onClose: () => void;
16
- anchorRef: React.RefObject<HTMLElement | null>;
17
- position?: "above" | "below" | "right";
18
- }
19
-
20
- export function PopupMenu(props: PopupMenuProps) {
21
- var menuRef = useRef<HTMLDivElement>(null);
22
-
23
- useEffect(function () {
24
- function handleClickOutside(e: MouseEvent) {
25
- if (
26
- menuRef.current &&
27
- !menuRef.current.contains(e.target as Node) &&
28
- props.anchorRef.current &&
29
- !props.anchorRef.current.contains(e.target as Node)
30
- ) {
31
- props.onClose();
32
- }
33
- }
34
- function handleEscape(e: KeyboardEvent) {
35
- if (e.key === "Escape") {
36
- props.onClose();
37
- }
38
- }
39
- function handleScroll() {
40
- props.onClose();
41
- }
42
- document.addEventListener("mousedown", handleClickOutside);
43
- document.addEventListener("keydown", handleEscape);
44
- window.addEventListener("scroll", handleScroll, true);
45
- return function () {
46
- document.removeEventListener("mousedown", handleClickOutside);
47
- document.removeEventListener("keydown", handleEscape);
48
- window.removeEventListener("scroll", handleScroll, true);
49
- };
50
- }, [props.onClose, props.anchorRef]);
51
-
52
- var style: React.CSSProperties = {};
53
- if (props.anchorRef.current) {
54
- var rect = props.anchorRef.current.getBoundingClientRect();
55
- var pos = props.position ?? "above";
56
- var menuWidth = 180;
57
- var menuHeight = 200;
58
-
59
- if (pos === "above") {
60
- style.bottom = window.innerHeight - rect.top + 4 + "px";
61
- var leftAbove = rect.left;
62
- if (leftAbove + menuWidth > window.innerWidth - 8) leftAbove = window.innerWidth - menuWidth - 8;
63
- if (leftAbove < 8) leftAbove = 8;
64
- style.left = leftAbove + "px";
65
- } else if (pos === "below") {
66
- var topBelow = rect.bottom + 4;
67
- if (topBelow + menuHeight > window.innerHeight - 8) {
68
- style.bottom = window.innerHeight - rect.top + 4 + "px";
69
- } else {
70
- style.top = topBelow + "px";
71
- }
72
- var leftBelow = rect.left;
73
- if (leftBelow + menuWidth > window.innerWidth - 8) leftBelow = window.innerWidth - menuWidth - 8;
74
- if (leftBelow < 8) leftBelow = 8;
75
- style.left = leftBelow + "px";
76
- } else if (pos === "right") {
77
- var topRight = rect.top;
78
- if (topRight + menuHeight > window.innerHeight - 8) topRight = window.innerHeight - menuHeight - 8;
79
- if (topRight < 8) topRight = 8;
80
- style.top = topRight + "px";
81
- var leftRight = rect.right + 4;
82
- if (leftRight + menuWidth > window.innerWidth - 8) leftRight = rect.left - menuWidth - 4;
83
- if (leftRight < 8) leftRight = 8;
84
- style.left = leftRight + "px";
85
- }
86
- }
87
-
88
- return createPortal(
89
- <div
90
- ref={menuRef}
91
- role="menu"
92
- aria-label="Actions"
93
- className="fixed z-[9999] bg-base-300 border border-base-content/10 rounded-lg shadow-xl p-1 min-w-[180px] max-h-[80vh] overflow-y-auto"
94
- style={style}
95
- >
96
- {props.items.map(function (item) {
97
- if (item.separator) {
98
- return <div key={item.id} className="h-px bg-base-content/8 my-1 mx-2" />;
99
- }
100
- return (
101
- <button
102
- key={item.id}
103
- role="menuitem"
104
- onClick={function () { props.onSelect(item.id); }}
105
- className={
106
- "w-full flex items-center gap-2 px-2.5 py-[6px] rounded text-[11px] text-left cursor-pointer transition-colors duration-[120ms] outline-none focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-inset " +
107
- (item.danger
108
- ? "text-error hover:bg-error/10"
109
- : "text-base-content/70 hover:bg-base-content/5 hover:text-base-content")
110
- }
111
- >
112
- {item.icon && <span className="opacity-60 flex-shrink-0">{item.icon}</span>}
113
- {item.label}
114
- </button>
115
- );
116
- })}
117
- </div>,
118
- document.body
119
- );
120
- }
@@ -1,63 +0,0 @@
1
- import { useEffect, useRef } from "react";
2
- import { Loader2, Check, X } from "lucide-react";
3
- import type { SaveState } from "../../hooks/useSaveState";
4
- import { showToast } from "./Toast";
5
-
6
- interface SaveFooterProps {
7
- dirty: boolean;
8
- saving: boolean;
9
- saveState: SaveState;
10
- onSave: () => void;
11
- extraStatus?: string;
12
- }
13
-
14
- export function SaveFooter({ dirty, saving, saveState, onSave, extraStatus }: SaveFooterProps) {
15
- var disabled = saving || (!dirty && saveState !== "error");
16
- var prevStateRef = useRef<SaveState>("idle");
17
-
18
- useEffect(function () {
19
- if (prevStateRef.current !== saveState) {
20
- if (saveState === "saved") {
21
- showToast("Settings saved", "info");
22
- } else if (saveState === "error") {
23
- showToast("Failed to save settings — server did not respond within 5 seconds", "error");
24
- }
25
- prevStateRef.current = saveState;
26
- }
27
- }, [saveState]);
28
-
29
- return (
30
- <div className="flex items-center justify-end gap-3">
31
- {extraStatus && (
32
- <div className="text-[11px] text-warning/70">{extraStatus}</div>
33
- )}
34
- {!extraStatus && dirty && saveState === "idle" && !saving && (
35
- <div className="text-[11px] text-warning/70">Unsaved changes</div>
36
- )}
37
- {saveState === "error" && (
38
- <div className="flex items-center gap-1.5 text-[11px] text-error">
39
- <X size={11} />
40
- Save failed — server did not respond
41
- </div>
42
- )}
43
- {saveState === "saved" && (
44
- <div className="flex items-center gap-1.5 text-[11px] text-success/70">
45
- <Check size={11} />
46
- Saved
47
- </div>
48
- )}
49
- <button
50
- onClick={onSave}
51
- disabled={disabled}
52
- className={
53
- "btn btn-sm gap-1.5 " +
54
- (saveState === "saved" ? "btn-success" : saveState === "error" ? "btn-error" : "btn-primary") +
55
- (disabled ? " opacity-50 cursor-not-allowed" : "")
56
- }
57
- >
58
- {saving && <Loader2 size={13} className="animate-spin" />}
59
- {saving ? "Saving..." : saveState === "error" ? "Retry" : "Save Changes"}
60
- </button>
61
- </div>
62
- );
63
- }
@@ -1,132 +0,0 @@
1
- import { useEffect, useState, useCallback } from "react";
2
- import { X, Info, AlertTriangle, AlertCircle } from "lucide-react";
3
-
4
- export interface ToastOptions {
5
- persistent?: boolean;
6
- duration?: number;
7
- }
8
-
9
- export interface ToastItem {
10
- id: string;
11
- message: string;
12
- type: "info" | "error" | "warning";
13
- persistent?: boolean;
14
- duration?: number;
15
- }
16
-
17
- interface ToastProps {
18
- items: ToastItem[];
19
- onDismiss: (id: string) => void;
20
- }
21
-
22
- var ICON_MAP = {
23
- info: Info,
24
- warning: AlertTriangle,
25
- error: AlertCircle,
26
- };
27
-
28
- var ACCENT_MAP = {
29
- info: "bg-primary",
30
- warning: "bg-warning",
31
- error: "bg-error",
32
- };
33
-
34
- var ICON_COLOR_MAP = {
35
- info: "text-primary",
36
- warning: "text-warning",
37
- error: "text-error",
38
- };
39
-
40
- export function Toast(props: ToastProps) {
41
- if (props.items.length === 0) {
42
- return null;
43
- }
44
-
45
- return (
46
- <div className="fixed top-3 right-3 z-[9999] flex flex-col gap-2 max-w-[340px]" role="status" aria-live="polite" aria-atomic="false">
47
- {props.items.map(function (item) {
48
- var Icon = ICON_MAP[item.type];
49
- return (
50
- <div
51
- key={item.id}
52
- className="flex items-start gap-2.5 bg-base-300 border border-base-content/10 rounded-lg shadow-xl px-3 py-2.5 animate-[toast-in_0.18s_ease]"
53
- >
54
- <div className={"w-0.5 self-stretch rounded-full flex-shrink-0 " + ACCENT_MAP[item.type]} />
55
- <Icon size={14} className={"flex-shrink-0 mt-0.5 " + ICON_COLOR_MAP[item.type]} />
56
- <span className="flex-1 text-[13px] text-base-content/80 leading-snug">{item.message}</span>
57
- <button
58
- onClick={function () { props.onDismiss(item.id); }}
59
- aria-label="Dismiss"
60
- className="flex-shrink-0 text-base-content/30 hover:text-base-content/60 transition-colors mt-0.5"
61
- >
62
- <X size={13} />
63
- </button>
64
- </div>
65
- );
66
- })}
67
- </div>
68
- );
69
- }
70
-
71
- var toastListeners: Array<(item: ToastItem) => void> = [];
72
-
73
- export function showToast(message: string, type: ToastItem["type"] = "info", options?: ToastOptions): void {
74
- var persistent = options?.persistent;
75
- var duration = options?.duration;
76
-
77
- if (type === "error" && persistent === undefined && duration === undefined) {
78
- persistent = true;
79
- }
80
-
81
- var item: ToastItem = {
82
- id: Math.random().toString(36).slice(2),
83
- message,
84
- type,
85
- persistent,
86
- duration,
87
- };
88
- toastListeners.forEach(function (listener) {
89
- listener(item);
90
- });
91
- }
92
-
93
- export function useToastState(): { items: ToastItem[]; dismiss: (id: string) => void } {
94
- var [items, setItems] = useState<ToastItem[]>([]);
95
-
96
- var dismiss = useCallback(function (id: string) {
97
- setItems(function (prev) {
98
- return prev.filter(function (item) {
99
- return item.id !== id;
100
- });
101
- });
102
- }, []);
103
-
104
- useEffect(function () {
105
- function listener(item: ToastItem) {
106
- setItems(function (prev) {
107
- return [...prev, item];
108
- });
109
-
110
- if (item.persistent) return;
111
-
112
- var timeout = item.duration ?? 5000;
113
- setTimeout(function () {
114
- setItems(function (prev) {
115
- return prev.filter(function (i) {
116
- return i.id !== item.id;
117
- });
118
- });
119
- }, timeout);
120
- }
121
-
122
- toastListeners.push(listener);
123
-
124
- return function () {
125
- toastListeners = toastListeners.filter(function (l) {
126
- return l !== listener;
127
- });
128
- };
129
- }, []);
130
-
131
- return { items, dismiss };
132
- }