@myrialabs/clopen 0.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 (456) hide show
  1. package/.env.example +6 -0
  2. package/.github/workflows/release.yml +60 -0
  3. package/.github/workflows/test.yml +40 -0
  4. package/CONTRIBUTING.md +499 -0
  5. package/LICENSE +21 -0
  6. package/README.md +209 -0
  7. package/backend/index.ts +156 -0
  8. package/backend/lib/chat/helpers.ts +42 -0
  9. package/backend/lib/chat/index.ts +2 -0
  10. package/backend/lib/chat/stream-manager.ts +1126 -0
  11. package/backend/lib/database/README.md +77 -0
  12. package/backend/lib/database/index.ts +119 -0
  13. package/backend/lib/database/migrations/001_create_projects_table.ts +31 -0
  14. package/backend/lib/database/migrations/002_create_chat_sessions_table.ts +33 -0
  15. package/backend/lib/database/migrations/003_create_messages_table.ts +32 -0
  16. package/backend/lib/database/migrations/004_create_prompt_templates_table.ts +34 -0
  17. package/backend/lib/database/migrations/005_create_settings_table.ts +24 -0
  18. package/backend/lib/database/migrations/006_add_user_to_messages.ts +58 -0
  19. package/backend/lib/database/migrations/007_create_stream_states_table.ts +41 -0
  20. package/backend/lib/database/migrations/008_create_message_snapshots_table.ts +62 -0
  21. package/backend/lib/database/migrations/009_add_delta_snapshot_fields.ts +41 -0
  22. package/backend/lib/database/migrations/010_add_soft_delete_and_branch_support.ts +70 -0
  23. package/backend/lib/database/migrations/011_git_like_commit_graph.ts +156 -0
  24. package/backend/lib/database/migrations/012_add_file_change_statistics.ts +41 -0
  25. package/backend/lib/database/migrations/013_checkpoint_tree_state.ts +118 -0
  26. package/backend/lib/database/migrations/014_add_engine_to_sessions.ts +18 -0
  27. package/backend/lib/database/migrations/015_add_model_to_sessions.ts +18 -0
  28. package/backend/lib/database/migrations/016_create_user_projects_table.ts +34 -0
  29. package/backend/lib/database/migrations/017_add_current_session_to_user_projects.ts +32 -0
  30. package/backend/lib/database/migrations/018_create_claude_accounts_table.ts +24 -0
  31. package/backend/lib/database/migrations/019_add_claude_account_to_sessions.ts +18 -0
  32. package/backend/lib/database/migrations/020_add_snapshot_tree_hash.ts +32 -0
  33. package/backend/lib/database/migrations/021_drop_prompt_templates_table.ts +33 -0
  34. package/backend/lib/database/migrations/index.ts +154 -0
  35. package/backend/lib/database/queries/checkpoint-queries.ts +87 -0
  36. package/backend/lib/database/queries/engine-queries.ts +75 -0
  37. package/backend/lib/database/queries/index.ts +9 -0
  38. package/backend/lib/database/queries/message-queries.ts +472 -0
  39. package/backend/lib/database/queries/project-queries.ts +117 -0
  40. package/backend/lib/database/queries/session-queries.ts +271 -0
  41. package/backend/lib/database/queries/settings-queries.ts +34 -0
  42. package/backend/lib/database/queries/snapshot-queries.ts +326 -0
  43. package/backend/lib/database/queries/utils-queries.ts +59 -0
  44. package/backend/lib/database/seeders/index.ts +13 -0
  45. package/backend/lib/database/seeders/settings_seeder.ts +84 -0
  46. package/backend/lib/database/utils/connection.ts +174 -0
  47. package/backend/lib/database/utils/index.ts +4 -0
  48. package/backend/lib/database/utils/migration-runner.ts +118 -0
  49. package/backend/lib/database/utils/seeder-runner.ts +121 -0
  50. package/backend/lib/engine/adapters/claude/environment.ts +164 -0
  51. package/backend/lib/engine/adapters/claude/error-handler.ts +60 -0
  52. package/backend/lib/engine/adapters/claude/index.ts +1 -0
  53. package/backend/lib/engine/adapters/claude/path-utils.ts +38 -0
  54. package/backend/lib/engine/adapters/claude/stream.ts +177 -0
  55. package/backend/lib/engine/adapters/opencode/index.ts +2 -0
  56. package/backend/lib/engine/adapters/opencode/message-converter.ts +862 -0
  57. package/backend/lib/engine/adapters/opencode/server.ts +104 -0
  58. package/backend/lib/engine/adapters/opencode/stream.ts +755 -0
  59. package/backend/lib/engine/index.ts +196 -0
  60. package/backend/lib/engine/types.ts +58 -0
  61. package/backend/lib/files/file-operations.ts +478 -0
  62. package/backend/lib/files/file-reading.ts +308 -0
  63. package/backend/lib/files/file-watcher.ts +383 -0
  64. package/backend/lib/files/path-browsing.ts +382 -0
  65. package/backend/lib/git/git-executor.ts +88 -0
  66. package/backend/lib/git/git-parser.ts +411 -0
  67. package/backend/lib/git/git-service.ts +505 -0
  68. package/backend/lib/mcp/README.md +1144 -0
  69. package/backend/lib/mcp/config.ts +316 -0
  70. package/backend/lib/mcp/index.ts +35 -0
  71. package/backend/lib/mcp/project-context.ts +236 -0
  72. package/backend/lib/mcp/servers/browser-automation/actions.ts +156 -0
  73. package/backend/lib/mcp/servers/browser-automation/browser.ts +419 -0
  74. package/backend/lib/mcp/servers/browser-automation/index.ts +791 -0
  75. package/backend/lib/mcp/servers/browser-automation/inspection.ts +501 -0
  76. package/backend/lib/mcp/servers/helper.ts +143 -0
  77. package/backend/lib/mcp/servers/index.ts +45 -0
  78. package/backend/lib/mcp/servers/weather/get-temperature.ts +56 -0
  79. package/backend/lib/mcp/servers/weather/index.ts +31 -0
  80. package/backend/lib/mcp/stdio-server.ts +103 -0
  81. package/backend/lib/mcp/types.ts +65 -0
  82. package/backend/lib/preview/browser/browser-audio-capture.ts +86 -0
  83. package/backend/lib/preview/browser/browser-console-manager.ts +263 -0
  84. package/backend/lib/preview/browser/browser-dialog-handler.ts +222 -0
  85. package/backend/lib/preview/browser/browser-interaction-handler.ts +421 -0
  86. package/backend/lib/preview/browser/browser-mcp-control.ts +415 -0
  87. package/backend/lib/preview/browser/browser-native-ui-handler.ts +512 -0
  88. package/backend/lib/preview/browser/browser-navigation-tracker.ts +104 -0
  89. package/backend/lib/preview/browser/browser-pool.ts +357 -0
  90. package/backend/lib/preview/browser/browser-preview-service.ts +882 -0
  91. package/backend/lib/preview/browser/browser-tab-manager.ts +935 -0
  92. package/backend/lib/preview/browser/browser-video-capture.ts +695 -0
  93. package/backend/lib/preview/browser/scripts/audio-stream.ts +292 -0
  94. package/backend/lib/preview/browser/scripts/cursor-tracking.ts +85 -0
  95. package/backend/lib/preview/browser/scripts/video-stream.ts +438 -0
  96. package/backend/lib/preview/browser/types.ts +359 -0
  97. package/backend/lib/preview/index.ts +24 -0
  98. package/backend/lib/project/index.ts +2 -0
  99. package/backend/lib/project/status-manager.ts +182 -0
  100. package/backend/lib/shared/index.ts +2 -0
  101. package/backend/lib/shared/port-utils.ts +25 -0
  102. package/backend/lib/shared/process-manager.ts +281 -0
  103. package/backend/lib/snapshot/blob-store.ts +227 -0
  104. package/backend/lib/snapshot/gitignore.ts +307 -0
  105. package/backend/lib/snapshot/helpers.ts +397 -0
  106. package/backend/lib/snapshot/snapshot-service.ts +483 -0
  107. package/backend/lib/terminal/helpers.ts +14 -0
  108. package/backend/lib/terminal/index.ts +8 -0
  109. package/backend/lib/terminal/pty-manager.ts +4 -0
  110. package/backend/lib/terminal/pty-session-manager.ts +387 -0
  111. package/backend/lib/terminal/shell-utils.ts +313 -0
  112. package/backend/lib/terminal/stream-manager.ts +293 -0
  113. package/backend/lib/tunnel/global-tunnel-manager.ts +243 -0
  114. package/backend/lib/tunnel/project-tunnel-manager.ts +311 -0
  115. package/backend/lib/user/helpers.ts +87 -0
  116. package/backend/lib/utils/ws.ts +944 -0
  117. package/backend/lib/vite-dev.ts +353 -0
  118. package/backend/middleware/cors.ts +15 -0
  119. package/backend/middleware/error-handler.ts +49 -0
  120. package/backend/middleware/logger.ts +9 -0
  121. package/backend/types/api.ts +24 -0
  122. package/backend/ws/README.md +1505 -0
  123. package/backend/ws/chat/background.ts +198 -0
  124. package/backend/ws/chat/index.ts +21 -0
  125. package/backend/ws/chat/stream.ts +707 -0
  126. package/backend/ws/engine/claude/accounts.ts +401 -0
  127. package/backend/ws/engine/claude/index.ts +13 -0
  128. package/backend/ws/engine/claude/status.ts +43 -0
  129. package/backend/ws/engine/index.ts +14 -0
  130. package/backend/ws/engine/opencode/index.ts +11 -0
  131. package/backend/ws/engine/opencode/status.ts +30 -0
  132. package/backend/ws/engine/utils.ts +36 -0
  133. package/backend/ws/files/index.ts +30 -0
  134. package/backend/ws/files/read.ts +189 -0
  135. package/backend/ws/files/search.ts +453 -0
  136. package/backend/ws/files/watch.ts +124 -0
  137. package/backend/ws/files/write.ts +143 -0
  138. package/backend/ws/git/branch.ts +106 -0
  139. package/backend/ws/git/commit.ts +39 -0
  140. package/backend/ws/git/conflict.ts +68 -0
  141. package/backend/ws/git/diff.ts +69 -0
  142. package/backend/ws/git/index.ts +24 -0
  143. package/backend/ws/git/log.ts +41 -0
  144. package/backend/ws/git/remote.ts +214 -0
  145. package/backend/ws/git/staging.ts +84 -0
  146. package/backend/ws/git/status.ts +90 -0
  147. package/backend/ws/index.ts +69 -0
  148. package/backend/ws/mcp/index.ts +61 -0
  149. package/backend/ws/messages/crud.ts +74 -0
  150. package/backend/ws/messages/index.ts +14 -0
  151. package/backend/ws/preview/browser/cleanup.ts +129 -0
  152. package/backend/ws/preview/browser/console.ts +114 -0
  153. package/backend/ws/preview/browser/interact.ts +513 -0
  154. package/backend/ws/preview/browser/mcp.ts +129 -0
  155. package/backend/ws/preview/browser/native-ui.ts +235 -0
  156. package/backend/ws/preview/browser/stats.ts +55 -0
  157. package/backend/ws/preview/browser/tab-info.ts +126 -0
  158. package/backend/ws/preview/browser/tab.ts +166 -0
  159. package/backend/ws/preview/browser/webcodecs.ts +293 -0
  160. package/backend/ws/preview/index.ts +146 -0
  161. package/backend/ws/projects/crud.ts +113 -0
  162. package/backend/ws/projects/index.ts +25 -0
  163. package/backend/ws/projects/presence.ts +46 -0
  164. package/backend/ws/projects/status.ts +116 -0
  165. package/backend/ws/sessions/crud.ts +327 -0
  166. package/backend/ws/sessions/index.ts +33 -0
  167. package/backend/ws/settings/crud.ts +112 -0
  168. package/backend/ws/settings/index.ts +14 -0
  169. package/backend/ws/snapshot/index.ts +17 -0
  170. package/backend/ws/snapshot/restore.ts +173 -0
  171. package/backend/ws/snapshot/timeline.ts +141 -0
  172. package/backend/ws/system/index.ts +14 -0
  173. package/backend/ws/system/operations.ts +49 -0
  174. package/backend/ws/terminal/index.ts +40 -0
  175. package/backend/ws/terminal/persistence.ts +153 -0
  176. package/backend/ws/terminal/session.ts +382 -0
  177. package/backend/ws/terminal/stream.ts +79 -0
  178. package/backend/ws/tunnel/index.ts +14 -0
  179. package/backend/ws/tunnel/operations.ts +91 -0
  180. package/backend/ws/types.ts +20 -0
  181. package/backend/ws/user/crud.ts +156 -0
  182. package/backend/ws/user/index.ts +14 -0
  183. package/bin/clopen.ts +307 -0
  184. package/bun.lock +1352 -0
  185. package/frontend/App.svelte +34 -0
  186. package/frontend/app.css +313 -0
  187. package/frontend/lib/app-environment.ts +10 -0
  188. package/frontend/lib/components/chat/ChatInterface.svelte +407 -0
  189. package/frontend/lib/components/chat/formatters/ErrorMessage.svelte +57 -0
  190. package/frontend/lib/components/chat/formatters/MessageFormatter.svelte +224 -0
  191. package/frontend/lib/components/chat/formatters/TextMessage.svelte +395 -0
  192. package/frontend/lib/components/chat/formatters/Tools.svelte +70 -0
  193. package/frontend/lib/components/chat/formatters/index.ts +3 -0
  194. package/frontend/lib/components/chat/input/ChatInput.svelte +421 -0
  195. package/frontend/lib/components/chat/input/components/ChatInputActions.svelte +78 -0
  196. package/frontend/lib/components/chat/input/components/DragDropOverlay.svelte +30 -0
  197. package/frontend/lib/components/chat/input/components/EditModeIndicator.svelte +33 -0
  198. package/frontend/lib/components/chat/input/components/EngineModelPicker.svelte +619 -0
  199. package/frontend/lib/components/chat/input/components/FileAttachmentPreview.svelte +48 -0
  200. package/frontend/lib/components/chat/input/components/LoadingIndicator.svelte +31 -0
  201. package/frontend/lib/components/chat/input/composables/use-animations.svelte.ts +201 -0
  202. package/frontend/lib/components/chat/input/composables/use-chat-actions.svelte.ts +148 -0
  203. package/frontend/lib/components/chat/input/composables/use-file-handling.svelte.ts +216 -0
  204. package/frontend/lib/components/chat/input/composables/use-input-state.svelte.ts +357 -0
  205. package/frontend/lib/components/chat/input/composables/use-textarea-resize.svelte.ts +57 -0
  206. package/frontend/lib/components/chat/message/ChatMessage.svelte +478 -0
  207. package/frontend/lib/components/chat/message/ChatMessages.svelte +541 -0
  208. package/frontend/lib/components/chat/message/DateSeparator.svelte +86 -0
  209. package/frontend/lib/components/chat/message/MessageBubble.svelte +86 -0
  210. package/frontend/lib/components/chat/message/MessageHeader.svelte +157 -0
  211. package/frontend/lib/components/chat/modal/DebugModal.svelte +59 -0
  212. package/frontend/lib/components/chat/modal/TokenUsageModal.svelte +124 -0
  213. package/frontend/lib/components/chat/shared/index.ts +2 -0
  214. package/frontend/lib/components/chat/shared/utils.ts +116 -0
  215. package/frontend/lib/components/chat/tools/BashOutputTool.svelte +35 -0
  216. package/frontend/lib/components/chat/tools/BashTool.svelte +46 -0
  217. package/frontend/lib/components/chat/tools/CustomMcpTool.svelte +139 -0
  218. package/frontend/lib/components/chat/tools/EditTool.svelte +48 -0
  219. package/frontend/lib/components/chat/tools/ExitPlanModeTool.svelte +32 -0
  220. package/frontend/lib/components/chat/tools/GlobTool.svelte +51 -0
  221. package/frontend/lib/components/chat/tools/GrepTool.svelte +90 -0
  222. package/frontend/lib/components/chat/tools/KillShellTool.svelte +26 -0
  223. package/frontend/lib/components/chat/tools/ListMcpResourcesTool.svelte +31 -0
  224. package/frontend/lib/components/chat/tools/NotebookEditTool.svelte +38 -0
  225. package/frontend/lib/components/chat/tools/ReadMcpResourceTool.svelte +34 -0
  226. package/frontend/lib/components/chat/tools/ReadTool.svelte +41 -0
  227. package/frontend/lib/components/chat/tools/TaskTool.svelte +64 -0
  228. package/frontend/lib/components/chat/tools/TodoWriteTool.svelte +75 -0
  229. package/frontend/lib/components/chat/tools/WebFetchTool.svelte +35 -0
  230. package/frontend/lib/components/chat/tools/WebSearchTool.svelte +84 -0
  231. package/frontend/lib/components/chat/tools/WriteTool.svelte +33 -0
  232. package/frontend/lib/components/chat/tools/components/CodeBlock.svelte +79 -0
  233. package/frontend/lib/components/chat/tools/components/DiffBlock.svelte +408 -0
  234. package/frontend/lib/components/chat/tools/components/FileHeader.svelte +45 -0
  235. package/frontend/lib/components/chat/tools/components/InfoLine.svelte +19 -0
  236. package/frontend/lib/components/chat/tools/components/StatsBadges.svelte +27 -0
  237. package/frontend/lib/components/chat/tools/components/TerminalCommand.svelte +54 -0
  238. package/frontend/lib/components/chat/tools/components/index.ts +7 -0
  239. package/frontend/lib/components/chat/tools/index.ts +26 -0
  240. package/frontend/lib/components/chat/widgets/FloatingTodoList.svelte +249 -0
  241. package/frontend/lib/components/chat/widgets/TokenUsage.svelte +78 -0
  242. package/frontend/lib/components/checkpoint/TimelineModal.svelte +391 -0
  243. package/frontend/lib/components/checkpoint/timeline/TimelineEdge.svelte +26 -0
  244. package/frontend/lib/components/checkpoint/timeline/TimelineGraph.svelte +87 -0
  245. package/frontend/lib/components/checkpoint/timeline/TimelineNode.svelte +108 -0
  246. package/frontend/lib/components/checkpoint/timeline/TimelineVersionGroup.svelte +59 -0
  247. package/frontend/lib/components/checkpoint/timeline/animation.ts +168 -0
  248. package/frontend/lib/components/checkpoint/timeline/config.ts +44 -0
  249. package/frontend/lib/components/checkpoint/timeline/graph-builder.ts +304 -0
  250. package/frontend/lib/components/checkpoint/timeline/types.ts +65 -0
  251. package/frontend/lib/components/checkpoint/timeline/utils.ts +53 -0
  252. package/frontend/lib/components/common/Alert.svelte +139 -0
  253. package/frontend/lib/components/common/AvatarBubble.svelte +56 -0
  254. package/frontend/lib/components/common/Button.svelte +71 -0
  255. package/frontend/lib/components/common/Card.svelte +102 -0
  256. package/frontend/lib/components/common/Checkbox.svelte +48 -0
  257. package/frontend/lib/components/common/Dialog.svelte +249 -0
  258. package/frontend/lib/components/common/FolderBrowser.svelte +843 -0
  259. package/frontend/lib/components/common/Icon.svelte +58 -0
  260. package/frontend/lib/components/common/Input.svelte +72 -0
  261. package/frontend/lib/components/common/Lightbox.svelte +233 -0
  262. package/frontend/lib/components/common/LoadingScreen.svelte +52 -0
  263. package/frontend/lib/components/common/LoadingSpinner.svelte +48 -0
  264. package/frontend/lib/components/common/Modal.svelte +177 -0
  265. package/frontend/lib/components/common/ModalProvider.svelte +28 -0
  266. package/frontend/lib/components/common/ModelSelector.svelte +110 -0
  267. package/frontend/lib/components/common/MonacoEditor.svelte +569 -0
  268. package/frontend/lib/components/common/NotificationToast.svelte +113 -0
  269. package/frontend/lib/components/common/PageTemplate.svelte +76 -0
  270. package/frontend/lib/components/common/ProjectUserAvatars.svelte +79 -0
  271. package/frontend/lib/components/common/Select.svelte +98 -0
  272. package/frontend/lib/components/common/Textarea.svelte +80 -0
  273. package/frontend/lib/components/common/ThemeToggle.svelte +44 -0
  274. package/frontend/lib/components/common/lucide-icons.ts +1642 -0
  275. package/frontend/lib/components/common/material-icons.ts +1082 -0
  276. package/frontend/lib/components/common/xterm/XTerm.svelte +796 -0
  277. package/frontend/lib/components/common/xterm/index.ts +16 -0
  278. package/frontend/lib/components/common/xterm/terminal-config.ts +68 -0
  279. package/frontend/lib/components/common/xterm/types.ts +31 -0
  280. package/frontend/lib/components/common/xterm/xterm-service.ts +353 -0
  281. package/frontend/lib/components/files/FileNode.svelte +384 -0
  282. package/frontend/lib/components/files/FileTree.svelte +681 -0
  283. package/frontend/lib/components/files/FileViewer.svelte +728 -0
  284. package/frontend/lib/components/files/SearchResults.svelte +303 -0
  285. package/frontend/lib/components/git/BranchManager.svelte +458 -0
  286. package/frontend/lib/components/git/ChangesSection.svelte +107 -0
  287. package/frontend/lib/components/git/CommitForm.svelte +76 -0
  288. package/frontend/lib/components/git/ConflictResolver.svelte +158 -0
  289. package/frontend/lib/components/git/DiffViewer.svelte +364 -0
  290. package/frontend/lib/components/git/FileChangeItem.svelte +97 -0
  291. package/frontend/lib/components/git/GitButton.svelte +33 -0
  292. package/frontend/lib/components/git/GitLog.svelte +361 -0
  293. package/frontend/lib/components/git/GitModal.svelte +80 -0
  294. package/frontend/lib/components/history/HistoryModal.svelte +563 -0
  295. package/frontend/lib/components/history/HistoryView.svelte +615 -0
  296. package/frontend/lib/components/index.ts +34 -0
  297. package/frontend/lib/components/preview/browser/BrowserPreview.svelte +549 -0
  298. package/frontend/lib/components/preview/browser/components/Canvas.svelte +1058 -0
  299. package/frontend/lib/components/preview/browser/components/ConsolePanel.svelte +757 -0
  300. package/frontend/lib/components/preview/browser/components/Container.svelte +450 -0
  301. package/frontend/lib/components/preview/browser/components/ContextMenu.svelte +236 -0
  302. package/frontend/lib/components/preview/browser/components/SelectDropdown.svelte +224 -0
  303. package/frontend/lib/components/preview/browser/components/Toolbar.svelte +339 -0
  304. package/frontend/lib/components/preview/browser/components/VirtualCursor.svelte +36 -0
  305. package/frontend/lib/components/preview/browser/core/cleanup.svelte.ts +155 -0
  306. package/frontend/lib/components/preview/browser/core/coordinator.svelte.ts +837 -0
  307. package/frontend/lib/components/preview/browser/core/interactions.svelte.ts +113 -0
  308. package/frontend/lib/components/preview/browser/core/mcp-handlers.svelte.ts +296 -0
  309. package/frontend/lib/components/preview/browser/core/native-ui-handlers.svelte.ts +391 -0
  310. package/frontend/lib/components/preview/browser/core/stream-handler.svelte.ts +231 -0
  311. package/frontend/lib/components/preview/browser/core/tab-manager.svelte.ts +210 -0
  312. package/frontend/lib/components/preview/browser/core/tab-operations.svelte.ts +239 -0
  313. package/frontend/lib/components/preview/index.ts +2 -0
  314. package/frontend/lib/components/settings/SettingsModal.svelte +235 -0
  315. package/frontend/lib/components/settings/SettingsView.svelte +36 -0
  316. package/frontend/lib/components/settings/appearance/AppearanceSettings.svelte +51 -0
  317. package/frontend/lib/components/settings/appearance/LayoutPresetSettings.svelte +160 -0
  318. package/frontend/lib/components/settings/appearance/LayoutPreview.svelte +76 -0
  319. package/frontend/lib/components/settings/engines/AIEnginesSettings.svelte +917 -0
  320. package/frontend/lib/components/settings/general/AdvancedSettings.svelte +187 -0
  321. package/frontend/lib/components/settings/general/DataManagementSettings.svelte +203 -0
  322. package/frontend/lib/components/settings/general/GeneralSettings.svelte +10 -0
  323. package/frontend/lib/components/settings/model/ModelSettings.svelte +357 -0
  324. package/frontend/lib/components/settings/notifications/NotificationSettings.svelte +205 -0
  325. package/frontend/lib/components/settings/user/UserSettings.svelte +197 -0
  326. package/frontend/lib/components/terminal/Terminal.svelte +368 -0
  327. package/frontend/lib/components/terminal/TerminalTabs.svelte +87 -0
  328. package/frontend/lib/components/terminal/TerminalView.svelte +55 -0
  329. package/frontend/lib/components/tunnel/TunnelActive.svelte +142 -0
  330. package/frontend/lib/components/tunnel/TunnelButton.svelte +54 -0
  331. package/frontend/lib/components/tunnel/TunnelInactive.svelte +284 -0
  332. package/frontend/lib/components/tunnel/TunnelModal.svelte +47 -0
  333. package/frontend/lib/components/tunnel/TunnelQRCode.svelte +49 -0
  334. package/frontend/lib/components/workspace/DesktopNavigator.svelte +382 -0
  335. package/frontend/lib/components/workspace/MobileNavigator.svelte +403 -0
  336. package/frontend/lib/components/workspace/PanelContainer.svelte +100 -0
  337. package/frontend/lib/components/workspace/PanelHeader.svelte +505 -0
  338. package/frontend/lib/components/workspace/ViewMenu.svelte +162 -0
  339. package/frontend/lib/components/workspace/WorkspaceLayout.svelte +169 -0
  340. package/frontend/lib/components/workspace/layout/DesktopLayout.svelte +15 -0
  341. package/frontend/lib/components/workspace/layout/MobileLayout.svelte +17 -0
  342. package/frontend/lib/components/workspace/layout/split-pane/Container.svelte +42 -0
  343. package/frontend/lib/components/workspace/layout/split-pane/Handle.svelte +85 -0
  344. package/frontend/lib/components/workspace/layout/split-pane/Layout.svelte +37 -0
  345. package/frontend/lib/components/workspace/panels/ChatPanel.svelte +274 -0
  346. package/frontend/lib/components/workspace/panels/FilesPanel.svelte +1261 -0
  347. package/frontend/lib/components/workspace/panels/GitPanel.svelte +1560 -0
  348. package/frontend/lib/components/workspace/panels/PreviewPanel.svelte +150 -0
  349. package/frontend/lib/components/workspace/panels/TerminalPanel.svelte +73 -0
  350. package/frontend/lib/constants/preview.ts +45 -0
  351. package/frontend/lib/services/chat/chat.service.ts +704 -0
  352. package/frontend/lib/services/chat/index.ts +7 -0
  353. package/frontend/lib/services/notification/global-stream-monitor.ts +86 -0
  354. package/frontend/lib/services/notification/index.ts +8 -0
  355. package/frontend/lib/services/notification/push.service.ts +144 -0
  356. package/frontend/lib/services/notification/sound.service.ts +127 -0
  357. package/frontend/lib/services/preview/browser/browser-console.service.ts +61 -0
  358. package/frontend/lib/services/preview/browser/browser-webcodecs.service.ts +1499 -0
  359. package/frontend/lib/services/preview/browser/mcp-integration.svelte.ts +67 -0
  360. package/frontend/lib/services/preview/index.ts +23 -0
  361. package/frontend/lib/services/project/index.ts +8 -0
  362. package/frontend/lib/services/project/status.service.ts +159 -0
  363. package/frontend/lib/services/snapshot/snapshot.service.ts +47 -0
  364. package/frontend/lib/services/terminal/background/index.ts +130 -0
  365. package/frontend/lib/services/terminal/background/session-restore.ts +274 -0
  366. package/frontend/lib/services/terminal/background/stream-manager.ts +286 -0
  367. package/frontend/lib/services/terminal/index.ts +14 -0
  368. package/frontend/lib/services/terminal/persistence.service.ts +260 -0
  369. package/frontend/lib/services/terminal/project.service.ts +953 -0
  370. package/frontend/lib/services/terminal/session.service.ts +364 -0
  371. package/frontend/lib/services/terminal/terminal.service.ts +369 -0
  372. package/frontend/lib/stores/core/app.svelte.ts +117 -0
  373. package/frontend/lib/stores/core/files.svelte.ts +73 -0
  374. package/frontend/lib/stores/core/presence.svelte.ts +48 -0
  375. package/frontend/lib/stores/core/projects.svelte.ts +317 -0
  376. package/frontend/lib/stores/core/sessions.svelte.ts +383 -0
  377. package/frontend/lib/stores/features/claude-accounts.svelte.ts +58 -0
  378. package/frontend/lib/stores/features/models.svelte.ts +89 -0
  379. package/frontend/lib/stores/features/settings.svelte.ts +87 -0
  380. package/frontend/lib/stores/features/terminal.svelte.ts +701 -0
  381. package/frontend/lib/stores/features/tunnel.svelte.ts +161 -0
  382. package/frontend/lib/stores/features/user.svelte.ts +96 -0
  383. package/frontend/lib/stores/ui/chat-input.svelte.ts +57 -0
  384. package/frontend/lib/stores/ui/chat-model.svelte.ts +61 -0
  385. package/frontend/lib/stores/ui/dialog.svelte.ts +59 -0
  386. package/frontend/lib/stores/ui/edit-mode.svelte.ts +214 -0
  387. package/frontend/lib/stores/ui/notification.svelte.ts +166 -0
  388. package/frontend/lib/stores/ui/settings-modal.svelte.ts +88 -0
  389. package/frontend/lib/stores/ui/theme.svelte.ts +179 -0
  390. package/frontend/lib/stores/ui/workspace.svelte.ts +754 -0
  391. package/frontend/lib/types/native-ui.ts +73 -0
  392. package/frontend/lib/utils/chat/date-separator.ts +39 -0
  393. package/frontend/lib/utils/chat/message-grouper.ts +219 -0
  394. package/frontend/lib/utils/chat/message-processor.ts +135 -0
  395. package/frontend/lib/utils/chat/tool-handler.ts +161 -0
  396. package/frontend/lib/utils/chat/virtual-scroll.svelte.ts +142 -0
  397. package/frontend/lib/utils/click-outside.ts +20 -0
  398. package/frontend/lib/utils/context-manager.ts +257 -0
  399. package/frontend/lib/utils/file-icon-mappings.ts +769 -0
  400. package/frontend/lib/utils/folder-icon-mappings.ts +1030 -0
  401. package/frontend/lib/utils/git-status.ts +68 -0
  402. package/frontend/lib/utils/platform.ts +113 -0
  403. package/frontend/lib/utils/port-check.ts +65 -0
  404. package/frontend/lib/utils/terminalFormatter.ts +207 -0
  405. package/frontend/lib/utils/theme.ts +6 -0
  406. package/frontend/lib/utils/tree-visualizer.ts +320 -0
  407. package/frontend/lib/utils/ws.ts +44 -0
  408. package/frontend/main.ts +13 -0
  409. package/index.html +70 -0
  410. package/package.json +111 -0
  411. package/scripts/generate-icons.ts +87 -0
  412. package/scripts/pre-publish-check.sh +142 -0
  413. package/scripts/setup-hooks.sh +134 -0
  414. package/scripts/validate-branch-name.sh +47 -0
  415. package/scripts/validate-commit-msg.sh +42 -0
  416. package/shared/constants/engines.ts +134 -0
  417. package/shared/types/database/connection.ts +16 -0
  418. package/shared/types/database/index.ts +6 -0
  419. package/shared/types/database/schema.ts +141 -0
  420. package/shared/types/engine/index.ts +45 -0
  421. package/shared/types/filesystem/index.ts +22 -0
  422. package/shared/types/git.ts +171 -0
  423. package/shared/types/messaging/index.ts +239 -0
  424. package/shared/types/messaging/tool.ts +526 -0
  425. package/shared/types/network/api.ts +18 -0
  426. package/shared/types/network/index.ts +5 -0
  427. package/shared/types/stores/app.ts +23 -0
  428. package/shared/types/stores/dialog.ts +21 -0
  429. package/shared/types/stores/index.ts +3 -0
  430. package/shared/types/stores/settings.ts +15 -0
  431. package/shared/types/terminal/index.ts +44 -0
  432. package/shared/types/ui/components.ts +61 -0
  433. package/shared/types/ui/icons.ts +23 -0
  434. package/shared/types/ui/index.ts +22 -0
  435. package/shared/types/ui/notifications.ts +14 -0
  436. package/shared/types/ui/theme.ts +12 -0
  437. package/shared/types/websocket/index.ts +43 -0
  438. package/shared/types/window.d.ts +13 -0
  439. package/shared/utils/anonymous-user.ts +168 -0
  440. package/shared/utils/async.ts +10 -0
  441. package/shared/utils/diff-calculator.ts +184 -0
  442. package/shared/utils/file-type-detection.ts +166 -0
  443. package/shared/utils/logger.ts +158 -0
  444. package/shared/utils/message-formatter.ts +79 -0
  445. package/shared/utils/path.ts +47 -0
  446. package/shared/utils/ws-client.ts +768 -0
  447. package/shared/utils/ws-server.ts +660 -0
  448. package/static/audio/notification.ogg +0 -0
  449. package/static/favicon.svg +8 -0
  450. package/static/fonts/dm-sans/dm-sans-italic-latin-ext.woff2 +0 -0
  451. package/static/fonts/dm-sans/dm-sans-italic-latin.woff2 +0 -0
  452. package/static/fonts/dm-sans/dm-sans-normal-latin-ext.woff2 +0 -0
  453. package/static/fonts/dm-sans/dm-sans-normal-latin.woff2 +0 -0
  454. package/static/fonts/dm-sans.css +96 -0
  455. package/svelte.config.js +20 -0
  456. package/vite.config.ts +33 -0
@@ -0,0 +1,48 @@
1
+ <script lang="ts">
2
+ import type { EditToolInput } from '$shared/types/messaging';
3
+ import { FileHeader, DiffBlock } from './components';
4
+ import Icon from '$frontend/lib/components/common/Icon.svelte';
5
+
6
+ const { toolInput }: { toolInput: EditToolInput } = $props();
7
+
8
+ const filePath = toolInput.input.file_path || '';
9
+ const fileName = filePath.split(/[/\\]/).pop() || filePath || 'unknown';
10
+ const oldString = toolInput.input.old_string || '';
11
+ const newString = toolInput.input.new_string || '';
12
+ const replaceAll = toolInput.input.replace_all || false;
13
+
14
+ const badges = replaceAll ? [{ text: 'Replace All', color: 'bg-amber-100 dark:bg-amber-900 text-amber-700 dark:text-amber-300' }] : [];
15
+ </script>
16
+
17
+ <FileHeader
18
+ {filePath}
19
+ {fileName}
20
+ iconColor="text-emerald-600 dark:text-emerald-400"
21
+ {badges}
22
+ />
23
+
24
+ <!-- Replace All Info -->
25
+ <!-- {#if replaceAll}
26
+ <div class="mt-3 flex items-start gap-2 bg-amber-50 dark:bg-amber-950/30 border border-amber-200 dark:border-amber-800 rounded-md p-3">
27
+ <Icon name="lucide:info" class="w-4 h-4 text-amber-600 dark:text-amber-400 flex-shrink-0 mt-0.5" />
28
+ <p class="text-xs text-amber-700 dark:text-amber-300">
29
+ This edit will replace <strong>all occurrences</strong> of the old string in the file. The actual file changes may affect multiple lines beyond what is shown in the diff preview below.
30
+ </p>
31
+ </div>
32
+ {/if} -->
33
+
34
+ <!-- Code Changes -->
35
+ <div class="mt-4">
36
+ <DiffBlock {oldString} {newString} label="Edit" />
37
+ </div>
38
+
39
+ <!-- Tool Result -->
40
+ <!-- {#if toolInput.$result?.content}
41
+ <div class="mt-4 bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
42
+ {#if typeof toolInput.$result.content === 'string'}
43
+ <TextMessage content={toolInput.$result.content} />
44
+ {:else}
45
+ <TextMessage content={JSON.stringify(toolInput.$result.content)} />
46
+ {/if}
47
+ </div>
48
+ {/if} -->
@@ -0,0 +1,32 @@
1
+ <script lang="ts">
2
+ import type { ExitPlanModeToolInput } from '$shared/types/messaging';
3
+ import { InfoLine, CodeBlock } from './components';
4
+ import TextMessage from '../formatters/TextMessage.svelte';
5
+
6
+ const { toolInput }: { toolInput: ExitPlanModeToolInput } = $props();
7
+
8
+ const plan = (toolInput.input as any).plan as string || '';
9
+ </script>
10
+
11
+ <div class="bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
12
+ <!-- Plan Info -->
13
+ <div class="flex gap-3 mb-2">
14
+ <InfoLine icon="lucide:map" text="Exiting plan mode with proposed plan" />
15
+ </div>
16
+
17
+ <!-- Plan Content -->
18
+ <div class="border-t border-slate-200 dark:border-slate-700 pt-3">
19
+ <CodeBlock code={plan} type="neutral" label="Plan" />
20
+ </div>
21
+ </div>
22
+
23
+ <!-- Tool Result -->
24
+ {#if toolInput.$result}
25
+ <div class="mt-4 bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
26
+ {#if typeof toolInput.$result.content === 'string'}
27
+ <TextMessage content={toolInput.$result.content} />
28
+ {:else}
29
+ <TextMessage content={JSON.stringify(toolInput.$result.content)} />
30
+ {/if}
31
+ </div>
32
+ {/if}
@@ -0,0 +1,51 @@
1
+ <script lang="ts">
2
+ import type { GlobToolInput } from '$shared/types/messaging';
3
+ import { InfoLine } from './components';
4
+ import { formatPath } from '../shared/utils';
5
+ import CodeBlock from './components/CodeBlock.svelte';
6
+
7
+ const { toolInput }: { toolInput: GlobToolInput } = $props();
8
+
9
+ const pattern = toolInput.input.pattern || '';
10
+ const searchPath = toolInput.input.path || 'current directory';
11
+
12
+ // Parse the pattern to get a readable description
13
+ function getPatternDescription(pattern: string): string {
14
+ if (pattern.includes('**/*.')) {
15
+ const ext = pattern.split('**/*.')[1];
16
+ return `all .${ext} files`;
17
+ } else if (pattern.includes('**/')) {
18
+ const rest = pattern.split('**/')[1];
19
+ return `all ${rest} in subdirectories`;
20
+ } else if (pattern.includes('*.')) {
21
+ const ext = pattern.split('*.')[1];
22
+ return `.${ext} files`;
23
+ }
24
+ return pattern;
25
+ }
26
+
27
+ const patternDescription = getPatternDescription(pattern);
28
+ const formattedPath = formatPath(searchPath);
29
+ </script>
30
+
31
+ <div class="bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
32
+ <div class="mb-2">
33
+ <h3 class="font-medium text-slate-900 dark:text-slate-100">
34
+ Searching for {patternDescription}
35
+ </h3>
36
+ <p class="text-xs text-slate-600 dark:text-slate-400 truncate" title={searchPath}>
37
+ in {formattedPath}
38
+ </p>
39
+ </div>
40
+
41
+ <div class="flex gap-2 border-t border-slate-200/60 dark:border-slate-700/60 pt-2">
42
+ <InfoLine icon="lucide:file-search-2" text={pattern} />
43
+ </div>
44
+ </div>
45
+
46
+ <!-- Tool Result -->
47
+ {#if toolInput.$result?.content}
48
+ <div class="mt-4 bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
49
+ <CodeBlock code={toolInput.$result.content} type="neutral" label="Output" />
50
+ </div>
51
+ {/if}
@@ -0,0 +1,90 @@
1
+ <script lang="ts">
2
+ import type { GrepToolInput } from '$shared/types/messaging';
3
+ import type { IconName } from '$shared/types/ui';
4
+ import { InfoLine } from './components';
5
+ import { formatPath, truncateText } from '../shared/utils';
6
+ import CodeBlock from './components/CodeBlock.svelte';
7
+
8
+ const { toolInput }: { toolInput: GrepToolInput } = $props();
9
+
10
+ const pattern = toolInput.input.pattern || '';
11
+ const searchPath = toolInput.input.path || 'current directory';
12
+
13
+ // Get active search parameters for display
14
+ function getActiveParameters() {
15
+ const params: { label: string; value: string; icon: IconName }[] = [];
16
+
17
+ params.push({ label: 'Output', value: toolInput.input.output_mode || 'files_with_matches', icon: 'lucide:filter' });
18
+
19
+ if (toolInput.input.glob) {
20
+ params.push({ label: 'Glob', value: toolInput.input.glob, icon: 'lucide:folder-search' });
21
+ }
22
+
23
+ if (toolInput.input.type) {
24
+ params.push({ label: 'File type', value: toolInput.input.type, icon: 'lucide:file-type' });
25
+ }
26
+
27
+ if (toolInput.input['-i']) {
28
+ params.push({ label: 'Case insensitive', value: '', icon: 'lucide:case-sensitive' });
29
+ }
30
+
31
+ if (toolInput.input['-n']) {
32
+ params.push({ label: 'Line numbers', value: '', icon: 'lucide:hash' });
33
+ }
34
+
35
+ if (toolInput.input['-A']) {
36
+ params.push({ label: 'After context', value: `${toolInput.input['-A']} lines`, icon: 'lucide:arrow-down' });
37
+ }
38
+
39
+ if (toolInput.input['-B']) {
40
+ params.push({ label: 'Before context', value: `${toolInput.input['-B']} lines`, icon: 'lucide:arrow-up' });
41
+ }
42
+
43
+ if (toolInput.input['-C']) {
44
+ params.push({ label: 'Context', value: `${toolInput.input['-C']} lines`, icon: 'lucide:arrow-up-down' });
45
+ }
46
+
47
+ if (toolInput.input.head_limit) {
48
+ params.push({ label: 'Limit', value: `${toolInput.input.head_limit} results`, icon: 'lucide:list-end' });
49
+ }
50
+
51
+ if (toolInput.input.multiline) {
52
+ params.push({ label: 'Multiline', value: '', icon: 'lucide:text' });
53
+ }
54
+
55
+ return params;
56
+ }
57
+
58
+ const activeParameters = getActiveParameters();
59
+
60
+ const formattedPattern = truncateText(pattern, 40);
61
+ const formattedPath = formatPath(searchPath);
62
+ </script>
63
+
64
+ <div class="bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
65
+ <div class="mb-2">
66
+ <h3 class="font-medium text-slate-900 dark:text-slate-100 truncate" title={pattern}>
67
+ Searching for: <span class="font-mono">{formattedPattern}</span>
68
+ </h3>
69
+ <p class="text-xs text-slate-600 dark:text-slate-400 truncate" title={searchPath}>
70
+ in {formattedPath}
71
+ </p>
72
+ </div>
73
+
74
+ {#if activeParameters.length > 0}
75
+ <div class="border-t border-slate-200 dark:border-slate-700 pt-3">
76
+ <div class="flex gap-x-3 gap-y-2 flex-wrap">
77
+ {#each activeParameters as param}
78
+ <InfoLine icon={param.icon} text={param.value == '' ? param.label : param.value} title={param.value == '' ? param.label : `${param.label}: ${param.value}`} />
79
+ {/each}
80
+ </div>
81
+ </div>
82
+ {/if}
83
+ </div>
84
+
85
+ <!-- Tool Result -->
86
+ {#if toolInput.$result?.content}
87
+ <div class="mt-4 bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
88
+ <CodeBlock code={toolInput.$result.content} type="neutral" label="Output" />
89
+ </div>
90
+ {/if}
@@ -0,0 +1,26 @@
1
+ <script lang="ts">
2
+ import type { KillShellToolInput } from '$shared/types/messaging';
3
+ import { InfoLine } from './components';
4
+ import TextMessage from '../formatters/TextMessage.svelte';
5
+
6
+ const { toolInput }: { toolInput: KillShellToolInput } = $props();
7
+
8
+ const shellId = toolInput.input.shell_id;
9
+ </script>
10
+
11
+ <div class="bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
12
+ <div class="flex gap-3">
13
+ <InfoLine icon="lucide:circle-x" text="Terminating shell process: {shellId}" />
14
+ </div>
15
+ </div>
16
+
17
+ <!-- Tool Result -->
18
+ {#if toolInput.$result}
19
+ <div class="mt-4 bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
20
+ {#if typeof toolInput.$result.content === 'string'}
21
+ <TextMessage content={toolInput.$result.content} />
22
+ {:else}
23
+ <TextMessage content={JSON.stringify(toolInput.$result.content)} />
24
+ {/if}
25
+ </div>
26
+ {/if}
@@ -0,0 +1,31 @@
1
+ <script lang="ts">
2
+ import type { ListMcpResourcesToolInput } from '$shared/types/messaging';
3
+ import { InfoLine } from './components';
4
+ import TextMessage from '../formatters/TextMessage.svelte';
5
+
6
+ const { toolInput }: { toolInput: ListMcpResourcesToolInput } = $props();
7
+
8
+ const server = toolInput.input.server;
9
+ </script>
10
+
11
+ <div class="bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
12
+ <div class="flex gap-3">
13
+ <InfoLine icon="lucide:server" text="Listing MCP resources" />
14
+ {#if server}
15
+ <InfoLine icon="lucide:filter" text="Server: {server}" />
16
+ {:else}
17
+ <InfoLine icon="lucide:globe" text="All servers" />
18
+ {/if}
19
+ </div>
20
+ </div>
21
+
22
+ <!-- Tool Result -->
23
+ {#if toolInput.$result}
24
+ <div class="mt-4 bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
25
+ {#if typeof toolInput.$result.content === 'string'}
26
+ <TextMessage content={toolInput.$result.content} />
27
+ {:else}
28
+ <TextMessage content={JSON.stringify(toolInput.$result.content)} />
29
+ {/if}
30
+ </div>
31
+ {/if}
@@ -0,0 +1,38 @@
1
+ <script lang="ts">
2
+ import type { NotebookEditToolInput } from '$shared/types/messaging';
3
+ import { FileHeader, InfoLine, CodeBlock } from './components';
4
+ import TextMessage from '../formatters/TextMessage.svelte';
5
+
6
+ const { toolInput }: { toolInput: NotebookEditToolInput } = $props();
7
+
8
+ const notebookPath = toolInput.input.notebook_path;
9
+ const fileName = notebookPath.split(/[/\\]/).pop() || notebookPath;
10
+ const cellId = toolInput.input.cell_id;
11
+ const cellType = toolInput.input.cell_type || 'code';
12
+ const editMode = toolInput.input.edit_mode || 'replace';
13
+ const newSource = toolInput.input.new_source;
14
+ </script>
15
+
16
+ <FileHeader filePath={notebookPath} fileName={fileName} />
17
+
18
+ <!-- Edit Details -->
19
+ <div class="flex gap-2 border-t border-slate-200/60 dark:border-slate-700/60 pt-2 mt-3">
20
+ <InfoLine icon="lucide:notebook" text="{editMode} {cellType} cell" />
21
+ {#if cellId}
22
+ <InfoLine icon="lucide:hash" text="Cell ID: {cellId}" />
23
+ {/if}
24
+ </div>
25
+
26
+ <!-- New Source -->
27
+ <CodeBlock code={newSource} type={editMode === 'insert' ? 'add' : editMode === 'delete' ? 'remove' : 'neutral'} label="{editMode === 'insert' ? 'Adding' : editMode === 'delete' ? 'Deleting' : 'Updating'} cell content" />
28
+
29
+ <!-- Tool Result -->
30
+ {#if toolInput.$result}
31
+ <div class="mt-4 bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
32
+ {#if typeof toolInput.$result.content === 'string'}
33
+ <TextMessage content={toolInput.$result.content} />
34
+ {:else}
35
+ <TextMessage content={JSON.stringify(toolInput.$result.content)} />
36
+ {/if}
37
+ </div>
38
+ {/if}
@@ -0,0 +1,34 @@
1
+ <script lang="ts">
2
+ import type { ReadMcpResourceToolInput } from '$shared/types/messaging';
3
+ import { InfoLine, CodeBlock } from './components';
4
+ import TextMessage from '../formatters/TextMessage.svelte';
5
+
6
+ const { toolInput }: { toolInput: ReadMcpResourceToolInput } = $props();
7
+
8
+ const server = toolInput.input.server;
9
+ const uri = toolInput.input.uri;
10
+ </script>
11
+
12
+ <div class="bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
13
+ <!-- Resource Info -->
14
+ <div class="flex gap-3 mb-2">
15
+ <InfoLine icon="lucide:file-text" text="Reading MCP resource" />
16
+ <InfoLine icon="lucide:server" text="Server: {server}" />
17
+ </div>
18
+
19
+ <!-- URI -->
20
+ <div class="border-t border-slate-200 dark:border-slate-700 pt-3">
21
+ <CodeBlock code={uri} type="neutral" label="Resource URI" />
22
+ </div>
23
+ </div>
24
+
25
+ <!-- Tool Result -->
26
+ {#if toolInput.$result}
27
+ <div class="mt-4 bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
28
+ {#if typeof toolInput.$result.content === 'string'}
29
+ <TextMessage content={toolInput.$result.content} />
30
+ {:else}
31
+ <TextMessage content={JSON.stringify(toolInput.$result.content)} />
32
+ {/if}
33
+ </div>
34
+ {/if}
@@ -0,0 +1,41 @@
1
+ <script lang="ts">
2
+ import type { ReadToolInput } from '$shared/types/messaging';
3
+ import { FileHeader, InfoLine } from './components';
4
+ import TextMessage from '../formatters/TextMessage.svelte';
5
+
6
+ const { toolInput }: { toolInput: ReadToolInput } = $props();
7
+
8
+ const filePath = toolInput.input.file_path || '';
9
+ const fileName = filePath.split(/[/\\]/).pop() || filePath || 'unknown';
10
+ const hasLimit = toolInput.input.limit !== undefined;
11
+ const hasOffset = toolInput.input.offset !== undefined;
12
+ </script>
13
+
14
+ <div class="bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
15
+ <FileHeader {filePath} {fileName} box={false} />
16
+
17
+ <!-- Reading Options -->
18
+ <div class="flex gap-2 border-t border-slate-200/60 dark:border-slate-700/60 pt-2 mt-2">
19
+ {#if hasLimit || hasOffset}
20
+ {#if hasOffset}
21
+ <InfoLine icon="lucide:skip-forward" text="Starting from line {toolInput.input.offset}" />
22
+ {/if}
23
+ {#if hasLimit}
24
+ <InfoLine icon="lucide:list" text="Reading {toolInput.input.limit} lines" />
25
+ {/if}
26
+ {:else}
27
+ <InfoLine icon="lucide:file-scan" text="Reading entire file" />
28
+ {/if}
29
+ </div>
30
+ </div>
31
+
32
+ <!-- Tool Result -->
33
+ <!-- {#if toolInput.$result?.content}
34
+ <div class="mt-4 bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
35
+ {#if typeof toolInput.$result.content === 'string'}
36
+ <TextMessage content={toolInput.$result.content} />
37
+ {:else}
38
+ <TextMessage content={JSON.stringify(toolInput.$result.content)} />
39
+ {/if}
40
+ </div>
41
+ {/if} -->
@@ -0,0 +1,64 @@
1
+ <script lang="ts">
2
+ import type { TaskToolInput } from '$shared/types/messaging';
3
+ import { InfoLine, CodeBlock } from './components';
4
+ import TextMessage from '../formatters/TextMessage.svelte';
5
+
6
+ const { toolInput }: { toolInput: TaskToolInput } = $props();
7
+
8
+ const showFullPrompt = $state(false);
9
+
10
+ // Format description for display
11
+ function formatDescription(desc: string): string {
12
+ if (desc.length > 50) {
13
+ return desc.substring(0, 47) + '...';
14
+ }
15
+ return desc;
16
+ }
17
+
18
+ const formattedDesc = formatDescription(toolInput.input.description || '');
19
+ </script>
20
+
21
+ <div class="bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
22
+ <div class="mb-2">
23
+ <h3 class="font-medium text-slate-900 dark:text-slate-100">
24
+ {formattedDesc}
25
+ </h3>
26
+ <p class="text-xs text-slate-600 dark:text-slate-400" title={toolInput.input.subagent_type}>
27
+ Using {toolInput.input.subagent_type} agent
28
+ </p>
29
+ </div>
30
+
31
+ <!-- <div class="border-t border-slate-200 dark:border-slate-700 pt-3">
32
+ <div class="flex gap-3">
33
+ <InfoLine icon="lucide:file-text" text="Full task prompt provided" />
34
+ <button
35
+ onclick={() => showFullPrompt = !showFullPrompt}
36
+ class="text-xs text-violet-600 dark:text-violet-400 hover:underline"
37
+ >
38
+ {showFullPrompt ? 'Hide' : 'Show'} details
39
+ </button>
40
+ </div>
41
+
42
+ {#if showFullPrompt}
43
+ <div class="mt-2 p-3 bg-slate-50 dark:bg-slate-800 rounded-md border border-slate-200 dark:border-slate-700">
44
+ <pre class="text-xs text-slate-700 dark:text-slate-300 whitespace-pre-wrap">{toolInput.input.prompt}</pre>
45
+ </div>
46
+ {/if}
47
+ </div> -->
48
+ </div>
49
+
50
+ <TextMessage content={toolInput.input.prompt} />
51
+
52
+ <!-- Tool Result -->
53
+ <!-- {#if toolInput.$result}
54
+ <div class="mt-4 bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
55
+ {#if typeof toolInput.$result.content === 'string'}
56
+ <TextMessage content={toolInput.$result.content} />
57
+ {:else}
58
+ <TextMessage content={JSON.stringify(toolInput.$result.content)} />
59
+ {/if}
60
+ </div>
61
+ <div class="mt-4 bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
62
+ <CodeBlock code={toolInput.input.prompt} type="neutral" label="Output" />
63
+ </div>
64
+ {/if} -->
@@ -0,0 +1,75 @@
1
+ <script lang="ts">
2
+ import Icon from '$frontend/lib/components/common/Icon.svelte';
3
+ import type { TodoWriteToolInput } from '$shared/types/messaging';
4
+ import type { IconName } from '$shared/types/ui/icons';
5
+
6
+ const { toolInput }: { toolInput: TodoWriteToolInput } = $props();
7
+
8
+ const todos = toolInput.input.todos;
9
+ const totalTodos = todos.length;
10
+ const completedTodos = todos.filter((t) => t.status === 'completed').length;
11
+ const percentage = totalTodos > 0 ? Math.round((completedTodos / totalTodos) * 100) : 0;
12
+
13
+ // Helper functions for todo items
14
+ function getStatusIcon(status: string): IconName {
15
+ switch (status) {
16
+ case 'completed': return 'lucide:circle-check';
17
+ case 'in_progress': return 'lucide:clock';
18
+ case 'pending': return 'lucide:circle';
19
+ default: return 'lucide:circle';
20
+ }
21
+ }
22
+
23
+ function getStatusColor(status: string): string {
24
+ switch (status) {
25
+ case 'completed': return 'text-green-600 dark:text-green-400';
26
+ case 'in_progress': return 'text-violet-600 dark:text-violet-400';
27
+ case 'pending': return 'text-slate-500 dark:text-slate-400';
28
+ default: return 'text-slate-500 dark:text-slate-400';
29
+ }
30
+ }
31
+
32
+ </script>
33
+
34
+ <!-- Header -->
35
+ <div class="flex items-center gap-2 mb-2">
36
+ <Icon name="lucide:list-todo" class="text-violet-600 dark:text-violet-400 w-4 h-4" />
37
+ <span class="font-medium text-sm text-violet-700 dark:text-violet-300">Task Planning</span>
38
+ <div class="ml-auto flex items-center gap-4 text-sm">
39
+ <div class="text-xs text-slate-600 dark:text-slate-400">
40
+ Progress: {percentage}%
41
+ </div>
42
+ </div>
43
+ </div>
44
+
45
+ <!-- Progress Bar -->
46
+ {#if totalTodos > 0}
47
+ <div class="mb-4">
48
+ <div class="w-full bg-slate-200 dark:bg-slate-700 rounded-full h-1.5">
49
+ <div
50
+ class="bg-violet-600 dark:bg-violet-400 h-1.5 rounded-full transition-all duration-300"
51
+ style="width: {percentage}%"
52
+ ></div>
53
+ </div>
54
+ </div>
55
+ {/if}
56
+
57
+ <!-- Todo List -->
58
+ <div class="space-y-2">
59
+ {#each todos as todo}
60
+ <div class="flex items-start gap-3 p-3 bg-white dark:bg-slate-800 rounded-lg border border-slate-200 dark:border-slate-700">
61
+ <!-- Status Icon -->
62
+ <Icon
63
+ name={getStatusIcon(todo.status)}
64
+ class="{getStatusColor(todo.status)} w-4 h-4 mt-0.5 flex-shrink-0"
65
+ />
66
+
67
+ <!-- Content -->
68
+ <div class="flex-1 min-w-0">
69
+ <p class="text-sm text-slate-900 dark:text-slate-100 {todo.status === 'completed' ? 'line-through opacity-75' : ''}">
70
+ {todo.status === 'in_progress' && todo.activeForm ? todo.activeForm : todo.content}
71
+ </p>
72
+ </div>
73
+ </div>
74
+ {/each}
75
+ </div>
@@ -0,0 +1,35 @@
1
+ <script lang="ts">
2
+ import type { WebFetchToolInput } from '$shared/types/messaging';
3
+ import TextMessage from '../formatters/TextMessage.svelte';
4
+
5
+ const { toolInput }: { toolInput: WebFetchToolInput } = $props();
6
+ </script>
7
+
8
+ <div class="bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
9
+ <div class="mb-2">
10
+ <h3 class="font-medium text-slate-900 dark:text-slate-100">
11
+ Web Fetch
12
+ </h3>
13
+ <p class="text-sm text-slate-700 dark:text-slate-300 mt-1">
14
+ Fetching: <span class="font-mono text-xs bg-slate-100 dark:bg-slate-800 px-1 rounded">{toolInput.input.url || ''}</span>
15
+ </p>
16
+ </div>
17
+
18
+ <div class="border-t border-slate-200 dark:border-slate-700 pt-3">
19
+ <p class="text-xs font-medium text-slate-700 dark:text-slate-300 mb-1">Processing prompt:</p>
20
+ <p class="text-xs text-slate-600 dark:text-slate-400 font-mono leading-relaxed">
21
+ {toolInput.input.prompt || ''}
22
+ </p>
23
+ </div>
24
+ </div>
25
+
26
+ <!-- Tool Result -->
27
+ <!-- {#if toolInput.$result}
28
+ <div class="mt-4 bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
29
+ {#if typeof toolInput.$result.content === 'string'}
30
+ <TextMessage content={toolInput.$result.content} />
31
+ {:else}
32
+ <TextMessage content={JSON.stringify(toolInput.$result.content)} />
33
+ {/if}
34
+ </div>
35
+ {/if} -->
@@ -0,0 +1,84 @@
1
+ <script lang="ts">
2
+ import type { WebSearchToolInput } from '$shared/types/messaging';
3
+ import { InfoLine } from './components';
4
+ import TextMessage from '../formatters/TextMessage.svelte';
5
+
6
+ const { toolInput }: { toolInput: WebSearchToolInput } = $props();
7
+
8
+ let showDetails = $state(false);
9
+
10
+ // Format query for display
11
+ function formatQuery(query: string): string {
12
+ if (query.length > 60) {
13
+ return query.substring(0, 57) + '...';
14
+ }
15
+ return query;
16
+ }
17
+
18
+ const formattedQuery = formatQuery(toolInput.input.query || '');
19
+ </script>
20
+
21
+ <div class="bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
22
+ <div class="mb-2">
23
+ <h3 class="font-medium text-slate-900 dark:text-slate-100">
24
+ Web Search
25
+ </h3>
26
+ <p class="text-sm text-slate-700 dark:text-slate-300 mt-1">
27
+ {formattedQuery}
28
+ </p>
29
+ </div>
30
+
31
+ <div class="border-t border-slate-200 dark:border-slate-700 pt-3">
32
+ <div class="flex gap-3 items-center">
33
+ <InfoLine icon="lucide:globe" text="Searching the web" />
34
+ {#if toolInput.input.allowed_domains?.length || toolInput.input.blocked_domains?.length}
35
+ <button
36
+ onclick={() => showDetails = !showDetails}
37
+ class="text-xs text-violet-600 dark:text-violet-400 hover:underline"
38
+ >
39
+ {showDetails ? 'Hide' : 'Show'} filters
40
+ </button>
41
+ {/if}
42
+ </div>
43
+
44
+ {#if showDetails && (toolInput.input.allowed_domains?.length || toolInput.input.blocked_domains?.length)}
45
+ <div class="mt-2 p-3 bg-slate-50 dark:bg-slate-800 rounded-md border border-slate-200 dark:border-slate-700">
46
+ {#if toolInput.input.allowed_domains?.length}
47
+ <div class="mb-2">
48
+ <p class="text-xs font-medium text-slate-700 dark:text-slate-300 mb-1">Allowed domains:</p>
49
+ <div class="flex flex-wrap gap-1">
50
+ {#each toolInput.input.allowed_domains as domain}
51
+ <span class="inline-block px-2 py-1 text-xs bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200 rounded">
52
+ {domain}
53
+ </span>
54
+ {/each}
55
+ </div>
56
+ </div>
57
+ {/if}
58
+ {#if toolInput.input.blocked_domains?.length}
59
+ <div>
60
+ <p class="text-xs font-medium text-slate-700 dark:text-slate-300 mb-1">Blocked domains:</p>
61
+ <div class="flex flex-wrap gap-1">
62
+ {#each toolInput.input.blocked_domains as domain}
63
+ <span class="inline-block px-2 py-1 text-xs bg-red-100 dark:bg-red-900 text-red-800 dark:text-red-200 rounded">
64
+ {domain}
65
+ </span>
66
+ {/each}
67
+ </div>
68
+ </div>
69
+ {/if}
70
+ </div>
71
+ {/if}
72
+ </div>
73
+ </div>
74
+
75
+ <!-- Tool Result -->
76
+ <!-- {#if toolInput.$result}
77
+ <div class="mt-4 bg-white dark:bg-slate-800 rounded-md border border-slate-200/60 dark:border-slate-700/60 p-3">
78
+ {#if typeof toolInput.$result.content === 'string'}
79
+ <TextMessage content={toolInput.$result.content} />
80
+ {:else}
81
+ <TextMessage content={JSON.stringify(toolInput.$result.content)} />
82
+ {/if}
83
+ </div>
84
+ {/if} -->