@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,170 +0,0 @@
1
- import { X, Columns2, Rows2, MessageSquare, FolderOpen, TerminalSquare, StickyNote, Calendar, Bookmark, BarChart3 } from "lucide-react";
2
- import { useWorkspace } from "../../hooks/useWorkspace";
3
- import { useSession } from "../../hooks/useSession";
4
- import type { Tab, TabType } from "../../stores/workspace";
5
- import { pinTab } from "../../stores/workspace";
6
- import { formatSessionTitle } from "../../utils/formatSessionTitle";
7
- import { ContextMenu, useContextMenu } from "../ui/ContextMenu";
8
-
9
- interface TabBarProps {
10
- paneId?: string;
11
- isActivePane?: boolean;
12
- }
13
-
14
- var TAB_ICONS: Record<TabType, typeof MessageSquare> = {
15
- chat: MessageSquare,
16
- files: FolderOpen,
17
- terminal: TerminalSquare,
18
- notes: StickyNote,
19
- tasks: Calendar,
20
- bookmarks: Bookmark,
21
- analytics: BarChart3,
22
- };
23
-
24
- export function TabBar({ paneId, isActivePane }: TabBarProps) {
25
- var workspace = useWorkspace();
26
- var session = useSession();
27
- var ctxMenu = useContextMenu<string>();
28
-
29
- var paneTabs: Tab[];
30
- var activeTabId: string;
31
-
32
- if (paneId) {
33
- var pane = workspace.panes.find(function (p) { return p.id === paneId; });
34
- if (!pane) return null;
35
- paneTabs = pane.tabIds.map(function (id) {
36
- return workspace.tabs.find(function (t) { return t.id === id; });
37
- }).filter(function (t): t is Tab { return t != null; });
38
- activeTabId = pane.activeTabId;
39
- } else {
40
- paneTabs = workspace.tabs;
41
- activeTabId = workspace.activeTabId;
42
- }
43
-
44
- var shouldShow = paneTabs.length > 1 || workspace.panes.length > 1;
45
-
46
- function getTabLabel(tab: Tab): string {
47
- if (tab.type === "chat" && tab.sessionId) {
48
- if (tab.sessionId === session.activeSessionId && session.activeSessionTitle) {
49
- return formatSessionTitle(session.activeSessionTitle) || tab.label;
50
- }
51
- return formatSessionTitle(tab.label) || "Session";
52
- }
53
- return tab.label;
54
- }
55
-
56
- function handleTabClick(tabId: string) {
57
- if (paneId) {
58
- workspace.setPaneActiveTab(paneId, tabId);
59
- } else {
60
- workspace.setActiveTab(tabId);
61
- }
62
- var tab = workspace.tabs.find(function (t) { return t.id === tabId; });
63
- if (tab && tab.type === "chat" && tab.sessionId && tab.projectSlug) {
64
- if (session.activeSessionId !== tab.sessionId) {
65
- session.activateSession(tab.projectSlug, tab.sessionId);
66
- }
67
- }
68
- }
69
-
70
- function handleCloseTab(tabId: string) {
71
- workspace.closeTab(tabId);
72
- }
73
-
74
- function handleContextMenu(e: React.MouseEvent, tabId: string) {
75
- if (workspace.panes.length >= 2) return;
76
- var contextPane = paneId
77
- ? workspace.panes.find(function (p) { return p.id === paneId; })
78
- : workspace.panes[0];
79
- if (!contextPane || contextPane.tabIds.length < 2) return;
80
- ctxMenu.open(e, tabId);
81
- }
82
-
83
- function handleSplit(direction: "horizontal" | "vertical") {
84
- if (!ctxMenu.state) return;
85
- workspace.splitPane(ctxMenu.state.data, direction);
86
- ctxMenu.close();
87
- }
88
-
89
- function handleMiddleClick(e: React.MouseEvent, tab: Tab) {
90
- if (e.button === 1 && tab.closeable) {
91
- e.preventDefault();
92
- handleCloseTab(tab.id);
93
- }
94
- }
95
-
96
- return (
97
- <>
98
- <div
99
- className={
100
- "flex items-stretch bg-base-200 overflow-x-auto flex-shrink-0 order-1 sm:order-none" +
101
- (shouldShow ? " border-b border-t sm:border-t-0 border-base-content/15" : "") +
102
- (isActivePane && shouldShow ? " sm:border-t-2 sm:border-t-primary/40" : "")
103
- }
104
- style={{
105
- maxHeight: shouldShow ? "3rem" : "0",
106
- opacity: shouldShow ? 1 : 0,
107
- overflow: shouldShow ? undefined : "hidden",
108
- transition: "max-height 0.2s ease, opacity 0.15s ease",
109
- }}
110
- >
111
- {paneTabs.map(function (tab) {
112
- var isActive = tab.id === activeTabId;
113
- var Icon = TAB_ICONS[tab.type] || MessageSquare;
114
- var label = getTabLabel(tab);
115
- return (
116
- <div
117
- key={tab.id}
118
- role="tab"
119
- tabIndex={0}
120
- aria-selected={isActive}
121
- onClick={function () { handleTabClick(tab.id); }}
122
- onDoubleClick={function () { if (!tab.pinned) pinTab(tab.id); }}
123
- onMouseDown={function (e) { handleMiddleClick(e, tab); }}
124
- onKeyDown={function (e) {
125
- if (e.key === "Enter" || e.key === " ") {
126
- e.preventDefault();
127
- handleTabClick(tab.id);
128
- }
129
- }}
130
- onContextMenu={function (e) { handleContextMenu(e, tab.id); }}
131
- className={
132
- "flex items-center gap-2 px-4 py-2.5 text-[13px] font-mono border-r border-base-content/10 transition-colors whitespace-nowrap flex-shrink-0 outline-none cursor-pointer select-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-inset max-w-[200px] " +
133
- (isActive
134
- ? "bg-base-100 text-base-content border-b-2 border-b-primary"
135
- : "text-base-content/40 hover:text-base-content/70 hover:bg-base-300/30")
136
- }
137
- >
138
- <Icon size={14} className={isActive ? "text-primary" : ""} />
139
- <span className={"truncate text-[12px]" + (tab.pinned ? "" : " italic")}>{label}</span>
140
- {tab.closeable && (
141
- <button
142
- aria-label={"Close " + label + " tab"}
143
- onClick={function (e) {
144
- e.stopPropagation();
145
- handleCloseTab(tab.id);
146
- }}
147
- className="ml-0.5 p-1 rounded hover:bg-base-content/15 text-base-content/30 hover:text-base-content/60 outline-none focus-visible:ring-2 focus-visible:ring-primary/50"
148
- >
149
- <X size={12} />
150
- </button>
151
- )}
152
- </div>
153
- );
154
- })}
155
- </div>
156
- {ctxMenu.state !== null && (
157
- <ContextMenu
158
- x={ctxMenu.state.x}
159
- y={ctxMenu.state.y}
160
- items={[
161
- { label: "Split Right", icon: <Columns2 size={14} />, onClick: function () { handleSplit("horizontal"); } },
162
- { label: "Split Down", icon: <Rows2 size={14} />, onClick: function () { handleSplit("vertical"); } },
163
- ]}
164
- onClose={ctxMenu.close}
165
- label="Tab actions"
166
- />
167
- )}
168
- </>
169
- );
170
- }
@@ -1,159 +0,0 @@
1
- import { useState } from "react";
2
- import { ChevronDown, ChevronRight, Pencil, Trash2 } from "lucide-react";
3
- import cronstrue from "cronstrue";
4
- import type { ScheduledTask } from "#shared";
5
-
6
- interface TaskCardProps {
7
- task: ScheduledTask;
8
- onToggle: (taskId: string) => void;
9
- onEdit: (task: ScheduledTask) => void;
10
- onDelete: (taskId: string) => void;
11
- disabled?: boolean;
12
- }
13
-
14
- function formatTime(ms: number | null): string {
15
- if (!ms) return "—";
16
- return new Date(ms).toLocaleString(undefined, {
17
- month: "short",
18
- day: "numeric",
19
- hour: "2-digit",
20
- minute: "2-digit",
21
- });
22
- }
23
-
24
- function humanCron(expr: string): string {
25
- try {
26
- return cronstrue.toString(expr, { use24HourTimeFormat: true });
27
- } catch {
28
- return expr;
29
- }
30
- }
31
-
32
- export function TaskCard(props: TaskCardProps) {
33
- var { task, onToggle, onEdit, onDelete, disabled } = props;
34
- var [expanded, setExpanded] = useState(false);
35
- var [confirming, setConfirming] = useState(false);
36
-
37
- function handleToggleExpand(e: React.MouseEvent) {
38
- e.stopPropagation();
39
- setExpanded(function (prev) { return !prev; });
40
- }
41
-
42
- function handleDelete(e: React.MouseEvent) {
43
- e.stopPropagation();
44
- if (confirming) {
45
- onDelete(task.id);
46
- } else {
47
- setConfirming(true);
48
- }
49
- }
50
-
51
- function handleCancelDelete(e: React.MouseEvent) {
52
- e.stopPropagation();
53
- setConfirming(false);
54
- }
55
-
56
- function handleEdit(e: React.MouseEvent) {
57
- e.stopPropagation();
58
- onEdit(task);
59
- }
60
-
61
- function handleToggle(e: React.MouseEvent) {
62
- e.stopPropagation();
63
- onToggle(task.id);
64
- }
65
-
66
- return (
67
- <div className="bg-base-200 border border-base-content/15 rounded-lg overflow-hidden">
68
- <div
69
- tabIndex={0}
70
- role="button"
71
- className="flex items-center gap-2.5 px-3 py-2.5 cursor-pointer hover:bg-base-300/50 transition-colors outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-1 focus-visible:ring-offset-base-200"
72
- onClick={handleToggleExpand}
73
- onKeyDown={function (e) {
74
- if (e.key === "Enter" || e.key === " ") {
75
- e.preventDefault();
76
- setExpanded(function (prev) { return !prev; });
77
- }
78
- }}
79
- aria-expanded={expanded}
80
- >
81
- <span className="text-base-content/40 flex-shrink-0">
82
- {expanded ? <ChevronDown className="!size-3.5" /> : <ChevronRight className="!size-3.5" />}
83
- </span>
84
- <div className="flex-1 min-w-0">
85
- <div className="flex items-center gap-2">
86
- <span className={`text-[13px] font-medium truncate ${task.enabled ? "text-base-content" : "text-base-content/40"}`}>
87
- {task.name}
88
- </span>
89
- </div>
90
- <div className="text-[11px] text-base-content/40 truncate mt-0.5">
91
- {humanCron(task.cron)}
92
- </div>
93
- </div>
94
- <label className="swap flex-shrink-0" onClick={disabled ? undefined : handleToggle}>
95
- <input
96
- type="checkbox"
97
- className="toggle toggle-primary toggle-xs"
98
- checked={task.enabled}
99
- disabled={disabled}
100
- aria-label={"Toggle " + task.name}
101
- onChange={function () {}}
102
- />
103
- </label>
104
- </div>
105
-
106
- {expanded && (
107
- <div className="px-3 pb-3 border-t border-base-content/15 bg-base-100/50">
108
- <div className="pt-2.5 space-y-2">
109
- <div>
110
- <span className="text-[11px] text-base-content/40 uppercase tracking-wider">Prompt</span>
111
- <p className="text-[12px] text-base-content/80 mt-0.5 whitespace-pre-wrap break-words leading-relaxed">
112
- {task.prompt}
113
- </p>
114
- </div>
115
- <div className="grid grid-cols-2 gap-2">
116
- <div>
117
- <span className="text-[11px] text-base-content/40 uppercase tracking-wider">Last Run</span>
118
- <p className="text-[12px] text-base-content/70 mt-0.5">{formatTime(task.lastRunAt)}</p>
119
- </div>
120
- <div>
121
- <span className="text-[11px] text-base-content/40 uppercase tracking-wider">Next Run</span>
122
- <p className="text-[12px] text-base-content/70 mt-0.5">{formatTime(task.nextRunAt)}</p>
123
- </div>
124
- </div>
125
- {!disabled && (
126
- <div className="flex items-center gap-1.5 pt-1">
127
- <button
128
- onClick={handleEdit}
129
- className="btn btn-ghost btn-xs border border-base-content/15 text-base-content/70 gap-1 outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-1 focus-visible:ring-offset-base-200"
130
- >
131
- <Pencil className="!size-3" />
132
- Edit
133
- </button>
134
- {confirming ? (
135
- <div className="flex gap-1.5">
136
- <button onClick={handleDelete} className="btn btn-error btn-xs outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-1 focus-visible:ring-offset-base-200">
137
- Confirm Delete
138
- </button>
139
- <button onClick={handleCancelDelete} className="btn btn-ghost btn-xs border border-base-content/15 outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-1 focus-visible:ring-offset-base-200">
140
- Cancel
141
- </button>
142
- </div>
143
- ) : (
144
- <button
145
- onClick={handleDelete}
146
- className="btn btn-ghost btn-xs border border-base-content/15 text-base-content/50 outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-1 focus-visible:ring-offset-base-200"
147
- aria-label="Delete task"
148
- >
149
- <Trash2 className="!size-3" />
150
- </button>
151
- )}
152
- </div>
153
- )}
154
- </div>
155
- </div>
156
- )}
157
- </div>
158
- );
159
- }
@@ -1,129 +0,0 @@
1
- import { useState, useRef, useCallback } from "react";
2
- import { X } from "lucide-react";
3
- import { useFocusTrap } from "../../hooks/useFocusTrap";
4
- import cronstrue from "cronstrue";
5
- import type { ScheduledTask } from "#shared";
6
-
7
- interface TaskEditModalProps {
8
- task: ScheduledTask | null;
9
- projectSlug: string;
10
- onSave: (data: { name: string; prompt: string; cron: string }) => void;
11
- onClose: () => void;
12
- }
13
-
14
- function getCronPreview(expr: string): string {
15
- if (!expr.trim()) return "";
16
- try {
17
- return cronstrue.toString(expr.trim(), { use24HourTimeFormat: true });
18
- } catch {
19
- return "Invalid cron expression";
20
- }
21
- }
22
-
23
- export function TaskEditModal(props: TaskEditModalProps) {
24
- var { task, onSave, onClose } = props;
25
- var [name, setName] = useState(task ? task.name : "");
26
- var [prompt, setPrompt] = useState(task ? task.prompt : "");
27
- var [cron, setCron] = useState(task ? task.cron : "0 9 * * 1-5");
28
-
29
- var modalRef = useRef<HTMLDivElement>(null);
30
- var stableOnClose = useCallback(function () { onClose(); }, [onClose]);
31
- useFocusTrap(modalRef, stableOnClose);
32
-
33
- var cronPreview = getCronPreview(cron);
34
- var cronValid = cronPreview !== "Invalid cron expression" && cronPreview !== "";
35
-
36
- function handleSubmit(e: React.FormEvent) {
37
- e.preventDefault();
38
- if (!name.trim() || !prompt.trim() || !cronValid) return;
39
- onSave({ name: name.trim(), prompt: prompt.trim(), cron: cron.trim() });
40
- }
41
-
42
- function handleBackdrop(e: React.MouseEvent<HTMLDivElement>) {
43
- if (e.target === e.currentTarget) onClose();
44
- }
45
-
46
- return (
47
- <div
48
- ref={modalRef}
49
- className="fixed inset-0 z-[9999] flex items-center justify-center bg-base-content/50 backdrop-blur-sm"
50
- onClick={handleBackdrop}
51
- role="dialog"
52
- aria-modal="true"
53
- aria-label={task ? "Edit Task" : "New Scheduled Task"}
54
- >
55
- <div className="bg-base-200 border border-base-content/15 rounded-2xl shadow-2xl w-full max-w-md mx-4">
56
- <div className="flex items-center justify-between px-5 py-4 border-b border-base-content/15">
57
- <h2 className="text-[14px] font-semibold text-base-content">
58
- {task ? "Edit Task" : "New Scheduled Task"}
59
- </h2>
60
- <button
61
- onClick={onClose}
62
- aria-label="Close"
63
- className="btn btn-ghost btn-xs btn-square text-base-content/50"
64
- >
65
- <X size={14} />
66
- </button>
67
- </div>
68
-
69
- <form onSubmit={handleSubmit} className="p-5 space-y-4">
70
- <div className="space-y-1.5">
71
- <label htmlFor="task-name" className="text-[12px] font-semibold text-base-content/40 uppercase tracking-wider">Name</label>
72
- <input
73
- id="task-name"
74
- type="text"
75
- 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]"
76
- placeholder="Daily standup summary"
77
- value={name}
78
- onChange={function (e) { setName(e.target.value); }}
79
- autoFocus
80
- />
81
- </div>
82
-
83
- <div className="space-y-1.5">
84
- <label htmlFor="task-prompt" className="text-[12px] font-semibold text-base-content/40 uppercase tracking-wider">Prompt</label>
85
- <textarea
86
- id="task-prompt"
87
- className="w-full px-3 py-2.5 bg-base-300 border border-base-content/15 rounded-xl text-base-content text-[13px] min-h-[96px] resize-y leading-relaxed focus:border-primary focus-visible:outline-none transition-colors duration-[120ms]"
88
- placeholder="Summarize yesterday's work and create a plan for today..."
89
- value={prompt}
90
- onChange={function (e) { setPrompt(e.target.value); }}
91
- />
92
- </div>
93
-
94
- <div className="space-y-1.5">
95
- <label htmlFor="task-cron" className="text-[12px] font-semibold text-base-content/40 uppercase tracking-wider">Cron Expression</label>
96
- <input
97
- id="task-cron"
98
- type="text"
99
- className={`w-full h-9 px-3 bg-base-300 border rounded-xl text-base-content text-[13px] font-mono focus:border-primary focus-visible:outline-none transition-colors duration-[120ms] ${cron.trim() && !cronValid ? "border-error" : "border-base-content/15"}`}
100
- placeholder="0 9 * * 1-5"
101
- value={cron}
102
- onChange={function (e) { setCron(e.target.value); }}
103
- aria-invalid={cron.trim() && !cronValid ? "true" : undefined}
104
- aria-describedby={cron.trim() ? "cron-preview" : undefined}
105
- />
106
- {cron.trim() && (
107
- <p id="cron-preview" className={`text-[11px] mt-1 ${cronValid ? "text-primary/80" : "text-error"}`}>
108
- {cronPreview}
109
- </p>
110
- )}
111
- </div>
112
-
113
- <div className="flex gap-2 pt-1">
114
- <button
115
- type="submit"
116
- className="btn btn-primary btn-sm flex-1"
117
- disabled={!name.trim() || !prompt.trim() || !cronValid}
118
- >
119
- {task ? "Save Changes" : "Create Task"}
120
- </button>
121
- <button type="button" onClick={onClose} className="btn btn-ghost btn-sm border border-base-content/15">
122
- Cancel
123
- </button>
124
- </div>
125
- </form>
126
- </div>
127
- </div>
128
- );
129
- }
@@ -1,171 +0,0 @@
1
- import { useEffect, useRef } from "react";
2
- import { Terminal as XTerm } from "@xterm/xterm";
3
- import { FitAddon } from "@xterm/addon-fit";
4
- import { WebLinksAddon } from "@xterm/addon-web-links";
5
- import { SearchAddon } from "@xterm/addon-search";
6
- import "@xterm/xterm/css/xterm.css";
7
- import { useWebSocket } from "../../hooks/useWebSocket";
8
- import { useSidebar } from "../../hooks/useSidebar";
9
- import type { ServerMessage, TerminalCreatedMessage, TerminalOutputMessage, TerminalExitedMessage } from "#shared";
10
-
11
- function getXtermTheme(): Record<string, string> {
12
- var root = document.documentElement;
13
- var cs = getComputedStyle(root);
14
-
15
- function resolveVar(prop: string, fallback: string): string {
16
- var val = cs.getPropertyValue(prop).trim();
17
- return val || fallback;
18
- }
19
-
20
- return {
21
- background: resolveVar("--base00", "#0d0d0d"),
22
- foreground: resolveVar("--base05", "#d4d4d4"),
23
- cursor: resolveVar("--base05", "#d4d4d4"),
24
- selectionBackground: resolveVar("--base02", "#264f78"),
25
- black: resolveVar("--base00", "#1e1e1e"),
26
- red: resolveVar("--base08", "#f44747"),
27
- green: resolveVar("--base0B", "#4ec9b0"),
28
- yellow: resolveVar("--base0A", "#dcdcaa"),
29
- blue: resolveVar("--base0D", "#569cd6"),
30
- magenta: resolveVar("--base0E", "#c586c0"),
31
- cyan: resolveVar("--base0C", "#9cdcfe"),
32
- white: resolveVar("--base05", "#d4d4d4"),
33
- brightBlack: resolveVar("--base03", "#808080"),
34
- brightRed: resolveVar("--base08", "#f44747"),
35
- brightGreen: resolveVar("--base0B", "#4ec9b0"),
36
- brightYellow: resolveVar("--base0A", "#dcdcaa"),
37
- brightBlue: resolveVar("--base0D", "#569cd6"),
38
- brightMagenta: resolveVar("--base0E", "#c586c0"),
39
- brightCyan: resolveVar("--base0C", "#9cdcfe"),
40
- brightWhite: resolveVar("--base07", "#ffffff"),
41
- };
42
- }
43
-
44
- interface TerminalInstanceProps {
45
- instanceId: string;
46
- visible: boolean;
47
- }
48
-
49
- export function TerminalInstance({ instanceId, visible }: TerminalInstanceProps) {
50
- var containerRef = useRef<HTMLDivElement | null>(null);
51
- var xtermRef = useRef<XTerm | null>(null);
52
- var fitAddonRef = useRef<FitAddon | null>(null);
53
- var searchAddonRef = useRef<SearchAddon | null>(null);
54
- var termIdRef = useRef<string | null>(null);
55
- var { activeProjectSlug } = useSidebar();
56
- var { send, subscribe, unsubscribe } = useWebSocket();
57
-
58
- useEffect(function() {
59
- if (!containerRef.current) {
60
- return;
61
- }
62
-
63
- var term = new XTerm({
64
- cursorBlink: true,
65
- fontFamily: getComputedStyle(document.documentElement).getPropertyValue("--font-mono").trim() || "JetBrains Mono, monospace",
66
- fontSize: 13,
67
- theme: getXtermTheme(),
68
- });
69
-
70
- var fitAddon = new FitAddon();
71
- var webLinksAddon = new WebLinksAddon();
72
- var searchAddon = new SearchAddon();
73
-
74
- term.loadAddon(fitAddon);
75
- term.loadAddon(webLinksAddon);
76
- term.loadAddon(searchAddon);
77
- term.open(containerRef.current);
78
- fitAddon.fit();
79
-
80
- xtermRef.current = term;
81
- fitAddonRef.current = fitAddon;
82
- searchAddonRef.current = searchAddon;
83
-
84
- var waitingForCreate = true;
85
-
86
- function onCreated(msg: ServerMessage) {
87
- if (!waitingForCreate) return;
88
- waitingForCreate = false;
89
- var created = msg as TerminalCreatedMessage;
90
- termIdRef.current = created.termId;
91
- }
92
-
93
- function onOutput(msg: ServerMessage) {
94
- var output = msg as TerminalOutputMessage;
95
- if (xtermRef.current && output.termId === termIdRef.current) {
96
- xtermRef.current.write(output.data);
97
- }
98
- }
99
-
100
- function onExited(msg: ServerMessage) {
101
- var exited = msg as TerminalExitedMessage;
102
- if (xtermRef.current && exited.termId === termIdRef.current) {
103
- xtermRef.current.write("\r\n\x1b[31m[process exited]\x1b[0m\r\n");
104
- }
105
- }
106
-
107
- subscribe("terminal:created", onCreated);
108
- subscribe("terminal:output", onOutput);
109
- subscribe("terminal:exited", onExited);
110
-
111
- send({ type: "terminal:create", projectSlug: activeProjectSlug || undefined });
112
-
113
- term.onData(function(data: string) {
114
- var termId = termIdRef.current;
115
- if (termId) {
116
- send({ type: "terminal:input", termId: termId, data: data });
117
- }
118
- });
119
-
120
- var resizeObserver = new ResizeObserver(function() {
121
- if (fitAddonRef.current) {
122
- fitAddonRef.current.fit();
123
- var termId = termIdRef.current;
124
- var dim = fitAddonRef.current.proposeDimensions();
125
- if (termId && dim) {
126
- send({ type: "terminal:resize", termId: termId, cols: dim.cols, rows: dim.rows });
127
- }
128
- }
129
- });
130
-
131
- if (containerRef.current) {
132
- resizeObserver.observe(containerRef.current);
133
- }
134
-
135
- return function() {
136
- unsubscribe("terminal:created", onCreated);
137
- unsubscribe("terminal:output", onOutput);
138
- unsubscribe("terminal:exited", onExited);
139
- resizeObserver.disconnect();
140
- term.dispose();
141
- xtermRef.current = null;
142
- fitAddonRef.current = null;
143
- searchAddonRef.current = null;
144
- };
145
- }, []);
146
-
147
- useEffect(function() {
148
- if (visible && fitAddonRef.current) {
149
- var timer = setTimeout(function() {
150
- if (fitAddonRef.current) {
151
- fitAddonRef.current.fit();
152
- var termId = termIdRef.current;
153
- var dim = fitAddonRef.current.proposeDimensions();
154
- if (termId && dim) {
155
- send({ type: "terminal:resize", termId: termId, cols: dim.cols, rows: dim.rows });
156
- }
157
- }
158
- }, 50);
159
- return function() { clearTimeout(timer); };
160
- }
161
- }, [visible]);
162
-
163
- return (
164
- <div
165
- ref={containerRef}
166
- className="w-full h-full overflow-hidden bg-base-100"
167
- style={{ display: visible ? "block" : "none" }}
168
- data-instance-id={instanceId}
169
- />
170
- );
171
- }