@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.
- package/.env.example +6 -0
- package/.github/workflows/release.yml +60 -0
- package/.github/workflows/test.yml +40 -0
- package/CONTRIBUTING.md +499 -0
- package/LICENSE +21 -0
- package/README.md +209 -0
- package/backend/index.ts +156 -0
- package/backend/lib/chat/helpers.ts +42 -0
- package/backend/lib/chat/index.ts +2 -0
- package/backend/lib/chat/stream-manager.ts +1126 -0
- package/backend/lib/database/README.md +77 -0
- package/backend/lib/database/index.ts +119 -0
- package/backend/lib/database/migrations/001_create_projects_table.ts +31 -0
- package/backend/lib/database/migrations/002_create_chat_sessions_table.ts +33 -0
- package/backend/lib/database/migrations/003_create_messages_table.ts +32 -0
- package/backend/lib/database/migrations/004_create_prompt_templates_table.ts +34 -0
- package/backend/lib/database/migrations/005_create_settings_table.ts +24 -0
- package/backend/lib/database/migrations/006_add_user_to_messages.ts +58 -0
- package/backend/lib/database/migrations/007_create_stream_states_table.ts +41 -0
- package/backend/lib/database/migrations/008_create_message_snapshots_table.ts +62 -0
- package/backend/lib/database/migrations/009_add_delta_snapshot_fields.ts +41 -0
- package/backend/lib/database/migrations/010_add_soft_delete_and_branch_support.ts +70 -0
- package/backend/lib/database/migrations/011_git_like_commit_graph.ts +156 -0
- package/backend/lib/database/migrations/012_add_file_change_statistics.ts +41 -0
- package/backend/lib/database/migrations/013_checkpoint_tree_state.ts +118 -0
- package/backend/lib/database/migrations/014_add_engine_to_sessions.ts +18 -0
- package/backend/lib/database/migrations/015_add_model_to_sessions.ts +18 -0
- package/backend/lib/database/migrations/016_create_user_projects_table.ts +34 -0
- package/backend/lib/database/migrations/017_add_current_session_to_user_projects.ts +32 -0
- package/backend/lib/database/migrations/018_create_claude_accounts_table.ts +24 -0
- package/backend/lib/database/migrations/019_add_claude_account_to_sessions.ts +18 -0
- package/backend/lib/database/migrations/020_add_snapshot_tree_hash.ts +32 -0
- package/backend/lib/database/migrations/021_drop_prompt_templates_table.ts +33 -0
- package/backend/lib/database/migrations/index.ts +154 -0
- package/backend/lib/database/queries/checkpoint-queries.ts +87 -0
- package/backend/lib/database/queries/engine-queries.ts +75 -0
- package/backend/lib/database/queries/index.ts +9 -0
- package/backend/lib/database/queries/message-queries.ts +472 -0
- package/backend/lib/database/queries/project-queries.ts +117 -0
- package/backend/lib/database/queries/session-queries.ts +271 -0
- package/backend/lib/database/queries/settings-queries.ts +34 -0
- package/backend/lib/database/queries/snapshot-queries.ts +326 -0
- package/backend/lib/database/queries/utils-queries.ts +59 -0
- package/backend/lib/database/seeders/index.ts +13 -0
- package/backend/lib/database/seeders/settings_seeder.ts +84 -0
- package/backend/lib/database/utils/connection.ts +174 -0
- package/backend/lib/database/utils/index.ts +4 -0
- package/backend/lib/database/utils/migration-runner.ts +118 -0
- package/backend/lib/database/utils/seeder-runner.ts +121 -0
- package/backend/lib/engine/adapters/claude/environment.ts +164 -0
- package/backend/lib/engine/adapters/claude/error-handler.ts +60 -0
- package/backend/lib/engine/adapters/claude/index.ts +1 -0
- package/backend/lib/engine/adapters/claude/path-utils.ts +38 -0
- package/backend/lib/engine/adapters/claude/stream.ts +177 -0
- package/backend/lib/engine/adapters/opencode/index.ts +2 -0
- package/backend/lib/engine/adapters/opencode/message-converter.ts +862 -0
- package/backend/lib/engine/adapters/opencode/server.ts +104 -0
- package/backend/lib/engine/adapters/opencode/stream.ts +755 -0
- package/backend/lib/engine/index.ts +196 -0
- package/backend/lib/engine/types.ts +58 -0
- package/backend/lib/files/file-operations.ts +478 -0
- package/backend/lib/files/file-reading.ts +308 -0
- package/backend/lib/files/file-watcher.ts +383 -0
- package/backend/lib/files/path-browsing.ts +382 -0
- package/backend/lib/git/git-executor.ts +88 -0
- package/backend/lib/git/git-parser.ts +411 -0
- package/backend/lib/git/git-service.ts +505 -0
- package/backend/lib/mcp/README.md +1144 -0
- package/backend/lib/mcp/config.ts +316 -0
- package/backend/lib/mcp/index.ts +35 -0
- package/backend/lib/mcp/project-context.ts +236 -0
- package/backend/lib/mcp/servers/browser-automation/actions.ts +156 -0
- package/backend/lib/mcp/servers/browser-automation/browser.ts +419 -0
- package/backend/lib/mcp/servers/browser-automation/index.ts +791 -0
- package/backend/lib/mcp/servers/browser-automation/inspection.ts +501 -0
- package/backend/lib/mcp/servers/helper.ts +143 -0
- package/backend/lib/mcp/servers/index.ts +45 -0
- package/backend/lib/mcp/servers/weather/get-temperature.ts +56 -0
- package/backend/lib/mcp/servers/weather/index.ts +31 -0
- package/backend/lib/mcp/stdio-server.ts +103 -0
- package/backend/lib/mcp/types.ts +65 -0
- package/backend/lib/preview/browser/browser-audio-capture.ts +86 -0
- package/backend/lib/preview/browser/browser-console-manager.ts +263 -0
- package/backend/lib/preview/browser/browser-dialog-handler.ts +222 -0
- package/backend/lib/preview/browser/browser-interaction-handler.ts +421 -0
- package/backend/lib/preview/browser/browser-mcp-control.ts +415 -0
- package/backend/lib/preview/browser/browser-native-ui-handler.ts +512 -0
- package/backend/lib/preview/browser/browser-navigation-tracker.ts +104 -0
- package/backend/lib/preview/browser/browser-pool.ts +357 -0
- package/backend/lib/preview/browser/browser-preview-service.ts +882 -0
- package/backend/lib/preview/browser/browser-tab-manager.ts +935 -0
- package/backend/lib/preview/browser/browser-video-capture.ts +695 -0
- package/backend/lib/preview/browser/scripts/audio-stream.ts +292 -0
- package/backend/lib/preview/browser/scripts/cursor-tracking.ts +85 -0
- package/backend/lib/preview/browser/scripts/video-stream.ts +438 -0
- package/backend/lib/preview/browser/types.ts +359 -0
- package/backend/lib/preview/index.ts +24 -0
- package/backend/lib/project/index.ts +2 -0
- package/backend/lib/project/status-manager.ts +182 -0
- package/backend/lib/shared/index.ts +2 -0
- package/backend/lib/shared/port-utils.ts +25 -0
- package/backend/lib/shared/process-manager.ts +281 -0
- package/backend/lib/snapshot/blob-store.ts +227 -0
- package/backend/lib/snapshot/gitignore.ts +307 -0
- package/backend/lib/snapshot/helpers.ts +397 -0
- package/backend/lib/snapshot/snapshot-service.ts +483 -0
- package/backend/lib/terminal/helpers.ts +14 -0
- package/backend/lib/terminal/index.ts +8 -0
- package/backend/lib/terminal/pty-manager.ts +4 -0
- package/backend/lib/terminal/pty-session-manager.ts +387 -0
- package/backend/lib/terminal/shell-utils.ts +313 -0
- package/backend/lib/terminal/stream-manager.ts +293 -0
- package/backend/lib/tunnel/global-tunnel-manager.ts +243 -0
- package/backend/lib/tunnel/project-tunnel-manager.ts +311 -0
- package/backend/lib/user/helpers.ts +87 -0
- package/backend/lib/utils/ws.ts +944 -0
- package/backend/lib/vite-dev.ts +353 -0
- package/backend/middleware/cors.ts +15 -0
- package/backend/middleware/error-handler.ts +49 -0
- package/backend/middleware/logger.ts +9 -0
- package/backend/types/api.ts +24 -0
- package/backend/ws/README.md +1505 -0
- package/backend/ws/chat/background.ts +198 -0
- package/backend/ws/chat/index.ts +21 -0
- package/backend/ws/chat/stream.ts +707 -0
- package/backend/ws/engine/claude/accounts.ts +401 -0
- package/backend/ws/engine/claude/index.ts +13 -0
- package/backend/ws/engine/claude/status.ts +43 -0
- package/backend/ws/engine/index.ts +14 -0
- package/backend/ws/engine/opencode/index.ts +11 -0
- package/backend/ws/engine/opencode/status.ts +30 -0
- package/backend/ws/engine/utils.ts +36 -0
- package/backend/ws/files/index.ts +30 -0
- package/backend/ws/files/read.ts +189 -0
- package/backend/ws/files/search.ts +453 -0
- package/backend/ws/files/watch.ts +124 -0
- package/backend/ws/files/write.ts +143 -0
- package/backend/ws/git/branch.ts +106 -0
- package/backend/ws/git/commit.ts +39 -0
- package/backend/ws/git/conflict.ts +68 -0
- package/backend/ws/git/diff.ts +69 -0
- package/backend/ws/git/index.ts +24 -0
- package/backend/ws/git/log.ts +41 -0
- package/backend/ws/git/remote.ts +214 -0
- package/backend/ws/git/staging.ts +84 -0
- package/backend/ws/git/status.ts +90 -0
- package/backend/ws/index.ts +69 -0
- package/backend/ws/mcp/index.ts +61 -0
- package/backend/ws/messages/crud.ts +74 -0
- package/backend/ws/messages/index.ts +14 -0
- package/backend/ws/preview/browser/cleanup.ts +129 -0
- package/backend/ws/preview/browser/console.ts +114 -0
- package/backend/ws/preview/browser/interact.ts +513 -0
- package/backend/ws/preview/browser/mcp.ts +129 -0
- package/backend/ws/preview/browser/native-ui.ts +235 -0
- package/backend/ws/preview/browser/stats.ts +55 -0
- package/backend/ws/preview/browser/tab-info.ts +126 -0
- package/backend/ws/preview/browser/tab.ts +166 -0
- package/backend/ws/preview/browser/webcodecs.ts +293 -0
- package/backend/ws/preview/index.ts +146 -0
- package/backend/ws/projects/crud.ts +113 -0
- package/backend/ws/projects/index.ts +25 -0
- package/backend/ws/projects/presence.ts +46 -0
- package/backend/ws/projects/status.ts +116 -0
- package/backend/ws/sessions/crud.ts +327 -0
- package/backend/ws/sessions/index.ts +33 -0
- package/backend/ws/settings/crud.ts +112 -0
- package/backend/ws/settings/index.ts +14 -0
- package/backend/ws/snapshot/index.ts +17 -0
- package/backend/ws/snapshot/restore.ts +173 -0
- package/backend/ws/snapshot/timeline.ts +141 -0
- package/backend/ws/system/index.ts +14 -0
- package/backend/ws/system/operations.ts +49 -0
- package/backend/ws/terminal/index.ts +40 -0
- package/backend/ws/terminal/persistence.ts +153 -0
- package/backend/ws/terminal/session.ts +382 -0
- package/backend/ws/terminal/stream.ts +79 -0
- package/backend/ws/tunnel/index.ts +14 -0
- package/backend/ws/tunnel/operations.ts +91 -0
- package/backend/ws/types.ts +20 -0
- package/backend/ws/user/crud.ts +156 -0
- package/backend/ws/user/index.ts +14 -0
- package/bin/clopen.ts +307 -0
- package/bun.lock +1352 -0
- package/frontend/App.svelte +34 -0
- package/frontend/app.css +313 -0
- package/frontend/lib/app-environment.ts +10 -0
- package/frontend/lib/components/chat/ChatInterface.svelte +407 -0
- package/frontend/lib/components/chat/formatters/ErrorMessage.svelte +57 -0
- package/frontend/lib/components/chat/formatters/MessageFormatter.svelte +224 -0
- package/frontend/lib/components/chat/formatters/TextMessage.svelte +395 -0
- package/frontend/lib/components/chat/formatters/Tools.svelte +70 -0
- package/frontend/lib/components/chat/formatters/index.ts +3 -0
- package/frontend/lib/components/chat/input/ChatInput.svelte +421 -0
- package/frontend/lib/components/chat/input/components/ChatInputActions.svelte +78 -0
- package/frontend/lib/components/chat/input/components/DragDropOverlay.svelte +30 -0
- package/frontend/lib/components/chat/input/components/EditModeIndicator.svelte +33 -0
- package/frontend/lib/components/chat/input/components/EngineModelPicker.svelte +619 -0
- package/frontend/lib/components/chat/input/components/FileAttachmentPreview.svelte +48 -0
- package/frontend/lib/components/chat/input/components/LoadingIndicator.svelte +31 -0
- package/frontend/lib/components/chat/input/composables/use-animations.svelte.ts +201 -0
- package/frontend/lib/components/chat/input/composables/use-chat-actions.svelte.ts +148 -0
- package/frontend/lib/components/chat/input/composables/use-file-handling.svelte.ts +216 -0
- package/frontend/lib/components/chat/input/composables/use-input-state.svelte.ts +357 -0
- package/frontend/lib/components/chat/input/composables/use-textarea-resize.svelte.ts +57 -0
- package/frontend/lib/components/chat/message/ChatMessage.svelte +478 -0
- package/frontend/lib/components/chat/message/ChatMessages.svelte +541 -0
- package/frontend/lib/components/chat/message/DateSeparator.svelte +86 -0
- package/frontend/lib/components/chat/message/MessageBubble.svelte +86 -0
- package/frontend/lib/components/chat/message/MessageHeader.svelte +157 -0
- package/frontend/lib/components/chat/modal/DebugModal.svelte +59 -0
- package/frontend/lib/components/chat/modal/TokenUsageModal.svelte +124 -0
- package/frontend/lib/components/chat/shared/index.ts +2 -0
- package/frontend/lib/components/chat/shared/utils.ts +116 -0
- package/frontend/lib/components/chat/tools/BashOutputTool.svelte +35 -0
- package/frontend/lib/components/chat/tools/BashTool.svelte +46 -0
- package/frontend/lib/components/chat/tools/CustomMcpTool.svelte +139 -0
- package/frontend/lib/components/chat/tools/EditTool.svelte +48 -0
- package/frontend/lib/components/chat/tools/ExitPlanModeTool.svelte +32 -0
- package/frontend/lib/components/chat/tools/GlobTool.svelte +51 -0
- package/frontend/lib/components/chat/tools/GrepTool.svelte +90 -0
- package/frontend/lib/components/chat/tools/KillShellTool.svelte +26 -0
- package/frontend/lib/components/chat/tools/ListMcpResourcesTool.svelte +31 -0
- package/frontend/lib/components/chat/tools/NotebookEditTool.svelte +38 -0
- package/frontend/lib/components/chat/tools/ReadMcpResourceTool.svelte +34 -0
- package/frontend/lib/components/chat/tools/ReadTool.svelte +41 -0
- package/frontend/lib/components/chat/tools/TaskTool.svelte +64 -0
- package/frontend/lib/components/chat/tools/TodoWriteTool.svelte +75 -0
- package/frontend/lib/components/chat/tools/WebFetchTool.svelte +35 -0
- package/frontend/lib/components/chat/tools/WebSearchTool.svelte +84 -0
- package/frontend/lib/components/chat/tools/WriteTool.svelte +33 -0
- package/frontend/lib/components/chat/tools/components/CodeBlock.svelte +79 -0
- package/frontend/lib/components/chat/tools/components/DiffBlock.svelte +408 -0
- package/frontend/lib/components/chat/tools/components/FileHeader.svelte +45 -0
- package/frontend/lib/components/chat/tools/components/InfoLine.svelte +19 -0
- package/frontend/lib/components/chat/tools/components/StatsBadges.svelte +27 -0
- package/frontend/lib/components/chat/tools/components/TerminalCommand.svelte +54 -0
- package/frontend/lib/components/chat/tools/components/index.ts +7 -0
- package/frontend/lib/components/chat/tools/index.ts +26 -0
- package/frontend/lib/components/chat/widgets/FloatingTodoList.svelte +249 -0
- package/frontend/lib/components/chat/widgets/TokenUsage.svelte +78 -0
- package/frontend/lib/components/checkpoint/TimelineModal.svelte +391 -0
- package/frontend/lib/components/checkpoint/timeline/TimelineEdge.svelte +26 -0
- package/frontend/lib/components/checkpoint/timeline/TimelineGraph.svelte +87 -0
- package/frontend/lib/components/checkpoint/timeline/TimelineNode.svelte +108 -0
- package/frontend/lib/components/checkpoint/timeline/TimelineVersionGroup.svelte +59 -0
- package/frontend/lib/components/checkpoint/timeline/animation.ts +168 -0
- package/frontend/lib/components/checkpoint/timeline/config.ts +44 -0
- package/frontend/lib/components/checkpoint/timeline/graph-builder.ts +304 -0
- package/frontend/lib/components/checkpoint/timeline/types.ts +65 -0
- package/frontend/lib/components/checkpoint/timeline/utils.ts +53 -0
- package/frontend/lib/components/common/Alert.svelte +139 -0
- package/frontend/lib/components/common/AvatarBubble.svelte +56 -0
- package/frontend/lib/components/common/Button.svelte +71 -0
- package/frontend/lib/components/common/Card.svelte +102 -0
- package/frontend/lib/components/common/Checkbox.svelte +48 -0
- package/frontend/lib/components/common/Dialog.svelte +249 -0
- package/frontend/lib/components/common/FolderBrowser.svelte +843 -0
- package/frontend/lib/components/common/Icon.svelte +58 -0
- package/frontend/lib/components/common/Input.svelte +72 -0
- package/frontend/lib/components/common/Lightbox.svelte +233 -0
- package/frontend/lib/components/common/LoadingScreen.svelte +52 -0
- package/frontend/lib/components/common/LoadingSpinner.svelte +48 -0
- package/frontend/lib/components/common/Modal.svelte +177 -0
- package/frontend/lib/components/common/ModalProvider.svelte +28 -0
- package/frontend/lib/components/common/ModelSelector.svelte +110 -0
- package/frontend/lib/components/common/MonacoEditor.svelte +569 -0
- package/frontend/lib/components/common/NotificationToast.svelte +113 -0
- package/frontend/lib/components/common/PageTemplate.svelte +76 -0
- package/frontend/lib/components/common/ProjectUserAvatars.svelte +79 -0
- package/frontend/lib/components/common/Select.svelte +98 -0
- package/frontend/lib/components/common/Textarea.svelte +80 -0
- package/frontend/lib/components/common/ThemeToggle.svelte +44 -0
- package/frontend/lib/components/common/lucide-icons.ts +1642 -0
- package/frontend/lib/components/common/material-icons.ts +1082 -0
- package/frontend/lib/components/common/xterm/XTerm.svelte +796 -0
- package/frontend/lib/components/common/xterm/index.ts +16 -0
- package/frontend/lib/components/common/xterm/terminal-config.ts +68 -0
- package/frontend/lib/components/common/xterm/types.ts +31 -0
- package/frontend/lib/components/common/xterm/xterm-service.ts +353 -0
- package/frontend/lib/components/files/FileNode.svelte +384 -0
- package/frontend/lib/components/files/FileTree.svelte +681 -0
- package/frontend/lib/components/files/FileViewer.svelte +728 -0
- package/frontend/lib/components/files/SearchResults.svelte +303 -0
- package/frontend/lib/components/git/BranchManager.svelte +458 -0
- package/frontend/lib/components/git/ChangesSection.svelte +107 -0
- package/frontend/lib/components/git/CommitForm.svelte +76 -0
- package/frontend/lib/components/git/ConflictResolver.svelte +158 -0
- package/frontend/lib/components/git/DiffViewer.svelte +364 -0
- package/frontend/lib/components/git/FileChangeItem.svelte +97 -0
- package/frontend/lib/components/git/GitButton.svelte +33 -0
- package/frontend/lib/components/git/GitLog.svelte +361 -0
- package/frontend/lib/components/git/GitModal.svelte +80 -0
- package/frontend/lib/components/history/HistoryModal.svelte +563 -0
- package/frontend/lib/components/history/HistoryView.svelte +615 -0
- package/frontend/lib/components/index.ts +34 -0
- package/frontend/lib/components/preview/browser/BrowserPreview.svelte +549 -0
- package/frontend/lib/components/preview/browser/components/Canvas.svelte +1058 -0
- package/frontend/lib/components/preview/browser/components/ConsolePanel.svelte +757 -0
- package/frontend/lib/components/preview/browser/components/Container.svelte +450 -0
- package/frontend/lib/components/preview/browser/components/ContextMenu.svelte +236 -0
- package/frontend/lib/components/preview/browser/components/SelectDropdown.svelte +224 -0
- package/frontend/lib/components/preview/browser/components/Toolbar.svelte +339 -0
- package/frontend/lib/components/preview/browser/components/VirtualCursor.svelte +36 -0
- package/frontend/lib/components/preview/browser/core/cleanup.svelte.ts +155 -0
- package/frontend/lib/components/preview/browser/core/coordinator.svelte.ts +837 -0
- package/frontend/lib/components/preview/browser/core/interactions.svelte.ts +113 -0
- package/frontend/lib/components/preview/browser/core/mcp-handlers.svelte.ts +296 -0
- package/frontend/lib/components/preview/browser/core/native-ui-handlers.svelte.ts +391 -0
- package/frontend/lib/components/preview/browser/core/stream-handler.svelte.ts +231 -0
- package/frontend/lib/components/preview/browser/core/tab-manager.svelte.ts +210 -0
- package/frontend/lib/components/preview/browser/core/tab-operations.svelte.ts +239 -0
- package/frontend/lib/components/preview/index.ts +2 -0
- package/frontend/lib/components/settings/SettingsModal.svelte +235 -0
- package/frontend/lib/components/settings/SettingsView.svelte +36 -0
- package/frontend/lib/components/settings/appearance/AppearanceSettings.svelte +51 -0
- package/frontend/lib/components/settings/appearance/LayoutPresetSettings.svelte +160 -0
- package/frontend/lib/components/settings/appearance/LayoutPreview.svelte +76 -0
- package/frontend/lib/components/settings/engines/AIEnginesSettings.svelte +917 -0
- package/frontend/lib/components/settings/general/AdvancedSettings.svelte +187 -0
- package/frontend/lib/components/settings/general/DataManagementSettings.svelte +203 -0
- package/frontend/lib/components/settings/general/GeneralSettings.svelte +10 -0
- package/frontend/lib/components/settings/model/ModelSettings.svelte +357 -0
- package/frontend/lib/components/settings/notifications/NotificationSettings.svelte +205 -0
- package/frontend/lib/components/settings/user/UserSettings.svelte +197 -0
- package/frontend/lib/components/terminal/Terminal.svelte +368 -0
- package/frontend/lib/components/terminal/TerminalTabs.svelte +87 -0
- package/frontend/lib/components/terminal/TerminalView.svelte +55 -0
- package/frontend/lib/components/tunnel/TunnelActive.svelte +142 -0
- package/frontend/lib/components/tunnel/TunnelButton.svelte +54 -0
- package/frontend/lib/components/tunnel/TunnelInactive.svelte +284 -0
- package/frontend/lib/components/tunnel/TunnelModal.svelte +47 -0
- package/frontend/lib/components/tunnel/TunnelQRCode.svelte +49 -0
- package/frontend/lib/components/workspace/DesktopNavigator.svelte +382 -0
- package/frontend/lib/components/workspace/MobileNavigator.svelte +403 -0
- package/frontend/lib/components/workspace/PanelContainer.svelte +100 -0
- package/frontend/lib/components/workspace/PanelHeader.svelte +505 -0
- package/frontend/lib/components/workspace/ViewMenu.svelte +162 -0
- package/frontend/lib/components/workspace/WorkspaceLayout.svelte +169 -0
- package/frontend/lib/components/workspace/layout/DesktopLayout.svelte +15 -0
- package/frontend/lib/components/workspace/layout/MobileLayout.svelte +17 -0
- package/frontend/lib/components/workspace/layout/split-pane/Container.svelte +42 -0
- package/frontend/lib/components/workspace/layout/split-pane/Handle.svelte +85 -0
- package/frontend/lib/components/workspace/layout/split-pane/Layout.svelte +37 -0
- package/frontend/lib/components/workspace/panels/ChatPanel.svelte +274 -0
- package/frontend/lib/components/workspace/panels/FilesPanel.svelte +1261 -0
- package/frontend/lib/components/workspace/panels/GitPanel.svelte +1560 -0
- package/frontend/lib/components/workspace/panels/PreviewPanel.svelte +150 -0
- package/frontend/lib/components/workspace/panels/TerminalPanel.svelte +73 -0
- package/frontend/lib/constants/preview.ts +45 -0
- package/frontend/lib/services/chat/chat.service.ts +704 -0
- package/frontend/lib/services/chat/index.ts +7 -0
- package/frontend/lib/services/notification/global-stream-monitor.ts +86 -0
- package/frontend/lib/services/notification/index.ts +8 -0
- package/frontend/lib/services/notification/push.service.ts +144 -0
- package/frontend/lib/services/notification/sound.service.ts +127 -0
- package/frontend/lib/services/preview/browser/browser-console.service.ts +61 -0
- package/frontend/lib/services/preview/browser/browser-webcodecs.service.ts +1499 -0
- package/frontend/lib/services/preview/browser/mcp-integration.svelte.ts +67 -0
- package/frontend/lib/services/preview/index.ts +23 -0
- package/frontend/lib/services/project/index.ts +8 -0
- package/frontend/lib/services/project/status.service.ts +159 -0
- package/frontend/lib/services/snapshot/snapshot.service.ts +47 -0
- package/frontend/lib/services/terminal/background/index.ts +130 -0
- package/frontend/lib/services/terminal/background/session-restore.ts +274 -0
- package/frontend/lib/services/terminal/background/stream-manager.ts +286 -0
- package/frontend/lib/services/terminal/index.ts +14 -0
- package/frontend/lib/services/terminal/persistence.service.ts +260 -0
- package/frontend/lib/services/terminal/project.service.ts +953 -0
- package/frontend/lib/services/terminal/session.service.ts +364 -0
- package/frontend/lib/services/terminal/terminal.service.ts +369 -0
- package/frontend/lib/stores/core/app.svelte.ts +117 -0
- package/frontend/lib/stores/core/files.svelte.ts +73 -0
- package/frontend/lib/stores/core/presence.svelte.ts +48 -0
- package/frontend/lib/stores/core/projects.svelte.ts +317 -0
- package/frontend/lib/stores/core/sessions.svelte.ts +383 -0
- package/frontend/lib/stores/features/claude-accounts.svelte.ts +58 -0
- package/frontend/lib/stores/features/models.svelte.ts +89 -0
- package/frontend/lib/stores/features/settings.svelte.ts +87 -0
- package/frontend/lib/stores/features/terminal.svelte.ts +701 -0
- package/frontend/lib/stores/features/tunnel.svelte.ts +161 -0
- package/frontend/lib/stores/features/user.svelte.ts +96 -0
- package/frontend/lib/stores/ui/chat-input.svelte.ts +57 -0
- package/frontend/lib/stores/ui/chat-model.svelte.ts +61 -0
- package/frontend/lib/stores/ui/dialog.svelte.ts +59 -0
- package/frontend/lib/stores/ui/edit-mode.svelte.ts +214 -0
- package/frontend/lib/stores/ui/notification.svelte.ts +166 -0
- package/frontend/lib/stores/ui/settings-modal.svelte.ts +88 -0
- package/frontend/lib/stores/ui/theme.svelte.ts +179 -0
- package/frontend/lib/stores/ui/workspace.svelte.ts +754 -0
- package/frontend/lib/types/native-ui.ts +73 -0
- package/frontend/lib/utils/chat/date-separator.ts +39 -0
- package/frontend/lib/utils/chat/message-grouper.ts +219 -0
- package/frontend/lib/utils/chat/message-processor.ts +135 -0
- package/frontend/lib/utils/chat/tool-handler.ts +161 -0
- package/frontend/lib/utils/chat/virtual-scroll.svelte.ts +142 -0
- package/frontend/lib/utils/click-outside.ts +20 -0
- package/frontend/lib/utils/context-manager.ts +257 -0
- package/frontend/lib/utils/file-icon-mappings.ts +769 -0
- package/frontend/lib/utils/folder-icon-mappings.ts +1030 -0
- package/frontend/lib/utils/git-status.ts +68 -0
- package/frontend/lib/utils/platform.ts +113 -0
- package/frontend/lib/utils/port-check.ts +65 -0
- package/frontend/lib/utils/terminalFormatter.ts +207 -0
- package/frontend/lib/utils/theme.ts +6 -0
- package/frontend/lib/utils/tree-visualizer.ts +320 -0
- package/frontend/lib/utils/ws.ts +44 -0
- package/frontend/main.ts +13 -0
- package/index.html +70 -0
- package/package.json +111 -0
- package/scripts/generate-icons.ts +87 -0
- package/scripts/pre-publish-check.sh +142 -0
- package/scripts/setup-hooks.sh +134 -0
- package/scripts/validate-branch-name.sh +47 -0
- package/scripts/validate-commit-msg.sh +42 -0
- package/shared/constants/engines.ts +134 -0
- package/shared/types/database/connection.ts +16 -0
- package/shared/types/database/index.ts +6 -0
- package/shared/types/database/schema.ts +141 -0
- package/shared/types/engine/index.ts +45 -0
- package/shared/types/filesystem/index.ts +22 -0
- package/shared/types/git.ts +171 -0
- package/shared/types/messaging/index.ts +239 -0
- package/shared/types/messaging/tool.ts +526 -0
- package/shared/types/network/api.ts +18 -0
- package/shared/types/network/index.ts +5 -0
- package/shared/types/stores/app.ts +23 -0
- package/shared/types/stores/dialog.ts +21 -0
- package/shared/types/stores/index.ts +3 -0
- package/shared/types/stores/settings.ts +15 -0
- package/shared/types/terminal/index.ts +44 -0
- package/shared/types/ui/components.ts +61 -0
- package/shared/types/ui/icons.ts +23 -0
- package/shared/types/ui/index.ts +22 -0
- package/shared/types/ui/notifications.ts +14 -0
- package/shared/types/ui/theme.ts +12 -0
- package/shared/types/websocket/index.ts +43 -0
- package/shared/types/window.d.ts +13 -0
- package/shared/utils/anonymous-user.ts +168 -0
- package/shared/utils/async.ts +10 -0
- package/shared/utils/diff-calculator.ts +184 -0
- package/shared/utils/file-type-detection.ts +166 -0
- package/shared/utils/logger.ts +158 -0
- package/shared/utils/message-formatter.ts +79 -0
- package/shared/utils/path.ts +47 -0
- package/shared/utils/ws-client.ts +768 -0
- package/shared/utils/ws-server.ts +660 -0
- package/static/audio/notification.ogg +0 -0
- package/static/favicon.svg +8 -0
- package/static/fonts/dm-sans/dm-sans-italic-latin-ext.woff2 +0 -0
- package/static/fonts/dm-sans/dm-sans-italic-latin.woff2 +0 -0
- package/static/fonts/dm-sans/dm-sans-normal-latin-ext.woff2 +0 -0
- package/static/fonts/dm-sans/dm-sans-normal-latin.woff2 +0 -0
- package/static/fonts/dm-sans.css +96 -0
- package/svelte.config.js +20 -0
- package/vite.config.ts +33 -0
package/README.md
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# 🎯 Clopen
|
|
2
|
+
|
|
3
|
+
> All-in-one web workspace for Claude Code & OpenCode
|
|
4
|
+
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://bun.sh)
|
|
7
|
+
|
|
8
|
+
**Clopen** provides a modern web interface for AI-assisted development, supporting both **Claude Code** and **OpenCode** as AI engines. It runs as a standalone web application — manage multiple Claude Code accounts, use built-in git source control, preview your app in a real browser, edit files, collaborate in real-time, and never lose progress with git-like checkpoints.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## ✨ Features
|
|
13
|
+
|
|
14
|
+
- 👤 **Multi-Account Claude Code** - Manage multiple accounts (personal, work, team) and switch instantly per session, isolated under `~/.clopen/claude/user/` without touching system-level Claude config
|
|
15
|
+
- 🔀 **Multi-Engine Support** - Switch between Claude Code and OpenCode
|
|
16
|
+
- 💬 **AI Chat Interface** - Streaming responses with tool use visualization
|
|
17
|
+
- 🔄 **Background Processing** - Chat, terminal, and other processes continue running even when you close the browser — come back later and pick up where you left off
|
|
18
|
+
- 🌿 **Git-like Checkpoints** - Multi-branch undo/redo system with file and folder snapshots
|
|
19
|
+
- 🌐 **Real Browser Preview** - Puppeteer-based Chromium rendering with WebCodecs streaming (80-90% bandwidth reduction), full click/type/scroll/drag interaction
|
|
20
|
+
- 💻 **Integrated Terminal** - Multi-tab terminal with full PTY control
|
|
21
|
+
- 📁 **File Management** - Directory browsing, live editing, and real-time file watching
|
|
22
|
+
- 🗂️ **Git Management** - Full source control: staging, commits, branches, push/pull, stash, log, conflict resolution
|
|
23
|
+
- 👥 **Real-time Collaboration** - Multiple users can work on the same project simultaneously
|
|
24
|
+
- 🚇 **Built-in Cloudflare Tunnel** - Expose local projects publicly for testing and sharing
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 🚀 Quick Start
|
|
28
|
+
|
|
29
|
+
### Prerequisites
|
|
30
|
+
|
|
31
|
+
- [Bun](https://bun.sh/) v1.2.12 or higher
|
|
32
|
+
- [Claude Code](https://github.com/anthropics/claude-code) and/or [OpenCode](https://opencode.ai) — required for AI chat functionality
|
|
33
|
+
|
|
34
|
+
### Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
bun add -g clopen
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
This installs dependencies, builds the frontend, and makes the `clopen` command available globally.
|
|
41
|
+
|
|
42
|
+
### Usage
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
clopen
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
On first run, Clopen creates `.env` from `.env.example`, verifies the build, and starts the server on `http://localhost:9141`.
|
|
49
|
+
|
|
50
|
+
**Configuration** — edit `.env` to customize:
|
|
51
|
+
```bash
|
|
52
|
+
PORT=9141 # Server port
|
|
53
|
+
NODE_ENV=production # Environment mode
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 🛠️ Development
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
git clone https://github.com/myrialabs/clopen.git
|
|
62
|
+
cd clopen
|
|
63
|
+
bun install
|
|
64
|
+
bun run dev # Start development server
|
|
65
|
+
bun run check # Type checking
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## 📚 Architecture
|
|
71
|
+
|
|
72
|
+
| Layer | Technology |
|
|
73
|
+
|-------|-----------|
|
|
74
|
+
| Runtime | Bun.js |
|
|
75
|
+
| Frontend | Svelte 5 (runes) + Vite |
|
|
76
|
+
| Backend | Elysia + WebSocket |
|
|
77
|
+
| Styling | Tailwind CSS v4 |
|
|
78
|
+
| Database | SQLite with migrations |
|
|
79
|
+
| Terminal | bun-pty |
|
|
80
|
+
| AI Engines | Claude Code + OpenCode |
|
|
81
|
+
|
|
82
|
+
### Engine Architecture
|
|
83
|
+
|
|
84
|
+
Clopen uses an engine-agnostic adapter pattern — the frontend and stream manager are not tied to any specific AI tool:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
┌─────────────────────────────────────────┐
|
|
88
|
+
│ Stream Manager │
|
|
89
|
+
└──────────────┬──────────────────────────┘
|
|
90
|
+
│
|
|
91
|
+
┌───────┴───────┐
|
|
92
|
+
▼ ▼
|
|
93
|
+
ClaudeCodeEngine OpenCodeEngine
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Both engines normalize output to Claude SDK message format, ensuring a consistent experience regardless of which engine is selected.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 🛣️ Planned Features
|
|
101
|
+
|
|
102
|
+
- [ ] **Configurable MCP Servers** - Add, remove, enable, and disable Model Context Protocol servers through the UI
|
|
103
|
+
- [ ] **Built-in Database Management** - Adminer/TablePlus-like interface
|
|
104
|
+
- [ ] **Additional Preview Platforms** - Android, iOS, and Desktop app preview
|
|
105
|
+
- [ ] **Enhanced Collaboration** - User authentication and permissions
|
|
106
|
+
- [ ] **Plugin System** - Extensible architecture for community plugins
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## 📖 Documentation
|
|
111
|
+
|
|
112
|
+
- [Technical Decisions](DECISIONS.md) - Architectural and technical decision log
|
|
113
|
+
- [Development Guidelines](CLAUDE.md) - Guidelines for working with Claude Code on this project
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## 🤝 Contributing
|
|
118
|
+
|
|
119
|
+
1. Fork the repository
|
|
120
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
121
|
+
3. Make your changes
|
|
122
|
+
4. Run `bun run check` to ensure code quality
|
|
123
|
+
5. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
124
|
+
6. Push to the branch (`git push origin feature/amazing-feature`)
|
|
125
|
+
7. Open a Pull Request
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## 🐛 Troubleshooting
|
|
130
|
+
|
|
131
|
+
### Port 9141 Already in Use
|
|
132
|
+
|
|
133
|
+
Use a different port:
|
|
134
|
+
```bash
|
|
135
|
+
clopen --port 9150
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Or kill the existing process:
|
|
139
|
+
```bash
|
|
140
|
+
# Unix/Linux/macOS
|
|
141
|
+
lsof -ti:9141 | xargs kill -9
|
|
142
|
+
|
|
143
|
+
# Windows
|
|
144
|
+
netstat -ano | findstr :9141
|
|
145
|
+
taskkill /PID <PID> /F
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Claude Code Not Found
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# macOS / Linux / WSL
|
|
152
|
+
curl -fsSL https://claude.ai/install.sh | bash
|
|
153
|
+
|
|
154
|
+
# Windows PowerShell
|
|
155
|
+
irm https://claude.ai/install.ps1 | iex
|
|
156
|
+
|
|
157
|
+
# Verify
|
|
158
|
+
claude --version
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
For complete installation instructions, visit the [official setup guide](https://code.claude.com/docs/en/quickstart).
|
|
162
|
+
|
|
163
|
+
### OpenCode Not Found
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
# macOS / Linux / WSL
|
|
167
|
+
curl -fsSL https://opencode.ai/install | bash
|
|
168
|
+
|
|
169
|
+
# Bun
|
|
170
|
+
bun add -g opencode-ai
|
|
171
|
+
|
|
172
|
+
# Verify
|
|
173
|
+
opencode --version
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
For complete installation instructions, visit the [official documentation](https://opencode.ai/docs).
|
|
177
|
+
|
|
178
|
+
### Browser Preview Issues
|
|
179
|
+
|
|
180
|
+
Browser sessions are automatically managed via Puppeteer's APIs and cleaned up when the preview is closed, the application exits, or the session times out.
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## 📄 License
|
|
185
|
+
|
|
186
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## 🙏 Acknowledgments
|
|
191
|
+
|
|
192
|
+
- [Claude Code](https://github.com/anthropics/claude-code) by Anthropic
|
|
193
|
+
- [OpenCode](https://opencode.ai) by SST
|
|
194
|
+
- [Bun](https://bun.sh/) runtime
|
|
195
|
+
- [Svelte](https://svelte.dev/) framework
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## 🔗 Links
|
|
200
|
+
|
|
201
|
+
- **Repository:** [github.com/myrialabs/clopen](https://github.com/myrialabs/clopen)
|
|
202
|
+
- **Organization:** [MyriaLabs](https://github.com/myrialabs)
|
|
203
|
+
- **Issues:** [Report a bug or request a feature](https://github.com/myrialabs/clopen/issues)
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
<div align="center">
|
|
208
|
+
<sub>Built with ❤️ by MyriaLabs</sub>
|
|
209
|
+
</div>
|
package/backend/index.ts
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { Elysia } from 'elysia';
|
|
3
|
+
import { staticPlugin } from '@elysiajs/static';
|
|
4
|
+
import { corsMiddleware } from './middleware/cors';
|
|
5
|
+
import { errorHandlerMiddleware } from './middleware/error-handler';
|
|
6
|
+
import { loggerMiddleware } from './middleware/logger';
|
|
7
|
+
|
|
8
|
+
// Database initialization
|
|
9
|
+
import { initializeDatabase, closeDatabase } from './lib/database';
|
|
10
|
+
import { disposeAllEngines } from './lib/engine';
|
|
11
|
+
import { debug } from '$shared/utils/logger';
|
|
12
|
+
import { isPortInUse } from './lib/shared/port-utils';
|
|
13
|
+
import { networkInterfaces } from 'os';
|
|
14
|
+
|
|
15
|
+
// Import WebSocket router
|
|
16
|
+
import { wsRouter } from './ws';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Clopen - Elysia Backend Server
|
|
20
|
+
*
|
|
21
|
+
* Single port: 9141 for everything.
|
|
22
|
+
* Development: Vite embedded as middleware (no separate server)
|
|
23
|
+
* Production: Serves frontend static files + API
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
function getLocalIps(): string[] {
|
|
27
|
+
const ips: string[] = [];
|
|
28
|
+
for (const ifaces of Object.values(networkInterfaces())) {
|
|
29
|
+
for (const iface of ifaces ?? []) {
|
|
30
|
+
if (iface.family === 'IPv4' && !iface.internal) ips.push(iface.address);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return ips;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const isDevelopment = process.env.NODE_ENV !== 'production';
|
|
37
|
+
const PORT = process.env.PORT ? parseInt(process.env.PORT) : 9141;
|
|
38
|
+
const HOST = process.env.HOST || 'localhost';
|
|
39
|
+
|
|
40
|
+
// Create Elysia app
|
|
41
|
+
const app = new Elysia()
|
|
42
|
+
// Apply middleware
|
|
43
|
+
.use(corsMiddleware)
|
|
44
|
+
.use(errorHandlerMiddleware)
|
|
45
|
+
.use(loggerMiddleware)
|
|
46
|
+
|
|
47
|
+
// Health check endpoint
|
|
48
|
+
.get('/health', () => ({
|
|
49
|
+
status: 'ok',
|
|
50
|
+
timestamp: new Date().toISOString(),
|
|
51
|
+
environment: process.env.NODE_ENV || 'development'
|
|
52
|
+
}))
|
|
53
|
+
|
|
54
|
+
// Mount WebSocket router (all functionality now via WebSocket)
|
|
55
|
+
.use(wsRouter.asPlugin('/ws'));
|
|
56
|
+
|
|
57
|
+
if (isDevelopment) {
|
|
58
|
+
// Development: Embed Vite as middleware — no separate port
|
|
59
|
+
// Uses Vite's direct APIs (transformIndexHtml, transformRequest) for speed,
|
|
60
|
+
// with Node.js compat middleware only as fallback for edge cases.
|
|
61
|
+
const { initViteDev, handleDevRequest, closeViteDev } = await import('./lib/vite-dev');
|
|
62
|
+
const vite = await initViteDev();
|
|
63
|
+
|
|
64
|
+
app.all('/*', async ({ request }) => handleDevRequest(vite, request));
|
|
65
|
+
|
|
66
|
+
// Store cleanup function for graceful shutdown
|
|
67
|
+
(globalThis as any).__closeViteDev = closeViteDev;
|
|
68
|
+
} else {
|
|
69
|
+
// Production: Serve static frontend files
|
|
70
|
+
app.use(
|
|
71
|
+
staticPlugin({
|
|
72
|
+
assets: './dist',
|
|
73
|
+
prefix: '/'
|
|
74
|
+
})
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
// SPA fallback: serve index.html for all non-file routes
|
|
78
|
+
// Pass BunFile directly (not .stream()) so Bun sets Content-Length automatically
|
|
79
|
+
app.all('/*', async () => {
|
|
80
|
+
return new Response(Bun.file('./dist/index.html'), {
|
|
81
|
+
headers: { 'Content-Type': 'text/html; charset=utf-8' }
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Start server with proper initialization sequence
|
|
88
|
+
async function startServer() {
|
|
89
|
+
// Strict check: refuse to start if port is already in use
|
|
90
|
+
if (await isPortInUse(PORT)) {
|
|
91
|
+
console.error(`❌ Port ${PORT} is already in use. Please close the existing process first.`);
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Initialize database first before accepting connections
|
|
96
|
+
try {
|
|
97
|
+
await initializeDatabase();
|
|
98
|
+
debug.log('database', '✅ Database initialized successfully');
|
|
99
|
+
} catch (error) {
|
|
100
|
+
debug.warn('database', '⚠️ Database initialization failed:', error);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Start listening after database is ready
|
|
104
|
+
app.listen({
|
|
105
|
+
port: PORT,
|
|
106
|
+
hostname: HOST
|
|
107
|
+
}, () => {
|
|
108
|
+
console.log(`🚀 Clopen running at http://localhost:${PORT}`);
|
|
109
|
+
if (HOST === '0.0.0.0') {
|
|
110
|
+
const ips = getLocalIps();
|
|
111
|
+
for (const ip of ips) {
|
|
112
|
+
console.log(`🌐 Network access: http://${ip}:${PORT}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
startServer().catch((error) => {
|
|
119
|
+
console.error('❌ Failed to start server:', error);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// Graceful shutdown - properly close server and database
|
|
124
|
+
async function gracefulShutdown() {
|
|
125
|
+
console.log('\n🛑 Shutting down server...');
|
|
126
|
+
try {
|
|
127
|
+
// Close Vite dev server if running
|
|
128
|
+
if (isDevelopment && (globalThis as any).__closeViteDev) {
|
|
129
|
+
await (globalThis as any).__closeViteDev();
|
|
130
|
+
}
|
|
131
|
+
// Dispose all AI engines
|
|
132
|
+
await disposeAllEngines();
|
|
133
|
+
// Stop accepting new connections
|
|
134
|
+
app.stop();
|
|
135
|
+
// Close database connection
|
|
136
|
+
closeDatabase();
|
|
137
|
+
debug.log('server', '✅ Graceful shutdown completed');
|
|
138
|
+
} catch (error) {
|
|
139
|
+
debug.error('server', '❌ Error during shutdown:', error);
|
|
140
|
+
}
|
|
141
|
+
process.exit(0);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
process.on('SIGINT', gracefulShutdown);
|
|
145
|
+
process.on('SIGTERM', gracefulShutdown);
|
|
146
|
+
|
|
147
|
+
// Safety net: prevent server crash from unhandled errors.
|
|
148
|
+
// These can occur when AI engine SDKs emit asynchronous errors that bypass
|
|
149
|
+
// the normal try/catch flow (e.g., subprocess killed during initialization).
|
|
150
|
+
process.on('unhandledRejection', (reason) => {
|
|
151
|
+
debug.error('server', 'Unhandled promise rejection (server still running):', reason);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
process.on('uncaughtException', (error) => {
|
|
155
|
+
debug.error('server', 'Uncaught exception (server still running):', error);
|
|
156
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { messageQueries } from '../database/queries';
|
|
2
|
+
import { debug } from '$shared/utils/logger';
|
|
3
|
+
import type { SDKMessage, ClaudeStreamRequest } from '$shared/types/messaging';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Bun-compatible existsSync implementation
|
|
7
|
+
*/
|
|
8
|
+
export async function existsSync(filePath: string): Promise<boolean> {
|
|
9
|
+
try {
|
|
10
|
+
const file = Bun.file(filePath);
|
|
11
|
+
await file.stat();
|
|
12
|
+
return true;
|
|
13
|
+
} catch {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* In-memory storage for stream sessions (in production, use Redis or database)
|
|
20
|
+
*/
|
|
21
|
+
export const sessionStore = new Map<string, ClaudeStreamRequest>();
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Track active connections to prevent duplicates
|
|
25
|
+
*/
|
|
26
|
+
export const activeConnections = new Map<string, string>(); // streamId -> connectionId
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Save message to database using database function with current timestamp
|
|
30
|
+
*/
|
|
31
|
+
export async function saveMessageToDatabase(message: SDKMessage, sessionId: string, timestamp?: string): Promise<void> {
|
|
32
|
+
try {
|
|
33
|
+
messageQueries.create({
|
|
34
|
+
session_id: sessionId,
|
|
35
|
+
sdk_message: message,
|
|
36
|
+
timestamp: timestamp || new Date().toISOString()
|
|
37
|
+
});
|
|
38
|
+
} catch (error) {
|
|
39
|
+
debug.error('chat', 'Failed to save message to database:', error);
|
|
40
|
+
// Don't throw - we don't want message saving to break the stream
|
|
41
|
+
}
|
|
42
|
+
}
|