codex-linux 1.0.0
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/.claude/settings.local.json +10 -0
- package/.eslintrc.json +27 -0
- package/.github/workflows/ci.yml +156 -0
- package/.huskyrc +7 -0
- package/.lintstagedrc +13 -0
- package/.prettierrc +12 -0
- package/CLAUDE.md +163 -0
- package/DESIGN_SUPERIOR.md +73 -0
- package/Dockerfile +64 -0
- package/INSTALLATION.md +152 -0
- package/LICENSE +21 -0
- package/README.md +245 -0
- package/assets/skills/code-review/instructions.md +102 -0
- package/assets/skills/code-review/skill.yaml +15 -0
- package/assets/skills/refactoring/instructions.md +149 -0
- package/assets/skills/refactoring/skill.yaml +15 -0
- package/assets/skills/testing/skill.yaml +15 -0
- package/commitlint.config.js +23 -0
- package/dist/main/DatabaseManager.js +763 -0
- package/dist/main/DatabaseManager.js.map +1 -0
- package/dist/main/SettingsManager.js +61 -0
- package/dist/main/SettingsManager.js.map +1 -0
- package/dist/main/agents/AgentOrchestrator.js +787 -0
- package/dist/main/agents/AgentOrchestrator.js.map +1 -0
- package/dist/main/agents/AgentSDK.js +219 -0
- package/dist/main/agents/AgentSDK.js.map +1 -0
- package/dist/main/agents/AgentTools.js +348 -0
- package/dist/main/agents/AgentTools.js.map +1 -0
- package/dist/main/agents/CodeIndex.js +233 -0
- package/dist/main/agents/CodeIndex.js.map +1 -0
- package/dist/main/agents/EmbeddingService.js +80 -0
- package/dist/main/agents/EmbeddingService.js.map +1 -0
- package/dist/main/agents/NativeToolCalling.js +206 -0
- package/dist/main/agents/NativeToolCalling.js.map +1 -0
- package/dist/main/api/APIServer.js +278 -0
- package/dist/main/api/APIServer.js.map +1 -0
- package/dist/main/api/RateLimiter.js +138 -0
- package/dist/main/api/RateLimiter.js.map +1 -0
- package/dist/main/api/WebSocketManager.js +300 -0
- package/dist/main/api/WebSocketManager.js.map +1 -0
- package/dist/main/assistant/ContextOptimizer.js +192 -0
- package/dist/main/assistant/ContextOptimizer.js.map +1 -0
- package/dist/main/assistant/PredictedOutputManager.js +172 -0
- package/dist/main/assistant/PredictedOutputManager.js.map +1 -0
- package/dist/main/assistant/PromptCacheManager.js +193 -0
- package/dist/main/assistant/PromptCacheManager.js.map +1 -0
- package/dist/main/assistant/PromptOptimizer.js +626 -0
- package/dist/main/assistant/PromptOptimizer.js.map +1 -0
- package/dist/main/assistant/SmartCodeAssistant.js +224 -0
- package/dist/main/assistant/SmartCodeAssistant.js.map +1 -0
- package/dist/main/auth/SessionManager.js +300 -0
- package/dist/main/auth/SessionManager.js.map +1 -0
- package/dist/main/automations/AdvancedWebhookSystem.js +212 -0
- package/dist/main/automations/AdvancedWebhookSystem.js.map +1 -0
- package/dist/main/automations/AutomationScheduler.js +269 -0
- package/dist/main/automations/AutomationScheduler.js.map +1 -0
- package/dist/main/automations/BatchProcessingSystem.js +159 -0
- package/dist/main/automations/BatchProcessingSystem.js.map +1 -0
- package/dist/main/automations/BrowserAutomationManager.js +195 -0
- package/dist/main/automations/BrowserAutomationManager.js.map +1 -0
- package/dist/main/automations/GitHubActionsManager.js +129 -0
- package/dist/main/automations/GitHubActionsManager.js.map +1 -0
- package/dist/main/automations/GitLabCIManager.js +122 -0
- package/dist/main/automations/GitLabCIManager.js.map +1 -0
- package/dist/main/automations/PriorityQueueManager.js +240 -0
- package/dist/main/automations/PriorityQueueManager.js.map +1 -0
- package/dist/main/background/BackgroundModeManager.js +117 -0
- package/dist/main/background/BackgroundModeManager.js.map +1 -0
- package/dist/main/backup/BackupManager.js +254 -0
- package/dist/main/backup/BackupManager.js.map +1 -0
- package/dist/main/backup/MigrationManager.js +114 -0
- package/dist/main/backup/MigrationManager.js.map +1 -0
- package/dist/main/commands/SlashCommandManager.js +399 -0
- package/dist/main/commands/SlashCommandManager.js.map +1 -0
- package/dist/main/config/ClaudeMdParser.js +519 -0
- package/dist/main/config/ClaudeMdParser.js.map +1 -0
- package/dist/main/config/CustomizationManager.js +381 -0
- package/dist/main/config/CustomizationManager.js.map +1 -0
- package/dist/main/config/LaunchConfigManager.js +211 -0
- package/dist/main/config/LaunchConfigManager.js.map +1 -0
- package/dist/main/config/SettingsManager.js +166 -0
- package/dist/main/config/SettingsManager.js.map +1 -0
- package/dist/main/connectors/ConnectorManager.js +151 -0
- package/dist/main/connectors/ConnectorManager.js.map +1 -0
- package/dist/main/connectors/DatabaseConnector.js +222 -0
- package/dist/main/connectors/DatabaseConnector.js.map +1 -0
- package/dist/main/cowork/CoworkManager.js +324 -0
- package/dist/main/cowork/CoworkManager.js.map +1 -0
- package/dist/main/evals/AgentEvalFramework.js +538 -0
- package/dist/main/evals/AgentEvalFramework.js.map +1 -0
- package/dist/main/evals/GraderManager.js +285 -0
- package/dist/main/evals/GraderManager.js.map +1 -0
- package/dist/main/git/GitWorktreeManager.js +214 -0
- package/dist/main/git/GitWorktreeManager.js.map +1 -0
- package/dist/main/github/GitHubPRMonitor.js +244 -0
- package/dist/main/github/GitHubPRMonitor.js.map +1 -0
- package/dist/main/ide/ContinueInManager.js +181 -0
- package/dist/main/ide/ContinueInManager.js.map +1 -0
- package/dist/main/ide/IDEIntegration.js +277 -0
- package/dist/main/ide/IDEIntegration.js.map +1 -0
- package/dist/main/integrations/LinearManager.js +252 -0
- package/dist/main/integrations/LinearManager.js.map +1 -0
- package/dist/main/integrations/SlackBotManager.js +247 -0
- package/dist/main/integrations/SlackBotManager.js.map +1 -0
- package/dist/main/lsp/LSPManager.js +394 -0
- package/dist/main/lsp/LSPManager.js.map +1 -0
- package/dist/main/main.js +1087 -0
- package/dist/main/main.js.map +1 -0
- package/dist/main/mcp/MCPConfigurationManager.js +281 -0
- package/dist/main/mcp/MCPConfigurationManager.js.map +1 -0
- package/dist/main/mcp/MCPManager.js +710 -0
- package/dist/main/mcp/MCPManager.js.map +1 -0
- package/dist/main/mcp/MCPRegistry.js +272 -0
- package/dist/main/mcp/MCPRegistry.js.map +1 -0
- package/dist/main/monitoring/ErrorRecoveryManager.js +268 -0
- package/dist/main/monitoring/ErrorRecoveryManager.js.map +1 -0
- package/dist/main/monitoring/ErrorTracker.js +57 -0
- package/dist/main/monitoring/ErrorTracker.js.map +1 -0
- package/dist/main/monitoring/MetricsCollector.js +155 -0
- package/dist/main/monitoring/MetricsCollector.js.map +1 -0
- package/dist/main/monitoring/TraceGradingSystem.js +148 -0
- package/dist/main/monitoring/TraceGradingSystem.js.map +1 -0
- package/dist/main/notifications/NotificationManager.js +67 -0
- package/dist/main/notifications/NotificationManager.js.map +1 -0
- package/dist/main/pair/AIPairProgramming.js +200 -0
- package/dist/main/pair/AIPairProgramming.js.map +1 -0
- package/dist/main/plugins/PluginManager.js +222 -0
- package/dist/main/plugins/PluginManager.js.map +1 -0
- package/dist/main/plugins/PluginMarketplace.js +237 -0
- package/dist/main/plugins/PluginMarketplace.js.map +1 -0
- package/dist/main/preload.js +189 -0
- package/dist/main/preload.js.map +1 -0
- package/dist/main/preview/PreviewSessionManager.js +170 -0
- package/dist/main/preview/PreviewSessionManager.js.map +1 -0
- package/dist/main/providers/AIProviderManager.js +327 -0
- package/dist/main/providers/AIProviderManager.js.map +1 -0
- package/dist/main/providers/FineTuningManager.js +276 -0
- package/dist/main/providers/FineTuningManager.js.map +1 -0
- package/dist/main/providers/FreeModelsProvider.js +1104 -0
- package/dist/main/providers/FreeModelsProvider.js.map +1 -0
- package/dist/main/realtime/RealtimeManager.js +116 -0
- package/dist/main/realtime/RealtimeManager.js.map +1 -0
- package/dist/main/remote/CloudEnvironmentManager.js +232 -0
- package/dist/main/remote/CloudEnvironmentManager.js.map +1 -0
- package/dist/main/remote/RemoteSessionManager.js +255 -0
- package/dist/main/remote/RemoteSessionManager.js.map +1 -0
- package/dist/main/search/DeepResearchManager.js +335 -0
- package/dist/main/search/DeepResearchManager.js.map +1 -0
- package/dist/main/search/WebSearchIntegration.js +147 -0
- package/dist/main/search/WebSearchIntegration.js.map +1 -0
- package/dist/main/security/AdminConsoleManager.js +223 -0
- package/dist/main/security/AdminConsoleManager.js.map +1 -0
- package/dist/main/security/AuditLogger.js +136 -0
- package/dist/main/security/AuditLogger.js.map +1 -0
- package/dist/main/security/PermissionManager.js +144 -0
- package/dist/main/security/PermissionManager.js.map +1 -0
- package/dist/main/security/SSOManager.js +173 -0
- package/dist/main/security/SSOManager.js.map +1 -0
- package/dist/main/security/SecurityManager.js +152 -0
- package/dist/main/security/SecurityManager.js.map +1 -0
- package/dist/main/skills/SkillsManager.js +223 -0
- package/dist/main/skills/SkillsManager.js.map +1 -0
- package/dist/main/ssh/SSHManager.js +65 -0
- package/dist/main/ssh/SSHManager.js.map +1 -0
- package/dist/main/streaming/StreamingManager.js +225 -0
- package/dist/main/streaming/StreamingManager.js.map +1 -0
- package/dist/main/sync/CloudSyncManager.js +422 -0
- package/dist/main/sync/CloudSyncManager.js.map +1 -0
- package/dist/main/types.js +28 -0
- package/dist/main/types.js.map +1 -0
- package/dist/main/verification/AutoVerifyManager.js +235 -0
- package/dist/main/verification/AutoVerifyManager.js.map +1 -0
- package/dist/main/vision/ComputerUseManager.js +376 -0
- package/dist/main/vision/ComputerUseManager.js.map +1 -0
- package/dist/main/vision/ImageVideoGenerationManager.js +401 -0
- package/dist/main/vision/ImageVideoGenerationManager.js.map +1 -0
- package/dist/main/vision/VisionManager.js +172 -0
- package/dist/main/vision/VisionManager.js.map +1 -0
- package/dist/renderer/assets/main-DJlZQBCA.js +304 -0
- package/dist/renderer/assets/main-N33ZXEr8.css +1 -0
- package/dist/renderer/index.html +21 -0
- package/dist/renderer/manifest.json +42 -0
- package/dist/renderer/sw.ts +109 -0
- package/dist/shared/types.js +35 -0
- package/dist/shared/types.js.map +1 -0
- package/docker-compose.yml +65 -0
- package/docs/API.md +307 -0
- package/docs/USER_GUIDE.md +476 -0
- package/examples/plugins/sample-plugin/package.json +41 -0
- package/examples/plugins/sample-plugin/src/index.ts +75 -0
- package/index.html +20 -0
- package/jest.config.js +39 -0
- package/package.json +180 -0
- package/packages/cli/package.json +29 -0
- package/packages/cli/src/commands/agents.ts +199 -0
- package/packages/cli/src/commands/tasks.ts +61 -0
- package/packages/cli/src/index.ts +91 -0
- package/packages/cli/src/utils/api.ts +45 -0
- package/packages/cli/src/utils/config.ts +61 -0
- package/packages/npm-installer/bin/codex-linux +126 -0
- package/packages/npm-installer/lib/download.js +273 -0
- package/packages/npm-installer/package.json +42 -0
- package/packages/vscode-extension/package.json +167 -0
- package/packages/vscode-extension/src/api.ts +68 -0
- package/packages/vscode-extension/src/extension.ts +161 -0
- package/packages/vscode-extension/src/panels/chatPanel.ts +265 -0
- package/packages/vscode-extension/src/panels/createAgentPanel.ts +227 -0
- package/packages/vscode-extension/src/providers/agentsProvider.ts +80 -0
- package/postcss.config.js +6 -0
- package/public/manifest.json +42 -0
- package/public/sw.ts +109 -0
- package/scripts/install-dev.sh +103 -0
- package/scripts/install.sh +275 -0
- package/src/main/DatabaseManager.ts +950 -0
- package/src/main/SettingsManager.ts +63 -0
- package/src/main/agents/AgentOrchestrator.ts +930 -0
- package/src/main/agents/AgentSDK.ts +269 -0
- package/src/main/agents/AgentTools.ts +380 -0
- package/src/main/agents/CodeIndex.ts +240 -0
- package/src/main/agents/EmbeddingService.ts +88 -0
- package/src/main/agents/NativeToolCalling.ts +245 -0
- package/src/main/api/APIServer.ts +316 -0
- package/src/main/api/RateLimiter.ts +165 -0
- package/src/main/api/WebSocketManager.ts +398 -0
- package/src/main/assistant/ContextOptimizer.ts +214 -0
- package/src/main/assistant/PredictedOutputManager.ts +265 -0
- package/src/main/assistant/PromptCacheManager.ts +280 -0
- package/src/main/assistant/PromptOptimizer.ts +746 -0
- package/src/main/assistant/SmartCodeAssistant.ts +234 -0
- package/src/main/auth/SessionManager.ts +415 -0
- package/src/main/automations/AdvancedWebhookSystem.ts +281 -0
- package/src/main/automations/AutomationScheduler.ts +272 -0
- package/src/main/automations/BatchProcessingSystem.ts +207 -0
- package/src/main/automations/BrowserAutomationManager.ts +203 -0
- package/src/main/automations/GitHubActionsManager.ts +151 -0
- package/src/main/automations/GitLabCIManager.ts +206 -0
- package/src/main/automations/PriorityQueueManager.ts +328 -0
- package/src/main/background/BackgroundModeManager.ts +130 -0
- package/src/main/backup/BackupManager.ts +287 -0
- package/src/main/backup/MigrationManager.ts +132 -0
- package/src/main/commands/SlashCommandManager.ts +407 -0
- package/src/main/config/ClaudeMdParser.ts +539 -0
- package/src/main/config/CustomizationManager.ts +493 -0
- package/src/main/config/LaunchConfigManager.ts +212 -0
- package/src/main/config/SettingsManager.ts +163 -0
- package/src/main/connectors/ConnectorManager.ts +175 -0
- package/src/main/connectors/DatabaseConnector.ts +212 -0
- package/src/main/cowork/CoworkManager.ts +431 -0
- package/src/main/evals/AgentEvalFramework.ts +665 -0
- package/src/main/evals/GraderManager.ts +417 -0
- package/src/main/git/GitWorktreeManager.ts +211 -0
- package/src/main/github/GitHubPRMonitor.ts +317 -0
- package/src/main/ide/ContinueInManager.ts +180 -0
- package/src/main/ide/IDEIntegration.ts +288 -0
- package/src/main/integrations/LinearManager.ts +327 -0
- package/src/main/integrations/SlackBotManager.ts +312 -0
- package/src/main/lsp/LSPManager.ts +445 -0
- package/src/main/main.ts +1221 -0
- package/src/main/mcp/MCPConfigurationManager.ts +281 -0
- package/src/main/mcp/MCPManager.ts +799 -0
- package/src/main/mcp/MCPRegistry.ts +273 -0
- package/src/main/monitoring/ErrorRecoveryManager.ts +359 -0
- package/src/main/monitoring/ErrorTracker.ts +60 -0
- package/src/main/monitoring/MetricsCollector.ts +196 -0
- package/src/main/monitoring/TraceGradingSystem.ts +196 -0
- package/src/main/notifications/NotificationManager.ts +96 -0
- package/src/main/pair/AIPairProgramming.ts +290 -0
- package/src/main/plugins/PluginManager.ts +266 -0
- package/src/main/plugins/PluginMarketplace.ts +318 -0
- package/src/main/preload.ts +215 -0
- package/src/main/preview/PreviewSessionManager.ts +186 -0
- package/src/main/providers/AIProviderManager.ts +394 -0
- package/src/main/providers/FineTuningManager.ts +390 -0
- package/src/main/providers/FreeModelsProvider.ts +1156 -0
- package/src/main/realtime/RealtimeManager.ts +147 -0
- package/src/main/remote/CloudEnvironmentManager.ts +253 -0
- package/src/main/remote/RemoteSessionManager.ts +323 -0
- package/src/main/search/DeepResearchManager.ts +458 -0
- package/src/main/search/WebSearchIntegration.ts +203 -0
- package/src/main/security/AdminConsoleManager.ts +244 -0
- package/src/main/security/AuditLogger.ts +143 -0
- package/src/main/security/PermissionManager.ts +184 -0
- package/src/main/security/SSOManager.ts +241 -0
- package/src/main/security/SecurityManager.ts +139 -0
- package/src/main/skills/SkillsManager.ts +218 -0
- package/src/main/ssh/SSHManager.ts +86 -0
- package/src/main/streaming/StreamingManager.ts +306 -0
- package/src/main/sync/CloudSyncManager.ts +532 -0
- package/src/main/verification/AutoVerifyManager.ts +285 -0
- package/src/main/vision/ComputerUseManager.ts +475 -0
- package/src/main/vision/ImageVideoGenerationManager.ts +526 -0
- package/src/main/vision/VisionManager.ts +186 -0
- package/src/renderer/App.tsx +314 -0
- package/src/renderer/components/AdvancedSettingsPanel.tsx +225 -0
- package/src/renderer/components/AgentPanel.tsx +760 -0
- package/src/renderer/components/AppPreview.tsx +220 -0
- package/src/renderer/components/AuditTrailPanel.tsx +148 -0
- package/src/renderer/components/AutomationPanel.tsx +220 -0
- package/src/renderer/components/ChatInterface.tsx +595 -0
- package/src/renderer/components/ChatTab.tsx +296 -0
- package/src/renderer/components/CodeEditor.tsx +257 -0
- package/src/renderer/components/CodeReviewPanel.tsx +256 -0
- package/src/renderer/components/CodeWorkspace.tsx +192 -0
- package/src/renderer/components/CodebaseDashboard.tsx +295 -0
- package/src/renderer/components/ComputerUsePanel.tsx +262 -0
- package/src/renderer/components/ConnectorsPanel.tsx +471 -0
- package/src/renderer/components/ContextMenu.tsx +155 -0
- package/src/renderer/components/ContextUsageDisplay.tsx +248 -0
- package/src/renderer/components/CoworkPanel.tsx +415 -0
- package/src/renderer/components/DiffViewer.tsx +452 -0
- package/src/renderer/components/ErrorBoundary.tsx +273 -0
- package/src/renderer/components/ExtendedThinkingToggle.tsx +244 -0
- package/src/renderer/components/FileAttachments.tsx +247 -0
- package/src/renderer/components/FileExplorer.tsx +242 -0
- package/src/renderer/components/FileExplorerPanel.tsx +302 -0
- package/src/renderer/components/GitPanel.tsx +154 -0
- package/src/renderer/components/Header.tsx +113 -0
- package/src/renderer/components/MCPPanel.tsx +326 -0
- package/src/renderer/components/MentionAutocomplete.tsx +239 -0
- package/src/renderer/components/PermissionPanel.tsx +159 -0
- package/src/renderer/components/PermissionSelector.tsx +203 -0
- package/src/renderer/components/PluginMarketplace.tsx +325 -0
- package/src/renderer/components/PromptOptimizerPanel.tsx +399 -0
- package/src/renderer/components/SearchPanel.tsx +173 -0
- package/src/renderer/components/SearchReplace.tsx +284 -0
- package/src/renderer/components/SessionSidebar.tsx +367 -0
- package/src/renderer/components/SettingsPanel.tsx +426 -0
- package/src/renderer/components/Sidebar.tsx +100 -0
- package/src/renderer/components/SkillsPanel.tsx +245 -0
- package/src/renderer/components/SplitPane.tsx +173 -0
- package/src/renderer/components/Terminal.tsx +190 -0
- package/src/renderer/components/VoiceCommand.tsx +129 -0
- package/src/renderer/components/WorktreePanel.tsx +163 -0
- package/src/renderer/components/ui/AriaComponents.tsx +193 -0
- package/src/renderer/components/ui/Button.tsx +68 -0
- package/src/renderer/components/ui/Card.tsx +102 -0
- package/src/renderer/components/ui/Input.tsx +44 -0
- package/src/renderer/components/ui/Skeleton.tsx +55 -0
- package/src/renderer/components/ui/VirtualList.tsx +196 -0
- package/src/renderer/i18n/I18nProvider.tsx +101 -0
- package/src/renderer/i18n/de.ts +161 -0
- package/src/renderer/i18n/en.ts +163 -0
- package/src/renderer/i18n/es.ts +161 -0
- package/src/renderer/i18n/fr.ts +161 -0
- package/src/renderer/i18n/index.ts +44 -0
- package/src/renderer/index.css +129 -0
- package/src/renderer/lib/accessibility.tsx +287 -0
- package/src/renderer/lib/hooks.ts +304 -0
- package/src/renderer/lib/utils.ts +6 -0
- package/src/renderer/main.tsx +25 -0
- package/src/renderer/styles/minimalist.css +539 -0
- package/src/renderer/sw.ts +180 -0
- package/src/renderer/types.d.ts +138 -0
- package/src/shared/types.ts +813 -0
- package/supabase/schema.sql +234 -0
- package/tailwind.config.js +78 -0
- package/tests/e2e/package.json +15 -0
- package/tests/e2e/playwright.config.ts +31 -0
- package/tests/e2e/specs/app.spec.ts +194 -0
- package/tests/setup.ts +99 -0
- package/tests/unit/AgentOrchestrator.test.ts +274 -0
- package/tests/unit/DatabaseManager.test.ts +262 -0
- package/tests/unit/GitWorktreeManager.test.ts +150 -0
- package/tests/unit/SecurityManager.test.ts +110 -0
- package/tsconfig.main.json +22 -0
- package/tsconfig.renderer.json +27 -0
- package/vite.config.ts +28 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { app } from 'electron';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as fs from 'fs/promises';
|
|
4
|
+
import * as crypto from 'crypto';
|
|
5
|
+
import { createWriteStream, createReadStream } from 'fs';
|
|
6
|
+
import { createGzip, createGunzip } from 'zlib';
|
|
7
|
+
import { pipeline } from 'stream/promises';
|
|
8
|
+
import log from 'electron-log';
|
|
9
|
+
import { format } from 'date-fns';
|
|
10
|
+
|
|
11
|
+
interface BackupMetadata {
|
|
12
|
+
id: string;
|
|
13
|
+
timestamp: string;
|
|
14
|
+
version: string;
|
|
15
|
+
size: number;
|
|
16
|
+
checksum: string;
|
|
17
|
+
contents: string[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface Migration {
|
|
21
|
+
version: string;
|
|
22
|
+
description: string;
|
|
23
|
+
up: () => Promise<void>;
|
|
24
|
+
down: () => Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class BackupManager {
|
|
28
|
+
private backupDir: string;
|
|
29
|
+
private dataDir: string;
|
|
30
|
+
private maxBackups = 10;
|
|
31
|
+
|
|
32
|
+
constructor() {
|
|
33
|
+
this.backupDir = path.join(app.getPath('userData'), 'backups');
|
|
34
|
+
this.dataDir = path.join(app.getPath('userData'), 'data');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async initialize(): Promise<void> {
|
|
38
|
+
await fs.mkdir(this.backupDir, { recursive: true });
|
|
39
|
+
await fs.mkdir(this.dataDir, { recursive: true });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async createBackup(): Promise<BackupMetadata> {
|
|
43
|
+
const timestamp = new Date();
|
|
44
|
+
const backupId = `backup-${format(timestamp, 'yyyy-MM-dd-HHmmss')}`;
|
|
45
|
+
const backupPath = path.join(this.backupDir, `${backupId}.json.gz`);
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
// List files to backup
|
|
49
|
+
const files = await this.listBackupFiles();
|
|
50
|
+
|
|
51
|
+
// Create backup archive
|
|
52
|
+
await this.createArchive(files, backupPath);
|
|
53
|
+
|
|
54
|
+
// Calculate checksum
|
|
55
|
+
const checksum = await this.calculateChecksum(backupPath);
|
|
56
|
+
|
|
57
|
+
// Get file size
|
|
58
|
+
const stats = await fs.stat(backupPath);
|
|
59
|
+
|
|
60
|
+
const metadata: BackupMetadata = {
|
|
61
|
+
id: backupId,
|
|
62
|
+
timestamp: timestamp.toISOString(),
|
|
63
|
+
version: app.getVersion(),
|
|
64
|
+
size: stats.size,
|
|
65
|
+
checksum,
|
|
66
|
+
contents: files,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Save metadata
|
|
70
|
+
await fs.writeFile(
|
|
71
|
+
path.join(this.backupDir, `${backupId}.json`),
|
|
72
|
+
JSON.stringify(metadata, null, 2)
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
// Clean old backups
|
|
76
|
+
await this.cleanupOldBackups();
|
|
77
|
+
|
|
78
|
+
log.info(`Backup created: ${backupId}`);
|
|
79
|
+
return metadata;
|
|
80
|
+
} catch (error) {
|
|
81
|
+
log.error('Failed to create backup:', error);
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async restoreBackup(backupId: string): Promise<void> {
|
|
87
|
+
const backupPath = path.join(this.backupDir, `${backupId}.json.gz`);
|
|
88
|
+
const metadataPath = path.join(this.backupDir, `${backupId}.json`);
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
// Verify backup exists
|
|
92
|
+
await fs.access(backupPath);
|
|
93
|
+
|
|
94
|
+
// Read metadata
|
|
95
|
+
const metadataContent = await fs.readFile(metadataPath, 'utf-8');
|
|
96
|
+
const metadata: BackupMetadata = JSON.parse(metadataContent);
|
|
97
|
+
|
|
98
|
+
// Verify checksum
|
|
99
|
+
const currentChecksum = await this.calculateChecksum(backupPath);
|
|
100
|
+
if (currentChecksum !== metadata.checksum) {
|
|
101
|
+
throw new Error('Backup checksum mismatch - file may be corrupted');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Create restore point
|
|
105
|
+
await this.createBackup();
|
|
106
|
+
|
|
107
|
+
// Extract backup
|
|
108
|
+
await this.extractArchive(backupPath, this.dataDir);
|
|
109
|
+
|
|
110
|
+
log.info(`Backup restored: ${backupId}`);
|
|
111
|
+
} catch (error) {
|
|
112
|
+
log.error('Failed to restore backup:', error);
|
|
113
|
+
throw error;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async listBackups(): Promise<BackupMetadata[]> {
|
|
118
|
+
try {
|
|
119
|
+
const files = await fs.readdir(this.backupDir);
|
|
120
|
+
const metadataFiles = files.filter(f => f.endsWith('.json'));
|
|
121
|
+
|
|
122
|
+
const backups: BackupMetadata[] = [];
|
|
123
|
+
for (const file of metadataFiles) {
|
|
124
|
+
const content = await fs.readFile(path.join(this.backupDir, file), 'utf-8');
|
|
125
|
+
backups.push(JSON.parse(content));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return backups.sort((a, b) =>
|
|
129
|
+
new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
|
|
130
|
+
);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
log.error('Failed to list backups:', error);
|
|
133
|
+
return [];
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async deleteBackup(backupId: string): Promise<void> {
|
|
138
|
+
try {
|
|
139
|
+
const backupPath = path.join(this.backupDir, `${backupId}.json.gz`);
|
|
140
|
+
const metadataPath = path.join(this.backupDir, `${backupId}.json`);
|
|
141
|
+
|
|
142
|
+
await fs.unlink(backupPath).catch(() => {});
|
|
143
|
+
await fs.unlink(metadataPath).catch(() => {});
|
|
144
|
+
|
|
145
|
+
log.info(`Backup deleted: ${backupId}`);
|
|
146
|
+
} catch (error) {
|
|
147
|
+
log.error('Failed to delete backup:', error);
|
|
148
|
+
throw error;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async exportBackup(backupId: string, exportPath: string): Promise<void> {
|
|
153
|
+
const backupPath = path.join(this.backupDir, `${backupId}.json.gz`);
|
|
154
|
+
await fs.copyFile(backupPath, exportPath);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
async importBackup(importPath: string): Promise<BackupMetadata> {
|
|
158
|
+
const filename = path.basename(importPath);
|
|
159
|
+
const backupId = filename.replace('.json.gz', '');
|
|
160
|
+
const backupPath = path.join(this.backupDir, filename);
|
|
161
|
+
|
|
162
|
+
await fs.copyFile(importPath, backupPath);
|
|
163
|
+
|
|
164
|
+
// Calculate metadata
|
|
165
|
+
const checksum = await this.calculateChecksum(backupPath);
|
|
166
|
+
const stats = await fs.stat(backupPath);
|
|
167
|
+
|
|
168
|
+
const metadata: BackupMetadata = {
|
|
169
|
+
id: backupId,
|
|
170
|
+
timestamp: new Date().toISOString(),
|
|
171
|
+
version: app.getVersion(),
|
|
172
|
+
size: stats.size,
|
|
173
|
+
checksum,
|
|
174
|
+
contents: [],
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
await fs.writeFile(
|
|
178
|
+
path.join(this.backupDir, `${backupId}.json`),
|
|
179
|
+
JSON.stringify(metadata, null, 2)
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
return metadata;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
private async listBackupFiles(): Promise<string[]> {
|
|
186
|
+
const files: string[] = [];
|
|
187
|
+
|
|
188
|
+
async function walk(dir: string, baseDir: string): Promise<void> {
|
|
189
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
190
|
+
|
|
191
|
+
for (const entry of entries) {
|
|
192
|
+
const fullPath = path.join(dir, entry.name);
|
|
193
|
+
const relativePath = path.relative(baseDir, fullPath);
|
|
194
|
+
|
|
195
|
+
if (entry.isDirectory()) {
|
|
196
|
+
await walk(fullPath, baseDir);
|
|
197
|
+
} else {
|
|
198
|
+
files.push(relativePath);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
await walk(this.dataDir, this.dataDir);
|
|
204
|
+
return files;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
private async createArchive(files: string[], outputPath: string): Promise<void> {
|
|
208
|
+
const backup = {
|
|
209
|
+
files: {} as Record<string, string>,
|
|
210
|
+
timestamp: new Date().toISOString(),
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
for (const file of files) {
|
|
214
|
+
const content = await fs.readFile(path.join(this.dataDir, file), 'utf-8');
|
|
215
|
+
backup.files[file] = content;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const jsonContent = JSON.stringify(backup, null, 2);
|
|
219
|
+
const compressed = await this.compress(jsonContent);
|
|
220
|
+
await fs.writeFile(outputPath, compressed);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
private async extractArchive(archivePath: string, outputDir: string): Promise<void> {
|
|
224
|
+
const compressed = await fs.readFile(archivePath);
|
|
225
|
+
const jsonContent = await this.decompress(compressed);
|
|
226
|
+
const backup = JSON.parse(jsonContent.toString());
|
|
227
|
+
|
|
228
|
+
for (const [filePath, content] of Object.entries(backup.files)) {
|
|
229
|
+
const fullPath = path.join(outputDir, filePath);
|
|
230
|
+
await fs.mkdir(path.dirname(fullPath), { recursive: true });
|
|
231
|
+
await fs.writeFile(fullPath, content as string);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
private async compress(data: string): Promise<Buffer> {
|
|
236
|
+
return new Promise((resolve, reject) => {
|
|
237
|
+
const gzip = createGzip();
|
|
238
|
+
const chunks: Buffer[] = [];
|
|
239
|
+
|
|
240
|
+
gzip.on('data', chunk => chunks.push(chunk));
|
|
241
|
+
gzip.on('end', () => resolve(Buffer.concat(chunks)));
|
|
242
|
+
gzip.on('error', reject);
|
|
243
|
+
|
|
244
|
+
gzip.end(data);
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
private async decompress(data: Buffer): Promise<string> {
|
|
249
|
+
return new Promise((resolve, reject) => {
|
|
250
|
+
const gunzip = createGunzip();
|
|
251
|
+
const chunks: Buffer[] = [];
|
|
252
|
+
|
|
253
|
+
gunzip.on('data', chunk => chunks.push(chunk));
|
|
254
|
+
gunzip.on('end', () => resolve(Buffer.concat(chunks).toString()));
|
|
255
|
+
gunzip.on('error', reject);
|
|
256
|
+
|
|
257
|
+
gunzip.end(data);
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
private async calculateChecksum(filePath: string): Promise<string> {
|
|
262
|
+
const hash = crypto.createHash('sha256');
|
|
263
|
+
const stream = createReadStream(filePath);
|
|
264
|
+
|
|
265
|
+
return new Promise((resolve, reject) => {
|
|
266
|
+
stream.on('data', chunk => hash.update(chunk));
|
|
267
|
+
stream.on('end', () => resolve(hash.digest('hex')));
|
|
268
|
+
stream.on('error', reject);
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
private async cleanupOldBackups(): Promise<void> {
|
|
273
|
+
const backups = await this.listBackups();
|
|
274
|
+
|
|
275
|
+
if (backups.length > this.maxBackups) {
|
|
276
|
+
const toDelete = backups.slice(this.maxBackups);
|
|
277
|
+
|
|
278
|
+
for (const backup of toDelete) {
|
|
279
|
+
await this.deleteBackup(backup.id);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
async cleanup(): Promise<void> {
|
|
285
|
+
log.info('Backup manager cleanup completed');
|
|
286
|
+
}
|
|
287
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { DatabaseManager } from '../DatabaseManager';
|
|
2
|
+
import log from 'electron-log';
|
|
3
|
+
|
|
4
|
+
interface Migration {
|
|
5
|
+
version: string;
|
|
6
|
+
name: string;
|
|
7
|
+
up: (db: DatabaseManager) => Promise<void>;
|
|
8
|
+
down: (db: DatabaseManager) => Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class MigrationManager {
|
|
12
|
+
private db: DatabaseManager;
|
|
13
|
+
private migrations: Migration[] = [];
|
|
14
|
+
|
|
15
|
+
constructor(db: DatabaseManager) {
|
|
16
|
+
this.db = db;
|
|
17
|
+
this.registerMigrations();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async initialize(): Promise<void> {
|
|
21
|
+
// Create migrations table
|
|
22
|
+
await this.createMigrationsTable();
|
|
23
|
+
|
|
24
|
+
// Run pending migrations
|
|
25
|
+
await this.migrate();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
private registerMigrations(): void {
|
|
29
|
+
// Migration 1: Initial schema
|
|
30
|
+
this.migrations.push({
|
|
31
|
+
version: '1.0.0',
|
|
32
|
+
name: 'initial_schema',
|
|
33
|
+
up: async (db) => {
|
|
34
|
+
// Tables already created in DatabaseManager
|
|
35
|
+
log.info('Applied migration: initial_schema');
|
|
36
|
+
},
|
|
37
|
+
down: async (db) => {
|
|
38
|
+
// Cannot rollback initial migration
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Migration 2: Add token usage tracking
|
|
43
|
+
this.migrations.push({
|
|
44
|
+
version: '1.1.0',
|
|
45
|
+
name: 'add_token_usage',
|
|
46
|
+
up: async (db) => {
|
|
47
|
+
// Add token_usage column to agent_tasks table
|
|
48
|
+
log.info('Applied migration: add_token_usage');
|
|
49
|
+
},
|
|
50
|
+
down: async (db) => {
|
|
51
|
+
// Remove token_usage column
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Migration 3: Add plugin support
|
|
56
|
+
this.migrations.push({
|
|
57
|
+
version: '1.2.0',
|
|
58
|
+
name: 'add_plugin_support',
|
|
59
|
+
up: async (db) => {
|
|
60
|
+
// Create plugins table
|
|
61
|
+
log.info('Applied migration: add_plugin_support');
|
|
62
|
+
},
|
|
63
|
+
down: async (db) => {
|
|
64
|
+
// Drop plugins table
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private async createMigrationsTable(): Promise<void> {
|
|
70
|
+
// Create table to track applied migrations
|
|
71
|
+
// This would be implemented in DatabaseManager
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async migrate(): Promise<void> {
|
|
75
|
+
const appliedMigrations = await this.getAppliedMigrations();
|
|
76
|
+
const pendingMigrations = this.migrations.filter(
|
|
77
|
+
m => !appliedMigrations.includes(m.version)
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
if (pendingMigrations.length === 0) {
|
|
81
|
+
log.info('No pending migrations');
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
log.info(`Running ${pendingMigrations.length} pending migrations...`);
|
|
86
|
+
|
|
87
|
+
for (const migration of pendingMigrations) {
|
|
88
|
+
try {
|
|
89
|
+
await migration.up(this.db);
|
|
90
|
+
await this.recordMigration(migration.version);
|
|
91
|
+
log.info(`✓ Applied migration ${migration.version}: ${migration.name}`);
|
|
92
|
+
} catch (error) {
|
|
93
|
+
log.error(`✗ Failed to apply migration ${migration.version}:`, error);
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
log.info('All migrations completed successfully');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async rollback(steps: number = 1): Promise<void> {
|
|
102
|
+
const appliedMigrations = await this.getAppliedMigrations();
|
|
103
|
+
const migrationsToRollback = appliedMigrations.slice(-steps);
|
|
104
|
+
|
|
105
|
+
for (const version of migrationsToRollback) {
|
|
106
|
+
const migration = this.migrations.find(m => m.version === version);
|
|
107
|
+
if (migration) {
|
|
108
|
+
try {
|
|
109
|
+
await migration.down(this.db);
|
|
110
|
+
await this.removeMigration(version);
|
|
111
|
+
log.info(`✓ Rolled back migration ${version}`);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
log.error(`✗ Failed to rollback migration ${version}:`, error);
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
private async getAppliedMigrations(): Promise<string[]> {
|
|
121
|
+
// Query database for applied migrations
|
|
122
|
+
return [];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private async recordMigration(version: string): Promise<void> {
|
|
126
|
+
// Insert into migrations table
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private async removeMigration(version: string): Promise<void> {
|
|
130
|
+
// Delete from migrations table
|
|
131
|
+
}
|
|
132
|
+
}
|