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,787 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.AgentOrchestrator = void 0;
|
|
40
|
+
const events_1 = require("events");
|
|
41
|
+
const uuid_1 = require("uuid");
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const fs = __importStar(require("fs/promises"));
|
|
44
|
+
const electron_log_1 = __importDefault(require("electron-log"));
|
|
45
|
+
const types_1 = require("../../shared/types");
|
|
46
|
+
const PermissionManager_1 = require("../security/PermissionManager");
|
|
47
|
+
const ClaudeMdParser_1 = require("../config/ClaudeMdParser");
|
|
48
|
+
class AgentOrchestrator extends events_1.EventEmitter {
|
|
49
|
+
aiProviderManager;
|
|
50
|
+
gitWorktreeManager;
|
|
51
|
+
skillsManager;
|
|
52
|
+
dbManager;
|
|
53
|
+
agents = new Map();
|
|
54
|
+
activeTasks = new Map();
|
|
55
|
+
lastActivity = new Map();
|
|
56
|
+
cleanupInterval = null;
|
|
57
|
+
INACTIVE_THRESHOLD = 24 * 60 * 60 * 1000; // 24 hours
|
|
58
|
+
MAX_RETRIES = 3;
|
|
59
|
+
RETRY_DELAY = 1000; // 1 second
|
|
60
|
+
AUTO_CONTEXT_MAX_FILES = 12;
|
|
61
|
+
AUTO_CONTEXT_MAX_CHARS_PER_FILE = 4000;
|
|
62
|
+
AUTO_CONTEXT_MAX_TOTAL_CHARS = 24000;
|
|
63
|
+
permissionManager;
|
|
64
|
+
constructor(aiProviderManager, gitWorktreeManager, skillsManager, dbManager) {
|
|
65
|
+
super();
|
|
66
|
+
this.aiProviderManager = aiProviderManager;
|
|
67
|
+
this.gitWorktreeManager = gitWorktreeManager;
|
|
68
|
+
this.skillsManager = skillsManager;
|
|
69
|
+
this.dbManager = dbManager;
|
|
70
|
+
this.permissionManager = new PermissionManager_1.PermissionManager();
|
|
71
|
+
this.startCleanupInterval();
|
|
72
|
+
}
|
|
73
|
+
startCleanupInterval() {
|
|
74
|
+
// Cleanup inactive agents every hour
|
|
75
|
+
this.cleanupInterval = setInterval(() => {
|
|
76
|
+
this.cleanupInactiveAgents();
|
|
77
|
+
}, 60 * 60 * 1000);
|
|
78
|
+
// Don't keep the process alive (important for tests)
|
|
79
|
+
this.cleanupInterval.unref?.();
|
|
80
|
+
}
|
|
81
|
+
async getAgentOrThrow(agentId) {
|
|
82
|
+
const cached = this.agents.get(agentId);
|
|
83
|
+
if (cached)
|
|
84
|
+
return cached;
|
|
85
|
+
const fromDb = await this.dbManager.getAgent(agentId);
|
|
86
|
+
if (!fromDb) {
|
|
87
|
+
throw new Error(`Agent ${agentId} not found`);
|
|
88
|
+
}
|
|
89
|
+
this.agents.set(agentId, fromDb);
|
|
90
|
+
this.lastActivity.set(agentId, fromDb.lastActiveAt || fromDb.updatedAt);
|
|
91
|
+
return fromDb;
|
|
92
|
+
}
|
|
93
|
+
async cleanupInactiveAgents() {
|
|
94
|
+
const now = new Date();
|
|
95
|
+
const agentsToDelete = [];
|
|
96
|
+
for (const [agentId, lastActive] of this.lastActivity) {
|
|
97
|
+
const inactiveTime = now.getTime() - lastActive.getTime();
|
|
98
|
+
if (inactiveTime > this.INACTIVE_THRESHOLD) {
|
|
99
|
+
const agent = this.agents.get(agentId);
|
|
100
|
+
if (agent && agent.status !== types_1.AgentStatus.RUNNING) {
|
|
101
|
+
agentsToDelete.push(agentId);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
for (const agentId of agentsToDelete) {
|
|
106
|
+
try {
|
|
107
|
+
await this.deleteAgent(agentId);
|
|
108
|
+
electron_log_1.default.info(`Cleaned up inactive agent: ${agentId}`);
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
electron_log_1.default.error(`Failed to cleanup agent ${agentId}:`, error);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async initialize() {
|
|
116
|
+
// Load existing agents from database
|
|
117
|
+
const agents = await this.dbManager.getAllAgents();
|
|
118
|
+
for (const agent of agents) {
|
|
119
|
+
this.agents.set(agent.id, agent);
|
|
120
|
+
this.lastActivity.set(agent.id, agent.lastActiveAt || agent.updatedAt);
|
|
121
|
+
if (agent.status === types_1.AgentStatus.RUNNING) {
|
|
122
|
+
// Mark as error since we can't restore running state
|
|
123
|
+
agent.status = types_1.AgentStatus.ERROR;
|
|
124
|
+
await this.dbManager.updateAgent(agent);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
electron_log_1.default.info(`Loaded ${agents.length} agents from database`);
|
|
128
|
+
}
|
|
129
|
+
async cleanup() {
|
|
130
|
+
// Stop cleanup interval
|
|
131
|
+
if (this.cleanupInterval) {
|
|
132
|
+
clearInterval(this.cleanupInterval);
|
|
133
|
+
this.cleanupInterval = null;
|
|
134
|
+
}
|
|
135
|
+
// Stop all running agents
|
|
136
|
+
const cleanupPromises = [];
|
|
137
|
+
for (const [agentId, agent] of this.agents) {
|
|
138
|
+
if (agent.status === types_1.AgentStatus.RUNNING) {
|
|
139
|
+
cleanupPromises.push(this.pauseAgent(agentId));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
await Promise.all(cleanupPromises);
|
|
143
|
+
// Clear maps
|
|
144
|
+
this.agents.clear();
|
|
145
|
+
this.activeTasks.clear();
|
|
146
|
+
this.lastActivity.clear();
|
|
147
|
+
}
|
|
148
|
+
async createAgent(config) {
|
|
149
|
+
const agentId = (0, uuid_1.v4)();
|
|
150
|
+
const worktreeName = `codex-agent-${agentId.slice(0, 8)}`;
|
|
151
|
+
// Create worktree for isolation
|
|
152
|
+
const worktree = await this.gitWorktreeManager.createWorktree(config.projectPath, worktreeName);
|
|
153
|
+
// Load CLAUDE.md configuration
|
|
154
|
+
const claudeMdParser = new ClaudeMdParser_1.ClaudeMdParser();
|
|
155
|
+
const claudeMdConfig = await claudeMdParser.load(config.projectPath);
|
|
156
|
+
// Merge CLAUDE.md config with provided config
|
|
157
|
+
const mergedConfig = {
|
|
158
|
+
...config,
|
|
159
|
+
// Override with CLAUDE.md agent settings if present
|
|
160
|
+
model: claudeMdConfig?.agents?.defaultModel || config.model,
|
|
161
|
+
providerId: claudeMdConfig?.agents?.defaultProvider || config.providerId,
|
|
162
|
+
skills: [...(config.skills || []), ...(claudeMdConfig?.agents?.skills || [])],
|
|
163
|
+
systemPrompt: this.buildSystemPrompt(config.systemPrompt, claudeMdConfig)
|
|
164
|
+
};
|
|
165
|
+
const agent = {
|
|
166
|
+
id: agentId,
|
|
167
|
+
name: mergedConfig.name,
|
|
168
|
+
status: types_1.AgentStatus.IDLE,
|
|
169
|
+
projectPath: mergedConfig.projectPath,
|
|
170
|
+
worktreeName,
|
|
171
|
+
worktreePath: worktree.path,
|
|
172
|
+
providerId: mergedConfig.providerId,
|
|
173
|
+
model: mergedConfig.model,
|
|
174
|
+
skills: mergedConfig.skills || [],
|
|
175
|
+
permissionMode: claudeMdConfig?.agents?.permissionMode || this.permissionManager.getDefaultMode(),
|
|
176
|
+
createdAt: new Date(),
|
|
177
|
+
updatedAt: new Date(),
|
|
178
|
+
lastActiveAt: null,
|
|
179
|
+
messages: [],
|
|
180
|
+
tasks: [],
|
|
181
|
+
metadata: {
|
|
182
|
+
...mergedConfig.metadata,
|
|
183
|
+
worktreePath: worktree.path,
|
|
184
|
+
claudeMdConfig: claudeMdConfig ? {
|
|
185
|
+
version: claudeMdConfig.version,
|
|
186
|
+
projectName: claudeMdConfig.project?.name,
|
|
187
|
+
loadedAt: new Date().toISOString()
|
|
188
|
+
} : undefined
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
// Add system message if provided
|
|
192
|
+
if (mergedConfig.systemPrompt) {
|
|
193
|
+
agent.messages.push({
|
|
194
|
+
id: (0, uuid_1.v4)(),
|
|
195
|
+
role: 'system',
|
|
196
|
+
content: mergedConfig.systemPrompt,
|
|
197
|
+
timestamp: new Date()
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
// Apply skills
|
|
201
|
+
if (agent.skills.length > 0) {
|
|
202
|
+
await this.applySkillsInternal(agent, agent.skills);
|
|
203
|
+
}
|
|
204
|
+
this.agents.set(agentId, agent);
|
|
205
|
+
this.lastActivity.set(agentId, new Date());
|
|
206
|
+
await this.dbManager.createAgent(agent);
|
|
207
|
+
this.emit('agent:created', agent);
|
|
208
|
+
electron_log_1.default.info(`Created agent ${agentId} (${agent.name})`);
|
|
209
|
+
return agent;
|
|
210
|
+
}
|
|
211
|
+
async listAgents() {
|
|
212
|
+
return Array.from(this.agents.values());
|
|
213
|
+
}
|
|
214
|
+
async getAgent(agentId) {
|
|
215
|
+
return this.agents.get(agentId) || null;
|
|
216
|
+
}
|
|
217
|
+
async sendMessage(agentId, message, options) {
|
|
218
|
+
const agent = await this.getAgentOrThrow(agentId);
|
|
219
|
+
const userMessage = {
|
|
220
|
+
id: (0, uuid_1.v4)(),
|
|
221
|
+
role: 'user',
|
|
222
|
+
content: message,
|
|
223
|
+
timestamp: new Date()
|
|
224
|
+
};
|
|
225
|
+
agent.messages.push(userMessage);
|
|
226
|
+
agent.lastActiveAt = new Date();
|
|
227
|
+
agent.status = types_1.AgentStatus.RUNNING;
|
|
228
|
+
this.lastActivity.set(agentId, new Date());
|
|
229
|
+
await this.dbManager.updateAgent(agent);
|
|
230
|
+
this.emit('agent:message', { agentId, message: userMessage });
|
|
231
|
+
// Get AI response with retry logic
|
|
232
|
+
try {
|
|
233
|
+
const autoContext = await this.buildAutoContext(agent, message);
|
|
234
|
+
const response = await this.getAIResponseWithRetry(agent, options, autoContext?.systemMessage);
|
|
235
|
+
const assistantMessage = {
|
|
236
|
+
id: (0, uuid_1.v4)(),
|
|
237
|
+
role: 'assistant',
|
|
238
|
+
content: response.content,
|
|
239
|
+
timestamp: new Date(),
|
|
240
|
+
metadata: {
|
|
241
|
+
...response.metadata,
|
|
242
|
+
autoContext: autoContext?.metadata
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
agent.messages.push(assistantMessage);
|
|
246
|
+
agent.status = types_1.AgentStatus.IDLE;
|
|
247
|
+
await this.dbManager.updateAgent(agent);
|
|
248
|
+
this.emit('agent:message', { agentId, message: assistantMessage });
|
|
249
|
+
return assistantMessage;
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
agent.status = types_1.AgentStatus.ERROR;
|
|
253
|
+
await this.dbManager.updateAgent(agent);
|
|
254
|
+
throw error;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
async sendMessageStream(agentId, message, callbacks) {
|
|
258
|
+
const agent = this.agents.get(agentId);
|
|
259
|
+
if (!agent) {
|
|
260
|
+
throw new Error(`Agent ${agentId} not found`);
|
|
261
|
+
}
|
|
262
|
+
const userMessage = {
|
|
263
|
+
id: (0, uuid_1.v4)(),
|
|
264
|
+
role: 'user',
|
|
265
|
+
content: message,
|
|
266
|
+
timestamp: new Date()
|
|
267
|
+
};
|
|
268
|
+
agent.messages.push(userMessage);
|
|
269
|
+
agent.lastActiveAt = new Date();
|
|
270
|
+
agent.status = types_1.AgentStatus.RUNNING;
|
|
271
|
+
this.lastActivity.set(agentId, new Date());
|
|
272
|
+
await this.dbManager.updateAgent(agent);
|
|
273
|
+
this.emit('agent:message', { agentId, message: userMessage });
|
|
274
|
+
try {
|
|
275
|
+
const provider = this.aiProviderManager.getProvider(agent.providerId);
|
|
276
|
+
if (!provider) {
|
|
277
|
+
throw new Error(`Provider ${agent.providerId} not found`);
|
|
278
|
+
}
|
|
279
|
+
const autoContext = await this.buildAutoContext(agent, message);
|
|
280
|
+
const modelMessages = (autoContext?.systemMessage
|
|
281
|
+
? [...agent.messages, autoContext.systemMessage]
|
|
282
|
+
: agent.messages);
|
|
283
|
+
// Check if provider supports streaming
|
|
284
|
+
if (typeof provider.sendMessageStream === 'function') {
|
|
285
|
+
await provider.sendMessageStream(agent.model, modelMessages, {
|
|
286
|
+
onChunk: (chunk) => {
|
|
287
|
+
callbacks.onChunk(chunk);
|
|
288
|
+
},
|
|
289
|
+
onComplete: async () => {
|
|
290
|
+
const response = await this.getAIResponseWithRetry(agent, undefined, autoContext?.systemMessage);
|
|
291
|
+
const assistantMessage = {
|
|
292
|
+
id: (0, uuid_1.v4)(),
|
|
293
|
+
role: 'assistant',
|
|
294
|
+
content: response.content,
|
|
295
|
+
timestamp: new Date(),
|
|
296
|
+
metadata: {
|
|
297
|
+
...response.metadata,
|
|
298
|
+
autoContext: autoContext?.metadata
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
agent.messages.push(assistantMessage);
|
|
302
|
+
agent.status = types_1.AgentStatus.IDLE;
|
|
303
|
+
await this.dbManager.updateAgent(agent);
|
|
304
|
+
this.emit('agent:message', { agentId, message: assistantMessage });
|
|
305
|
+
callbacks.onComplete();
|
|
306
|
+
},
|
|
307
|
+
onError: async (error) => {
|
|
308
|
+
agent.status = types_1.AgentStatus.ERROR;
|
|
309
|
+
await this.dbManager.updateAgent(agent);
|
|
310
|
+
callbacks.onError(error);
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
// Fallback to non-streaming
|
|
316
|
+
const response = await this.getAIResponseWithRetry(agent, undefined, autoContext?.systemMessage);
|
|
317
|
+
callbacks.onChunk(response.content);
|
|
318
|
+
const assistantMessage = {
|
|
319
|
+
id: (0, uuid_1.v4)(),
|
|
320
|
+
role: 'assistant',
|
|
321
|
+
content: response.content,
|
|
322
|
+
timestamp: new Date(),
|
|
323
|
+
metadata: {
|
|
324
|
+
...response.metadata,
|
|
325
|
+
autoContext: autoContext?.metadata
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
agent.messages.push(assistantMessage);
|
|
329
|
+
agent.status = types_1.AgentStatus.IDLE;
|
|
330
|
+
await this.dbManager.updateAgent(agent);
|
|
331
|
+
this.emit('agent:message', { agentId, message: assistantMessage });
|
|
332
|
+
callbacks.onComplete();
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
catch (error) {
|
|
336
|
+
agent.status = types_1.AgentStatus.ERROR;
|
|
337
|
+
await this.dbManager.updateAgent(agent);
|
|
338
|
+
callbacks.onError(error);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
async getAIResponseWithRetry(agent, options, ephemeralSystemMessage, attempt = 1) {
|
|
342
|
+
try {
|
|
343
|
+
return await this.getAIResponse(agent, options, ephemeralSystemMessage);
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
if (attempt < this.MAX_RETRIES && this.isRetryableError(error)) {
|
|
347
|
+
electron_log_1.default.warn(`Retrying AI request for agent ${agent.id}, attempt ${attempt + 1}/${this.MAX_RETRIES}`);
|
|
348
|
+
await this.delay(this.RETRY_DELAY * attempt); // Exponential backoff
|
|
349
|
+
return this.getAIResponseWithRetry(agent, options, ephemeralSystemMessage, attempt + 1);
|
|
350
|
+
}
|
|
351
|
+
throw error;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
async getAIResponse(agent, options, ephemeralSystemMessage) {
|
|
355
|
+
const provider = this.aiProviderManager.getProvider(agent.providerId);
|
|
356
|
+
if (!provider) {
|
|
357
|
+
throw new Error(`Provider ${agent.providerId} not found`);
|
|
358
|
+
}
|
|
359
|
+
const messages = (ephemeralSystemMessage
|
|
360
|
+
? [...agent.messages, ephemeralSystemMessage]
|
|
361
|
+
: agent.messages).map(m => ({ role: m.role, content: m.content }));
|
|
362
|
+
return await provider.sendMessage(agent.model, messages, {
|
|
363
|
+
signal: options?.signal,
|
|
364
|
+
onProgress: options?.onProgress,
|
|
365
|
+
extendedThinking: options?.extendedThinking,
|
|
366
|
+
reasoningEffort: options?.reasoningEffort
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
async buildAutoContext(agent, userIntent) {
|
|
370
|
+
const enabled = agent.metadata?.autoContext !== false;
|
|
371
|
+
if (!enabled)
|
|
372
|
+
return null;
|
|
373
|
+
if (!agent.projectPath || typeof agent.projectPath !== 'string') {
|
|
374
|
+
return null;
|
|
375
|
+
}
|
|
376
|
+
const worktreePath = agent.worktreePath
|
|
377
|
+
? agent.worktreePath
|
|
378
|
+
: (agent.worktreeName
|
|
379
|
+
? path.join(agent.projectPath, '.codex', 'worktrees', agent.worktreeName)
|
|
380
|
+
: agent.projectPath);
|
|
381
|
+
if (!worktreePath || typeof worktreePath !== 'string') {
|
|
382
|
+
return null;
|
|
383
|
+
}
|
|
384
|
+
const candidates = [];
|
|
385
|
+
const addCandidate = (relPath, reason) => {
|
|
386
|
+
if (!relPath)
|
|
387
|
+
return;
|
|
388
|
+
if (candidates.some(c => c.relPath === relPath))
|
|
389
|
+
return;
|
|
390
|
+
candidates.push({ relPath, reason });
|
|
391
|
+
};
|
|
392
|
+
// Always-valuable files
|
|
393
|
+
addCandidate('CLAUDE.md', 'Project conventions');
|
|
394
|
+
addCandidate('README.md', 'Project overview');
|
|
395
|
+
addCandidate('package.json', 'Dependencies/scripts');
|
|
396
|
+
addCandidate('tsconfig.json', 'TypeScript config');
|
|
397
|
+
addCandidate('tsconfig.main.json', 'Main TS config');
|
|
398
|
+
addCandidate('tsconfig.renderer.json', 'Renderer TS config');
|
|
399
|
+
// Recently changed files in this worktree
|
|
400
|
+
try {
|
|
401
|
+
const changes = await this.gitWorktreeManager.getChanges(worktreePath);
|
|
402
|
+
const recent = [...changes.staged, ...changes.unstaged].slice(0, 6);
|
|
403
|
+
for (const f of recent) {
|
|
404
|
+
addCandidate(f, 'Recently changed in worktree');
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
catch {
|
|
408
|
+
// ignore
|
|
409
|
+
}
|
|
410
|
+
const selected = candidates.slice(0, this.AUTO_CONTEXT_MAX_FILES);
|
|
411
|
+
let totalChars = 0;
|
|
412
|
+
const used = [];
|
|
413
|
+
const parts = [];
|
|
414
|
+
for (const c of selected) {
|
|
415
|
+
const abs = path.join(worktreePath, c.relPath);
|
|
416
|
+
try {
|
|
417
|
+
const raw = await fs.readFile(abs, 'utf-8');
|
|
418
|
+
const clipped = raw.length > this.AUTO_CONTEXT_MAX_CHARS_PER_FILE
|
|
419
|
+
? raw.slice(0, this.AUTO_CONTEXT_MAX_CHARS_PER_FILE) + '\n\n[TRUNCATED]'
|
|
420
|
+
: raw;
|
|
421
|
+
if (totalChars + clipped.length > this.AUTO_CONTEXT_MAX_TOTAL_CHARS)
|
|
422
|
+
break;
|
|
423
|
+
totalChars += clipped.length;
|
|
424
|
+
used.push({ path: c.relPath, reason: c.reason });
|
|
425
|
+
parts.push(`## ${c.relPath}\nReason: ${c.reason}\n\n${clipped}`);
|
|
426
|
+
}
|
|
427
|
+
catch {
|
|
428
|
+
// ignore
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
if (parts.length === 0)
|
|
432
|
+
return null;
|
|
433
|
+
const systemMessage = {
|
|
434
|
+
id: (0, uuid_1.v4)(),
|
|
435
|
+
role: 'system',
|
|
436
|
+
content: `# Auto-context (ephemeral)\nUser intent: ${userIntent}\n\n${parts.join('\n\n')}`,
|
|
437
|
+
timestamp: new Date(),
|
|
438
|
+
metadata: {
|
|
439
|
+
autoContext: {
|
|
440
|
+
files: used,
|
|
441
|
+
totalChars
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
return {
|
|
446
|
+
systemMessage,
|
|
447
|
+
metadata: {
|
|
448
|
+
files: used,
|
|
449
|
+
totalChars
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
isRetryableError(error) {
|
|
454
|
+
// Retry on network errors, timeouts, rate limits
|
|
455
|
+
if (!error)
|
|
456
|
+
return false;
|
|
457
|
+
const retryableCodes = ['ECONNRESET', 'ETIMEDOUT', 'ECONNREFUSED', 'RATE_LIMITED'];
|
|
458
|
+
const retryableStatuses = [429, 502, 503, 504];
|
|
459
|
+
return retryableCodes.includes(error.code) ||
|
|
460
|
+
retryableStatuses.includes(error.status) ||
|
|
461
|
+
error.message?.includes('timeout') ||
|
|
462
|
+
error.message?.includes('rate limit');
|
|
463
|
+
}
|
|
464
|
+
delay(ms) {
|
|
465
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
466
|
+
}
|
|
467
|
+
async executeTask(agentId, task, timeout = 30 * 60 * 1000) {
|
|
468
|
+
const agent = await this.getAgentOrThrow(agentId);
|
|
469
|
+
const taskId = (0, uuid_1.v4)();
|
|
470
|
+
const agentTask = {
|
|
471
|
+
id: taskId,
|
|
472
|
+
description: task,
|
|
473
|
+
status: types_1.TaskStatus.RUNNING,
|
|
474
|
+
progress: 0,
|
|
475
|
+
startedAt: new Date()
|
|
476
|
+
};
|
|
477
|
+
agent.tasks.push(agentTask);
|
|
478
|
+
agent.status = types_1.AgentStatus.RUNNING;
|
|
479
|
+
this.lastActivity.set(agentId, new Date());
|
|
480
|
+
await this.dbManager.updateAgent(agent);
|
|
481
|
+
this.emit('agent:taskStarted', { agentId, task: agentTask });
|
|
482
|
+
// Create abort controller for this task
|
|
483
|
+
const abortController = new AbortController();
|
|
484
|
+
this.activeTasks.set(taskId, abortController);
|
|
485
|
+
// Set up timeout
|
|
486
|
+
const timeoutId = setTimeout(() => {
|
|
487
|
+
abortController.abort();
|
|
488
|
+
electron_log_1.default.warn(`Task ${taskId} timed out after ${timeout}ms`);
|
|
489
|
+
}, timeout);
|
|
490
|
+
// Execute task in background
|
|
491
|
+
this.runTask(agent, agentTask, abortController)
|
|
492
|
+
.then(() => {
|
|
493
|
+
clearTimeout(timeoutId);
|
|
494
|
+
})
|
|
495
|
+
.catch(error => {
|
|
496
|
+
clearTimeout(timeoutId);
|
|
497
|
+
electron_log_1.default.error(`Task ${taskId} failed:`, error);
|
|
498
|
+
agentTask.status = types_1.TaskStatus.FAILED;
|
|
499
|
+
agentTask.error = error.message;
|
|
500
|
+
agentTask.completedAt = new Date();
|
|
501
|
+
this.emit('agent:taskFailed', { agentId, task: agentTask, error });
|
|
502
|
+
});
|
|
503
|
+
return agentTask;
|
|
504
|
+
}
|
|
505
|
+
async runTask(agent, task, abortController) {
|
|
506
|
+
try {
|
|
507
|
+
// Set up task context
|
|
508
|
+
const taskMessage = {
|
|
509
|
+
id: (0, uuid_1.v4)(),
|
|
510
|
+
role: 'user',
|
|
511
|
+
content: `[TASK] ${task.description}`,
|
|
512
|
+
timestamp: new Date()
|
|
513
|
+
};
|
|
514
|
+
agent.messages.push(taskMessage);
|
|
515
|
+
// Process the task with streaming updates
|
|
516
|
+
const autoContext = await this.buildAutoContext(agent, task.description);
|
|
517
|
+
const response = await this.getAIResponse(agent, {
|
|
518
|
+
signal: abortController.signal,
|
|
519
|
+
onProgress: (progress) => {
|
|
520
|
+
task.progress = progress;
|
|
521
|
+
this.emit('agent:progress', { agentId: agent.id, taskId: task.id, progress });
|
|
522
|
+
}
|
|
523
|
+
}, autoContext?.systemMessage);
|
|
524
|
+
// Parse and apply code changes
|
|
525
|
+
const changes = await this.parseAndApplyChanges(agent, response.content);
|
|
526
|
+
task.result = response.content;
|
|
527
|
+
task.status = types_1.TaskStatus.COMPLETED;
|
|
528
|
+
task.progress = 100;
|
|
529
|
+
task.completedAt = new Date();
|
|
530
|
+
const assistantMessage = {
|
|
531
|
+
id: (0, uuid_1.v4)(),
|
|
532
|
+
role: 'assistant',
|
|
533
|
+
content: response.content,
|
|
534
|
+
timestamp: new Date(),
|
|
535
|
+
metadata: {
|
|
536
|
+
changes: changes.map(c => c.id),
|
|
537
|
+
autoContext: autoContext?.metadata
|
|
538
|
+
}
|
|
539
|
+
};
|
|
540
|
+
agent.messages.push(assistantMessage);
|
|
541
|
+
agent.status = types_1.AgentStatus.IDLE;
|
|
542
|
+
agent.lastActiveAt = new Date();
|
|
543
|
+
await this.dbManager.updateAgent(agent);
|
|
544
|
+
this.emit('agent:taskCompleted', { agentId: agent.id, task });
|
|
545
|
+
}
|
|
546
|
+
catch (error) {
|
|
547
|
+
if (abortController.signal.aborted) {
|
|
548
|
+
task.status = types_1.TaskStatus.CANCELLED;
|
|
549
|
+
}
|
|
550
|
+
else {
|
|
551
|
+
task.status = types_1.TaskStatus.FAILED;
|
|
552
|
+
task.error = error instanceof Error ? error.message : String(error);
|
|
553
|
+
}
|
|
554
|
+
task.completedAt = new Date();
|
|
555
|
+
agent.status = types_1.AgentStatus.ERROR;
|
|
556
|
+
await this.dbManager.updateAgent(agent);
|
|
557
|
+
throw error;
|
|
558
|
+
}
|
|
559
|
+
finally {
|
|
560
|
+
this.activeTasks.delete(task.id);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
async pauseAgent(agentId) {
|
|
564
|
+
const agent = await this.getAgentOrThrow(agentId);
|
|
565
|
+
// Abort any running tasks
|
|
566
|
+
for (const [taskId, controller] of this.activeTasks) {
|
|
567
|
+
const task = agent.tasks.find(t => t.id === taskId);
|
|
568
|
+
if (task && task.status === types_1.TaskStatus.RUNNING) {
|
|
569
|
+
controller.abort();
|
|
570
|
+
task.status = types_1.TaskStatus.PAUSED;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
agent.status = types_1.AgentStatus.PAUSED;
|
|
574
|
+
await this.dbManager.updateAgent(agent);
|
|
575
|
+
this.emit('agent:paused', { agentId });
|
|
576
|
+
}
|
|
577
|
+
async resumeAgent(agentId) {
|
|
578
|
+
const agent = await this.getAgentOrThrow(agentId);
|
|
579
|
+
agent.status = types_1.AgentStatus.IDLE;
|
|
580
|
+
await this.dbManager.updateAgent(agent);
|
|
581
|
+
this.emit('agent:resumed', { agentId });
|
|
582
|
+
}
|
|
583
|
+
async stopAgent(agentId) {
|
|
584
|
+
const agent = await this.getAgentOrThrow(agentId);
|
|
585
|
+
// Abort all tasks
|
|
586
|
+
for (const [taskId, controller] of this.activeTasks) {
|
|
587
|
+
const task = agent.tasks.find(t => t.id === taskId);
|
|
588
|
+
if (task) {
|
|
589
|
+
controller.abort();
|
|
590
|
+
task.status = types_1.TaskStatus.CANCELLED;
|
|
591
|
+
task.completedAt = new Date();
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
agent.status = types_1.AgentStatus.IDLE;
|
|
595
|
+
await this.dbManager.updateAgent(agent);
|
|
596
|
+
this.emit('agent:stopped', { agentId });
|
|
597
|
+
}
|
|
598
|
+
async deleteAgent(agentId) {
|
|
599
|
+
const agent = await this.getAgentOrThrow(agentId);
|
|
600
|
+
// Stop any running tasks
|
|
601
|
+
await this.stopAgent(agentId);
|
|
602
|
+
// Remove worktree
|
|
603
|
+
try {
|
|
604
|
+
await this.gitWorktreeManager.removeWorktree(agent.projectPath, agent.worktreeName);
|
|
605
|
+
}
|
|
606
|
+
catch (error) {
|
|
607
|
+
electron_log_1.default.warn(`Failed to remove worktree for agent ${agentId}:`, error);
|
|
608
|
+
}
|
|
609
|
+
this.agents.delete(agentId);
|
|
610
|
+
this.lastActivity.delete(agentId);
|
|
611
|
+
await this.dbManager.deleteAgent(agentId);
|
|
612
|
+
this.emit('agent:deleted', { agentId });
|
|
613
|
+
electron_log_1.default.info(`Deleted agent ${agentId}`);
|
|
614
|
+
}
|
|
615
|
+
async applySkills(agentId, skillIds) {
|
|
616
|
+
const agent = await this.getAgentOrThrow(agentId);
|
|
617
|
+
await this.applySkillsInternal(agent, skillIds);
|
|
618
|
+
agent.skills = [...new Set([...agent.skills, ...skillIds])];
|
|
619
|
+
await this.dbManager.updateAgent(agent);
|
|
620
|
+
this.emit('skill:applied', { agentId, skillIds });
|
|
621
|
+
}
|
|
622
|
+
async applySkillsInternal(agent, skillIds) {
|
|
623
|
+
for (const skillId of skillIds) {
|
|
624
|
+
const skill = await this.skillsManager.getSkill(skillId);
|
|
625
|
+
if (skill) {
|
|
626
|
+
// Add skill instructions to system context
|
|
627
|
+
const instructionFiles = skill.files.filter(f => f.type === 'instruction');
|
|
628
|
+
for (const file of instructionFiles) {
|
|
629
|
+
agent.messages.push({
|
|
630
|
+
id: (0, uuid_1.v4)(),
|
|
631
|
+
role: 'system',
|
|
632
|
+
content: `[SKILL: ${skill.name}]\n${file.content}`,
|
|
633
|
+
timestamp: new Date(),
|
|
634
|
+
metadata: { skillId, skillName: skill.name }
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
async parseAndApplyChanges(agent, content) {
|
|
641
|
+
const changes = [];
|
|
642
|
+
const diffRegex = /diff --git a\/(.+?) b\/(.+?)\n([\s\S]*?)(?=\ndiff --git|$)/g;
|
|
643
|
+
let match;
|
|
644
|
+
const worktreePath = agent.worktreePath
|
|
645
|
+
? agent.worktreePath
|
|
646
|
+
: (agent.worktreeName
|
|
647
|
+
? path.join(agent.projectPath, '.codex', 'worktrees', agent.worktreeName)
|
|
648
|
+
: agent.projectPath);
|
|
649
|
+
while ((match = diffRegex.exec(content)) !== null) {
|
|
650
|
+
const [, oldFile, newFile, diffContent] = match;
|
|
651
|
+
const filePath = newFile.trim();
|
|
652
|
+
let originalContent = '';
|
|
653
|
+
let newContent = '';
|
|
654
|
+
try {
|
|
655
|
+
const fullFilePath = path.join(worktreePath, filePath);
|
|
656
|
+
originalContent = await fs.readFile(fullFilePath, 'utf-8');
|
|
657
|
+
}
|
|
658
|
+
catch {
|
|
659
|
+
electron_log_1.default.warn(`Could not read original file: ${filePath}, file may be new`);
|
|
660
|
+
}
|
|
661
|
+
newContent = this.applyDiff(originalContent, diffContent);
|
|
662
|
+
const change = {
|
|
663
|
+
id: (0, uuid_1.v4)(),
|
|
664
|
+
filePath,
|
|
665
|
+
originalContent,
|
|
666
|
+
newContent,
|
|
667
|
+
diff: diffContent,
|
|
668
|
+
agentId: agent.id,
|
|
669
|
+
taskId: agent.tasks[agent.tasks.length - 1]?.id || '',
|
|
670
|
+
status: types_1.ChangeStatus.PENDING,
|
|
671
|
+
createdAt: new Date()
|
|
672
|
+
};
|
|
673
|
+
changes.push(change);
|
|
674
|
+
await this.dbManager.createCodeChange(change);
|
|
675
|
+
this.emit('changes:created', { agentId: agent.id, changeId: change.id });
|
|
676
|
+
}
|
|
677
|
+
return changes;
|
|
678
|
+
}
|
|
679
|
+
applyDiff(originalContent, diffContent) {
|
|
680
|
+
const lines = diffContent.split('\n');
|
|
681
|
+
const result = [];
|
|
682
|
+
let i = 0;
|
|
683
|
+
while (i < lines.length) {
|
|
684
|
+
const line = lines[i];
|
|
685
|
+
if (line.startsWith('@@')) {
|
|
686
|
+
const hunkHeader = line;
|
|
687
|
+
const match = hunkHeader.match(/@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@/);
|
|
688
|
+
if (match) {
|
|
689
|
+
const [, oldStart, oldCount, newStart, newCount] = match.map(Number);
|
|
690
|
+
const originalLines = originalContent.split('\n');
|
|
691
|
+
const beforeContext = originalLines.slice(Math.max(0, oldStart - 2), oldStart - 1);
|
|
692
|
+
result.push(...beforeContext);
|
|
693
|
+
i++;
|
|
694
|
+
const hunkOldLines = [];
|
|
695
|
+
const hunkNewLines = [];
|
|
696
|
+
while (i < lines.length && !lines[i].startsWith('@@') && !lines[i].startsWith('diff ')) {
|
|
697
|
+
if (lines[i].startsWith('-')) {
|
|
698
|
+
hunkOldLines.push(lines[i].substring(1));
|
|
699
|
+
}
|
|
700
|
+
else if (lines[i].startsWith('+')) {
|
|
701
|
+
hunkNewLines.push(lines[i].substring(1));
|
|
702
|
+
}
|
|
703
|
+
else if (!lines[i].startsWith('\\')) {
|
|
704
|
+
hunkOldLines.push(lines[i]);
|
|
705
|
+
hunkNewLines.push(lines[i]);
|
|
706
|
+
}
|
|
707
|
+
i++;
|
|
708
|
+
}
|
|
709
|
+
result.push(...hunkNewLines);
|
|
710
|
+
const afterContext = originalLines.slice(oldStart - 1 + (oldCount || hunkOldLines.length), oldStart - 1 + (oldCount || hunkOldLines.length) + 2);
|
|
711
|
+
result.push(...afterContext);
|
|
712
|
+
continue;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
i++;
|
|
716
|
+
}
|
|
717
|
+
if (result.length === 0 && diffContent.includes('new file')) {
|
|
718
|
+
const newFileMatch = diffContent.match(/\+\+\+ b\/(.+)/);
|
|
719
|
+
if (newFileMatch) {
|
|
720
|
+
const newLines = [];
|
|
721
|
+
for (const line of lines) {
|
|
722
|
+
if (line.startsWith('+') && !line.startsWith('+++')) {
|
|
723
|
+
newLines.push(line.substring(1));
|
|
724
|
+
}
|
|
725
|
+
else if (line.startsWith(' ')) {
|
|
726
|
+
newLines.push(line.substring(1));
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
return newLines.join('\n');
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
return result.join('\n');
|
|
733
|
+
}
|
|
734
|
+
// Permission Management
|
|
735
|
+
setAgentPermissionMode(agentId, mode) {
|
|
736
|
+
const agent = this.agents.get(agentId);
|
|
737
|
+
if (!agent) {
|
|
738
|
+
throw new Error(`Agent ${agentId} not found`);
|
|
739
|
+
}
|
|
740
|
+
agent.permissionMode = mode;
|
|
741
|
+
this.permissionManager.setAgentMode(agentId, mode);
|
|
742
|
+
this.emit('agent:permissionModeChanged', { agentId, mode });
|
|
743
|
+
electron_log_1.default.info(`Permission mode changed to ${mode} for agent ${agentId}`);
|
|
744
|
+
}
|
|
745
|
+
getAgentPermissionMode(agentId) {
|
|
746
|
+
return this.permissionManager.getAgentMode(agentId);
|
|
747
|
+
}
|
|
748
|
+
getPermissionManager() {
|
|
749
|
+
return this.permissionManager;
|
|
750
|
+
}
|
|
751
|
+
setAllowBypassMode(allowed) {
|
|
752
|
+
this.permissionManager.setAllowBypassMode(allowed);
|
|
753
|
+
}
|
|
754
|
+
isBypassModeAllowed() {
|
|
755
|
+
return this.permissionManager.isBypassAllowed();
|
|
756
|
+
}
|
|
757
|
+
async checkPermission(agentId, action) {
|
|
758
|
+
return this.permissionManager.checkPermission(agentId, action);
|
|
759
|
+
}
|
|
760
|
+
async approvePermissionRequest(requestId) {
|
|
761
|
+
await this.permissionManager.approveRequest(requestId);
|
|
762
|
+
}
|
|
763
|
+
async rejectPermissionRequest(requestId) {
|
|
764
|
+
await this.permissionManager.rejectRequest(requestId);
|
|
765
|
+
}
|
|
766
|
+
getPendingPermissionRequests(agentId) {
|
|
767
|
+
return this.permissionManager.getPendingRequests(agentId);
|
|
768
|
+
}
|
|
769
|
+
buildSystemPrompt(userPrompt, claudeMdConfig) {
|
|
770
|
+
const parts = [];
|
|
771
|
+
if (claudeMdConfig) {
|
|
772
|
+
const parser = new ClaudeMdParser_1.ClaudeMdParser();
|
|
773
|
+
// Temporarily set config to generate prompt
|
|
774
|
+
parser.config = claudeMdConfig;
|
|
775
|
+
const claudePrompt = parser.generateSystemPrompt();
|
|
776
|
+
if (claudePrompt) {
|
|
777
|
+
parts.push(claudePrompt);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
if (userPrompt) {
|
|
781
|
+
parts.push(userPrompt);
|
|
782
|
+
}
|
|
783
|
+
return parts.join('\n\n');
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
exports.AgentOrchestrator = AgentOrchestrator;
|
|
787
|
+
//# sourceMappingURL=AgentOrchestrator.js.map
|