@cryptiklemur/lattice 4.0.2 → 5.0.1

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 +533 -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,438 +0,0 @@
1
- import { useState, useEffect, useRef, useCallback } from "react";
2
- import { useFocusTrap } from "../../hooks/useFocusTrap";
3
- import { X, FolderOpen, FileText, Loader2 } from "lucide-react";
4
- import { useWebSocket } from "../../hooks/useWebSocket";
5
- import { useProjects } from "../../hooks/useProjects";
6
- import type { ServerMessage } from "#shared";
7
-
8
- interface BrowseEntry {
9
- name: string;
10
- path: string;
11
- hasClaudeMd: boolean;
12
- projectName: string | null;
13
- }
14
-
15
- interface AddProjectModalProps {
16
- isOpen: boolean;
17
- onClose: () => void;
18
- }
19
-
20
- export function AddProjectModal({ isOpen, onClose }: AddProjectModalProps) {
21
- var { send, subscribe, unsubscribe } = useWebSocket();
22
- var { projects } = useProjects();
23
-
24
- var [path, setPath] = useState("");
25
- var [entries, setEntries] = useState<BrowseEntry[]>([]);
26
- var [title, setTitle] = useState("");
27
- var [titleManuallySet, setTitleManuallySet] = useState(false);
28
- var [dropdownOpen, setDropdownOpen] = useState(false);
29
- var [highlightIndex, setHighlightIndex] = useState(-1);
30
- var [error, setError] = useState<string | null>(null);
31
- var [adding, setAdding] = useState(false);
32
- var [suggestions, setSuggestions] = useState<Array<{ path: string; name: string; hasClaudeMd: boolean }>>([]);
33
- var [homedir, setHomedir] = useState("");
34
- var debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);
35
- var inputRef = useRef<HTMLInputElement>(null);
36
- var dropdownRef = useRef<HTMLDivElement>(null);
37
- var inputFocusedRef = useRef(false);
38
- var addingRef = useRef(false);
39
- var modalRef = useRef<HTMLDivElement>(null);
40
- var stableOnClose = useCallback(function () { onClose(); }, [onClose]);
41
- useFocusTrap(modalRef, stableOnClose, isOpen);
42
-
43
- useEffect(function () {
44
- if (!isOpen) return;
45
-
46
- setPath("");
47
- setEntries([]);
48
- setTitle("");
49
- setTitleManuallySet(false);
50
- setDropdownOpen(false);
51
- setError(null);
52
- setAdding(false);
53
- setSuggestions([]);
54
- addingRef.current = false;
55
-
56
- send({ type: "browse:list", path: "~" } as any);
57
- send({ type: "browse:suggestions" } as any);
58
-
59
- function handleBrowseResult(msg: ServerMessage) {
60
- if (msg.type !== "browse:list_result") return;
61
- var data = msg as { type: "browse:list_result"; path: string; homedir: string; entries: BrowseEntry[] };
62
- setEntries(data.entries);
63
- setHomedir(data.homedir);
64
- setHighlightIndex(-1);
65
- if (inputFocusedRef.current && data.entries.length > 0) {
66
- setDropdownOpen(true);
67
- }
68
- }
69
-
70
- function handleSuggestions(msg: ServerMessage) {
71
- if (msg.type !== "browse:suggestions_result") return;
72
- var data = msg as { type: "browse:suggestions_result"; suggestions: Array<{ path: string; name: string; hasClaudeMd: boolean }> };
73
- setSuggestions(data.suggestions);
74
- }
75
-
76
- function handleProjectsList(msg: ServerMessage) {
77
- if (msg.type !== "projects:list") return;
78
- if (addingRef.current) {
79
- addingRef.current = false;
80
- setAdding(false);
81
- onClose();
82
- }
83
- }
84
-
85
- subscribe("browse:list_result", handleBrowseResult);
86
- subscribe("browse:suggestions_result", handleSuggestions);
87
- subscribe("projects:list", handleProjectsList);
88
-
89
- return function () {
90
- unsubscribe("browse:list_result", handleBrowseResult);
91
- unsubscribe("browse:suggestions_result", handleSuggestions);
92
- unsubscribe("projects:list", handleProjectsList);
93
- };
94
- }, [isOpen]);
95
-
96
- useEffect(function () {
97
- if (!isOpen) return;
98
-
99
- function handleMouseDown(e: MouseEvent) {
100
- if (
101
- dropdownRef.current &&
102
- !dropdownRef.current.contains(e.target as Node) &&
103
- inputRef.current &&
104
- !inputRef.current.contains(e.target as Node)
105
- ) {
106
- setDropdownOpen(false);
107
- }
108
- }
109
-
110
- document.addEventListener("mousedown", handleMouseDown);
111
- return function () {
112
- document.removeEventListener("mousedown", handleMouseDown);
113
- };
114
- }, [isOpen]);
115
-
116
- useEffect(function () {
117
- if (!isOpen) return;
118
- if (debounceRef.current) clearTimeout(debounceRef.current);
119
-
120
- var trimmed = path.trim();
121
- if (!trimmed) {
122
- send({ type: "browse:list", path: "~" } as any);
123
- return;
124
- }
125
-
126
- debounceRef.current = setTimeout(function () {
127
- var parentDir = trimmed;
128
- if (!trimmed.endsWith("/")) {
129
- var lastSlash = trimmed.lastIndexOf("/");
130
- parentDir = lastSlash >= 0 ? trimmed.slice(0, lastSlash + 1) : trimmed;
131
- }
132
- send({ type: "browse:list", path: parentDir } as any);
133
- }, 200);
134
- }, [path, isOpen]);
135
-
136
- function resolvePath(p: string): string {
137
- if (p.startsWith("~/") && homedir) return homedir + p.slice(1);
138
- if (p === "~" && homedir) return homedir;
139
- return p;
140
- }
141
-
142
- function handleSelectEntry(entry: BrowseEntry) {
143
- var newPath = entry.path + "/";
144
- setPath(newPath);
145
- setDropdownOpen(false);
146
- setError(null);
147
-
148
- if (!titleManuallySet) {
149
- if (entry.projectName) {
150
- setTitle(entry.projectName);
151
- } else {
152
- setTitle(entry.name);
153
- }
154
- }
155
-
156
- send({ type: "browse:list", path: entry.path } as any);
157
-
158
- if (inputRef.current) {
159
- inputRef.current.focus();
160
- }
161
- }
162
-
163
- function handleTitleChange(value: string) {
164
- setTitle(value);
165
- setTitleManuallySet(value.length > 0);
166
- }
167
-
168
- function handleInputFocus() {
169
- inputFocusedRef.current = true;
170
- if (getFilteredEntries().length > 0) {
171
- setDropdownOpen(true);
172
- }
173
- }
174
-
175
- function handleInputBlur() {
176
- inputFocusedRef.current = false;
177
- }
178
-
179
- function getFilteredEntries(): BrowseEntry[] {
180
- var trimmed = path.trim();
181
- if (!trimmed || trimmed.endsWith("/")) return entries;
182
-
183
- var lastSlash = trimmed.lastIndexOf("/");
184
- var filter = lastSlash >= 0 ? trimmed.slice(lastSlash + 1).toLowerCase() : trimmed.toLowerCase();
185
- if (!filter) return entries;
186
-
187
- return entries.filter(function (e) {
188
- return e.name.toLowerCase().startsWith(filter);
189
- });
190
- }
191
-
192
- function isValidPath(): boolean {
193
- var trimmed = path.trim();
194
- if (!trimmed) return false;
195
- var resolved = resolvePath(trimmed.endsWith("/") ? trimmed.slice(0, -1) : trimmed);
196
- var alreadyAdded = projects.some(function (p) { return p.path === resolved; });
197
- if (alreadyAdded) return false;
198
- return true;
199
- }
200
-
201
- function getValidationMessage(): { type: "info" | "error" | "success"; text: string } | null {
202
- var trimmed = path.trim();
203
- if (!trimmed) return { type: "info", text: "Type a path to browse directories" };
204
-
205
- var resolved = resolvePath(trimmed.endsWith("/") ? trimmed.slice(0, -1) : trimmed);
206
- var alreadyAdded = projects.some(function (p) { return p.path === resolved; });
207
- if (alreadyAdded) return { type: "error", text: "Already added as a project" };
208
-
209
- return null;
210
- }
211
-
212
- function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
213
- var filtered = getFilteredEntries();
214
- if (!dropdownOpen || filtered.length === 0) {
215
- if (e.key === "Enter" && canAdd) {
216
- e.preventDefault();
217
- handleAdd();
218
- }
219
- return;
220
- }
221
-
222
- if (e.key === "ArrowDown") {
223
- e.preventDefault();
224
- setHighlightIndex(function (prev) {
225
- var next = prev + 1;
226
- if (next >= filtered.length) next = 0;
227
- scrollHighlightIntoView(next);
228
- return next;
229
- });
230
- } else if (e.key === "ArrowUp") {
231
- e.preventDefault();
232
- setHighlightIndex(function (prev) {
233
- var next = prev - 1;
234
- if (next < 0) next = filtered.length - 1;
235
- scrollHighlightIntoView(next);
236
- return next;
237
- });
238
- } else if (e.key === "Tab" || e.key === "Enter") {
239
- if (highlightIndex >= 0 && highlightIndex < filtered.length) {
240
- e.preventDefault();
241
- handleSelectEntry(filtered[highlightIndex]);
242
- setHighlightIndex(-1);
243
- } else if (e.key === "Enter" && canAdd) {
244
- e.preventDefault();
245
- handleAdd();
246
- }
247
- } else if (e.key === "Escape") {
248
- e.stopPropagation();
249
- setDropdownOpen(false);
250
- setHighlightIndex(-1);
251
- }
252
- }
253
-
254
- function scrollHighlightIntoView(index: number) {
255
- if (!dropdownRef.current) return;
256
- var items = dropdownRef.current.children;
257
- if (items[index]) {
258
- (items[index] as HTMLElement).scrollIntoView({ block: "nearest" });
259
- }
260
- }
261
-
262
- var canAdd = isValidPath() && !adding;
263
-
264
- function handleAdd() {
265
- var trimmed = path.trim();
266
- if (!trimmed || adding) return;
267
-
268
- var resolved = resolvePath(trimmed.endsWith("/") ? trimmed.slice(0, -1) : trimmed);
269
- var finalTitle = title.trim() || resolved.split("/").pop() || "Untitled";
270
-
271
- setAdding(true);
272
- addingRef.current = true;
273
- send({
274
- type: "settings:update",
275
- settings: {
276
- projects: [{ path: resolved, title: finalTitle }],
277
- },
278
- } as any);
279
- }
280
-
281
- if (!isOpen) return null;
282
-
283
- var filtered = getFilteredEntries();
284
- var validation = getValidationMessage();
285
-
286
- return (
287
- <div ref={modalRef} className="fixed inset-0 z-[9999] flex items-center justify-center" role="dialog" aria-modal="true" aria-label="Add Project">
288
- <div className="absolute inset-0 bg-base-content/50" onClick={onClose} />
289
- <div className="relative bg-base-200 border border-base-content/15 rounded-2xl shadow-2xl w-full max-w-3xl mx-4 overflow-hidden">
290
- <div className="flex items-center justify-between px-5 py-4 border-b border-base-content/15">
291
- <h2 className="text-[15px] font-mono font-bold text-base-content">Add Project</h2>
292
- <button
293
- onClick={onClose}
294
- aria-label="Close"
295
- className="btn btn-ghost btn-xs btn-square text-base-content/40 hover:text-base-content"
296
- >
297
- <X size={16} />
298
- </button>
299
- </div>
300
-
301
- <div className="px-5 py-4 space-y-4">
302
- <div>
303
- <label htmlFor="project-path" className="block text-[12px] font-semibold text-base-content/40 mb-1.5">
304
- Project Path
305
- </label>
306
- <div className="relative">
307
- <input
308
- ref={inputRef}
309
- id="project-path"
310
- type="text"
311
- value={path}
312
- onChange={function (e) { setPath(e.target.value); setDropdownOpen(true); setHighlightIndex(-1); setError(null); }}
313
- onFocus={handleInputFocus}
314
- onBlur={handleInputBlur}
315
- onKeyDown={handleKeyDown}
316
- placeholder="~/projects/my-app"
317
- autoFocus
318
- className="w-full h-9 px-3 bg-base-300 border border-base-content/15 rounded-xl text-base-content font-mono text-[12px] focus:border-primary focus-visible:outline-none transition-colors duration-[120ms]"
319
- />
320
-
321
- {dropdownOpen && filtered.length > 0 && (
322
- <div
323
- ref={dropdownRef}
324
- className="absolute top-full left-0 right-0 mt-1 z-50 bg-base-200 border border-base-content/15 rounded-xl shadow-lg max-h-48 overflow-y-auto"
325
- >
326
- {filtered.map(function (entry, idx) {
327
- var isHighlighted = idx === highlightIndex;
328
- return (
329
- <button
330
- key={entry.path}
331
- onMouseDown={function (e) { e.preventDefault(); }}
332
- onClick={function () { handleSelectEntry(entry); setHighlightIndex(-1); }}
333
- onMouseEnter={function () { setHighlightIndex(idx); }}
334
- className={
335
- "w-full flex items-center gap-2 px-3 py-2 text-left text-[12px] font-mono transition-colors duration-[80ms] " +
336
- (isHighlighted
337
- ? "bg-base-content/10 text-base-content"
338
- : "text-base-content/60 hover:bg-base-content/5 hover:text-base-content")
339
- }
340
- >
341
- <FolderOpen size={12} className="text-base-content/25 flex-shrink-0" />
342
- <span className="flex-1 truncate">{entry.name}/</span>
343
- {entry.projectName && (
344
- <span className="text-[10px] px-1.5 py-0.5 rounded-md bg-accent/15 text-accent/70 flex-shrink-0 truncate max-w-[100px]">
345
- {entry.projectName}
346
- </span>
347
- )}
348
- {entry.hasClaudeMd && (
349
- <span className="flex items-center gap-0.5 text-[10px] px-1.5 py-0.5 rounded-md bg-primary/15 text-primary/70 flex-shrink-0">
350
- <FileText size={8} />
351
- CLAUDE.md
352
- </span>
353
- )}
354
- </button>
355
- );
356
- })}
357
- </div>
358
- )}
359
- </div>
360
- <div className="text-[10px] text-base-content/25 mt-1">Type a path or click directories to navigate</div>
361
-
362
- {!path.trim() && suggestions.length > 0 && !dropdownOpen && (
363
- <div className="mt-2">
364
- <div className="text-[11px] font-semibold text-base-content/30 mb-1.5">Projects Claude has worked in</div>
365
- <div className="flex flex-col gap-1 max-h-48 overflow-y-auto">
366
- {suggestions.map(function (s) {
367
- return (
368
- <button
369
- key={s.path}
370
- title={s.path}
371
- onClick={function () {
372
- setPath(s.path + "/");
373
- if (!titleManuallySet) setTitle(s.name);
374
- setSuggestions([]);
375
- send({ type: "browse:list", path: s.path } as any);
376
- }}
377
- className="w-full flex items-center gap-2 px-3 py-1.5 text-left text-[12px] font-mono text-base-content/50 hover:bg-base-content/5 hover:text-base-content rounded-lg transition-colors duration-[80ms]"
378
- >
379
- <FolderOpen size={12} className="text-base-content/25 flex-shrink-0" />
380
- <span className="flex-1 truncate">{s.path}</span>
381
- {s.hasClaudeMd && (
382
- <span className="flex items-center gap-0.5 text-[10px] px-1.5 py-0.5 rounded-md bg-primary/15 text-primary/70 flex-shrink-0">
383
- <FileText size={8} />
384
- CLAUDE.md
385
- </span>
386
- )}
387
- </button>
388
- );
389
- })}
390
- </div>
391
- </div>
392
- )}
393
- </div>
394
-
395
- <div>
396
- <label htmlFor="project-title" className="block text-[12px] font-semibold text-base-content/40 mb-1.5">
397
- Title <span className="font-normal opacity-60">(optional)</span>
398
- </label>
399
- <input
400
- id="project-title"
401
- type="text"
402
- value={title}
403
- onChange={function (e) { handleTitleChange(e.target.value); }}
404
- placeholder="Auto-derived from path"
405
- className="w-full 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]"
406
- />
407
- </div>
408
-
409
- {validation && (
410
- <div className={
411
- "flex items-center gap-2 px-3 py-2 rounded-xl border text-[11px] " +
412
- (validation.type === "error"
413
- ? "bg-error/10 border-error/20 text-error"
414
- : validation.type === "success"
415
- ? "bg-success/10 border-success/20 text-success"
416
- : "bg-base-content/5 border-base-content/10 text-base-content/40")
417
- }>
418
- {validation.text}
419
- </div>
420
- )}
421
- </div>
422
-
423
- <div className="px-5 py-3 border-t border-base-content/15 flex justify-end gap-2">
424
- <button onClick={onClose} className="btn btn-ghost btn-sm text-[12px]">
425
- Cancel
426
- </button>
427
- <button
428
- onClick={handleAdd}
429
- disabled={!canAdd}
430
- className={"btn btn-primary btn-sm text-[12px]" + (!canAdd ? " opacity-50 cursor-not-allowed" : "")}
431
- >
432
- {adding ? <Loader2 size={14} className="animate-spin" /> : "Add Project"}
433
- </button>
434
- </div>
435
- </div>
436
- </div>
437
- );
438
- }
@@ -1,206 +0,0 @@
1
- import { useState, useEffect, useRef, useCallback } from "react";
2
- import { useFocusTrap } from "../../hooks/useFocusTrap";
3
- import { X, Copy, Check } from "lucide-react";
4
- import { useWebSocket } from "../../hooks/useWebSocket";
5
- import { useMesh } from "../../hooks/useMesh";
6
- import { useSaveState } from "../../hooks/useSaveState";
7
- import { SaveFooter } from "../ui/SaveFooter";
8
- import type { ServerMessage, SettingsDataMessage, LatticeConfig } from "#shared";
9
-
10
- interface NodeSettingsModalProps {
11
- isOpen: boolean;
12
- onClose: () => void;
13
- }
14
-
15
- export function NodeSettingsModal({ isOpen, onClose }: NodeSettingsModalProps) {
16
- var { send, subscribe, unsubscribe } = useWebSocket();
17
- var { nodes } = useMesh();
18
- var save = useSaveState();
19
-
20
- var localNode = nodes.find(function (n) { return n.isLocal; });
21
- var nodeId = localNode ? localNode.id : "";
22
-
23
- var [config, setConfig] = useState<LatticeConfig | null>(null);
24
- var [name, setName] = useState("");
25
- var [port, setPort] = useState(7654);
26
- var [tls, setTls] = useState(false);
27
- var [debug, setDebug] = useState(false);
28
- var [copied, setCopied] = useState(false);
29
- var [wsl, setWsl] = useState<boolean | "auto">("auto");
30
- var copyTimeout = useRef<ReturnType<typeof setTimeout> | null>(null);
31
- var modalRef = useRef<HTMLDivElement>(null);
32
- var stableOnClose = useCallback(function () { onClose(); }, [onClose]);
33
- useFocusTrap(modalRef, stableOnClose, isOpen);
34
-
35
- useEffect(function () {
36
- if (!isOpen) return;
37
-
38
- function handleData(msg: ServerMessage) {
39
- if (msg.type !== "settings:data") return;
40
- var data = msg as SettingsDataMessage;
41
- var cfg = data.config;
42
- setConfig(cfg);
43
-
44
- if (save.saving) {
45
- save.confirmSave();
46
- } else {
47
- setName(cfg.name);
48
- setPort(cfg.port);
49
- setTls(cfg.tls);
50
- setDebug(cfg.debug);
51
- setWsl(cfg.wsl ?? "auto");
52
- save.resetFromServer();
53
- }
54
- }
55
-
56
- subscribe("settings:data", handleData);
57
- send({ type: "settings:get" });
58
-
59
- return function () {
60
- unsubscribe("settings:data", handleData);
61
- };
62
- }, [isOpen]);
63
-
64
- useEffect(function () {
65
- return function () {
66
- if (copyTimeout.current) clearTimeout(copyTimeout.current);
67
- };
68
- }, []);
69
-
70
- function handleSave() {
71
- save.startSave();
72
- send({
73
- type: "settings:update",
74
- settings: { name, port, tls, debug, wsl },
75
- } as any);
76
- }
77
-
78
- function handleCopyId() {
79
- if (!nodeId) return;
80
- navigator.clipboard.writeText(nodeId);
81
- setCopied(true);
82
- if (copyTimeout.current) clearTimeout(copyTimeout.current);
83
- copyTimeout.current = setTimeout(function () { setCopied(false); }, 2000);
84
- }
85
-
86
- if (!isOpen) return null;
87
-
88
- var inputClass = "w-full 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]";
89
-
90
- return (
91
- <div ref={modalRef} className="fixed inset-0 z-[9999] flex items-center justify-center" role="dialog" aria-modal="true" aria-label="Node Settings">
92
- <div className="absolute inset-0 bg-base-content/50" onClick={onClose} />
93
- <div className="relative bg-base-200 border border-base-content/15 rounded-2xl shadow-2xl w-full max-w-md mx-4 overflow-hidden">
94
- <div className="flex items-center justify-between px-5 py-4 border-b border-base-content/15">
95
- <h2 className="text-[15px] font-mono font-bold text-base-content">Node Settings</h2>
96
- <button
97
- onClick={onClose}
98
- aria-label="Close"
99
- className="btn btn-ghost btn-xs btn-square text-base-content/40 hover:text-base-content"
100
- >
101
- <X size={16} />
102
- </button>
103
- </div>
104
-
105
- <div className="px-5 py-4 space-y-4 max-h-[70vh] overflow-y-auto">
106
- <div>
107
- <label htmlFor="node-id" className="block text-[12px] font-semibold text-base-content/40 mb-1.5">Node ID</label>
108
- <div className="flex items-center gap-2">
109
- <div className="flex-1 h-9 px-3 bg-base-300/50 border border-base-content/10 rounded-xl font-mono text-[11px] text-base-content/50 flex items-center truncate select-all">
110
- {nodeId || "Loading..."}
111
- </div>
112
- <button
113
- onClick={handleCopyId}
114
- disabled={!nodeId}
115
- aria-label="Copy node ID"
116
- className="btn btn-ghost btn-sm btn-square text-base-content/30 hover:text-base-content flex-shrink-0"
117
- >
118
- {copied ? <Check size={14} className="text-success" /> : <Copy size={14} />}
119
- </button>
120
- </div>
121
- </div>
122
-
123
- <div>
124
- <label htmlFor="node-name" className="block text-[12px] font-semibold text-base-content/40 mb-1.5">Node Name</label>
125
- <input
126
- id="node-name"
127
- type="text"
128
- value={name}
129
- onChange={function (e) { setName(e.target.value); save.markDirty(); }}
130
- placeholder="My Node"
131
- className={inputClass}
132
- />
133
- </div>
134
-
135
- <div>
136
- <label htmlFor="node-port" className="block text-[12px] font-semibold text-base-content/40 mb-1.5">Port</label>
137
- <input
138
- id="node-port"
139
- type="number"
140
- value={port}
141
- onChange={function (e) {
142
- var val = parseInt(e.target.value, 10);
143
- if (!isNaN(val)) { setPort(val); save.markDirty(); }
144
- }}
145
- min={1}
146
- max={65535}
147
- className={inputClass + " font-mono"}
148
- />
149
- </div>
150
-
151
- <div className="flex items-center justify-between py-1">
152
- <div>
153
- <div className="text-[12px] font-semibold text-base-content/40">TLS</div>
154
- <div className="text-[11px] text-base-content/30">Encrypt connections between nodes</div>
155
- </div>
156
- <input
157
- type="checkbox"
158
- checked={tls}
159
- onChange={function (e) { setTls(e.target.checked); save.markDirty(); }}
160
- className="toggle toggle-sm toggle-primary"
161
- aria-label="Enable TLS"
162
- />
163
- </div>
164
-
165
- <div className="flex items-center justify-between py-1">
166
- <div>
167
- <div className="text-[12px] font-semibold text-base-content/40">Debug Mode</div>
168
- <div className="text-[11px] text-base-content/30">Enable verbose logging</div>
169
- </div>
170
- <input
171
- type="checkbox"
172
- checked={debug}
173
- onChange={function (e) { setDebug(e.target.checked); save.markDirty(); }}
174
- className="toggle toggle-sm toggle-primary"
175
- aria-label="Enable debug mode"
176
- />
177
- </div>
178
-
179
- <div>
180
- <div className="text-[12px] font-semibold text-base-content/40 mb-1.5">WSL Mode</div>
181
- <div className="text-[11px] text-base-content/30 mb-2">Convert file paths for Windows editors when running under WSL</div>
182
- <select
183
- value={String(wsl)}
184
- onChange={function (e) {
185
- var val = e.target.value;
186
- if (val === "true") { setWsl(true); }
187
- else if (val === "false") { setWsl(false); }
188
- else { setWsl("auto"); }
189
- save.markDirty();
190
- }}
191
- className={inputClass}
192
- >
193
- <option value="auto">Auto-detect</option>
194
- <option value="true">Enabled</option>
195
- <option value="false">Disabled</option>
196
- </select>
197
- </div>
198
- </div>
199
-
200
- <div className="px-5 py-3 border-t border-base-content/15">
201
- <SaveFooter dirty={save.dirty} saving={save.saving} saveState={save.saveState} onSave={handleSave} />
202
- </div>
203
- </div>
204
- </div>
205
- );
206
- }