@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
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vite Dev Server Integration (Bun-optimized)
|
|
3
|
+
*
|
|
4
|
+
* Embeds Vite as middleware inside the Elysia/Bun server.
|
|
5
|
+
*
|
|
6
|
+
* Performance optimizations:
|
|
7
|
+
* - HTML requests use vite.transformIndexHtml() directly (bypass Node compat layer)
|
|
8
|
+
* - Module requests use vite.transformRequest() directly (bypass Node compat layer)
|
|
9
|
+
* - Only edge cases (Vite internals, pre-bundled deps) go through middleware adapter
|
|
10
|
+
*
|
|
11
|
+
* Reliability:
|
|
12
|
+
* - All async operations have timeouts to prevent hanging promises
|
|
13
|
+
* - HTML has raw fallback if Vite transform hangs
|
|
14
|
+
* - Middleware adapter has safety timeout
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { createServer as createViteServer, type ViteDevServer, type Connect } from 'vite';
|
|
18
|
+
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
19
|
+
import { resolve } from 'node:path';
|
|
20
|
+
|
|
21
|
+
let vite: ViteDevServer | null = null;
|
|
22
|
+
|
|
23
|
+
// Resolved paths (computed once at startup)
|
|
24
|
+
const PUBLIC_DIR = resolve(process.cwd(), 'static');
|
|
25
|
+
const INDEX_PATH = resolve(process.cwd(), 'index.html');
|
|
26
|
+
|
|
27
|
+
// Timeouts (ms)
|
|
28
|
+
const HTML_TRANSFORM_TIMEOUT = 5000;
|
|
29
|
+
const MODULE_TRANSFORM_TIMEOUT = 10000;
|
|
30
|
+
const MIDDLEWARE_TIMEOUT = 10000;
|
|
31
|
+
|
|
32
|
+
// ============================================================================
|
|
33
|
+
// Utilities
|
|
34
|
+
// ============================================================================
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Race a promise against a timeout. Returns null on timeout (never rejects).
|
|
38
|
+
*/
|
|
39
|
+
function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T | null> {
|
|
40
|
+
let timer: ReturnType<typeof setTimeout>;
|
|
41
|
+
return Promise.race([
|
|
42
|
+
promise,
|
|
43
|
+
new Promise<null>((resolve) => { timer = setTimeout(() => resolve(null), ms); })
|
|
44
|
+
]).finally(() => clearTimeout(timer));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ============================================================================
|
|
48
|
+
// Lifecycle
|
|
49
|
+
// ============================================================================
|
|
50
|
+
|
|
51
|
+
export async function initViteDev(): Promise<ViteDevServer> {
|
|
52
|
+
vite = await createViteServer({
|
|
53
|
+
configFile: './vite.config.ts',
|
|
54
|
+
server: { middlewareMode: true },
|
|
55
|
+
appType: 'spa'
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
return vite;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function getViteDev(): ViteDevServer | null {
|
|
62
|
+
return vite;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export async function closeViteDev(): Promise<void> {
|
|
66
|
+
if (vite) {
|
|
67
|
+
await vite.close();
|
|
68
|
+
vite = null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ============================================================================
|
|
73
|
+
// Main Request Handler
|
|
74
|
+
// ============================================================================
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Handle an HTTP request in dev mode.
|
|
78
|
+
* Uses Vite's direct APIs for speed, middleware only as fallback.
|
|
79
|
+
* All paths have timeouts to guarantee a response — never hangs.
|
|
80
|
+
*/
|
|
81
|
+
export async function handleDevRequest(viteServer: ViteDevServer, request: Request): Promise<Response> {
|
|
82
|
+
const url = new URL(request.url);
|
|
83
|
+
const pathname = url.pathname;
|
|
84
|
+
|
|
85
|
+
// 1. Static public files — fast Bun.file() (no Vite overhead)
|
|
86
|
+
const publicFile = await servePublicFile(pathname);
|
|
87
|
+
if (publicFile) return publicFile;
|
|
88
|
+
|
|
89
|
+
// 2. HTML / SPA routes — direct vite.transformIndexHtml() with timeout + fallback
|
|
90
|
+
if (isHtmlRequest(pathname)) {
|
|
91
|
+
const htmlResponse = await withTimeout(serveHtml(viteServer, pathname), HTML_TRANSFORM_TIMEOUT);
|
|
92
|
+
if (htmlResponse) return htmlResponse;
|
|
93
|
+
|
|
94
|
+
// Fallback: serve raw HTML without Vite transforms (HMR won't work but page loads)
|
|
95
|
+
try {
|
|
96
|
+
const rawHtml = await Bun.file(INDEX_PATH).text();
|
|
97
|
+
return new Response(rawHtml, {
|
|
98
|
+
headers: { 'Content-Type': 'text/html; charset=utf-8' }
|
|
99
|
+
});
|
|
100
|
+
} catch {
|
|
101
|
+
// INDEX_PATH doesn't exist — fall through
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// 3. Module requests — direct vite.transformRequest() with timeout
|
|
106
|
+
if (!pathname.startsWith('/__')) {
|
|
107
|
+
const moduleResponse = await withTimeout(
|
|
108
|
+
serveModule(viteServer, pathname + url.search, request),
|
|
109
|
+
MODULE_TRANSFORM_TIMEOUT
|
|
110
|
+
);
|
|
111
|
+
if (moduleResponse) return moduleResponse;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// 4. Fallback: pipe through Vite's connect middleware (with safety timeout)
|
|
115
|
+
const middlewareResponse = await pipeViteMiddleware(viteServer.middlewares, request);
|
|
116
|
+
if (middlewareResponse) return middlewareResponse;
|
|
117
|
+
|
|
118
|
+
return new Response('Not Found', { status: 404 });
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ============================================================================
|
|
122
|
+
// Fast Path: Public Files
|
|
123
|
+
// ============================================================================
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Try serving a static file from the public directory (static/).
|
|
127
|
+
* Uses BunFile directly (not .stream()) so Bun sets Content-Length automatically,
|
|
128
|
+
* preventing endless loading when the browser can't detect stream end.
|
|
129
|
+
*/
|
|
130
|
+
async function servePublicFile(pathname: string): Promise<Response | null> {
|
|
131
|
+
if (pathname.includes('..')) return null;
|
|
132
|
+
|
|
133
|
+
const filePath = resolve(PUBLIC_DIR, pathname.slice(1));
|
|
134
|
+
if (!filePath.startsWith(PUBLIC_DIR)) return null;
|
|
135
|
+
|
|
136
|
+
const file = Bun.file(filePath);
|
|
137
|
+
if (!(await file.exists())) return null;
|
|
138
|
+
|
|
139
|
+
return new Response(file, {
|
|
140
|
+
headers: {
|
|
141
|
+
'Content-Type': file.type || 'application/octet-stream',
|
|
142
|
+
'Cache-Control': 'public, max-age=3600'
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// ============================================================================
|
|
148
|
+
// Fast Path: HTML / SPA
|
|
149
|
+
// ============================================================================
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Check if a request is for an HTML page (root or SPA client-side route).
|
|
153
|
+
*/
|
|
154
|
+
function isHtmlRequest(pathname: string): boolean {
|
|
155
|
+
if (pathname === '/') return true;
|
|
156
|
+
if (pathname.startsWith('/@') || pathname.startsWith('/__')) return false;
|
|
157
|
+
if (pathname.startsWith('/node_modules/')) return false;
|
|
158
|
+
const lastSegment = pathname.split('/').pop() || '';
|
|
159
|
+
return !lastSegment.includes('.');
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Serve transformed HTML directly via Vite's API.
|
|
164
|
+
*/
|
|
165
|
+
async function serveHtml(viteServer: ViteDevServer, pathname: string): Promise<Response> {
|
|
166
|
+
const rawHtml = await Bun.file(INDEX_PATH).text();
|
|
167
|
+
const html = await viteServer.transformIndexHtml(pathname, rawHtml);
|
|
168
|
+
return new Response(html, {
|
|
169
|
+
headers: { 'Content-Type': 'text/html; charset=utf-8' }
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// ============================================================================
|
|
174
|
+
// Fast Path: Module Requests
|
|
175
|
+
// ============================================================================
|
|
176
|
+
|
|
177
|
+
function getModuleContentType(url: string): string {
|
|
178
|
+
const pathname = url.split('?')[0];
|
|
179
|
+
// Only serve as raw CSS when explicitly requested with ?direct (e.g. <link> tags).
|
|
180
|
+
// CSS imported via JS is always transformed to a JavaScript module by Vite
|
|
181
|
+
// (for HMR / style injection), so it must be served as application/javascript.
|
|
182
|
+
if (pathname.endsWith('.css') && url.includes('direct')) {
|
|
183
|
+
return 'text/css';
|
|
184
|
+
}
|
|
185
|
+
return 'application/javascript';
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Try to serve a module using Vite's transformRequest API.
|
|
190
|
+
*/
|
|
191
|
+
async function serveModule(viteServer: ViteDevServer, url: string, request: Request): Promise<Response | null> {
|
|
192
|
+
try {
|
|
193
|
+
const result = await viteServer.transformRequest(url);
|
|
194
|
+
if (!result) return null;
|
|
195
|
+
|
|
196
|
+
if (result.etag) {
|
|
197
|
+
const ifNoneMatch = request.headers.get('if-none-match');
|
|
198
|
+
if (ifNoneMatch === result.etag) {
|
|
199
|
+
return new Response(null, { status: 304 });
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const headers: Record<string, string> = {
|
|
204
|
+
'Content-Type': getModuleContentType(url),
|
|
205
|
+
};
|
|
206
|
+
if (result.etag) {
|
|
207
|
+
headers['ETag'] = result.etag;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return new Response(result.code, { headers });
|
|
211
|
+
} catch {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// ============================================================================
|
|
217
|
+
// Fallback: Vite Connect Middleware Adapter (with safety timeout)
|
|
218
|
+
// ============================================================================
|
|
219
|
+
|
|
220
|
+
const MOCK_SOCKET = {
|
|
221
|
+
remoteAddress: '127.0.0.1',
|
|
222
|
+
remotePort: 0,
|
|
223
|
+
remoteFamily: 'IPv4',
|
|
224
|
+
encrypted: false,
|
|
225
|
+
writable: true,
|
|
226
|
+
readable: true,
|
|
227
|
+
destroy() {},
|
|
228
|
+
end() {},
|
|
229
|
+
write() { return true; },
|
|
230
|
+
on() { return this; },
|
|
231
|
+
once() { return this; },
|
|
232
|
+
off() { return this; },
|
|
233
|
+
emit() { return false; },
|
|
234
|
+
addListener() { return this; },
|
|
235
|
+
removeListener() { return this; },
|
|
236
|
+
setTimeout() { return this; },
|
|
237
|
+
setNoDelay() { return this; },
|
|
238
|
+
setKeepAlive() { return this; },
|
|
239
|
+
ref() { return this; },
|
|
240
|
+
unref() { return this; },
|
|
241
|
+
address() { return { address: '127.0.0.1', family: 'IPv4', port: 0 }; }
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Pipe a request through Vite's connect middleware.
|
|
246
|
+
* Has a safety timeout to prevent promises that never resolve
|
|
247
|
+
* (e.g., middleware errors without calling res.end() or next()).
|
|
248
|
+
*/
|
|
249
|
+
function pipeViteMiddleware(
|
|
250
|
+
middleware: Connect.Server,
|
|
251
|
+
request: Request
|
|
252
|
+
): Promise<Response | null> {
|
|
253
|
+
return new Promise((resolve) => {
|
|
254
|
+
const url = new URL(request.url);
|
|
255
|
+
|
|
256
|
+
const req = new IncomingMessage(MOCK_SOCKET as any);
|
|
257
|
+
req.method = request.method;
|
|
258
|
+
req.url = url.pathname + url.search;
|
|
259
|
+
req.headers = request.headers.toJSON();
|
|
260
|
+
req.push(null);
|
|
261
|
+
|
|
262
|
+
const res = new ServerResponse(req);
|
|
263
|
+
let ended = false;
|
|
264
|
+
const chunks: Uint8Array[] = [];
|
|
265
|
+
|
|
266
|
+
// Safety timeout — if middleware never calls res.end() or next(),
|
|
267
|
+
// resolve with null to prevent hanging the HTTP response forever.
|
|
268
|
+
const safetyTimer = setTimeout(() => {
|
|
269
|
+
if (!ended) {
|
|
270
|
+
ended = true;
|
|
271
|
+
resolve(null);
|
|
272
|
+
}
|
|
273
|
+
}, MIDDLEWARE_TIMEOUT);
|
|
274
|
+
|
|
275
|
+
function finalize() {
|
|
276
|
+
if (ended) return;
|
|
277
|
+
ended = true;
|
|
278
|
+
clearTimeout(safetyTimer);
|
|
279
|
+
|
|
280
|
+
const nodeHeaders = res.getHeaders();
|
|
281
|
+
const h = new Headers();
|
|
282
|
+
for (const key in nodeHeaders) {
|
|
283
|
+
// Skip hop-by-hop headers — these are transport-level headers that
|
|
284
|
+
// must NOT be forwarded through the adapter. Bun will set the correct
|
|
285
|
+
// Content-Length and Transfer-Encoding based on the actual body.
|
|
286
|
+
// Forwarding stale Content-Length from the Node.js ServerResponse
|
|
287
|
+
// can cause a mismatch with the collected body, making the browser
|
|
288
|
+
// wait for more data that never arrives (infinite loading spinner).
|
|
289
|
+
const lower = key.toLowerCase();
|
|
290
|
+
if (lower === 'transfer-encoding' || lower === 'content-length' ||
|
|
291
|
+
lower === 'connection' || lower === 'keep-alive') continue;
|
|
292
|
+
|
|
293
|
+
const v = nodeHeaders[key];
|
|
294
|
+
if (v === undefined) continue;
|
|
295
|
+
if (Array.isArray(v)) {
|
|
296
|
+
for (let i = 0; i < v.length; i++) h.append(key, v[i]);
|
|
297
|
+
} else {
|
|
298
|
+
h.set(key, String(v));
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const body = chunks.length === 0
|
|
303
|
+
? null
|
|
304
|
+
: chunks.length === 1
|
|
305
|
+
? chunks[0]
|
|
306
|
+
: Buffer.concat(chunks);
|
|
307
|
+
|
|
308
|
+
resolve(new Response(body, { status: res.statusCode, headers: h }));
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
res.write = function (chunk: any, encodingOrCb?: any, cb?: any): boolean {
|
|
312
|
+
if (chunk != null) {
|
|
313
|
+
chunks.push(
|
|
314
|
+
typeof chunk === 'string'
|
|
315
|
+
? Buffer.from(chunk, typeof encodingOrCb === 'string' ? encodingOrCb as BufferEncoding : 'utf-8')
|
|
316
|
+
: chunk instanceof Uint8Array ? chunk : Buffer.from(chunk)
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
const callback = typeof encodingOrCb === 'function' ? encodingOrCb : cb;
|
|
320
|
+
if (typeof callback === 'function') callback();
|
|
321
|
+
return true;
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
res.end = function (data?: any, encodingOrCb?: any, cb?: any): ServerResponse {
|
|
325
|
+
if (ended) return res;
|
|
326
|
+
|
|
327
|
+
if (typeof data === 'function') {
|
|
328
|
+
data();
|
|
329
|
+
} else {
|
|
330
|
+
if (data != null) {
|
|
331
|
+
chunks.push(
|
|
332
|
+
typeof data === 'string'
|
|
333
|
+
? Buffer.from(data, typeof encodingOrCb === 'string' ? encodingOrCb as BufferEncoding : 'utf-8')
|
|
334
|
+
: data instanceof Uint8Array ? data : Buffer.from(data)
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
const callback = typeof encodingOrCb === 'function' ? encodingOrCb : cb;
|
|
338
|
+
if (typeof callback === 'function') callback();
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
finalize();
|
|
342
|
+
return res;
|
|
343
|
+
} as any;
|
|
344
|
+
|
|
345
|
+
middleware(req as any, res as any, () => {
|
|
346
|
+
if (!ended) {
|
|
347
|
+
ended = true;
|
|
348
|
+
clearTimeout(safetyTimer);
|
|
349
|
+
resolve(null);
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { cors } from '@elysiajs/cors';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CORS Middleware Configuration
|
|
5
|
+
* Single port setup — frontend and backend share the same origin.
|
|
6
|
+
*/
|
|
7
|
+
const port = process.env.PORT || '9141';
|
|
8
|
+
const host = process.env.HOST || 'localhost';
|
|
9
|
+
export const corsMiddleware = cors({
|
|
10
|
+
origin: `http://${host}:${port}`,
|
|
11
|
+
credentials: true,
|
|
12
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
|
13
|
+
allowedHeaders: ['Content-Type', 'Authorization'],
|
|
14
|
+
exposeHeaders: ['Content-Type']
|
|
15
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Elysia } from 'elysia';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Global Error Handler Middleware
|
|
5
|
+
* Catches all errors and returns consistent error responses
|
|
6
|
+
*/
|
|
7
|
+
export function errorHandlerMiddleware(app: Elysia) {
|
|
8
|
+
return app.onError(({ code, error, set }) => {
|
|
9
|
+
console.error('[Error]', code, error);
|
|
10
|
+
|
|
11
|
+
// Handle different error types
|
|
12
|
+
switch (code) {
|
|
13
|
+
case 'VALIDATION':
|
|
14
|
+
set.status = 400;
|
|
15
|
+
return {
|
|
16
|
+
success: false,
|
|
17
|
+
error: 'Validation error',
|
|
18
|
+
message: error.message
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
case 'NOT_FOUND':
|
|
22
|
+
set.status = 404;
|
|
23
|
+
return {
|
|
24
|
+
success: false,
|
|
25
|
+
error: 'Not found',
|
|
26
|
+
message: error.message
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
case 'PARSE':
|
|
30
|
+
set.status = 400;
|
|
31
|
+
return {
|
|
32
|
+
success: false,
|
|
33
|
+
error: 'Parse error',
|
|
34
|
+
message: 'Invalid request body'
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
default:
|
|
38
|
+
set.status = 500;
|
|
39
|
+
return {
|
|
40
|
+
success: false,
|
|
41
|
+
error: 'Internal server error',
|
|
42
|
+
message:
|
|
43
|
+
process.env.NODE_ENV === 'production'
|
|
44
|
+
? 'An error occurred'
|
|
45
|
+
: error.toString()
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared API Types for Elysia Server
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface ApiResponse<T = any> {
|
|
6
|
+
success: boolean;
|
|
7
|
+
data?: T;
|
|
8
|
+
error?: string;
|
|
9
|
+
message?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface PaginationParams {
|
|
13
|
+
page?: number;
|
|
14
|
+
limit?: number;
|
|
15
|
+
offset?: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface ErrorResponse {
|
|
19
|
+
success: false;
|
|
20
|
+
error: string;
|
|
21
|
+
message: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// More types will be added as needed during Phase 2 migration
|