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.
Files changed (367) hide show
  1. package/.claude/settings.local.json +10 -0
  2. package/.eslintrc.json +27 -0
  3. package/.github/workflows/ci.yml +156 -0
  4. package/.huskyrc +7 -0
  5. package/.lintstagedrc +13 -0
  6. package/.prettierrc +12 -0
  7. package/CLAUDE.md +163 -0
  8. package/DESIGN_SUPERIOR.md +73 -0
  9. package/Dockerfile +64 -0
  10. package/INSTALLATION.md +152 -0
  11. package/LICENSE +21 -0
  12. package/README.md +245 -0
  13. package/assets/skills/code-review/instructions.md +102 -0
  14. package/assets/skills/code-review/skill.yaml +15 -0
  15. package/assets/skills/refactoring/instructions.md +149 -0
  16. package/assets/skills/refactoring/skill.yaml +15 -0
  17. package/assets/skills/testing/skill.yaml +15 -0
  18. package/commitlint.config.js +23 -0
  19. package/dist/main/DatabaseManager.js +763 -0
  20. package/dist/main/DatabaseManager.js.map +1 -0
  21. package/dist/main/SettingsManager.js +61 -0
  22. package/dist/main/SettingsManager.js.map +1 -0
  23. package/dist/main/agents/AgentOrchestrator.js +787 -0
  24. package/dist/main/agents/AgentOrchestrator.js.map +1 -0
  25. package/dist/main/agents/AgentSDK.js +219 -0
  26. package/dist/main/agents/AgentSDK.js.map +1 -0
  27. package/dist/main/agents/AgentTools.js +348 -0
  28. package/dist/main/agents/AgentTools.js.map +1 -0
  29. package/dist/main/agents/CodeIndex.js +233 -0
  30. package/dist/main/agents/CodeIndex.js.map +1 -0
  31. package/dist/main/agents/EmbeddingService.js +80 -0
  32. package/dist/main/agents/EmbeddingService.js.map +1 -0
  33. package/dist/main/agents/NativeToolCalling.js +206 -0
  34. package/dist/main/agents/NativeToolCalling.js.map +1 -0
  35. package/dist/main/api/APIServer.js +278 -0
  36. package/dist/main/api/APIServer.js.map +1 -0
  37. package/dist/main/api/RateLimiter.js +138 -0
  38. package/dist/main/api/RateLimiter.js.map +1 -0
  39. package/dist/main/api/WebSocketManager.js +300 -0
  40. package/dist/main/api/WebSocketManager.js.map +1 -0
  41. package/dist/main/assistant/ContextOptimizer.js +192 -0
  42. package/dist/main/assistant/ContextOptimizer.js.map +1 -0
  43. package/dist/main/assistant/PredictedOutputManager.js +172 -0
  44. package/dist/main/assistant/PredictedOutputManager.js.map +1 -0
  45. package/dist/main/assistant/PromptCacheManager.js +193 -0
  46. package/dist/main/assistant/PromptCacheManager.js.map +1 -0
  47. package/dist/main/assistant/PromptOptimizer.js +626 -0
  48. package/dist/main/assistant/PromptOptimizer.js.map +1 -0
  49. package/dist/main/assistant/SmartCodeAssistant.js +224 -0
  50. package/dist/main/assistant/SmartCodeAssistant.js.map +1 -0
  51. package/dist/main/auth/SessionManager.js +300 -0
  52. package/dist/main/auth/SessionManager.js.map +1 -0
  53. package/dist/main/automations/AdvancedWebhookSystem.js +212 -0
  54. package/dist/main/automations/AdvancedWebhookSystem.js.map +1 -0
  55. package/dist/main/automations/AutomationScheduler.js +269 -0
  56. package/dist/main/automations/AutomationScheduler.js.map +1 -0
  57. package/dist/main/automations/BatchProcessingSystem.js +159 -0
  58. package/dist/main/automations/BatchProcessingSystem.js.map +1 -0
  59. package/dist/main/automations/BrowserAutomationManager.js +195 -0
  60. package/dist/main/automations/BrowserAutomationManager.js.map +1 -0
  61. package/dist/main/automations/GitHubActionsManager.js +129 -0
  62. package/dist/main/automations/GitHubActionsManager.js.map +1 -0
  63. package/dist/main/automations/GitLabCIManager.js +122 -0
  64. package/dist/main/automations/GitLabCIManager.js.map +1 -0
  65. package/dist/main/automations/PriorityQueueManager.js +240 -0
  66. package/dist/main/automations/PriorityQueueManager.js.map +1 -0
  67. package/dist/main/background/BackgroundModeManager.js +117 -0
  68. package/dist/main/background/BackgroundModeManager.js.map +1 -0
  69. package/dist/main/backup/BackupManager.js +254 -0
  70. package/dist/main/backup/BackupManager.js.map +1 -0
  71. package/dist/main/backup/MigrationManager.js +114 -0
  72. package/dist/main/backup/MigrationManager.js.map +1 -0
  73. package/dist/main/commands/SlashCommandManager.js +399 -0
  74. package/dist/main/commands/SlashCommandManager.js.map +1 -0
  75. package/dist/main/config/ClaudeMdParser.js +519 -0
  76. package/dist/main/config/ClaudeMdParser.js.map +1 -0
  77. package/dist/main/config/CustomizationManager.js +381 -0
  78. package/dist/main/config/CustomizationManager.js.map +1 -0
  79. package/dist/main/config/LaunchConfigManager.js +211 -0
  80. package/dist/main/config/LaunchConfigManager.js.map +1 -0
  81. package/dist/main/config/SettingsManager.js +166 -0
  82. package/dist/main/config/SettingsManager.js.map +1 -0
  83. package/dist/main/connectors/ConnectorManager.js +151 -0
  84. package/dist/main/connectors/ConnectorManager.js.map +1 -0
  85. package/dist/main/connectors/DatabaseConnector.js +222 -0
  86. package/dist/main/connectors/DatabaseConnector.js.map +1 -0
  87. package/dist/main/cowork/CoworkManager.js +324 -0
  88. package/dist/main/cowork/CoworkManager.js.map +1 -0
  89. package/dist/main/evals/AgentEvalFramework.js +538 -0
  90. package/dist/main/evals/AgentEvalFramework.js.map +1 -0
  91. package/dist/main/evals/GraderManager.js +285 -0
  92. package/dist/main/evals/GraderManager.js.map +1 -0
  93. package/dist/main/git/GitWorktreeManager.js +214 -0
  94. package/dist/main/git/GitWorktreeManager.js.map +1 -0
  95. package/dist/main/github/GitHubPRMonitor.js +244 -0
  96. package/dist/main/github/GitHubPRMonitor.js.map +1 -0
  97. package/dist/main/ide/ContinueInManager.js +181 -0
  98. package/dist/main/ide/ContinueInManager.js.map +1 -0
  99. package/dist/main/ide/IDEIntegration.js +277 -0
  100. package/dist/main/ide/IDEIntegration.js.map +1 -0
  101. package/dist/main/integrations/LinearManager.js +252 -0
  102. package/dist/main/integrations/LinearManager.js.map +1 -0
  103. package/dist/main/integrations/SlackBotManager.js +247 -0
  104. package/dist/main/integrations/SlackBotManager.js.map +1 -0
  105. package/dist/main/lsp/LSPManager.js +394 -0
  106. package/dist/main/lsp/LSPManager.js.map +1 -0
  107. package/dist/main/main.js +1087 -0
  108. package/dist/main/main.js.map +1 -0
  109. package/dist/main/mcp/MCPConfigurationManager.js +281 -0
  110. package/dist/main/mcp/MCPConfigurationManager.js.map +1 -0
  111. package/dist/main/mcp/MCPManager.js +710 -0
  112. package/dist/main/mcp/MCPManager.js.map +1 -0
  113. package/dist/main/mcp/MCPRegistry.js +272 -0
  114. package/dist/main/mcp/MCPRegistry.js.map +1 -0
  115. package/dist/main/monitoring/ErrorRecoveryManager.js +268 -0
  116. package/dist/main/monitoring/ErrorRecoveryManager.js.map +1 -0
  117. package/dist/main/monitoring/ErrorTracker.js +57 -0
  118. package/dist/main/monitoring/ErrorTracker.js.map +1 -0
  119. package/dist/main/monitoring/MetricsCollector.js +155 -0
  120. package/dist/main/monitoring/MetricsCollector.js.map +1 -0
  121. package/dist/main/monitoring/TraceGradingSystem.js +148 -0
  122. package/dist/main/monitoring/TraceGradingSystem.js.map +1 -0
  123. package/dist/main/notifications/NotificationManager.js +67 -0
  124. package/dist/main/notifications/NotificationManager.js.map +1 -0
  125. package/dist/main/pair/AIPairProgramming.js +200 -0
  126. package/dist/main/pair/AIPairProgramming.js.map +1 -0
  127. package/dist/main/plugins/PluginManager.js +222 -0
  128. package/dist/main/plugins/PluginManager.js.map +1 -0
  129. package/dist/main/plugins/PluginMarketplace.js +237 -0
  130. package/dist/main/plugins/PluginMarketplace.js.map +1 -0
  131. package/dist/main/preload.js +189 -0
  132. package/dist/main/preload.js.map +1 -0
  133. package/dist/main/preview/PreviewSessionManager.js +170 -0
  134. package/dist/main/preview/PreviewSessionManager.js.map +1 -0
  135. package/dist/main/providers/AIProviderManager.js +327 -0
  136. package/dist/main/providers/AIProviderManager.js.map +1 -0
  137. package/dist/main/providers/FineTuningManager.js +276 -0
  138. package/dist/main/providers/FineTuningManager.js.map +1 -0
  139. package/dist/main/providers/FreeModelsProvider.js +1104 -0
  140. package/dist/main/providers/FreeModelsProvider.js.map +1 -0
  141. package/dist/main/realtime/RealtimeManager.js +116 -0
  142. package/dist/main/realtime/RealtimeManager.js.map +1 -0
  143. package/dist/main/remote/CloudEnvironmentManager.js +232 -0
  144. package/dist/main/remote/CloudEnvironmentManager.js.map +1 -0
  145. package/dist/main/remote/RemoteSessionManager.js +255 -0
  146. package/dist/main/remote/RemoteSessionManager.js.map +1 -0
  147. package/dist/main/search/DeepResearchManager.js +335 -0
  148. package/dist/main/search/DeepResearchManager.js.map +1 -0
  149. package/dist/main/search/WebSearchIntegration.js +147 -0
  150. package/dist/main/search/WebSearchIntegration.js.map +1 -0
  151. package/dist/main/security/AdminConsoleManager.js +223 -0
  152. package/dist/main/security/AdminConsoleManager.js.map +1 -0
  153. package/dist/main/security/AuditLogger.js +136 -0
  154. package/dist/main/security/AuditLogger.js.map +1 -0
  155. package/dist/main/security/PermissionManager.js +144 -0
  156. package/dist/main/security/PermissionManager.js.map +1 -0
  157. package/dist/main/security/SSOManager.js +173 -0
  158. package/dist/main/security/SSOManager.js.map +1 -0
  159. package/dist/main/security/SecurityManager.js +152 -0
  160. package/dist/main/security/SecurityManager.js.map +1 -0
  161. package/dist/main/skills/SkillsManager.js +223 -0
  162. package/dist/main/skills/SkillsManager.js.map +1 -0
  163. package/dist/main/ssh/SSHManager.js +65 -0
  164. package/dist/main/ssh/SSHManager.js.map +1 -0
  165. package/dist/main/streaming/StreamingManager.js +225 -0
  166. package/dist/main/streaming/StreamingManager.js.map +1 -0
  167. package/dist/main/sync/CloudSyncManager.js +422 -0
  168. package/dist/main/sync/CloudSyncManager.js.map +1 -0
  169. package/dist/main/types.js +28 -0
  170. package/dist/main/types.js.map +1 -0
  171. package/dist/main/verification/AutoVerifyManager.js +235 -0
  172. package/dist/main/verification/AutoVerifyManager.js.map +1 -0
  173. package/dist/main/vision/ComputerUseManager.js +376 -0
  174. package/dist/main/vision/ComputerUseManager.js.map +1 -0
  175. package/dist/main/vision/ImageVideoGenerationManager.js +401 -0
  176. package/dist/main/vision/ImageVideoGenerationManager.js.map +1 -0
  177. package/dist/main/vision/VisionManager.js +172 -0
  178. package/dist/main/vision/VisionManager.js.map +1 -0
  179. package/dist/renderer/assets/main-DJlZQBCA.js +304 -0
  180. package/dist/renderer/assets/main-N33ZXEr8.css +1 -0
  181. package/dist/renderer/index.html +21 -0
  182. package/dist/renderer/manifest.json +42 -0
  183. package/dist/renderer/sw.ts +109 -0
  184. package/dist/shared/types.js +35 -0
  185. package/dist/shared/types.js.map +1 -0
  186. package/docker-compose.yml +65 -0
  187. package/docs/API.md +307 -0
  188. package/docs/USER_GUIDE.md +476 -0
  189. package/examples/plugins/sample-plugin/package.json +41 -0
  190. package/examples/plugins/sample-plugin/src/index.ts +75 -0
  191. package/index.html +20 -0
  192. package/jest.config.js +39 -0
  193. package/package.json +180 -0
  194. package/packages/cli/package.json +29 -0
  195. package/packages/cli/src/commands/agents.ts +199 -0
  196. package/packages/cli/src/commands/tasks.ts +61 -0
  197. package/packages/cli/src/index.ts +91 -0
  198. package/packages/cli/src/utils/api.ts +45 -0
  199. package/packages/cli/src/utils/config.ts +61 -0
  200. package/packages/npm-installer/bin/codex-linux +126 -0
  201. package/packages/npm-installer/lib/download.js +273 -0
  202. package/packages/npm-installer/package.json +42 -0
  203. package/packages/vscode-extension/package.json +167 -0
  204. package/packages/vscode-extension/src/api.ts +68 -0
  205. package/packages/vscode-extension/src/extension.ts +161 -0
  206. package/packages/vscode-extension/src/panels/chatPanel.ts +265 -0
  207. package/packages/vscode-extension/src/panels/createAgentPanel.ts +227 -0
  208. package/packages/vscode-extension/src/providers/agentsProvider.ts +80 -0
  209. package/postcss.config.js +6 -0
  210. package/public/manifest.json +42 -0
  211. package/public/sw.ts +109 -0
  212. package/scripts/install-dev.sh +103 -0
  213. package/scripts/install.sh +275 -0
  214. package/src/main/DatabaseManager.ts +950 -0
  215. package/src/main/SettingsManager.ts +63 -0
  216. package/src/main/agents/AgentOrchestrator.ts +930 -0
  217. package/src/main/agents/AgentSDK.ts +269 -0
  218. package/src/main/agents/AgentTools.ts +380 -0
  219. package/src/main/agents/CodeIndex.ts +240 -0
  220. package/src/main/agents/EmbeddingService.ts +88 -0
  221. package/src/main/agents/NativeToolCalling.ts +245 -0
  222. package/src/main/api/APIServer.ts +316 -0
  223. package/src/main/api/RateLimiter.ts +165 -0
  224. package/src/main/api/WebSocketManager.ts +398 -0
  225. package/src/main/assistant/ContextOptimizer.ts +214 -0
  226. package/src/main/assistant/PredictedOutputManager.ts +265 -0
  227. package/src/main/assistant/PromptCacheManager.ts +280 -0
  228. package/src/main/assistant/PromptOptimizer.ts +746 -0
  229. package/src/main/assistant/SmartCodeAssistant.ts +234 -0
  230. package/src/main/auth/SessionManager.ts +415 -0
  231. package/src/main/automations/AdvancedWebhookSystem.ts +281 -0
  232. package/src/main/automations/AutomationScheduler.ts +272 -0
  233. package/src/main/automations/BatchProcessingSystem.ts +207 -0
  234. package/src/main/automations/BrowserAutomationManager.ts +203 -0
  235. package/src/main/automations/GitHubActionsManager.ts +151 -0
  236. package/src/main/automations/GitLabCIManager.ts +206 -0
  237. package/src/main/automations/PriorityQueueManager.ts +328 -0
  238. package/src/main/background/BackgroundModeManager.ts +130 -0
  239. package/src/main/backup/BackupManager.ts +287 -0
  240. package/src/main/backup/MigrationManager.ts +132 -0
  241. package/src/main/commands/SlashCommandManager.ts +407 -0
  242. package/src/main/config/ClaudeMdParser.ts +539 -0
  243. package/src/main/config/CustomizationManager.ts +493 -0
  244. package/src/main/config/LaunchConfigManager.ts +212 -0
  245. package/src/main/config/SettingsManager.ts +163 -0
  246. package/src/main/connectors/ConnectorManager.ts +175 -0
  247. package/src/main/connectors/DatabaseConnector.ts +212 -0
  248. package/src/main/cowork/CoworkManager.ts +431 -0
  249. package/src/main/evals/AgentEvalFramework.ts +665 -0
  250. package/src/main/evals/GraderManager.ts +417 -0
  251. package/src/main/git/GitWorktreeManager.ts +211 -0
  252. package/src/main/github/GitHubPRMonitor.ts +317 -0
  253. package/src/main/ide/ContinueInManager.ts +180 -0
  254. package/src/main/ide/IDEIntegration.ts +288 -0
  255. package/src/main/integrations/LinearManager.ts +327 -0
  256. package/src/main/integrations/SlackBotManager.ts +312 -0
  257. package/src/main/lsp/LSPManager.ts +445 -0
  258. package/src/main/main.ts +1221 -0
  259. package/src/main/mcp/MCPConfigurationManager.ts +281 -0
  260. package/src/main/mcp/MCPManager.ts +799 -0
  261. package/src/main/mcp/MCPRegistry.ts +273 -0
  262. package/src/main/monitoring/ErrorRecoveryManager.ts +359 -0
  263. package/src/main/monitoring/ErrorTracker.ts +60 -0
  264. package/src/main/monitoring/MetricsCollector.ts +196 -0
  265. package/src/main/monitoring/TraceGradingSystem.ts +196 -0
  266. package/src/main/notifications/NotificationManager.ts +96 -0
  267. package/src/main/pair/AIPairProgramming.ts +290 -0
  268. package/src/main/plugins/PluginManager.ts +266 -0
  269. package/src/main/plugins/PluginMarketplace.ts +318 -0
  270. package/src/main/preload.ts +215 -0
  271. package/src/main/preview/PreviewSessionManager.ts +186 -0
  272. package/src/main/providers/AIProviderManager.ts +394 -0
  273. package/src/main/providers/FineTuningManager.ts +390 -0
  274. package/src/main/providers/FreeModelsProvider.ts +1156 -0
  275. package/src/main/realtime/RealtimeManager.ts +147 -0
  276. package/src/main/remote/CloudEnvironmentManager.ts +253 -0
  277. package/src/main/remote/RemoteSessionManager.ts +323 -0
  278. package/src/main/search/DeepResearchManager.ts +458 -0
  279. package/src/main/search/WebSearchIntegration.ts +203 -0
  280. package/src/main/security/AdminConsoleManager.ts +244 -0
  281. package/src/main/security/AuditLogger.ts +143 -0
  282. package/src/main/security/PermissionManager.ts +184 -0
  283. package/src/main/security/SSOManager.ts +241 -0
  284. package/src/main/security/SecurityManager.ts +139 -0
  285. package/src/main/skills/SkillsManager.ts +218 -0
  286. package/src/main/ssh/SSHManager.ts +86 -0
  287. package/src/main/streaming/StreamingManager.ts +306 -0
  288. package/src/main/sync/CloudSyncManager.ts +532 -0
  289. package/src/main/verification/AutoVerifyManager.ts +285 -0
  290. package/src/main/vision/ComputerUseManager.ts +475 -0
  291. package/src/main/vision/ImageVideoGenerationManager.ts +526 -0
  292. package/src/main/vision/VisionManager.ts +186 -0
  293. package/src/renderer/App.tsx +314 -0
  294. package/src/renderer/components/AdvancedSettingsPanel.tsx +225 -0
  295. package/src/renderer/components/AgentPanel.tsx +760 -0
  296. package/src/renderer/components/AppPreview.tsx +220 -0
  297. package/src/renderer/components/AuditTrailPanel.tsx +148 -0
  298. package/src/renderer/components/AutomationPanel.tsx +220 -0
  299. package/src/renderer/components/ChatInterface.tsx +595 -0
  300. package/src/renderer/components/ChatTab.tsx +296 -0
  301. package/src/renderer/components/CodeEditor.tsx +257 -0
  302. package/src/renderer/components/CodeReviewPanel.tsx +256 -0
  303. package/src/renderer/components/CodeWorkspace.tsx +192 -0
  304. package/src/renderer/components/CodebaseDashboard.tsx +295 -0
  305. package/src/renderer/components/ComputerUsePanel.tsx +262 -0
  306. package/src/renderer/components/ConnectorsPanel.tsx +471 -0
  307. package/src/renderer/components/ContextMenu.tsx +155 -0
  308. package/src/renderer/components/ContextUsageDisplay.tsx +248 -0
  309. package/src/renderer/components/CoworkPanel.tsx +415 -0
  310. package/src/renderer/components/DiffViewer.tsx +452 -0
  311. package/src/renderer/components/ErrorBoundary.tsx +273 -0
  312. package/src/renderer/components/ExtendedThinkingToggle.tsx +244 -0
  313. package/src/renderer/components/FileAttachments.tsx +247 -0
  314. package/src/renderer/components/FileExplorer.tsx +242 -0
  315. package/src/renderer/components/FileExplorerPanel.tsx +302 -0
  316. package/src/renderer/components/GitPanel.tsx +154 -0
  317. package/src/renderer/components/Header.tsx +113 -0
  318. package/src/renderer/components/MCPPanel.tsx +326 -0
  319. package/src/renderer/components/MentionAutocomplete.tsx +239 -0
  320. package/src/renderer/components/PermissionPanel.tsx +159 -0
  321. package/src/renderer/components/PermissionSelector.tsx +203 -0
  322. package/src/renderer/components/PluginMarketplace.tsx +325 -0
  323. package/src/renderer/components/PromptOptimizerPanel.tsx +399 -0
  324. package/src/renderer/components/SearchPanel.tsx +173 -0
  325. package/src/renderer/components/SearchReplace.tsx +284 -0
  326. package/src/renderer/components/SessionSidebar.tsx +367 -0
  327. package/src/renderer/components/SettingsPanel.tsx +426 -0
  328. package/src/renderer/components/Sidebar.tsx +100 -0
  329. package/src/renderer/components/SkillsPanel.tsx +245 -0
  330. package/src/renderer/components/SplitPane.tsx +173 -0
  331. package/src/renderer/components/Terminal.tsx +190 -0
  332. package/src/renderer/components/VoiceCommand.tsx +129 -0
  333. package/src/renderer/components/WorktreePanel.tsx +163 -0
  334. package/src/renderer/components/ui/AriaComponents.tsx +193 -0
  335. package/src/renderer/components/ui/Button.tsx +68 -0
  336. package/src/renderer/components/ui/Card.tsx +102 -0
  337. package/src/renderer/components/ui/Input.tsx +44 -0
  338. package/src/renderer/components/ui/Skeleton.tsx +55 -0
  339. package/src/renderer/components/ui/VirtualList.tsx +196 -0
  340. package/src/renderer/i18n/I18nProvider.tsx +101 -0
  341. package/src/renderer/i18n/de.ts +161 -0
  342. package/src/renderer/i18n/en.ts +163 -0
  343. package/src/renderer/i18n/es.ts +161 -0
  344. package/src/renderer/i18n/fr.ts +161 -0
  345. package/src/renderer/i18n/index.ts +44 -0
  346. package/src/renderer/index.css +129 -0
  347. package/src/renderer/lib/accessibility.tsx +287 -0
  348. package/src/renderer/lib/hooks.ts +304 -0
  349. package/src/renderer/lib/utils.ts +6 -0
  350. package/src/renderer/main.tsx +25 -0
  351. package/src/renderer/styles/minimalist.css +539 -0
  352. package/src/renderer/sw.ts +180 -0
  353. package/src/renderer/types.d.ts +138 -0
  354. package/src/shared/types.ts +813 -0
  355. package/supabase/schema.sql +234 -0
  356. package/tailwind.config.js +78 -0
  357. package/tests/e2e/package.json +15 -0
  358. package/tests/e2e/playwright.config.ts +31 -0
  359. package/tests/e2e/specs/app.spec.ts +194 -0
  360. package/tests/setup.ts +99 -0
  361. package/tests/unit/AgentOrchestrator.test.ts +274 -0
  362. package/tests/unit/DatabaseManager.test.ts +262 -0
  363. package/tests/unit/GitWorktreeManager.test.ts +150 -0
  364. package/tests/unit/SecurityManager.test.ts +110 -0
  365. package/tsconfig.main.json +22 -0
  366. package/tsconfig.renderer.json +27 -0
  367. package/vite.config.ts +28 -0
@@ -0,0 +1,763 @@
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.DatabaseManager = void 0;
40
+ const path = __importStar(require("path"));
41
+ const os = __importStar(require("os"));
42
+ const fs = __importStar(require("fs"));
43
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
44
+ const electron_log_1 = __importDefault(require("electron-log"));
45
+ const types_1 = require("../shared/types");
46
+ const DB_DIR = path.join(os.homedir(), '.config', 'codex');
47
+ const DB_PATH = path.join(DB_DIR, 'codex.db');
48
+ function safeJsonParse(str, defaultValue) {
49
+ if (!str)
50
+ return defaultValue;
51
+ try {
52
+ return JSON.parse(str);
53
+ }
54
+ catch (error) {
55
+ electron_log_1.default.error('JSON parse error:', error);
56
+ return defaultValue;
57
+ }
58
+ }
59
+ class DatabaseManager {
60
+ db = null;
61
+ async initialize() {
62
+ try {
63
+ // Ensure directory exists
64
+ await fs.promises.mkdir(DB_DIR, { recursive: true });
65
+ this.db = new better_sqlite3_1.default(DB_PATH);
66
+ // Enable WAL mode for better concurrency
67
+ this.db.pragma('journal_mode = WAL');
68
+ // Create tables
69
+ this.createTables();
70
+ // Reset any "running" queue items from previous sessions
71
+ this.db.prepare("UPDATE agent_queue_items SET status = 'pending' WHERE status = 'running'").run();
72
+ electron_log_1.default.info(`Database initialized at ${DB_PATH}`);
73
+ }
74
+ catch (error) {
75
+ electron_log_1.default.error('Failed to initialize database:', error);
76
+ throw error;
77
+ }
78
+ }
79
+ async close() {
80
+ if (this.db) {
81
+ this.db.pragma('wal_checkpoint(TRUNCATE)');
82
+ this.db.close();
83
+ this.db = null;
84
+ electron_log_1.default.info('Database connection closed');
85
+ }
86
+ }
87
+ createTables() {
88
+ if (!this.db)
89
+ return;
90
+ // Agents table
91
+ this.db.exec(`
92
+ CREATE TABLE IF NOT EXISTS agents (
93
+ id TEXT PRIMARY KEY,
94
+ name TEXT NOT NULL,
95
+ status TEXT NOT NULL,
96
+ project_path TEXT NOT NULL,
97
+ worktree_name TEXT NOT NULL,
98
+ provider_id TEXT NOT NULL,
99
+ model TEXT NOT NULL,
100
+ skills TEXT NOT NULL,
101
+ permission_mode TEXT NOT NULL DEFAULT 'ask',
102
+ created_at INTEGER NOT NULL,
103
+ updated_at INTEGER NOT NULL,
104
+ last_active_at INTEGER,
105
+ metadata TEXT
106
+ )
107
+ `);
108
+ // Agent queue items table
109
+ this.db.exec(`
110
+ CREATE TABLE IF NOT EXISTS agent_queue_items (
111
+ id TEXT PRIMARY KEY,
112
+ agent_id TEXT NOT NULL,
113
+ type TEXT NOT NULL,
114
+ content TEXT NOT NULL,
115
+ status TEXT NOT NULL,
116
+ position INTEGER NOT NULL,
117
+ created_at INTEGER NOT NULL,
118
+ started_at INTEGER,
119
+ completed_at INTEGER,
120
+ error TEXT,
121
+ FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE CASCADE
122
+ )
123
+ `);
124
+ // Agent messages table
125
+ this.db.exec(`
126
+ CREATE TABLE IF NOT EXISTS agent_messages (
127
+ id TEXT PRIMARY KEY,
128
+ agent_id TEXT NOT NULL,
129
+ role TEXT NOT NULL,
130
+ content TEXT NOT NULL,
131
+ timestamp INTEGER NOT NULL,
132
+ metadata TEXT,
133
+ FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE CASCADE
134
+ )
135
+ `);
136
+ // Agent tasks table
137
+ this.db.exec(`
138
+ CREATE TABLE IF NOT EXISTS agent_tasks (
139
+ id TEXT PRIMARY KEY,
140
+ agent_id TEXT NOT NULL,
141
+ description TEXT NOT NULL,
142
+ status TEXT NOT NULL,
143
+ progress REAL NOT NULL,
144
+ started_at INTEGER NOT NULL,
145
+ completed_at INTEGER,
146
+ result TEXT,
147
+ error TEXT,
148
+ FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE CASCADE
149
+ )
150
+ `);
151
+ // Code changes table
152
+ this.db.exec(`
153
+ CREATE TABLE IF NOT EXISTS code_changes (
154
+ id TEXT PRIMARY KEY,
155
+ file_path TEXT NOT NULL,
156
+ original_content TEXT,
157
+ new_content TEXT,
158
+ diff TEXT NOT NULL,
159
+ agent_id TEXT NOT NULL,
160
+ task_id TEXT NOT NULL,
161
+ status TEXT NOT NULL,
162
+ created_at INTEGER NOT NULL,
163
+ reviewed_at INTEGER,
164
+ reviewed_by TEXT,
165
+ comment TEXT
166
+ )
167
+ `);
168
+ // Automations table
169
+ this.db.exec(`
170
+ CREATE TABLE IF NOT EXISTS automations (
171
+ id TEXT PRIMARY KEY,
172
+ name TEXT NOT NULL,
173
+ description TEXT,
174
+ enabled INTEGER NOT NULL DEFAULT 0,
175
+ trigger_type TEXT NOT NULL,
176
+ trigger_config TEXT NOT NULL,
177
+ actions TEXT NOT NULL,
178
+ created_at INTEGER NOT NULL,
179
+ updated_at INTEGER NOT NULL,
180
+ last_run_at INTEGER,
181
+ run_count INTEGER NOT NULL DEFAULT 0
182
+ )
183
+ `);
184
+ // Projects table
185
+ this.db.exec(`
186
+ CREATE TABLE IF NOT EXISTS projects (
187
+ id TEXT PRIMARY KEY,
188
+ name TEXT NOT NULL,
189
+ path TEXT NOT NULL UNIQUE,
190
+ git_remote TEXT,
191
+ created_at INTEGER NOT NULL,
192
+ updated_at INTEGER NOT NULL
193
+ )
194
+ `);
195
+ // Cowork sessions table
196
+ this.db.exec(`
197
+ CREATE TABLE IF NOT EXISTS cowork_sessions (
198
+ id TEXT PRIMARY KEY,
199
+ name TEXT NOT NULL,
200
+ agent_id TEXT NOT NULL,
201
+ status TEXT NOT NULL,
202
+ objective TEXT NOT NULL,
203
+ progress REAL NOT NULL DEFAULT 0,
204
+ created_at INTEGER NOT NULL,
205
+ updated_at INTEGER NOT NULL,
206
+ completed_at INTEGER,
207
+ logs TEXT NOT NULL DEFAULT '[]',
208
+ deliverables TEXT NOT NULL DEFAULT '[]',
209
+ auto_approve INTEGER NOT NULL DEFAULT 0,
210
+ FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE CASCADE
211
+ )
212
+ `);
213
+ // Checkpoints table
214
+ this.db.exec(`
215
+ CREATE TABLE IF NOT EXISTS checkpoints (
216
+ id TEXT PRIMARY KEY,
217
+ agent_id TEXT NOT NULL,
218
+ change_id TEXT NOT NULL,
219
+ file_path TEXT NOT NULL,
220
+ content TEXT NOT NULL,
221
+ created_at INTEGER NOT NULL,
222
+ restored_at INTEGER
223
+ )
224
+ `);
225
+ // Create indexes
226
+ this.db.exec(`
227
+ CREATE INDEX IF NOT EXISTS idx_messages_agent ON agent_messages(agent_id);
228
+ CREATE INDEX IF NOT EXISTS idx_tasks_agent ON agent_tasks(agent_id);
229
+ CREATE INDEX IF NOT EXISTS idx_changes_agent ON code_changes(agent_id);
230
+ CREATE INDEX IF NOT EXISTS idx_automations_enabled ON automations(enabled);
231
+ CREATE INDEX IF NOT EXISTS idx_checkpoints_agent ON checkpoints(agent_id);
232
+ CREATE INDEX IF NOT EXISTS idx_queue_agent ON agent_queue_items(agent_id);
233
+ CREATE INDEX IF NOT EXISTS idx_queue_agent_pos ON agent_queue_items(agent_id, position);
234
+ `);
235
+ }
236
+ // Agent queue
237
+ async listAgentQueueItems(agentId) {
238
+ if (!this.db)
239
+ throw new Error('Database not initialized');
240
+ const rows = this.db.prepare("SELECT * FROM agent_queue_items WHERE agent_id = ? AND status IN ('pending','running') ORDER BY position ASC").all(agentId);
241
+ return rows.map(r => ({
242
+ id: r.id,
243
+ agentId: r.agent_id,
244
+ type: r.type,
245
+ content: r.content,
246
+ status: r.status,
247
+ position: r.position,
248
+ createdAt: new Date(r.created_at)
249
+ }));
250
+ }
251
+ async enqueueAgentQueueItem(agentId, type, content) {
252
+ if (!this.db)
253
+ throw new Error('Database not initialized');
254
+ const trimmed = content.trim();
255
+ if (!trimmed)
256
+ throw new Error('Queue item content cannot be empty');
257
+ const maxPosRow = this.db.prepare('SELECT MAX(position) as maxPos FROM agent_queue_items WHERE agent_id = ?').get(agentId);
258
+ const nextPos = (maxPosRow?.maxPos ?? -1) + 1;
259
+ const id = `q_${Date.now()}_${Math.random().toString(16).slice(2)}`;
260
+ this.db.prepare('INSERT INTO agent_queue_items (id, agent_id, type, content, status, position, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)').run(id, agentId, type, trimmed, 'pending', nextPos, Date.now());
261
+ return { id };
262
+ }
263
+ async deleteAgentQueueItem(agentId, itemId) {
264
+ if (!this.db)
265
+ throw new Error('Database not initialized');
266
+ const tx = this.db.transaction(() => {
267
+ this.db.prepare('DELETE FROM agent_queue_items WHERE id = ? AND agent_id = ?').run(itemId, agentId);
268
+ const rows = this.db.prepare('SELECT id FROM agent_queue_items WHERE agent_id = ? ORDER BY position ASC').all(agentId);
269
+ const update = this.db.prepare('UPDATE agent_queue_items SET position = ? WHERE id = ?');
270
+ rows.forEach((r, idx) => update.run(idx, r.id));
271
+ });
272
+ tx();
273
+ }
274
+ async moveAgentQueueItemUp(agentId, itemId) {
275
+ if (!this.db)
276
+ throw new Error('Database not initialized');
277
+ const row = this.db.prepare('SELECT id, position FROM agent_queue_items WHERE id = ? AND agent_id = ?').get(itemId, agentId);
278
+ if (!row)
279
+ return;
280
+ if (row.position <= 0)
281
+ return;
282
+ const prev = this.db.prepare('SELECT id, position FROM agent_queue_items WHERE agent_id = ? AND position = ?').get(agentId, row.position - 1);
283
+ if (!prev)
284
+ return;
285
+ const tx = this.db.transaction(() => {
286
+ this.db.prepare('UPDATE agent_queue_items SET position = ? WHERE id = ?').run(row.position - 1, row.id);
287
+ this.db.prepare('UPDATE agent_queue_items SET position = ? WHERE id = ?').run(prev.position + 1, prev.id);
288
+ });
289
+ tx();
290
+ }
291
+ async claimNextAgentQueueItem(agentId) {
292
+ if (!this.db)
293
+ throw new Error('Database not initialized');
294
+ const tx = this.db.transaction(() => {
295
+ const next = this.db.prepare("SELECT * FROM agent_queue_items WHERE agent_id = ? AND status = 'pending' ORDER BY position ASC LIMIT 1").get(agentId);
296
+ if (!next)
297
+ return null;
298
+ this.db.prepare("UPDATE agent_queue_items SET status = 'running', started_at = ? WHERE id = ?").run(Date.now(), next.id);
299
+ return { id: next.id, type: next.type, content: next.content };
300
+ });
301
+ return tx();
302
+ }
303
+ async completeAgentQueueItem(agentId, itemId, outcome, error) {
304
+ if (!this.db)
305
+ throw new Error('Database not initialized');
306
+ // Mark as completed/failed with outcome and error
307
+ this.db.prepare("UPDATE agent_queue_items SET status = ?, completed_at = ?, error = ? WHERE id = ? AND agent_id = ?").run(outcome, Date.now(), error || null, itemId, agentId);
308
+ }
309
+ async getQueueHistory(agentId, limit = 50) {
310
+ if (!this.db)
311
+ throw new Error('Database not initialized');
312
+ const rows = this.db.prepare("SELECT * FROM agent_queue_items WHERE agent_id = ? AND status IN ('completed','failed') ORDER BY completed_at DESC LIMIT ?").all(agentId, limit);
313
+ return rows.map(r => ({
314
+ id: r.id,
315
+ type: r.type,
316
+ content: r.content,
317
+ status: r.status,
318
+ createdAt: new Date(r.created_at),
319
+ completedAt: r.completed_at ? new Date(r.completed_at) : undefined,
320
+ error: r.error || undefined
321
+ }));
322
+ }
323
+ // Checkpoints
324
+ async listCheckpoints(agentId) {
325
+ if (!this.db)
326
+ throw new Error('Database not initialized');
327
+ let query = 'SELECT * FROM checkpoints';
328
+ const params = [];
329
+ if (agentId) {
330
+ query += ' WHERE agent_id = ?';
331
+ params.push(agentId);
332
+ }
333
+ query += ' ORDER BY created_at DESC';
334
+ const rows = this.db.prepare(query).all(...params);
335
+ return rows.map(row => ({
336
+ id: row.id,
337
+ agentId: row.agent_id,
338
+ changeId: row.change_id,
339
+ filePath: row.file_path,
340
+ content: row.content,
341
+ createdAt: new Date(row.created_at),
342
+ restoredAt: row.restored_at ? new Date(row.restored_at) : undefined
343
+ }));
344
+ }
345
+ async restoreCheckpoint(checkpointId) {
346
+ if (!this.db)
347
+ throw new Error('Database not initialized');
348
+ const checkpointRow = this.db.prepare('SELECT * FROM checkpoints WHERE id = ?').get(checkpointId);
349
+ if (!checkpointRow) {
350
+ throw new Error(`Checkpoint ${checkpointId} not found`);
351
+ }
352
+ const agentRow = this.db.prepare('SELECT * FROM agents WHERE id = ?').get(checkpointRow.agent_id);
353
+ if (!agentRow) {
354
+ throw new Error(`Agent ${checkpointRow.agent_id} not found for checkpoint ${checkpointId}`);
355
+ }
356
+ const agentMetadata = safeJsonParse(agentRow.metadata, {});
357
+ const worktreePath = agentMetadata.worktreePath || undefined;
358
+ if (!worktreePath || typeof worktreePath !== 'string') {
359
+ throw new Error(`Worktree path not available for agent ${agentRow.id}`);
360
+ }
361
+ const relativeFilePath = String(checkpointRow.file_path || '').trim();
362
+ if (!relativeFilePath) {
363
+ throw new Error(`Invalid file path for checkpoint ${checkpointId}`);
364
+ }
365
+ const targetPath = path.resolve(worktreePath, relativeFilePath);
366
+ const resolvedRoot = path.resolve(worktreePath);
367
+ if (!targetPath.startsWith(resolvedRoot + path.sep) && targetPath !== resolvedRoot) {
368
+ throw new Error('Refusing to write outside of worktree root');
369
+ }
370
+ await fs.promises.mkdir(path.dirname(targetPath), { recursive: true });
371
+ await fs.promises.writeFile(targetPath, checkpointRow.content || '', 'utf-8');
372
+ this.db.prepare('UPDATE checkpoints SET restored_at = ? WHERE id = ?').run(Date.now(), checkpointId);
373
+ electron_log_1.default.info(`Restored checkpoint ${checkpointId} to ${relativeFilePath}`);
374
+ }
375
+ async restoreLastCheckpoint(agentId) {
376
+ if (!this.db)
377
+ throw new Error('Database not initialized');
378
+ const row = this.db.prepare('SELECT * FROM checkpoints WHERE agent_id = ? AND restored_at IS NULL ORDER BY created_at DESC LIMIT 1').get(agentId);
379
+ if (!row) {
380
+ throw new Error('No checkpoint available');
381
+ }
382
+ await this.restoreCheckpoint(row.id);
383
+ }
384
+ // Agent operations
385
+ async createAgent(agent) {
386
+ if (!this.db)
387
+ throw new Error('Database not initialized');
388
+ const stmt = this.db.prepare(`
389
+ INSERT INTO agents (
390
+ id, name, status, project_path, worktree_name, provider_id, model,
391
+ skills, created_at, updated_at, last_active_at, metadata
392
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
393
+ `);
394
+ stmt.run(agent.id, agent.name, agent.status, agent.projectPath, agent.worktreeName, agent.providerId, agent.model, JSON.stringify(agent.skills), agent.createdAt.getTime(), agent.updatedAt.getTime(), agent.lastActiveAt?.getTime() || null, JSON.stringify(agent.metadata));
395
+ }
396
+ async updateAgent(agent) {
397
+ if (!this.db)
398
+ throw new Error('Database not initialized');
399
+ const stmt = this.db.prepare(`
400
+ UPDATE agents SET
401
+ name = ?,
402
+ status = ?,
403
+ provider_id = ?,
404
+ model = ?,
405
+ skills = ?,
406
+ updated_at = ?,
407
+ last_active_at = ?,
408
+ metadata = ?
409
+ WHERE id = ?
410
+ `);
411
+ stmt.run(agent.name, agent.status, agent.providerId, agent.model, JSON.stringify(agent.skills), agent.updatedAt.getTime(), agent.lastActiveAt?.getTime() || null, JSON.stringify(agent.metadata), agent.id);
412
+ }
413
+ async deleteAgent(agentId) {
414
+ if (!this.db)
415
+ throw new Error('Database not initialized');
416
+ const stmt = this.db.prepare('DELETE FROM agents WHERE id = ?');
417
+ stmt.run(agentId);
418
+ }
419
+ async getAllAgents() {
420
+ if (!this.db)
421
+ throw new Error('Database not initialized');
422
+ const stmt = this.db.prepare('SELECT * FROM agents ORDER BY created_at DESC');
423
+ const rows = stmt.all();
424
+ return rows.map(row => this.mapAgentRow(row));
425
+ }
426
+ async getAgent(agentId) {
427
+ if (!this.db)
428
+ throw new Error('Database not initialized');
429
+ const stmt = this.db.prepare('SELECT * FROM agents WHERE id = ?');
430
+ const row = stmt.get(agentId);
431
+ if (!row)
432
+ return null;
433
+ const agent = this.mapAgentRow(row);
434
+ // Load messages
435
+ agent.messages = await this.getAgentMessages(agentId);
436
+ // Load tasks
437
+ agent.tasks = await this.getAgentTasks(agentId);
438
+ return agent;
439
+ }
440
+ // Agent messages
441
+ async addAgentMessage(message, agentId) {
442
+ if (!this.db)
443
+ throw new Error('Database not initialized');
444
+ const stmt = this.db.prepare(`
445
+ INSERT INTO agent_messages (id, agent_id, role, content, timestamp, metadata)
446
+ VALUES (?, ?, ?, ?, ?, ?)
447
+ `);
448
+ stmt.run(message.id, agentId, message.role, message.content, message.timestamp.getTime(), JSON.stringify(message.metadata));
449
+ }
450
+ async getAgentMessages(agentId) {
451
+ if (!this.db)
452
+ throw new Error('Database not initialized');
453
+ const stmt = this.db.prepare(`
454
+ SELECT * FROM agent_messages WHERE agent_id = ? ORDER BY timestamp ASC
455
+ `);
456
+ const rows = stmt.all(agentId);
457
+ return rows.map(row => ({
458
+ id: row.id,
459
+ role: row.role,
460
+ content: row.content,
461
+ timestamp: new Date(row.timestamp),
462
+ metadata: safeJsonParse(row.metadata, undefined)
463
+ }));
464
+ }
465
+ // Agent tasks
466
+ async addAgentTask(task, agentId) {
467
+ if (!this.db)
468
+ throw new Error('Database not initialized');
469
+ const stmt = this.db.prepare(`
470
+ INSERT INTO agent_tasks (
471
+ id, agent_id, description, status, progress, started_at, completed_at, result, error
472
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
473
+ `);
474
+ stmt.run(task.id, agentId, task.description, task.status, task.progress, task.startedAt.getTime(), task.completedAt?.getTime() || null, task.result || null, task.error || null);
475
+ }
476
+ async updateAgentTask(task) {
477
+ if (!this.db)
478
+ throw new Error('Database not initialized');
479
+ const stmt = this.db.prepare(`
480
+ UPDATE agent_tasks SET
481
+ status = ?,
482
+ progress = ?,
483
+ completed_at = ?,
484
+ result = ?,
485
+ error = ?
486
+ WHERE id = ?
487
+ `);
488
+ stmt.run(task.status, task.progress, task.completedAt?.getTime() || null, task.result || null, task.error || null, task.id);
489
+ }
490
+ async getAgentTasks(agentId) {
491
+ if (!this.db)
492
+ throw new Error('Database not initialized');
493
+ const stmt = this.db.prepare(`
494
+ SELECT * FROM agent_tasks WHERE agent_id = ? ORDER BY started_at DESC
495
+ `);
496
+ const rows = stmt.all(agentId);
497
+ return rows.map(row => ({
498
+ id: row.id,
499
+ description: row.description,
500
+ status: row.status,
501
+ progress: row.progress,
502
+ startedAt: new Date(row.started_at),
503
+ completedAt: row.completed_at ? new Date(row.completed_at) : undefined,
504
+ result: row.result || undefined,
505
+ error: row.error || undefined
506
+ }));
507
+ }
508
+ // Code changes
509
+ async createCodeChange(change) {
510
+ if (!this.db)
511
+ throw new Error('Database not initialized');
512
+ const stmt = this.db.prepare(`
513
+ INSERT INTO code_changes (
514
+ id, file_path, original_content, new_content, diff,
515
+ agent_id, task_id, status, created_at
516
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
517
+ `);
518
+ stmt.run(change.id, change.filePath, change.originalContent, change.newContent, change.diff, change.agentId, change.taskId, change.status, change.createdAt.getTime());
519
+ }
520
+ async updateCodeChange(change) {
521
+ if (!this.db)
522
+ throw new Error('Database not initialized');
523
+ const stmt = this.db.prepare(`
524
+ UPDATE code_changes SET
525
+ status = ?,
526
+ reviewed_at = ?,
527
+ reviewed_by = ?,
528
+ comment = ?
529
+ WHERE id = ?
530
+ `);
531
+ stmt.run(change.status, change.reviewedAt?.getTime() || null, change.reviewedBy || null, change.comment || null, change.id);
532
+ }
533
+ // Code changes operations
534
+ async getCodeChanges(agentId) {
535
+ if (!this.db)
536
+ throw new Error('Database not initialized');
537
+ let query = 'SELECT * FROM code_changes';
538
+ const params = [];
539
+ if (agentId) {
540
+ query += ' WHERE agent_id = ?';
541
+ params.push(agentId);
542
+ }
543
+ query += ' ORDER BY created_at DESC';
544
+ const stmt = this.db.prepare(query);
545
+ const rows = stmt.all(...params);
546
+ return rows.map(row => ({
547
+ id: row.id,
548
+ filePath: row.file_path,
549
+ originalContent: row.original_content,
550
+ newContent: row.new_content,
551
+ diff: row.diff,
552
+ agentId: row.agent_id,
553
+ taskId: row.task_id,
554
+ status: row.status,
555
+ createdAt: new Date(row.created_at),
556
+ reviewedAt: row.reviewed_at ? new Date(row.reviewed_at) : undefined,
557
+ reviewedBy: row.reviewed_by || undefined,
558
+ comment: row.comment || undefined
559
+ }));
560
+ }
561
+ async approveCodeChange(changeId) {
562
+ if (!this.db)
563
+ throw new Error('Database not initialized');
564
+ const stmt = this.db.prepare(`
565
+ UPDATE code_changes SET
566
+ status = ?,
567
+ reviewed_at = ?,
568
+ reviewed_by = ?
569
+ WHERE id = ?
570
+ `);
571
+ stmt.run(types_1.ChangeStatus.APPROVED, Date.now(), 'user', // In real app, would get current user
572
+ changeId);
573
+ }
574
+ async rejectCodeChange(changeId, comment) {
575
+ if (!this.db)
576
+ throw new Error('Database not initialized');
577
+ const stmt = this.db.prepare(`
578
+ UPDATE code_changes SET
579
+ status = ?,
580
+ reviewed_at = ?,
581
+ reviewed_by = ?,
582
+ comment = ?
583
+ WHERE id = ?
584
+ `);
585
+ stmt.run(types_1.ChangeStatus.REJECTED, Date.now(), 'user', comment || null, changeId);
586
+ }
587
+ async applyCodeChange(changeId) {
588
+ if (!this.db)
589
+ throw new Error('Database not initialized');
590
+ const changeRow = this.db.prepare('SELECT * FROM code_changes WHERE id = ?').get(changeId);
591
+ if (!changeRow) {
592
+ throw new Error(`Code change ${changeId} not found`);
593
+ }
594
+ if (changeRow.status !== types_1.ChangeStatus.APPROVED) {
595
+ throw new Error(`Code change ${changeId} must be approved before applying`);
596
+ }
597
+ const agentRow = this.db.prepare('SELECT * FROM agents WHERE id = ?').get(changeRow.agent_id);
598
+ if (!agentRow) {
599
+ throw new Error(`Agent ${changeRow.agent_id} not found for code change ${changeId}`);
600
+ }
601
+ const agentMetadata = safeJsonParse(agentRow.metadata, {});
602
+ const worktreePath = agentMetadata.worktreePath || undefined;
603
+ if (!worktreePath || typeof worktreePath !== 'string') {
604
+ throw new Error(`Worktree path not available for agent ${agentRow.id}`);
605
+ }
606
+ const relativeFilePath = String(changeRow.file_path || '').trim();
607
+ if (!relativeFilePath) {
608
+ throw new Error(`Invalid file path for code change ${changeId}`);
609
+ }
610
+ const targetPath = path.resolve(worktreePath, relativeFilePath);
611
+ const resolvedRoot = path.resolve(worktreePath);
612
+ if (!targetPath.startsWith(resolvedRoot + path.sep) && targetPath !== resolvedRoot) {
613
+ throw new Error('Refusing to write outside of worktree root');
614
+ }
615
+ let currentContent = '';
616
+ try {
617
+ currentContent = await fs.promises.readFile(targetPath, 'utf-8');
618
+ }
619
+ catch {
620
+ currentContent = '';
621
+ }
622
+ const checkpointId = `cp_${changeId}_${Date.now()}`;
623
+ this.db.prepare('INSERT INTO checkpoints (id, agent_id, change_id, file_path, content, created_at) VALUES (?, ?, ?, ?, ?, ?)').run(checkpointId, changeRow.agent_id, changeId, relativeFilePath, currentContent, Date.now());
624
+ await fs.promises.mkdir(path.dirname(targetPath), { recursive: true });
625
+ await fs.promises.writeFile(targetPath, changeRow.new_content || '', 'utf-8');
626
+ this.db.prepare('UPDATE code_changes SET status = ? WHERE id = ?').run(types_1.ChangeStatus.APPLIED, changeId);
627
+ electron_log_1.default.info(`Applied code change ${changeId} to ${relativeFilePath}`);
628
+ }
629
+ // Cowork sessions
630
+ async getCoworkSessions() {
631
+ if (!this.db)
632
+ throw new Error('Database not initialized');
633
+ const stmt = this.db.prepare('SELECT * FROM cowork_sessions ORDER BY created_at DESC');
634
+ const rows = stmt.all();
635
+ return rows.map(row => ({
636
+ id: row.id,
637
+ name: row.name,
638
+ agentId: row.agent_id,
639
+ status: row.status,
640
+ objective: row.objective,
641
+ progress: row.progress,
642
+ createdAt: new Date(row.created_at),
643
+ updatedAt: new Date(row.updated_at),
644
+ completedAt: row.completed_at ? new Date(row.completed_at) : undefined,
645
+ logs: safeJsonParse(row.logs, []),
646
+ deliverables: safeJsonParse(row.deliverables, []),
647
+ autoApprove: Boolean(row.auto_approve)
648
+ }));
649
+ }
650
+ async saveCoworkSession(session) {
651
+ if (!this.db)
652
+ throw new Error('Database not initialized');
653
+ const stmt = this.db.prepare(`
654
+ INSERT OR REPLACE INTO cowork_sessions (
655
+ id, name, agent_id, status, objective, progress,
656
+ created_at, updated_at, completed_at, logs, deliverables, auto_approve
657
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
658
+ `);
659
+ stmt.run(session.id, session.name, session.agentId, session.status, session.objective, session.progress, session.createdAt.getTime(), session.updatedAt.getTime(), session.completedAt?.getTime() || null, JSON.stringify(session.logs), JSON.stringify(session.deliverables), session.autoApprove ? 1 : 0);
660
+ }
661
+ mapAgentRow(row) {
662
+ return {
663
+ id: row.id,
664
+ name: row.name,
665
+ status: row.status,
666
+ projectPath: row.project_path,
667
+ worktreeName: row.worktree_name,
668
+ providerId: row.provider_id,
669
+ model: row.model,
670
+ skills: safeJsonParse(row.skills, []),
671
+ permissionMode: row.permission_mode || 'ask',
672
+ createdAt: new Date(row.created_at),
673
+ updatedAt: new Date(row.updated_at),
674
+ lastActiveAt: row.last_active_at ? new Date(row.last_active_at) : null,
675
+ messages: [],
676
+ tasks: [],
677
+ metadata: safeJsonParse(row.metadata, {})
678
+ };
679
+ }
680
+ // Project operations
681
+ async createProject(project) {
682
+ if (!this.db)
683
+ throw new Error('Database not initialized');
684
+ const stmt = this.db.prepare(`
685
+ INSERT INTO projects (id, name, path, git_remote, created_at, updated_at)
686
+ VALUES (?, ?, ?, ?, ?, ?)
687
+ `);
688
+ stmt.run(project.id, project.name, project.path, project.gitRemote || null, project.createdAt.getTime(), project.updatedAt.getTime());
689
+ }
690
+ async updateProject(project) {
691
+ if (!this.db)
692
+ throw new Error('Database not initialized');
693
+ const stmt = this.db.prepare(`
694
+ UPDATE projects SET
695
+ name = ?,
696
+ path = ?,
697
+ git_remote = ?,
698
+ updated_at = ?
699
+ WHERE id = ?
700
+ `);
701
+ stmt.run(project.name, project.path, project.gitRemote || null, project.updatedAt.getTime(), project.id);
702
+ }
703
+ async getProject(id) {
704
+ if (!this.db)
705
+ throw new Error('Database not initialized');
706
+ const stmt = this.db.prepare('SELECT * FROM projects WHERE id = ?');
707
+ const row = stmt.get(id);
708
+ if (!row)
709
+ return null;
710
+ return {
711
+ id: row.id,
712
+ name: row.name,
713
+ path: row.path,
714
+ gitRemote: row.git_remote || undefined,
715
+ agents: [],
716
+ worktrees: [],
717
+ createdAt: new Date(row.created_at),
718
+ updatedAt: new Date(row.updated_at)
719
+ };
720
+ }
721
+ async getProjectByPath(projectPath) {
722
+ if (!this.db)
723
+ throw new Error('Database not initialized');
724
+ const stmt = this.db.prepare('SELECT * FROM projects WHERE path = ?');
725
+ const row = stmt.get(projectPath);
726
+ if (!row)
727
+ return null;
728
+ return {
729
+ id: row.id,
730
+ name: row.name,
731
+ path: row.path,
732
+ gitRemote: row.git_remote || undefined,
733
+ agents: [],
734
+ worktrees: [],
735
+ createdAt: new Date(row.created_at),
736
+ updatedAt: new Date(row.updated_at)
737
+ };
738
+ }
739
+ async listProjects() {
740
+ if (!this.db)
741
+ throw new Error('Database not initialized');
742
+ const stmt = this.db.prepare('SELECT * FROM projects ORDER BY updated_at DESC');
743
+ const rows = stmt.all();
744
+ return rows.map(row => ({
745
+ id: row.id,
746
+ name: row.name,
747
+ path: row.path,
748
+ gitRemote: row.git_remote || undefined,
749
+ agents: [],
750
+ worktrees: [],
751
+ createdAt: new Date(row.created_at),
752
+ updatedAt: new Date(row.updated_at)
753
+ }));
754
+ }
755
+ async deleteProject(id) {
756
+ if (!this.db)
757
+ throw new Error('Database not initialized');
758
+ const stmt = this.db.prepare('DELETE FROM projects WHERE id = ?');
759
+ stmt.run(id);
760
+ }
761
+ }
762
+ exports.DatabaseManager = DatabaseManager;
763
+ //# sourceMappingURL=DatabaseManager.js.map