@myrialabs/clopen 0.0.5 → 0.0.6
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 +5 -5
- package/.github/workflows/ci.yml +86 -86
- package/CONTRIBUTING.md +499 -499
- package/LICENSE +21 -21
- package/README.md +209 -209
- package/backend/index.ts +168 -165
- package/backend/lib/chat/helpers.ts +42 -42
- package/backend/lib/chat/index.ts +1 -1
- package/backend/lib/chat/stream-manager.ts +1126 -1126
- package/backend/lib/database/README.md +76 -76
- package/backend/lib/database/index.ts +118 -118
- package/backend/lib/database/migrations/001_create_projects_table.ts +30 -30
- package/backend/lib/database/migrations/002_create_chat_sessions_table.ts +32 -32
- package/backend/lib/database/migrations/003_create_messages_table.ts +31 -31
- package/backend/lib/database/migrations/004_create_prompt_templates_table.ts +34 -34
- package/backend/lib/database/migrations/005_create_settings_table.ts +23 -23
- package/backend/lib/database/migrations/006_add_user_to_messages.ts +57 -57
- package/backend/lib/database/migrations/007_create_stream_states_table.ts +40 -40
- package/backend/lib/database/migrations/008_create_message_snapshots_table.ts +61 -61
- package/backend/lib/database/migrations/009_add_delta_snapshot_fields.ts +41 -41
- package/backend/lib/database/migrations/010_add_soft_delete_and_branch_support.ts +70 -70
- package/backend/lib/database/migrations/011_git_like_commit_graph.ts +156 -156
- package/backend/lib/database/migrations/012_add_file_change_statistics.ts +41 -41
- package/backend/lib/database/migrations/013_checkpoint_tree_state.ts +118 -118
- package/backend/lib/database/migrations/014_add_engine_to_sessions.ts +18 -18
- package/backend/lib/database/migrations/015_add_model_to_sessions.ts +18 -18
- package/backend/lib/database/migrations/016_create_user_projects_table.ts +34 -34
- package/backend/lib/database/migrations/017_add_current_session_to_user_projects.ts +32 -32
- package/backend/lib/database/migrations/018_create_claude_accounts_table.ts +24 -24
- package/backend/lib/database/migrations/019_add_claude_account_to_sessions.ts +18 -18
- package/backend/lib/database/migrations/020_add_snapshot_tree_hash.ts +32 -32
- package/backend/lib/database/migrations/021_drop_prompt_templates_table.ts +33 -33
- package/backend/lib/database/migrations/index.ts +153 -153
- package/backend/lib/database/queries/checkpoint-queries.ts +87 -87
- package/backend/lib/database/queries/engine-queries.ts +75 -75
- package/backend/lib/database/queries/index.ts +8 -8
- package/backend/lib/database/queries/message-queries.ts +471 -471
- package/backend/lib/database/queries/project-queries.ts +117 -117
- package/backend/lib/database/queries/session-queries.ts +270 -270
- package/backend/lib/database/queries/settings-queries.ts +33 -33
- package/backend/lib/database/queries/snapshot-queries.ts +325 -325
- package/backend/lib/database/queries/utils-queries.ts +58 -58
- package/backend/lib/database/seeders/index.ts +12 -12
- package/backend/lib/database/seeders/settings_seeder.ts +83 -83
- package/backend/lib/database/utils/connection.ts +173 -173
- package/backend/lib/database/utils/index.ts +3 -3
- package/backend/lib/database/utils/migration-runner.ts +117 -117
- package/backend/lib/database/utils/seeder-runner.ts +120 -120
- package/backend/lib/engine/adapters/claude/environment.ts +160 -164
- package/backend/lib/engine/adapters/claude/error-handler.ts +60 -60
- package/backend/lib/engine/adapters/claude/index.ts +1 -1
- package/backend/lib/engine/adapters/claude/path-utils.ts +38 -38
- package/backend/lib/engine/adapters/claude/stream.ts +177 -177
- package/backend/lib/engine/adapters/opencode/index.ts +2 -2
- package/backend/lib/engine/adapters/opencode/message-converter.ts +862 -862
- package/backend/lib/engine/adapters/opencode/server.ts +104 -104
- package/backend/lib/engine/adapters/opencode/stream.ts +755 -755
- package/backend/lib/engine/index.ts +196 -196
- package/backend/lib/engine/types.ts +58 -58
- package/backend/lib/files/file-operations.ts +478 -478
- package/backend/lib/files/file-reading.ts +308 -308
- package/backend/lib/files/file-watcher.ts +383 -383
- package/backend/lib/files/path-browsing.ts +382 -382
- package/backend/lib/git/git-executor.ts +89 -88
- package/backend/lib/git/git-parser.ts +411 -411
- package/backend/lib/git/git-service.ts +505 -505
- package/backend/lib/mcp/README.md +1144 -1144
- package/backend/lib/mcp/config.ts +317 -316
- package/backend/lib/mcp/index.ts +35 -35
- package/backend/lib/mcp/project-context.ts +236 -236
- package/backend/lib/mcp/servers/browser-automation/actions.ts +156 -156
- package/backend/lib/mcp/servers/browser-automation/browser.ts +419 -419
- package/backend/lib/mcp/servers/browser-automation/index.ts +791 -791
- package/backend/lib/mcp/servers/browser-automation/inspection.ts +501 -501
- package/backend/lib/mcp/servers/helper.ts +143 -143
- package/backend/lib/mcp/servers/index.ts +44 -44
- package/backend/lib/mcp/servers/weather/get-temperature.ts +56 -56
- package/backend/lib/mcp/servers/weather/index.ts +31 -31
- package/backend/lib/mcp/stdio-server.ts +103 -103
- package/backend/lib/mcp/types.ts +65 -65
- package/backend/lib/preview/browser/browser-audio-capture.ts +86 -86
- package/backend/lib/preview/browser/browser-console-manager.ts +262 -262
- package/backend/lib/preview/browser/browser-dialog-handler.ts +222 -222
- package/backend/lib/preview/browser/browser-interaction-handler.ts +421 -421
- package/backend/lib/preview/browser/browser-mcp-control.ts +415 -415
- package/backend/lib/preview/browser/browser-native-ui-handler.ts +512 -512
- package/backend/lib/preview/browser/browser-navigation-tracker.ts +103 -103
- package/backend/lib/preview/browser/browser-pool.ts +357 -357
- package/backend/lib/preview/browser/browser-preview-service.ts +882 -882
- package/backend/lib/preview/browser/browser-tab-manager.ts +935 -935
- package/backend/lib/preview/browser/browser-video-capture.ts +695 -695
- package/backend/lib/preview/browser/scripts/audio-stream.ts +292 -292
- package/backend/lib/preview/browser/scripts/cursor-tracking.ts +85 -85
- package/backend/lib/preview/browser/scripts/video-stream.ts +438 -438
- package/backend/lib/preview/browser/types.ts +359 -359
- package/backend/lib/preview/index.ts +23 -23
- package/backend/lib/project/index.ts +1 -1
- package/backend/lib/project/status-manager.ts +181 -181
- package/backend/lib/shared/env.ts +117 -0
- package/backend/lib/shared/index.ts +5 -2
- package/backend/lib/shared/port-utils.ts +25 -25
- package/backend/lib/shared/process-manager.ts +280 -280
- package/backend/lib/snapshot/blob-store.ts +227 -227
- package/backend/lib/snapshot/gitignore.ts +307 -307
- package/backend/lib/snapshot/helpers.ts +397 -397
- package/backend/lib/snapshot/snapshot-service.ts +483 -483
- package/backend/lib/terminal/helpers.ts +14 -14
- package/backend/lib/terminal/index.ts +7 -7
- package/backend/lib/terminal/pty-manager.ts +3 -3
- package/backend/lib/terminal/pty-session-manager.ts +370 -387
- package/backend/lib/terminal/shell-utils.ts +315 -312
- package/backend/lib/terminal/stream-manager.ts +292 -292
- package/backend/lib/tunnel/global-tunnel-manager.ts +266 -243
- package/backend/lib/tunnel/project-tunnel-manager.ts +311 -311
- package/backend/lib/user/helpers.ts +87 -87
- package/backend/lib/utils/ws.ts +944 -944
- package/backend/lib/vite-dev.ts +295 -295
- package/backend/middleware/cors.ts +16 -15
- package/backend/middleware/error-handler.ts +50 -49
- package/backend/middleware/logger.ts +9 -9
- package/backend/types/api.ts +24 -24
- package/backend/ws/README.md +1505 -1505
- package/backend/ws/chat/background.ts +198 -198
- package/backend/ws/chat/index.ts +21 -21
- package/backend/ws/chat/stream.ts +707 -707
- package/backend/ws/engine/claude/accounts.ts +399 -401
- package/backend/ws/engine/claude/index.ts +13 -13
- package/backend/ws/engine/claude/status.ts +43 -43
- package/backend/ws/engine/index.ts +14 -14
- package/backend/ws/engine/opencode/index.ts +11 -11
- package/backend/ws/engine/opencode/status.ts +30 -30
- package/backend/ws/engine/utils.ts +36 -36
- package/backend/ws/files/index.ts +30 -30
- package/backend/ws/files/read.ts +189 -189
- package/backend/ws/files/search.ts +453 -453
- package/backend/ws/files/watch.ts +124 -124
- package/backend/ws/files/write.ts +143 -143
- package/backend/ws/git/branch.ts +106 -106
- package/backend/ws/git/commit.ts +39 -39
- package/backend/ws/git/conflict.ts +68 -68
- package/backend/ws/git/diff.ts +69 -69
- package/backend/ws/git/index.ts +24 -24
- package/backend/ws/git/log.ts +41 -41
- package/backend/ws/git/remote.ts +214 -214
- package/backend/ws/git/staging.ts +84 -84
- package/backend/ws/git/status.ts +90 -90
- package/backend/ws/index.ts +69 -69
- package/backend/ws/mcp/index.ts +61 -61
- package/backend/ws/messages/crud.ts +74 -74
- package/backend/ws/messages/index.ts +14 -14
- package/backend/ws/preview/browser/cleanup.ts +129 -129
- package/backend/ws/preview/browser/console.ts +114 -114
- package/backend/ws/preview/browser/interact.ts +513 -513
- package/backend/ws/preview/browser/mcp.ts +129 -129
- package/backend/ws/preview/browser/native-ui.ts +235 -235
- package/backend/ws/preview/browser/stats.ts +55 -55
- package/backend/ws/preview/browser/tab-info.ts +126 -126
- package/backend/ws/preview/browser/tab.ts +166 -166
- package/backend/ws/preview/browser/webcodecs.ts +293 -293
- package/backend/ws/preview/index.ts +146 -146
- package/backend/ws/projects/crud.ts +113 -113
- package/backend/ws/projects/index.ts +25 -25
- package/backend/ws/projects/presence.ts +46 -46
- package/backend/ws/projects/status.ts +116 -116
- package/backend/ws/sessions/crud.ts +327 -327
- package/backend/ws/sessions/index.ts +33 -33
- package/backend/ws/settings/crud.ts +112 -112
- package/backend/ws/settings/index.ts +14 -14
- package/backend/ws/snapshot/index.ts +17 -17
- package/backend/ws/snapshot/restore.ts +173 -173
- package/backend/ws/snapshot/timeline.ts +141 -141
- package/backend/ws/system/index.ts +14 -14
- package/backend/ws/system/operations.ts +49 -49
- package/backend/ws/terminal/index.ts +40 -40
- package/backend/ws/terminal/persistence.ts +153 -153
- package/backend/ws/terminal/session.ts +382 -382
- package/backend/ws/terminal/stream.ts +79 -79
- package/backend/ws/tunnel/index.ts +14 -14
- package/backend/ws/tunnel/operations.ts +91 -91
- package/backend/ws/types.ts +20 -20
- package/backend/ws/user/crud.ts +156 -156
- package/backend/ws/user/index.ts +14 -14
- package/bin/clopen.ts +307 -307
- package/bun.lock +1353 -1352
- package/frontend/App.svelte +38 -34
- package/frontend/app.css +313 -313
- package/frontend/lib/app-environment.ts +10 -10
- package/frontend/lib/components/chat/ChatInterface.svelte +406 -406
- package/frontend/lib/components/chat/formatters/ErrorMessage.svelte +56 -56
- package/frontend/lib/components/chat/formatters/MessageFormatter.svelte +223 -223
- package/frontend/lib/components/chat/formatters/TextMessage.svelte +394 -394
- package/frontend/lib/components/chat/formatters/Tools.svelte +69 -69
- package/frontend/lib/components/chat/formatters/index.ts +2 -2
- package/frontend/lib/components/chat/input/ChatInput.svelte +421 -421
- package/frontend/lib/components/chat/input/components/ChatInputActions.svelte +78 -78
- package/frontend/lib/components/chat/input/components/DragDropOverlay.svelte +30 -30
- package/frontend/lib/components/chat/input/components/EditModeIndicator.svelte +33 -33
- package/frontend/lib/components/chat/input/components/EngineModelPicker.svelte +619 -619
- package/frontend/lib/components/chat/input/components/FileAttachmentPreview.svelte +48 -48
- package/frontend/lib/components/chat/input/components/LoadingIndicator.svelte +31 -31
- package/frontend/lib/components/chat/input/composables/use-animations.svelte.ts +201 -201
- package/frontend/lib/components/chat/input/composables/use-chat-actions.svelte.ts +148 -148
- package/frontend/lib/components/chat/input/composables/use-file-handling.svelte.ts +216 -216
- package/frontend/lib/components/chat/input/composables/use-input-state.svelte.ts +357 -357
- package/frontend/lib/components/chat/input/composables/use-textarea-resize.svelte.ts +57 -57
- package/frontend/lib/components/chat/message/ChatMessage.svelte +478 -478
- package/frontend/lib/components/chat/message/ChatMessages.svelte +541 -541
- package/frontend/lib/components/chat/message/DateSeparator.svelte +86 -86
- package/frontend/lib/components/chat/message/MessageBubble.svelte +86 -86
- package/frontend/lib/components/chat/message/MessageHeader.svelte +157 -157
- package/frontend/lib/components/chat/modal/DebugModal.svelte +59 -59
- package/frontend/lib/components/chat/modal/TokenUsageModal.svelte +124 -124
- package/frontend/lib/components/chat/shared/index.ts +1 -1
- package/frontend/lib/components/chat/shared/utils.ts +115 -115
- package/frontend/lib/components/chat/tools/BashOutputTool.svelte +35 -35
- package/frontend/lib/components/chat/tools/BashTool.svelte +45 -45
- package/frontend/lib/components/chat/tools/CustomMcpTool.svelte +139 -139
- package/frontend/lib/components/chat/tools/EditTool.svelte +47 -47
- package/frontend/lib/components/chat/tools/ExitPlanModeTool.svelte +31 -31
- package/frontend/lib/components/chat/tools/GlobTool.svelte +50 -50
- package/frontend/lib/components/chat/tools/GrepTool.svelte +89 -89
- package/frontend/lib/components/chat/tools/KillShellTool.svelte +25 -25
- package/frontend/lib/components/chat/tools/ListMcpResourcesTool.svelte +30 -30
- package/frontend/lib/components/chat/tools/NotebookEditTool.svelte +37 -37
- package/frontend/lib/components/chat/tools/ReadMcpResourceTool.svelte +33 -33
- package/frontend/lib/components/chat/tools/ReadTool.svelte +40 -40
- package/frontend/lib/components/chat/tools/TaskTool.svelte +63 -63
- package/frontend/lib/components/chat/tools/TodoWriteTool.svelte +74 -74
- package/frontend/lib/components/chat/tools/WebFetchTool.svelte +34 -34
- package/frontend/lib/components/chat/tools/WebSearchTool.svelte +83 -83
- package/frontend/lib/components/chat/tools/WriteTool.svelte +32 -32
- package/frontend/lib/components/chat/tools/components/CodeBlock.svelte +78 -78
- package/frontend/lib/components/chat/tools/components/DiffBlock.svelte +407 -407
- package/frontend/lib/components/chat/tools/components/FileHeader.svelte +45 -45
- package/frontend/lib/components/chat/tools/components/InfoLine.svelte +18 -18
- package/frontend/lib/components/chat/tools/components/StatsBadges.svelte +26 -26
- package/frontend/lib/components/chat/tools/components/TerminalCommand.svelte +53 -53
- package/frontend/lib/components/chat/tools/components/index.ts +7 -7
- package/frontend/lib/components/chat/tools/index.ts +25 -25
- package/frontend/lib/components/chat/widgets/FloatingTodoList.svelte +248 -248
- package/frontend/lib/components/chat/widgets/TokenUsage.svelte +78 -78
- package/frontend/lib/components/checkpoint/TimelineModal.svelte +391 -391
- package/frontend/lib/components/checkpoint/timeline/TimelineEdge.svelte +26 -26
- package/frontend/lib/components/checkpoint/timeline/TimelineGraph.svelte +86 -86
- package/frontend/lib/components/checkpoint/timeline/TimelineNode.svelte +108 -108
- package/frontend/lib/components/checkpoint/timeline/TimelineVersionGroup.svelte +59 -59
- package/frontend/lib/components/checkpoint/timeline/animation.ts +168 -168
- package/frontend/lib/components/checkpoint/timeline/config.ts +44 -44
- package/frontend/lib/components/checkpoint/timeline/graph-builder.ts +304 -304
- package/frontend/lib/components/checkpoint/timeline/types.ts +65 -65
- package/frontend/lib/components/checkpoint/timeline/utils.ts +53 -53
- package/frontend/lib/components/common/Alert.svelte +138 -138
- package/frontend/lib/components/common/AvatarBubble.svelte +55 -55
- package/frontend/lib/components/common/Button.svelte +71 -71
- package/frontend/lib/components/common/Card.svelte +102 -102
- package/frontend/lib/components/common/Checkbox.svelte +48 -48
- package/frontend/lib/components/common/Dialog.svelte +248 -248
- package/frontend/lib/components/common/FolderBrowser.svelte +842 -842
- package/frontend/lib/components/common/Icon.svelte +57 -57
- package/frontend/lib/components/common/Input.svelte +72 -72
- package/frontend/lib/components/common/Lightbox.svelte +232 -232
- package/frontend/lib/components/common/LoadingScreen.svelte +52 -52
- package/frontend/lib/components/common/LoadingSpinner.svelte +48 -48
- package/frontend/lib/components/common/Modal.svelte +177 -177
- package/frontend/lib/components/common/ModalProvider.svelte +27 -27
- package/frontend/lib/components/common/ModelSelector.svelte +110 -110
- package/frontend/lib/components/common/MonacoEditor.svelte +568 -568
- package/frontend/lib/components/common/NotificationToast.svelte +113 -113
- package/frontend/lib/components/common/PageTemplate.svelte +75 -75
- package/frontend/lib/components/common/ProjectUserAvatars.svelte +79 -79
- package/frontend/lib/components/common/Select.svelte +97 -97
- package/frontend/lib/components/common/Textarea.svelte +79 -79
- package/frontend/lib/components/common/ThemeToggle.svelte +44 -44
- package/frontend/lib/components/common/lucide-icons.ts +1642 -1642
- package/frontend/lib/components/common/material-icons.ts +1082 -1082
- package/frontend/lib/components/common/xterm/XTerm.svelte +809 -795
- package/frontend/lib/components/common/xterm/index.ts +15 -15
- package/frontend/lib/components/common/xterm/terminal-config.ts +67 -67
- package/frontend/lib/components/common/xterm/types.ts +30 -30
- package/frontend/lib/components/common/xterm/xterm-service.ts +379 -353
- package/frontend/lib/components/files/FileNode.svelte +383 -383
- package/frontend/lib/components/files/FileTree.svelte +681 -681
- package/frontend/lib/components/files/FileViewer.svelte +728 -728
- package/frontend/lib/components/files/SearchResults.svelte +303 -303
- package/frontend/lib/components/git/BranchManager.svelte +458 -458
- package/frontend/lib/components/git/ChangesSection.svelte +107 -107
- package/frontend/lib/components/git/CommitForm.svelte +76 -76
- package/frontend/lib/components/git/ConflictResolver.svelte +158 -158
- package/frontend/lib/components/git/DiffViewer.svelte +364 -364
- package/frontend/lib/components/git/FileChangeItem.svelte +97 -97
- package/frontend/lib/components/git/GitButton.svelte +33 -33
- package/frontend/lib/components/git/GitLog.svelte +361 -361
- package/frontend/lib/components/git/GitModal.svelte +80 -80
- package/frontend/lib/components/history/HistoryModal.svelte +563 -563
- package/frontend/lib/components/history/HistoryView.svelte +614 -614
- package/frontend/lib/components/index.ts +34 -34
- package/frontend/lib/components/preview/browser/BrowserPreview.svelte +549 -549
- package/frontend/lib/components/preview/browser/components/Canvas.svelte +1058 -1058
- package/frontend/lib/components/preview/browser/components/ConsolePanel.svelte +756 -756
- package/frontend/lib/components/preview/browser/components/Container.svelte +450 -450
- package/frontend/lib/components/preview/browser/components/ContextMenu.svelte +236 -236
- package/frontend/lib/components/preview/browser/components/SelectDropdown.svelte +224 -224
- package/frontend/lib/components/preview/browser/components/Toolbar.svelte +338 -338
- package/frontend/lib/components/preview/browser/components/VirtualCursor.svelte +35 -35
- package/frontend/lib/components/preview/browser/core/cleanup.svelte.ts +155 -155
- package/frontend/lib/components/preview/browser/core/coordinator.svelte.ts +837 -837
- package/frontend/lib/components/preview/browser/core/interactions.svelte.ts +113 -113
- package/frontend/lib/components/preview/browser/core/mcp-handlers.svelte.ts +296 -296
- package/frontend/lib/components/preview/browser/core/native-ui-handlers.svelte.ts +391 -391
- package/frontend/lib/components/preview/browser/core/stream-handler.svelte.ts +231 -231
- package/frontend/lib/components/preview/browser/core/tab-manager.svelte.ts +210 -210
- package/frontend/lib/components/preview/browser/core/tab-operations.svelte.ts +239 -239
- package/frontend/lib/components/preview/index.ts +1 -1
- package/frontend/lib/components/settings/SettingsModal.svelte +235 -235
- package/frontend/lib/components/settings/SettingsView.svelte +36 -36
- package/frontend/lib/components/settings/appearance/AppearanceSettings.svelte +51 -51
- package/frontend/lib/components/settings/appearance/LayoutPresetSettings.svelte +160 -160
- package/frontend/lib/components/settings/appearance/LayoutPreview.svelte +76 -76
- package/frontend/lib/components/settings/engines/AIEnginesSettings.svelte +917 -917
- package/frontend/lib/components/settings/general/AdvancedSettings.svelte +187 -187
- package/frontend/lib/components/settings/general/DataManagementSettings.svelte +203 -203
- package/frontend/lib/components/settings/general/GeneralSettings.svelte +10 -10
- package/frontend/lib/components/settings/model/ModelSettings.svelte +357 -357
- package/frontend/lib/components/settings/notifications/NotificationSettings.svelte +205 -205
- package/frontend/lib/components/settings/user/UserSettings.svelte +197 -197
- package/frontend/lib/components/terminal/Terminal.svelte +367 -367
- package/frontend/lib/components/terminal/TerminalTabs.svelte +87 -87
- package/frontend/lib/components/terminal/TerminalView.svelte +54 -54
- package/frontend/lib/components/tunnel/TunnelActive.svelte +157 -142
- package/frontend/lib/components/tunnel/TunnelButton.svelte +60 -54
- package/frontend/lib/components/tunnel/TunnelInactive.svelte +285 -284
- package/frontend/lib/components/tunnel/TunnelModal.svelte +48 -47
- package/frontend/lib/components/tunnel/TunnelQRCode.svelte +49 -49
- package/frontend/lib/components/workspace/DesktopNavigator.svelte +382 -382
- package/frontend/lib/components/workspace/MobileNavigator.svelte +394 -403
- package/frontend/lib/components/workspace/PanelContainer.svelte +100 -100
- package/frontend/lib/components/workspace/PanelHeader.svelte +505 -505
- package/frontend/lib/components/workspace/ViewMenu.svelte +162 -162
- package/frontend/lib/components/workspace/WorkspaceLayout.svelte +169 -169
- package/frontend/lib/components/workspace/layout/DesktopLayout.svelte +15 -15
- package/frontend/lib/components/workspace/layout/MobileLayout.svelte +17 -17
- package/frontend/lib/components/workspace/layout/split-pane/Container.svelte +42 -42
- package/frontend/lib/components/workspace/layout/split-pane/Handle.svelte +84 -84
- package/frontend/lib/components/workspace/layout/split-pane/Layout.svelte +37 -37
- package/frontend/lib/components/workspace/panels/ChatPanel.svelte +274 -274
- package/frontend/lib/components/workspace/panels/FilesPanel.svelte +1261 -1261
- package/frontend/lib/components/workspace/panels/GitPanel.svelte +1560 -1560
- package/frontend/lib/components/workspace/panels/PreviewPanel.svelte +150 -150
- package/frontend/lib/components/workspace/panels/TerminalPanel.svelte +73 -73
- package/frontend/lib/constants/preview.ts +44 -44
- package/frontend/lib/services/chat/chat.service.ts +704 -704
- package/frontend/lib/services/chat/index.ts +6 -6
- package/frontend/lib/services/notification/global-stream-monitor.ts +86 -86
- package/frontend/lib/services/notification/index.ts +7 -7
- package/frontend/lib/services/notification/push.service.ts +143 -143
- package/frontend/lib/services/notification/sound.service.ts +126 -126
- package/frontend/lib/services/preview/browser/browser-console.service.ts +61 -61
- package/frontend/lib/services/preview/browser/browser-webcodecs.service.ts +1499 -1499
- package/frontend/lib/services/preview/browser/mcp-integration.svelte.ts +67 -67
- package/frontend/lib/services/preview/index.ts +22 -22
- package/frontend/lib/services/project/index.ts +7 -7
- package/frontend/lib/services/project/status.service.ts +159 -159
- package/frontend/lib/services/snapshot/snapshot.service.ts +47 -47
- package/frontend/lib/services/terminal/background/index.ts +129 -129
- package/frontend/lib/services/terminal/background/session-restore.ts +273 -273
- package/frontend/lib/services/terminal/background/stream-manager.ts +285 -285
- package/frontend/lib/services/terminal/index.ts +13 -13
- package/frontend/lib/services/terminal/persistence.service.ts +260 -260
- package/frontend/lib/services/terminal/project.service.ts +952 -952
- package/frontend/lib/services/terminal/session.service.ts +363 -363
- package/frontend/lib/services/terminal/terminal.service.ts +369 -369
- package/frontend/lib/stores/core/app.svelte.ts +117 -117
- package/frontend/lib/stores/core/files.svelte.ts +72 -72
- package/frontend/lib/stores/core/presence.svelte.ts +48 -48
- package/frontend/lib/stores/core/projects.svelte.ts +317 -317
- package/frontend/lib/stores/core/sessions.svelte.ts +383 -383
- package/frontend/lib/stores/features/claude-accounts.svelte.ts +58 -58
- package/frontend/lib/stores/features/models.svelte.ts +89 -89
- package/frontend/lib/stores/features/settings.svelte.ts +87 -87
- package/frontend/lib/stores/features/terminal.svelte.ts +700 -700
- package/frontend/lib/stores/features/tunnel.svelte.ts +163 -161
- package/frontend/lib/stores/features/user.svelte.ts +95 -95
- package/frontend/lib/stores/ui/chat-input.svelte.ts +56 -56
- package/frontend/lib/stores/ui/chat-model.svelte.ts +61 -61
- package/frontend/lib/stores/ui/dialog.svelte.ts +58 -58
- package/frontend/lib/stores/ui/edit-mode.svelte.ts +214 -214
- package/frontend/lib/stores/ui/notification.svelte.ts +166 -166
- package/frontend/lib/stores/ui/settings-modal.svelte.ts +88 -88
- package/frontend/lib/stores/ui/theme.svelte.ts +179 -179
- package/frontend/lib/stores/ui/workspace.svelte.ts +754 -754
- package/frontend/lib/types/native-ui.ts +73 -73
- package/frontend/lib/utils/chat/date-separator.ts +38 -38
- package/frontend/lib/utils/chat/message-grouper.ts +218 -218
- package/frontend/lib/utils/chat/message-processor.ts +134 -134
- package/frontend/lib/utils/chat/tool-handler.ts +160 -160
- package/frontend/lib/utils/chat/virtual-scroll.svelte.ts +142 -142
- package/frontend/lib/utils/click-outside.ts +20 -20
- package/frontend/lib/utils/context-manager.ts +256 -256
- package/frontend/lib/utils/file-icon-mappings.ts +768 -768
- package/frontend/lib/utils/folder-icon-mappings.ts +1029 -1029
- package/frontend/lib/utils/git-status.ts +68 -68
- package/frontend/lib/utils/platform.ts +112 -112
- package/frontend/lib/utils/port-check.ts +64 -64
- package/frontend/lib/utils/terminalFormatter.ts +206 -206
- package/frontend/lib/utils/theme.ts +6 -6
- package/frontend/lib/utils/tree-visualizer.ts +320 -320
- package/frontend/lib/utils/ws.ts +44 -44
- package/frontend/main.ts +13 -13
- package/index.html +70 -70
- package/package.json +111 -111
- package/scripts/generate-icons.ts +86 -86
- package/scripts/pre-publish-check.sh +142 -142
- package/scripts/setup-hooks.sh +134 -134
- package/scripts/validate-branch-name.sh +47 -47
- package/scripts/validate-commit-msg.sh +42 -42
- package/shared/constants/engines.ts +134 -134
- package/shared/types/database/connection.ts +15 -15
- package/shared/types/database/index.ts +5 -5
- package/shared/types/database/schema.ts +140 -140
- package/shared/types/engine/index.ts +45 -45
- package/shared/types/filesystem/index.ts +21 -21
- package/shared/types/git.ts +171 -171
- package/shared/types/messaging/index.ts +238 -238
- package/shared/types/messaging/tool.ts +525 -525
- package/shared/types/network/api.ts +17 -17
- package/shared/types/network/index.ts +4 -4
- package/shared/types/stores/app.ts +22 -22
- package/shared/types/stores/dialog.ts +20 -20
- package/shared/types/stores/index.ts +2 -2
- package/shared/types/stores/settings.ts +15 -15
- package/shared/types/terminal/index.ts +43 -43
- package/shared/types/ui/components.ts +60 -60
- package/shared/types/ui/icons.ts +22 -22
- package/shared/types/ui/index.ts +21 -21
- package/shared/types/ui/notifications.ts +13 -13
- package/shared/types/ui/theme.ts +11 -11
- package/shared/types/websocket/index.ts +43 -43
- package/shared/types/window.d.ts +12 -12
- package/shared/utils/anonymous-user.ts +167 -167
- package/shared/utils/async.ts +10 -10
- package/shared/utils/diff-calculator.ts +184 -184
- package/shared/utils/file-type-detection.ts +165 -165
- package/shared/utils/logger.ts +144 -144
- package/shared/utils/message-formatter.ts +79 -79
- package/shared/utils/path.ts +47 -47
- package/shared/utils/ws-client.ts +768 -768
- package/shared/utils/ws-server.ts +660 -660
- package/static/favicon.svg +7 -7
- package/static/fonts/dm-sans.css +96 -96
- package/svelte.config.js +20 -20
- package/tsconfig.json +41 -41
- package/vite.config.ts +33 -33
|
@@ -1,271 +1,271 @@
|
|
|
1
|
-
import { getDatabase } from '../index';
|
|
2
|
-
import type { ChatSession, Branch } from '$shared/types/database/schema';
|
|
3
|
-
|
|
4
|
-
export const sessionQueries = {
|
|
5
|
-
getAll(): ChatSession[] {
|
|
6
|
-
const db = getDatabase();
|
|
7
|
-
return db.prepare(`
|
|
8
|
-
SELECT * FROM chat_sessions
|
|
9
|
-
ORDER BY started_at DESC
|
|
10
|
-
`).all() as ChatSession[];
|
|
11
|
-
},
|
|
12
|
-
|
|
13
|
-
getByProjectId(projectId: string): ChatSession[] {
|
|
14
|
-
const db = getDatabase();
|
|
15
|
-
return db.prepare(`
|
|
16
|
-
SELECT * FROM chat_sessions
|
|
17
|
-
WHERE project_id = ?
|
|
18
|
-
ORDER BY started_at DESC
|
|
19
|
-
`).all(projectId) as ChatSession[];
|
|
20
|
-
},
|
|
21
|
-
|
|
22
|
-
getById(id: string): ChatSession | null {
|
|
23
|
-
const db = getDatabase();
|
|
24
|
-
return db.prepare(`
|
|
25
|
-
SELECT * FROM chat_sessions WHERE id = ?
|
|
26
|
-
`).get(id) as ChatSession | null;
|
|
27
|
-
},
|
|
28
|
-
|
|
29
|
-
create(session: Omit<ChatSession, 'id'>): ChatSession {
|
|
30
|
-
const db = getDatabase();
|
|
31
|
-
const id = crypto.randomUUID();
|
|
32
|
-
const newSession = { id, ...session };
|
|
33
|
-
|
|
34
|
-
db.prepare(`
|
|
35
|
-
INSERT INTO chat_sessions (id, project_id, title, engine, latest_sdk_session_id, current_head_message_id, started_at, ended_at)
|
|
36
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
37
|
-
`).run(
|
|
38
|
-
id,
|
|
39
|
-
session.project_id,
|
|
40
|
-
session.title || null,
|
|
41
|
-
session.engine || 'claude-code',
|
|
42
|
-
session.latest_sdk_session_id || null,
|
|
43
|
-
session.current_head_message_id || null,
|
|
44
|
-
session.started_at,
|
|
45
|
-
session.ended_at || null
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
return newSession;
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
updateTitle(id: string, title: string): void {
|
|
52
|
-
const db = getDatabase();
|
|
53
|
-
db.prepare(`
|
|
54
|
-
UPDATE chat_sessions
|
|
55
|
-
SET title = ?
|
|
56
|
-
WHERE id = ?
|
|
57
|
-
`).run(title, id);
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
updateLatestSdkSessionId(id: string, sdkSessionId: string): void {
|
|
61
|
-
const db = getDatabase();
|
|
62
|
-
db.prepare(`
|
|
63
|
-
UPDATE chat_sessions
|
|
64
|
-
SET latest_sdk_session_id = ?
|
|
65
|
-
WHERE id = ?
|
|
66
|
-
`).run(sdkSessionId, id);
|
|
67
|
-
},
|
|
68
|
-
|
|
69
|
-
updateEngineModel(id: string, engine: string, model: string): void {
|
|
70
|
-
const db = getDatabase();
|
|
71
|
-
db.prepare(`
|
|
72
|
-
UPDATE chat_sessions
|
|
73
|
-
SET engine = ?, model = ?
|
|
74
|
-
WHERE id = ?
|
|
75
|
-
`).run(engine, model, id);
|
|
76
|
-
},
|
|
77
|
-
|
|
78
|
-
updateClaudeAccountId(id: string, claudeAccountId: number | null): void {
|
|
79
|
-
const db = getDatabase();
|
|
80
|
-
db.prepare(`
|
|
81
|
-
UPDATE chat_sessions
|
|
82
|
-
SET claude_account_id = ?
|
|
83
|
-
WHERE id = ?
|
|
84
|
-
`).run(claudeAccountId, id);
|
|
85
|
-
},
|
|
86
|
-
|
|
87
|
-
end(id: string): void {
|
|
88
|
-
const db = getDatabase();
|
|
89
|
-
const now = new Date().toISOString();
|
|
90
|
-
db.prepare(`
|
|
91
|
-
UPDATE chat_sessions
|
|
92
|
-
SET ended_at = ?
|
|
93
|
-
WHERE id = ?
|
|
94
|
-
`).run(now, id);
|
|
95
|
-
},
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Reactivate a session (clear ended_at).
|
|
99
|
-
* Does NOT end other sessions — multiple sessions can be active in parallel.
|
|
100
|
-
*/
|
|
101
|
-
reactivate(id: string): void {
|
|
102
|
-
const db = getDatabase();
|
|
103
|
-
|
|
104
|
-
const session = this.getById(id);
|
|
105
|
-
if (!session) {
|
|
106
|
-
throw new Error('Session not found');
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Clear ended_at for the target session (reactivate it)
|
|
110
|
-
db.prepare(`
|
|
111
|
-
UPDATE chat_sessions
|
|
112
|
-
SET ended_at = NULL
|
|
113
|
-
WHERE id = ?
|
|
114
|
-
`).run(id);
|
|
115
|
-
},
|
|
116
|
-
|
|
117
|
-
delete(id: string): void {
|
|
118
|
-
const db = getDatabase();
|
|
119
|
-
// Delete related messages first
|
|
120
|
-
db.prepare('DELETE FROM messages WHERE session_id = ?').run(id);
|
|
121
|
-
db.prepare('DELETE FROM chat_sessions WHERE id = ?').run(id);
|
|
122
|
-
},
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Get the active shared session for a project
|
|
126
|
-
* Returns the most recent session that hasn't ended
|
|
127
|
-
*/
|
|
128
|
-
getActiveSessionForProject(projectId: string): ChatSession | null {
|
|
129
|
-
const db = getDatabase();
|
|
130
|
-
return db.prepare(`
|
|
131
|
-
SELECT * FROM chat_sessions
|
|
132
|
-
WHERE project_id = ? AND ended_at IS NULL
|
|
133
|
-
ORDER BY started_at DESC
|
|
134
|
-
LIMIT 1
|
|
135
|
-
`).get(projectId) as ChatSession | null;
|
|
136
|
-
},
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Get all active (non-ended) sessions for a project.
|
|
140
|
-
* Supports parallel multi-session workflow.
|
|
141
|
-
*/
|
|
142
|
-
getActiveSessionsForProject(projectId: string): ChatSession[] {
|
|
143
|
-
const db = getDatabase();
|
|
144
|
-
return db.prepare(`
|
|
145
|
-
SELECT * FROM chat_sessions
|
|
146
|
-
WHERE project_id = ? AND ended_at IS NULL
|
|
147
|
-
ORDER BY started_at DESC
|
|
148
|
-
`).all(projectId) as ChatSession[];
|
|
149
|
-
},
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Get or create a shared session for a project.
|
|
153
|
-
* When forceNew=true, creates a new session WITHOUT ending existing ones
|
|
154
|
-
* (multiple sessions can be active in parallel).
|
|
155
|
-
*/
|
|
156
|
-
getOrCreateSharedSession(projectId: string, projectName: string, forceNew: boolean = false): ChatSession {
|
|
157
|
-
if (!forceNew) {
|
|
158
|
-
// Return most recent active session if exists
|
|
159
|
-
const activeSession = this.getActiveSessionForProject(projectId);
|
|
160
|
-
if (activeSession) {
|
|
161
|
-
return activeSession;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Create a new session (existing sessions stay active)
|
|
166
|
-
const now = new Date().toISOString();
|
|
167
|
-
return this.create({
|
|
168
|
-
project_id: projectId,
|
|
169
|
-
title: `Shared Chat - ${projectName} (${new Date().toLocaleString()})`,
|
|
170
|
-
started_at: now,
|
|
171
|
-
ended_at: undefined,
|
|
172
|
-
latest_sdk_session_id: undefined
|
|
173
|
-
});
|
|
174
|
-
},
|
|
175
|
-
|
|
176
|
-
// ==================== GIT-LIKE BRANCH OPERATIONS ====================
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Update the current HEAD pointer of a session
|
|
180
|
-
* This is like "git checkout" - moves HEAD to a different commit
|
|
181
|
-
*/
|
|
182
|
-
updateHead(sessionId: string, messageId: string): void {
|
|
183
|
-
const db = getDatabase();
|
|
184
|
-
db.prepare(`
|
|
185
|
-
UPDATE chat_sessions
|
|
186
|
-
SET current_head_message_id = ?
|
|
187
|
-
WHERE id = ?
|
|
188
|
-
`).run(messageId, sessionId);
|
|
189
|
-
},
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Get current HEAD message ID for a session
|
|
193
|
-
*/
|
|
194
|
-
getHead(sessionId: string): string | null {
|
|
195
|
-
const db = getDatabase();
|
|
196
|
-
const session = db.prepare(`
|
|
197
|
-
SELECT current_head_message_id FROM chat_sessions WHERE id = ?
|
|
198
|
-
`).get(sessionId) as { current_head_message_id: string | null } | null;
|
|
199
|
-
|
|
200
|
-
return session?.current_head_message_id || null;
|
|
201
|
-
},
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Save a branch (creates a named pointer to a message)
|
|
205
|
-
*/
|
|
206
|
-
saveBranch(sessionId: string, branchName: string, headMessageId: string): Branch {
|
|
207
|
-
const db = getDatabase();
|
|
208
|
-
const id = crypto.randomUUID();
|
|
209
|
-
const now = new Date().toISOString();
|
|
210
|
-
|
|
211
|
-
const branch: Branch = {
|
|
212
|
-
id,
|
|
213
|
-
session_id: sessionId,
|
|
214
|
-
branch_name: branchName,
|
|
215
|
-
head_message_id: headMessageId,
|
|
216
|
-
created_at: now
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
db.prepare(`
|
|
220
|
-
INSERT INTO branches (id, session_id, branch_name, head_message_id, created_at)
|
|
221
|
-
VALUES (?, ?, ?, ?, ?)
|
|
222
|
-
`).run(id, sessionId, branchName, headMessageId, now);
|
|
223
|
-
|
|
224
|
-
return branch;
|
|
225
|
-
},
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Get branch HEAD by branch name
|
|
229
|
-
*/
|
|
230
|
-
getBranchHead(sessionId: string, branchName: string): string | null {
|
|
231
|
-
const db = getDatabase();
|
|
232
|
-
const branch = db.prepare(`
|
|
233
|
-
SELECT head_message_id FROM branches
|
|
234
|
-
WHERE session_id = ? AND branch_name = ?
|
|
235
|
-
`).get(sessionId, branchName) as { head_message_id: string } | null;
|
|
236
|
-
|
|
237
|
-
return branch?.head_message_id || null;
|
|
238
|
-
},
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Get all branches for a session
|
|
242
|
-
*/
|
|
243
|
-
getAllBranches(sessionId: string): Branch[] {
|
|
244
|
-
const db = getDatabase();
|
|
245
|
-
return db.prepare(`
|
|
246
|
-
SELECT * FROM branches
|
|
247
|
-
WHERE session_id = ?
|
|
248
|
-
ORDER BY created_at DESC
|
|
249
|
-
`).all(sessionId) as Branch[];
|
|
250
|
-
},
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Delete a branch
|
|
254
|
-
*/
|
|
255
|
-
deleteBranch(branchId: string): void {
|
|
256
|
-
const db = getDatabase();
|
|
257
|
-
db.prepare('DELETE FROM branches WHERE id = ?').run(branchId);
|
|
258
|
-
},
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Update branch HEAD (when branch grows with new commits)
|
|
262
|
-
*/
|
|
263
|
-
updateBranchHead(sessionId: string, branchName: string, newHeadMessageId: string): void {
|
|
264
|
-
const db = getDatabase();
|
|
265
|
-
db.prepare(`
|
|
266
|
-
UPDATE branches
|
|
267
|
-
SET head_message_id = ?
|
|
268
|
-
WHERE session_id = ? AND branch_name = ?
|
|
269
|
-
`).run(newHeadMessageId, sessionId, branchName);
|
|
270
|
-
}
|
|
1
|
+
import { getDatabase } from '../index';
|
|
2
|
+
import type { ChatSession, Branch } from '$shared/types/database/schema';
|
|
3
|
+
|
|
4
|
+
export const sessionQueries = {
|
|
5
|
+
getAll(): ChatSession[] {
|
|
6
|
+
const db = getDatabase();
|
|
7
|
+
return db.prepare(`
|
|
8
|
+
SELECT * FROM chat_sessions
|
|
9
|
+
ORDER BY started_at DESC
|
|
10
|
+
`).all() as ChatSession[];
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
getByProjectId(projectId: string): ChatSession[] {
|
|
14
|
+
const db = getDatabase();
|
|
15
|
+
return db.prepare(`
|
|
16
|
+
SELECT * FROM chat_sessions
|
|
17
|
+
WHERE project_id = ?
|
|
18
|
+
ORDER BY started_at DESC
|
|
19
|
+
`).all(projectId) as ChatSession[];
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
getById(id: string): ChatSession | null {
|
|
23
|
+
const db = getDatabase();
|
|
24
|
+
return db.prepare(`
|
|
25
|
+
SELECT * FROM chat_sessions WHERE id = ?
|
|
26
|
+
`).get(id) as ChatSession | null;
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
create(session: Omit<ChatSession, 'id'>): ChatSession {
|
|
30
|
+
const db = getDatabase();
|
|
31
|
+
const id = crypto.randomUUID();
|
|
32
|
+
const newSession = { id, ...session };
|
|
33
|
+
|
|
34
|
+
db.prepare(`
|
|
35
|
+
INSERT INTO chat_sessions (id, project_id, title, engine, latest_sdk_session_id, current_head_message_id, started_at, ended_at)
|
|
36
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
37
|
+
`).run(
|
|
38
|
+
id,
|
|
39
|
+
session.project_id,
|
|
40
|
+
session.title || null,
|
|
41
|
+
session.engine || 'claude-code',
|
|
42
|
+
session.latest_sdk_session_id || null,
|
|
43
|
+
session.current_head_message_id || null,
|
|
44
|
+
session.started_at,
|
|
45
|
+
session.ended_at || null
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
return newSession;
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
updateTitle(id: string, title: string): void {
|
|
52
|
+
const db = getDatabase();
|
|
53
|
+
db.prepare(`
|
|
54
|
+
UPDATE chat_sessions
|
|
55
|
+
SET title = ?
|
|
56
|
+
WHERE id = ?
|
|
57
|
+
`).run(title, id);
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
updateLatestSdkSessionId(id: string, sdkSessionId: string): void {
|
|
61
|
+
const db = getDatabase();
|
|
62
|
+
db.prepare(`
|
|
63
|
+
UPDATE chat_sessions
|
|
64
|
+
SET latest_sdk_session_id = ?
|
|
65
|
+
WHERE id = ?
|
|
66
|
+
`).run(sdkSessionId, id);
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
updateEngineModel(id: string, engine: string, model: string): void {
|
|
70
|
+
const db = getDatabase();
|
|
71
|
+
db.prepare(`
|
|
72
|
+
UPDATE chat_sessions
|
|
73
|
+
SET engine = ?, model = ?
|
|
74
|
+
WHERE id = ?
|
|
75
|
+
`).run(engine, model, id);
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
updateClaudeAccountId(id: string, claudeAccountId: number | null): void {
|
|
79
|
+
const db = getDatabase();
|
|
80
|
+
db.prepare(`
|
|
81
|
+
UPDATE chat_sessions
|
|
82
|
+
SET claude_account_id = ?
|
|
83
|
+
WHERE id = ?
|
|
84
|
+
`).run(claudeAccountId, id);
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
end(id: string): void {
|
|
88
|
+
const db = getDatabase();
|
|
89
|
+
const now = new Date().toISOString();
|
|
90
|
+
db.prepare(`
|
|
91
|
+
UPDATE chat_sessions
|
|
92
|
+
SET ended_at = ?
|
|
93
|
+
WHERE id = ?
|
|
94
|
+
`).run(now, id);
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Reactivate a session (clear ended_at).
|
|
99
|
+
* Does NOT end other sessions — multiple sessions can be active in parallel.
|
|
100
|
+
*/
|
|
101
|
+
reactivate(id: string): void {
|
|
102
|
+
const db = getDatabase();
|
|
103
|
+
|
|
104
|
+
const session = this.getById(id);
|
|
105
|
+
if (!session) {
|
|
106
|
+
throw new Error('Session not found');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Clear ended_at for the target session (reactivate it)
|
|
110
|
+
db.prepare(`
|
|
111
|
+
UPDATE chat_sessions
|
|
112
|
+
SET ended_at = NULL
|
|
113
|
+
WHERE id = ?
|
|
114
|
+
`).run(id);
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
delete(id: string): void {
|
|
118
|
+
const db = getDatabase();
|
|
119
|
+
// Delete related messages first
|
|
120
|
+
db.prepare('DELETE FROM messages WHERE session_id = ?').run(id);
|
|
121
|
+
db.prepare('DELETE FROM chat_sessions WHERE id = ?').run(id);
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Get the active shared session for a project
|
|
126
|
+
* Returns the most recent session that hasn't ended
|
|
127
|
+
*/
|
|
128
|
+
getActiveSessionForProject(projectId: string): ChatSession | null {
|
|
129
|
+
const db = getDatabase();
|
|
130
|
+
return db.prepare(`
|
|
131
|
+
SELECT * FROM chat_sessions
|
|
132
|
+
WHERE project_id = ? AND ended_at IS NULL
|
|
133
|
+
ORDER BY started_at DESC
|
|
134
|
+
LIMIT 1
|
|
135
|
+
`).get(projectId) as ChatSession | null;
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Get all active (non-ended) sessions for a project.
|
|
140
|
+
* Supports parallel multi-session workflow.
|
|
141
|
+
*/
|
|
142
|
+
getActiveSessionsForProject(projectId: string): ChatSession[] {
|
|
143
|
+
const db = getDatabase();
|
|
144
|
+
return db.prepare(`
|
|
145
|
+
SELECT * FROM chat_sessions
|
|
146
|
+
WHERE project_id = ? AND ended_at IS NULL
|
|
147
|
+
ORDER BY started_at DESC
|
|
148
|
+
`).all(projectId) as ChatSession[];
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Get or create a shared session for a project.
|
|
153
|
+
* When forceNew=true, creates a new session WITHOUT ending existing ones
|
|
154
|
+
* (multiple sessions can be active in parallel).
|
|
155
|
+
*/
|
|
156
|
+
getOrCreateSharedSession(projectId: string, projectName: string, forceNew: boolean = false): ChatSession {
|
|
157
|
+
if (!forceNew) {
|
|
158
|
+
// Return most recent active session if exists
|
|
159
|
+
const activeSession = this.getActiveSessionForProject(projectId);
|
|
160
|
+
if (activeSession) {
|
|
161
|
+
return activeSession;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Create a new session (existing sessions stay active)
|
|
166
|
+
const now = new Date().toISOString();
|
|
167
|
+
return this.create({
|
|
168
|
+
project_id: projectId,
|
|
169
|
+
title: `Shared Chat - ${projectName} (${new Date().toLocaleString()})`,
|
|
170
|
+
started_at: now,
|
|
171
|
+
ended_at: undefined,
|
|
172
|
+
latest_sdk_session_id: undefined
|
|
173
|
+
});
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
// ==================== GIT-LIKE BRANCH OPERATIONS ====================
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Update the current HEAD pointer of a session
|
|
180
|
+
* This is like "git checkout" - moves HEAD to a different commit
|
|
181
|
+
*/
|
|
182
|
+
updateHead(sessionId: string, messageId: string): void {
|
|
183
|
+
const db = getDatabase();
|
|
184
|
+
db.prepare(`
|
|
185
|
+
UPDATE chat_sessions
|
|
186
|
+
SET current_head_message_id = ?
|
|
187
|
+
WHERE id = ?
|
|
188
|
+
`).run(messageId, sessionId);
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Get current HEAD message ID for a session
|
|
193
|
+
*/
|
|
194
|
+
getHead(sessionId: string): string | null {
|
|
195
|
+
const db = getDatabase();
|
|
196
|
+
const session = db.prepare(`
|
|
197
|
+
SELECT current_head_message_id FROM chat_sessions WHERE id = ?
|
|
198
|
+
`).get(sessionId) as { current_head_message_id: string | null } | null;
|
|
199
|
+
|
|
200
|
+
return session?.current_head_message_id || null;
|
|
201
|
+
},
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Save a branch (creates a named pointer to a message)
|
|
205
|
+
*/
|
|
206
|
+
saveBranch(sessionId: string, branchName: string, headMessageId: string): Branch {
|
|
207
|
+
const db = getDatabase();
|
|
208
|
+
const id = crypto.randomUUID();
|
|
209
|
+
const now = new Date().toISOString();
|
|
210
|
+
|
|
211
|
+
const branch: Branch = {
|
|
212
|
+
id,
|
|
213
|
+
session_id: sessionId,
|
|
214
|
+
branch_name: branchName,
|
|
215
|
+
head_message_id: headMessageId,
|
|
216
|
+
created_at: now
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
db.prepare(`
|
|
220
|
+
INSERT INTO branches (id, session_id, branch_name, head_message_id, created_at)
|
|
221
|
+
VALUES (?, ?, ?, ?, ?)
|
|
222
|
+
`).run(id, sessionId, branchName, headMessageId, now);
|
|
223
|
+
|
|
224
|
+
return branch;
|
|
225
|
+
},
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Get branch HEAD by branch name
|
|
229
|
+
*/
|
|
230
|
+
getBranchHead(sessionId: string, branchName: string): string | null {
|
|
231
|
+
const db = getDatabase();
|
|
232
|
+
const branch = db.prepare(`
|
|
233
|
+
SELECT head_message_id FROM branches
|
|
234
|
+
WHERE session_id = ? AND branch_name = ?
|
|
235
|
+
`).get(sessionId, branchName) as { head_message_id: string } | null;
|
|
236
|
+
|
|
237
|
+
return branch?.head_message_id || null;
|
|
238
|
+
},
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Get all branches for a session
|
|
242
|
+
*/
|
|
243
|
+
getAllBranches(sessionId: string): Branch[] {
|
|
244
|
+
const db = getDatabase();
|
|
245
|
+
return db.prepare(`
|
|
246
|
+
SELECT * FROM branches
|
|
247
|
+
WHERE session_id = ?
|
|
248
|
+
ORDER BY created_at DESC
|
|
249
|
+
`).all(sessionId) as Branch[];
|
|
250
|
+
},
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Delete a branch
|
|
254
|
+
*/
|
|
255
|
+
deleteBranch(branchId: string): void {
|
|
256
|
+
const db = getDatabase();
|
|
257
|
+
db.prepare('DELETE FROM branches WHERE id = ?').run(branchId);
|
|
258
|
+
},
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Update branch HEAD (when branch grows with new commits)
|
|
262
|
+
*/
|
|
263
|
+
updateBranchHead(sessionId: string, branchName: string, newHeadMessageId: string): void {
|
|
264
|
+
const db = getDatabase();
|
|
265
|
+
db.prepare(`
|
|
266
|
+
UPDATE branches
|
|
267
|
+
SET head_message_id = ?
|
|
268
|
+
WHERE session_id = ? AND branch_name = ?
|
|
269
|
+
`).run(newHeadMessageId, sessionId, branchName);
|
|
270
|
+
}
|
|
271
271
|
};
|
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import { getDatabase } from '../index';
|
|
2
|
-
import type { Setting } from '$shared/types/database/schema';
|
|
3
|
-
|
|
4
|
-
export const settingsQueries = {
|
|
5
|
-
getAll(): Setting[] {
|
|
6
|
-
const db = getDatabase();
|
|
7
|
-
return db.prepare(`
|
|
8
|
-
SELECT * FROM settings
|
|
9
|
-
ORDER BY key
|
|
10
|
-
`).all() as Setting[];
|
|
11
|
-
},
|
|
12
|
-
|
|
13
|
-
get(key: string): Setting | null {
|
|
14
|
-
const db = getDatabase();
|
|
15
|
-
return db.prepare(`
|
|
16
|
-
SELECT * FROM settings WHERE key = ?
|
|
17
|
-
`).get(key) as Setting | null;
|
|
18
|
-
},
|
|
19
|
-
|
|
20
|
-
set(key: string, value: string): void {
|
|
21
|
-
const db = getDatabase();
|
|
22
|
-
const now = new Date().toISOString();
|
|
23
|
-
|
|
24
|
-
db.prepare(`
|
|
25
|
-
INSERT OR REPLACE INTO settings (key, value, updated_at)
|
|
26
|
-
VALUES (?, ?, ?)
|
|
27
|
-
`).run(key, value, now);
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
delete(key: string): void {
|
|
31
|
-
const db = getDatabase();
|
|
32
|
-
db.prepare('DELETE FROM settings WHERE key = ?').run(key);
|
|
33
|
-
}
|
|
1
|
+
import { getDatabase } from '../index';
|
|
2
|
+
import type { Setting } from '$shared/types/database/schema';
|
|
3
|
+
|
|
4
|
+
export const settingsQueries = {
|
|
5
|
+
getAll(): Setting[] {
|
|
6
|
+
const db = getDatabase();
|
|
7
|
+
return db.prepare(`
|
|
8
|
+
SELECT * FROM settings
|
|
9
|
+
ORDER BY key
|
|
10
|
+
`).all() as Setting[];
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
get(key: string): Setting | null {
|
|
14
|
+
const db = getDatabase();
|
|
15
|
+
return db.prepare(`
|
|
16
|
+
SELECT * FROM settings WHERE key = ?
|
|
17
|
+
`).get(key) as Setting | null;
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
set(key: string, value: string): void {
|
|
21
|
+
const db = getDatabase();
|
|
22
|
+
const now = new Date().toISOString();
|
|
23
|
+
|
|
24
|
+
db.prepare(`
|
|
25
|
+
INSERT OR REPLACE INTO settings (key, value, updated_at)
|
|
26
|
+
VALUES (?, ?, ?)
|
|
27
|
+
`).run(key, value, now);
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
delete(key: string): void {
|
|
31
|
+
const db = getDatabase();
|
|
32
|
+
db.prepare('DELETE FROM settings WHERE key = ?').run(key);
|
|
33
|
+
}
|
|
34
34
|
};
|