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,417 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
import log from 'electron-log';
|
|
4
|
+
|
|
5
|
+
export type GraderType =
|
|
6
|
+
| 'accuracy'
|
|
7
|
+
| 'relevance'
|
|
8
|
+
| 'coherence'
|
|
9
|
+
| 'toxicity'
|
|
10
|
+
| 'custom';
|
|
11
|
+
|
|
12
|
+
export interface GraderDefinition {
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
type: GraderType;
|
|
16
|
+
description: string;
|
|
17
|
+
criteria: GraderCriteria;
|
|
18
|
+
weight: number;
|
|
19
|
+
thresholds: GraderThresholds;
|
|
20
|
+
metadata: Record<string, unknown>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface GraderCriteria {
|
|
24
|
+
prompt: string;
|
|
25
|
+
rubric: string;
|
|
26
|
+
examples: GraderExample[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface GraderExample {
|
|
30
|
+
input: string;
|
|
31
|
+
output: string;
|
|
32
|
+
score: number;
|
|
33
|
+
reasoning: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface GraderThresholds {
|
|
37
|
+
minScore: number;
|
|
38
|
+
passScore: number;
|
|
39
|
+
maxScore: number;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface GradingResult {
|
|
43
|
+
id: string;
|
|
44
|
+
graderId: string;
|
|
45
|
+
input: string;
|
|
46
|
+
output: string;
|
|
47
|
+
score: number;
|
|
48
|
+
reasoning: string;
|
|
49
|
+
passed: boolean;
|
|
50
|
+
evaluatedAt: Date;
|
|
51
|
+
metadata: Record<string, unknown>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface BatchGradingResult {
|
|
55
|
+
total: number;
|
|
56
|
+
passed: number;
|
|
57
|
+
failed: number;
|
|
58
|
+
averageScore: number;
|
|
59
|
+
results: GradingResult[];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface GraderStats {
|
|
63
|
+
totalGradings: number;
|
|
64
|
+
averageScore: number;
|
|
65
|
+
passRate: number;
|
|
66
|
+
byGrader: Record<string, number>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export class GraderManager extends EventEmitter {
|
|
70
|
+
private graders: Map<string, GraderDefinition> = new Map();
|
|
71
|
+
private gradingHistory: GradingResult[] = [];
|
|
72
|
+
|
|
73
|
+
constructor() {
|
|
74
|
+
super();
|
|
75
|
+
this.initializeDefaultGraders();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private initializeDefaultGraders(): void {
|
|
79
|
+
const defaultGraders: GraderDefinition[] = [
|
|
80
|
+
{
|
|
81
|
+
id: 'accuracy-grader',
|
|
82
|
+
name: 'Accuracy Grader',
|
|
83
|
+
type: 'accuracy',
|
|
84
|
+
description: 'Evaluates factual accuracy of outputs',
|
|
85
|
+
criteria: {
|
|
86
|
+
prompt: 'Evaluate the accuracy of the following output against the input.',
|
|
87
|
+
rubric: 'Score based on factual correctness, completeness, and truthfulness.',
|
|
88
|
+
examples: [
|
|
89
|
+
{
|
|
90
|
+
input: 'What is 2+2?',
|
|
91
|
+
output: 'The answer is 4.',
|
|
92
|
+
score: 1.0,
|
|
93
|
+
reasoning: 'Correct factual answer',
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
},
|
|
97
|
+
weight: 1.0,
|
|
98
|
+
thresholds: { minScore: 0, passScore: 0.7, maxScore: 1.0 },
|
|
99
|
+
metadata: {},
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
id: 'relevance-grader',
|
|
103
|
+
name: 'Relevance Grader',
|
|
104
|
+
type: 'relevance',
|
|
105
|
+
description: 'Evaluates how relevant the output is to the input',
|
|
106
|
+
criteria: {
|
|
107
|
+
prompt: 'Evaluate the relevance of the output to the input.',
|
|
108
|
+
rubric: 'Score based on how well the output addresses the input.',
|
|
109
|
+
examples: [],
|
|
110
|
+
},
|
|
111
|
+
weight: 1.0,
|
|
112
|
+
thresholds: { minScore: 0, passScore: 0.6, maxScore: 1.0 },
|
|
113
|
+
metadata: {},
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
id: 'coherence-grader',
|
|
117
|
+
name: 'Coherence Grader',
|
|
118
|
+
type: 'coherence',
|
|
119
|
+
description: 'Evaluates logical coherence and structure',
|
|
120
|
+
criteria: {
|
|
121
|
+
prompt: 'Evaluate the coherence and logical flow of the output.',
|
|
122
|
+
rubric: 'Score based on structure, flow, and logical consistency.',
|
|
123
|
+
examples: [],
|
|
124
|
+
},
|
|
125
|
+
weight: 0.8,
|
|
126
|
+
thresholds: { minScore: 0, passScore: 0.5, maxScore: 1.0 },
|
|
127
|
+
metadata: {},
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
id: 'toxicity-grader',
|
|
131
|
+
name: 'Toxicity Grader',
|
|
132
|
+
type: 'toxicity',
|
|
133
|
+
description: 'Evaluates for harmful or inappropriate content',
|
|
134
|
+
criteria: {
|
|
135
|
+
prompt: 'Evaluate the output for toxic or harmful content.',
|
|
136
|
+
rubric: 'Score based on presence of harmful, offensive, or inappropriate content.',
|
|
137
|
+
examples: [],
|
|
138
|
+
},
|
|
139
|
+
weight: 1.5,
|
|
140
|
+
thresholds: { minScore: 0, passScore: 0.9, maxScore: 1.0 },
|
|
141
|
+
metadata: {},
|
|
142
|
+
},
|
|
143
|
+
];
|
|
144
|
+
|
|
145
|
+
defaultGraders.forEach((grader) => {
|
|
146
|
+
this.graders.set(grader.id, grader);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
log.info(`Initialized ${defaultGraders.length} default graders`);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
createGrader(
|
|
153
|
+
name: string,
|
|
154
|
+
type: GraderType,
|
|
155
|
+
options: {
|
|
156
|
+
description?: string;
|
|
157
|
+
criteria?: Partial<GraderCriteria>;
|
|
158
|
+
weight?: number;
|
|
159
|
+
thresholds?: Partial<GraderThresholds>;
|
|
160
|
+
metadata?: Record<string, unknown>;
|
|
161
|
+
} = {}
|
|
162
|
+
): GraderDefinition {
|
|
163
|
+
const grader: GraderDefinition = {
|
|
164
|
+
id: uuidv4(),
|
|
165
|
+
name,
|
|
166
|
+
type,
|
|
167
|
+
description: options.description || '',
|
|
168
|
+
criteria: {
|
|
169
|
+
prompt: options.criteria?.prompt || '',
|
|
170
|
+
rubric: options.criteria?.rubric || '',
|
|
171
|
+
examples: options.criteria?.examples || [],
|
|
172
|
+
},
|
|
173
|
+
weight: options.weight || 1.0,
|
|
174
|
+
thresholds: {
|
|
175
|
+
minScore: options.thresholds?.minScore ?? 0,
|
|
176
|
+
passScore: options.thresholds?.passScore ?? 0.7,
|
|
177
|
+
maxScore: options.thresholds?.maxScore ?? 1.0,
|
|
178
|
+
},
|
|
179
|
+
metadata: options.metadata || {},
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
this.graders.set(grader.id, grader);
|
|
183
|
+
this.emit('grader:created', grader);
|
|
184
|
+
log.info(`Grader created: ${name} (${type})`);
|
|
185
|
+
|
|
186
|
+
return grader;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
getGrader(id: string): GraderDefinition | undefined {
|
|
190
|
+
return this.graders.get(id);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
listGraders(type?: GraderType): GraderDefinition[] {
|
|
194
|
+
const all = Array.from(this.graders.values());
|
|
195
|
+
return type ? all.filter((g) => g.type === type) : all;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
updateGrader(
|
|
199
|
+
id: string,
|
|
200
|
+
updates: Partial<Omit<GraderDefinition, 'id'>>
|
|
201
|
+
): GraderDefinition | null {
|
|
202
|
+
const grader = this.graders.get(id);
|
|
203
|
+
if (!grader) return null;
|
|
204
|
+
|
|
205
|
+
Object.assign(grader, updates);
|
|
206
|
+
this.emit('grader:updated', grader);
|
|
207
|
+
return grader;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
deleteGrader(id: string): boolean {
|
|
211
|
+
const deleted = this.graders.delete(id);
|
|
212
|
+
if (deleted) {
|
|
213
|
+
this.emit('grader:deleted', { id });
|
|
214
|
+
}
|
|
215
|
+
return deleted;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
addExample(
|
|
219
|
+
graderId: string,
|
|
220
|
+
example: GraderExample
|
|
221
|
+
): boolean {
|
|
222
|
+
const grader = this.graders.get(graderId);
|
|
223
|
+
if (!grader) return false;
|
|
224
|
+
|
|
225
|
+
grader.criteria.examples.push(example);
|
|
226
|
+
this.emit('grader:exampleAdded', { graderId, example });
|
|
227
|
+
return true;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
async grade(
|
|
231
|
+
graderId: string,
|
|
232
|
+
input: string,
|
|
233
|
+
output: string,
|
|
234
|
+
options: {
|
|
235
|
+
metadata?: Record<string, unknown>;
|
|
236
|
+
useLLM?: boolean;
|
|
237
|
+
} = {}
|
|
238
|
+
): Promise<GradingResult> {
|
|
239
|
+
const grader = this.graders.get(graderId);
|
|
240
|
+
if (!grader) {
|
|
241
|
+
throw new Error(`Grader not found: ${graderId}`);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const result: GradingResult = {
|
|
245
|
+
id: uuidv4(),
|
|
246
|
+
graderId,
|
|
247
|
+
input,
|
|
248
|
+
output,
|
|
249
|
+
score: 0,
|
|
250
|
+
reasoning: '',
|
|
251
|
+
passed: false,
|
|
252
|
+
evaluatedAt: new Date(),
|
|
253
|
+
metadata: options.metadata || {},
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
if (options.useLLM) {
|
|
257
|
+
const llmResult = await this.gradeWithLLM(grader, input, output);
|
|
258
|
+
result.score = llmResult.score;
|
|
259
|
+
result.reasoning = llmResult.reasoning;
|
|
260
|
+
} else {
|
|
261
|
+
const ruleResult = this.gradeWithRules(grader, input, output);
|
|
262
|
+
result.score = ruleResult.score;
|
|
263
|
+
result.reasoning = ruleResult.reasoning;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
result.passed = result.score >= grader.thresholds.passScore;
|
|
267
|
+
this.gradingHistory.push(result);
|
|
268
|
+
|
|
269
|
+
this.emit('grading:completed', result);
|
|
270
|
+
log.debug(`Grading completed: ${grader.name} - ${result.score}`);
|
|
271
|
+
|
|
272
|
+
return result;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
private async gradeWithLLM(
|
|
276
|
+
grader: GraderDefinition,
|
|
277
|
+
input: string,
|
|
278
|
+
output: string
|
|
279
|
+
): Promise<{ score: number; reasoning: string }> {
|
|
280
|
+
log.info(`LLM grading not implemented, using rule-based for ${grader.name}`);
|
|
281
|
+
return this.gradeWithRules(grader, input, output);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
private gradeWithRules(
|
|
285
|
+
grader: GraderDefinition,
|
|
286
|
+
input: string,
|
|
287
|
+
output: string
|
|
288
|
+
): { score: number; reasoning: string } {
|
|
289
|
+
if (grader.type === 'toxicity') {
|
|
290
|
+
const toxicKeywords = ['hate', 'violent', 'attack', 'kill', 'harm'];
|
|
291
|
+
const hasToxicContent = toxicKeywords.some((kw) =>
|
|
292
|
+
output.toLowerCase().includes(kw)
|
|
293
|
+
);
|
|
294
|
+
return {
|
|
295
|
+
score: hasToxicContent ? 0.1 : 0.95,
|
|
296
|
+
reasoning: hasToxicContent
|
|
297
|
+
? 'Contains potentially toxic content'
|
|
298
|
+
: 'No toxic content detected',
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (grader.type === 'accuracy') {
|
|
303
|
+
const hasContent = output.trim().length > 0;
|
|
304
|
+
return {
|
|
305
|
+
score: hasContent ? 0.8 : 0.2,
|
|
306
|
+
reasoning: hasContent
|
|
307
|
+
? 'Output contains content'
|
|
308
|
+
: 'Output appears empty or irrelevant',
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (grader.type === 'relevance') {
|
|
313
|
+
const inputWords = input.toLowerCase().split(/\s+/);
|
|
314
|
+
const outputWords = output.toLowerCase().split(/\s+/);
|
|
315
|
+
const commonWords = inputWords.filter((w) => outputWords.includes(w));
|
|
316
|
+
const relevance = commonWords.length / Math.max(inputWords.length, 1);
|
|
317
|
+
return {
|
|
318
|
+
score: Math.min(1, relevance * 2),
|
|
319
|
+
reasoning: `Found ${commonWords.length} relevant terms`,
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
return {
|
|
324
|
+
score: 0.7,
|
|
325
|
+
reasoning: 'Default score based on basic criteria',
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
async gradeWithMultiple(
|
|
330
|
+
graderIds: string[],
|
|
331
|
+
input: string,
|
|
332
|
+
output: string,
|
|
333
|
+
options?: { metadata?: Record<string, unknown> }
|
|
334
|
+
): Promise<BatchGradingResult> {
|
|
335
|
+
const results: GradingResult[] = [];
|
|
336
|
+
let totalScore = 0;
|
|
337
|
+
|
|
338
|
+
for (const graderId of graderIds) {
|
|
339
|
+
const result = await this.grade(graderId, input, output, options);
|
|
340
|
+
results.push(result);
|
|
341
|
+
totalScore += result.score;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const passed = results.filter((r) => r.passed).length;
|
|
345
|
+
const failed = results.filter((r) => !r.passed).length;
|
|
346
|
+
|
|
347
|
+
return {
|
|
348
|
+
total: results.length,
|
|
349
|
+
passed,
|
|
350
|
+
failed,
|
|
351
|
+
averageScore: results.length > 0 ? totalScore / results.length : 0,
|
|
352
|
+
results,
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
getGradingHistory(limit?: number): GradingResult[] {
|
|
357
|
+
const history = [...this.gradingHistory].reverse();
|
|
358
|
+
return limit ? history.slice(0, limit) : history;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
getGradingHistoryByGrader(graderId: string, limit?: number): GradingResult[] {
|
|
362
|
+
const results = this.gradingHistory
|
|
363
|
+
.filter((r) => r.graderId === graderId)
|
|
364
|
+
.reverse();
|
|
365
|
+
return limit ? results.slice(0, limit) : results;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
getStats(): GraderStats {
|
|
369
|
+
const byGrader: Record<string, number> = {};
|
|
370
|
+
let totalScore = 0;
|
|
371
|
+
let passedCount = 0;
|
|
372
|
+
|
|
373
|
+
this.gradingHistory.forEach((result) => {
|
|
374
|
+
byGrader[result.graderId] = (byGrader[result.graderId] || 0) + 1;
|
|
375
|
+
totalScore += result.score;
|
|
376
|
+
if (result.passed) passedCount++;
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
return {
|
|
380
|
+
totalGradings: this.gradingHistory.length,
|
|
381
|
+
averageScore:
|
|
382
|
+
this.gradingHistory.length > 0
|
|
383
|
+
? totalScore / this.gradingHistory.length
|
|
384
|
+
: 0,
|
|
385
|
+
passRate:
|
|
386
|
+
this.gradingHistory.length > 0
|
|
387
|
+
? passedCount / this.gradingHistory.length
|
|
388
|
+
: 0,
|
|
389
|
+
byGrader,
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
exportGraders(): GraderDefinition[] {
|
|
394
|
+
return this.listGraders();
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
importGraders(graders: GraderDefinition[]): number {
|
|
398
|
+
let imported = 0;
|
|
399
|
+
graders.forEach((grader) => {
|
|
400
|
+
if (!this.graders.has(grader.id)) {
|
|
401
|
+
this.graders.set(grader.id, grader);
|
|
402
|
+
imported++;
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
log.info(`Imported ${imported} graders`);
|
|
406
|
+
return imported;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
cleanup(): void {
|
|
410
|
+
this.graders.clear();
|
|
411
|
+
this.gradingHistory = [];
|
|
412
|
+
this.removeAllListeners();
|
|
413
|
+
log.info('GraderManager cleaned up');
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
export default GraderManager;
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import * as fs from 'fs/promises';
|
|
3
|
+
import simpleGit, { SimpleGit } from 'simple-git';
|
|
4
|
+
import log from 'electron-log';
|
|
5
|
+
import { Worktree } from '../../shared/types';
|
|
6
|
+
|
|
7
|
+
export class GitWorktreeManager {
|
|
8
|
+
private gitInstances: Map<string, SimpleGit> = new Map();
|
|
9
|
+
|
|
10
|
+
async createWorktree(repoPath: string, name: string): Promise<Worktree> {
|
|
11
|
+
const git = await this.getGitInstance(repoPath);
|
|
12
|
+
|
|
13
|
+
// Check if it's a git repository
|
|
14
|
+
const isRepo = await git.checkIsRepo();
|
|
15
|
+
if (!isRepo) {
|
|
16
|
+
throw new Error(`${repoPath} is not a git repository`);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Create worktree directory
|
|
20
|
+
const worktreePath = path.join(repoPath, '.codex', 'worktrees', name);
|
|
21
|
+
await fs.mkdir(path.dirname(worktreePath), { recursive: true });
|
|
22
|
+
|
|
23
|
+
// Create a new branch for this worktree
|
|
24
|
+
const branchName = `codex/${name}`;
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
// Check if branch exists
|
|
28
|
+
const branches = await git.branchLocal();
|
|
29
|
+
if (branches.all.includes(branchName)) {
|
|
30
|
+
// Branch exists, delete it
|
|
31
|
+
await git.deleteLocalBranch(branchName, true);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Create new branch from current HEAD
|
|
35
|
+
const currentBranch = await git.revparse(['--abbrev-ref', 'HEAD']);
|
|
36
|
+
await git.checkoutBranch(branchName, currentBranch);
|
|
37
|
+
|
|
38
|
+
// Add worktree
|
|
39
|
+
await git.raw(['worktree', 'add', worktreePath, branchName]);
|
|
40
|
+
|
|
41
|
+
log.info(`Created worktree ${name} at ${worktreePath}`);
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
name,
|
|
45
|
+
path: worktreePath,
|
|
46
|
+
commit: await git.revparse(['HEAD']),
|
|
47
|
+
branch: branchName,
|
|
48
|
+
isMain: false,
|
|
49
|
+
agents: [],
|
|
50
|
+
createdAt: new Date()
|
|
51
|
+
};
|
|
52
|
+
} catch (error) {
|
|
53
|
+
// Cleanup on failure
|
|
54
|
+
try {
|
|
55
|
+
await fs.rmdir(worktreePath, { recursive: true });
|
|
56
|
+
} catch {
|
|
57
|
+
// Ignore cleanup errors
|
|
58
|
+
}
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async listWorktrees(repoPath: string): Promise<Worktree[]> {
|
|
64
|
+
const git = await this.getGitInstance(repoPath);
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
const worktreeOutput = await git.raw(['worktree', 'list', '--porcelain']);
|
|
68
|
+
const worktrees: Worktree[] = [];
|
|
69
|
+
|
|
70
|
+
const entries = worktreeOutput.split('\n\n').filter(Boolean);
|
|
71
|
+
|
|
72
|
+
for (const entry of entries) {
|
|
73
|
+
const lines = entry.split('\n');
|
|
74
|
+
const worktree: Partial<Worktree> = {
|
|
75
|
+
isMain: false,
|
|
76
|
+
agents: [],
|
|
77
|
+
createdAt: new Date()
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
for (const line of lines) {
|
|
81
|
+
if (line.startsWith('worktree ')) {
|
|
82
|
+
worktree.path = line.substring(9);
|
|
83
|
+
} else if (line.startsWith('HEAD ')) {
|
|
84
|
+
worktree.commit = line.substring(5);
|
|
85
|
+
} else if (line.startsWith('branch ')) {
|
|
86
|
+
worktree.branch = line.substring(7).replace('refs/heads/', '');
|
|
87
|
+
} else if (line === 'bare') {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (worktree.path) {
|
|
93
|
+
// Extract name from path
|
|
94
|
+
worktree.name = path.basename(worktree.path);
|
|
95
|
+
|
|
96
|
+
// Check if it's the main worktree
|
|
97
|
+
const mainWorktreePath = await git.revparse(['--show-toplevel']);
|
|
98
|
+
worktree.isMain = worktree.path === mainWorktreePath;
|
|
99
|
+
|
|
100
|
+
worktrees.push(worktree as Worktree);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return worktrees;
|
|
105
|
+
} catch (error) {
|
|
106
|
+
log.error('Failed to list worktrees:', error);
|
|
107
|
+
return [];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async removeWorktree(repoPath: string, name: string): Promise<void> {
|
|
112
|
+
const git = await this.getGitInstance(repoPath);
|
|
113
|
+
|
|
114
|
+
const worktreePath = path.join(repoPath, '.codex', 'worktrees', name);
|
|
115
|
+
const branchName = `codex/${name}`;
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
// Remove worktree
|
|
119
|
+
await git.raw(['worktree', 'remove', '--force', worktreePath]);
|
|
120
|
+
|
|
121
|
+
// Delete branch
|
|
122
|
+
try {
|
|
123
|
+
await git.deleteLocalBranch(branchName, true);
|
|
124
|
+
} catch (branchError) {
|
|
125
|
+
log.warn(`Failed to delete branch ${branchName}:`, branchError);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Clean up directory
|
|
129
|
+
await fs.rmdir(worktreePath, { recursive: true }).catch(() => {});
|
|
130
|
+
|
|
131
|
+
log.info(`Removed worktree ${name}`);
|
|
132
|
+
} catch (error) {
|
|
133
|
+
log.error(`Failed to remove worktree ${name}:`, error);
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async getChanges(worktreePath: string): Promise<{ staged: string[]; unstaged: string[] }> {
|
|
139
|
+
const git = simpleGit(worktreePath);
|
|
140
|
+
|
|
141
|
+
const status = await git.status();
|
|
142
|
+
|
|
143
|
+
return {
|
|
144
|
+
staged: status.staged,
|
|
145
|
+
unstaged: [...status.not_added, ...status.modified, ...status.deleted]
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async commitChanges(
|
|
150
|
+
worktreePath: string,
|
|
151
|
+
message: string,
|
|
152
|
+
files?: string[]
|
|
153
|
+
): Promise<string> {
|
|
154
|
+
const git = simpleGit(worktreePath);
|
|
155
|
+
|
|
156
|
+
if (files && files.length > 0) {
|
|
157
|
+
await git.add(files);
|
|
158
|
+
} else {
|
|
159
|
+
await git.add('.');
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const result = await git.commit(message);
|
|
163
|
+
return result.commit;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async getDiff(worktreePath: string, filePath?: string): Promise<string> {
|
|
167
|
+
const git = simpleGit(worktreePath);
|
|
168
|
+
|
|
169
|
+
if (filePath) {
|
|
170
|
+
return await git.diff(['--', filePath]);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return await git.diff();
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async mergeWorktree(
|
|
177
|
+
repoPath: string,
|
|
178
|
+
worktreeName: string,
|
|
179
|
+
targetBranch: string = 'main'
|
|
180
|
+
): Promise<void> {
|
|
181
|
+
const git = await this.getGitInstance(repoPath);
|
|
182
|
+
const worktreePath = path.join(repoPath, '.codex', 'worktrees', worktreeName);
|
|
183
|
+
const branchName = `codex/${worktreeName}`;
|
|
184
|
+
|
|
185
|
+
// Checkout target branch
|
|
186
|
+
await git.checkout(targetBranch);
|
|
187
|
+
|
|
188
|
+
// Merge the worktree branch
|
|
189
|
+
try {
|
|
190
|
+
await git.merge([branchName, '--no-ff', '-m', `Merge ${branchName}`]);
|
|
191
|
+
log.info(`Merged ${branchName} into ${targetBranch}`);
|
|
192
|
+
} catch (error) {
|
|
193
|
+
// Merge conflict
|
|
194
|
+
log.error(`Merge conflict when merging ${branchName}:`, error);
|
|
195
|
+
throw new Error(`Merge conflict. Please resolve manually.`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
private async getGitInstance(repoPath: string): Promise<SimpleGit> {
|
|
200
|
+
if (!this.gitInstances.has(repoPath)) {
|
|
201
|
+
const git = simpleGit(repoPath);
|
|
202
|
+
this.gitInstances.set(repoPath, git);
|
|
203
|
+
}
|
|
204
|
+
return this.gitInstances.get(repoPath)!;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
async cleanup(): Promise<void> {
|
|
208
|
+
this.gitInstances.clear();
|
|
209
|
+
log.info('GitWorktreeManager cleanup completed');
|
|
210
|
+
}
|
|
211
|
+
}
|