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,234 @@
1
+ -- Supabase Database Schema for Codex Linux Cloud Sync
2
+ -- Run this in your Supabase SQL Editor
3
+
4
+ -- Enable realtime for threads table
5
+ alter publication supabase_realtime add table threads;
6
+
7
+ -- Create threads table
8
+ CREATE TABLE IF NOT EXISTS threads (
9
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
10
+ agent_id UUID NOT NULL,
11
+ user_id UUID NOT NULL,
12
+ device_id TEXT NOT NULL,
13
+ project_path TEXT NOT NULL,
14
+ messages JSONB NOT NULL DEFAULT '[]',
15
+ status TEXT NOT NULL DEFAULT 'idle',
16
+ last_modified BIGINT NOT NULL DEFAULT EXTRACT(EPOCH FROM NOW()) * 1000,
17
+ version INTEGER NOT NULL DEFAULT 1,
18
+ is_deleted BOOLEAN NOT NULL DEFAULT FALSE,
19
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
20
+ updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
21
+ );
22
+
23
+ -- Create indexes for better performance
24
+ CREATE INDEX IF NOT EXISTS idx_threads_user_id ON threads(user_id);
25
+ CREATE INDEX IF NOT EXISTS idx_threads_agent_id ON threads(agent_id);
26
+ CREATE INDEX IF NOT EXISTS idx_threads_device_id ON threads(device_id);
27
+ CREATE INDEX IF NOT EXISTS idx_threads_last_modified ON threads(last_modified);
28
+ CREATE INDEX IF NOT EXISTS idx_threads_user_deleted ON threads(user_id, is_deleted);
29
+
30
+ -- Create users table for cloud sync
31
+ CREATE TABLE IF NOT EXISTS cloud_users (
32
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
33
+ email TEXT UNIQUE NOT NULL,
34
+ display_name TEXT,
35
+ avatar_url TEXT,
36
+ devices JSONB NOT NULL DEFAULT '[]',
37
+ settings JSONB NOT NULL DEFAULT '{}',
38
+ subscription_tier TEXT DEFAULT 'free',
39
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
40
+ updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
41
+ );
42
+
43
+ -- Create devices table to track user devices
44
+ CREATE TABLE IF NOT EXISTS user_devices (
45
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
46
+ user_id UUID NOT NULL REFERENCES cloud_users(id) ON DELETE CASCADE,
47
+ device_id TEXT NOT NULL,
48
+ device_name TEXT NOT NULL,
49
+ device_type TEXT NOT NULL,
50
+ last_sync BIGINT,
51
+ is_active BOOLEAN NOT NULL DEFAULT TRUE,
52
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
53
+ UNIQUE(user_id, device_id)
54
+ );
55
+
56
+ -- Create sync conflicts table for manual resolution
57
+ CREATE TABLE IF NOT EXISTS sync_conflicts (
58
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
59
+ thread_id UUID NOT NULL REFERENCES threads(id) ON DELETE CASCADE,
60
+ user_id UUID NOT NULL,
61
+ local_version JSONB NOT NULL,
62
+ remote_version JSONB NOT NULL,
63
+ resolution TEXT,
64
+ resolved_at TIMESTAMP WITH TIME ZONE,
65
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
66
+ );
67
+
68
+ -- Row Level Security (RLS) Policies
69
+
70
+ -- Enable RLS on all tables
71
+ ALTER TABLE threads ENABLE ROW LEVEL SECURITY;
72
+ ALTER TABLE cloud_users ENABLE ROW LEVEL SECURITY;
73
+ ALTER TABLE user_devices ENABLE ROW LEVEL SECURITY;
74
+ ALTER TABLE sync_conflicts ENABLE ROW LEVEL SECURITY;
75
+
76
+ -- Threads policies
77
+ CREATE POLICY "Users can only access their own threads"
78
+ ON threads FOR ALL
79
+ USING (user_id = auth.uid());
80
+
81
+ -- Cloud users policies
82
+ CREATE POLICY "Users can only access their own profile"
83
+ ON cloud_users FOR ALL
84
+ USING (id = auth.uid());
85
+
86
+ -- User devices policies
87
+ CREATE POLICY "Users can only access their own devices"
88
+ ON user_devices FOR ALL
89
+ USING (user_id = auth.uid());
90
+
91
+ -- Sync conflicts policies
92
+ CREATE POLICY "Users can only access their own conflicts"
93
+ ON sync_conflicts FOR ALL
94
+ USING (user_id = auth_uid());
95
+
96
+ -- Functions
97
+
98
+ -- Function to update the updated_at timestamp
99
+ CREATE OR REPLACE FUNCTION update_updated_at_column()
100
+ RETURNS TRIGGER AS $$
101
+ BEGIN
102
+ NEW.updated_at = NOW();
103
+ RETURN NEW;
104
+ END;
105
+ $$ language 'plpgsql';
106
+
107
+ -- Triggers for updated_at
108
+ CREATE TRIGGER update_threads_updated_at
109
+ BEFORE UPDATE ON threads
110
+ FOR EACH ROW
111
+ EXECUTE FUNCTION update_updated_at_column();
112
+
113
+ CREATE TRIGGER update_cloud_users_updated_at
114
+ BEFORE UPDATE ON cloud_users
115
+ FOR EACH ROW
116
+ EXECUTE FUNCTION update_updated_at_column();
117
+
118
+ -- Function to get threads modified since a timestamp
119
+ CREATE OR REPLACE FUNCTION get_threads_since(
120
+ p_user_id UUID,
121
+ p_since BIGINT
122
+ )
123
+ RETURNS TABLE (
124
+ id UUID,
125
+ agent_id UUID,
126
+ user_id UUID,
127
+ device_id TEXT,
128
+ project_path TEXT,
129
+ messages JSONB,
130
+ status TEXT,
131
+ last_modified BIGINT,
132
+ version INTEGER,
133
+ is_deleted BOOLEAN,
134
+ created_at TIMESTAMP WITH TIME ZONE,
135
+ updated_at TIMESTAMP WITH TIME ZONE
136
+ ) AS $$
137
+ BEGIN
138
+ RETURN QUERY
139
+ SELECT t.*
140
+ FROM threads t
141
+ WHERE t.user_id = p_user_id
142
+ AND t.last_modified > p_since
143
+ AND t.is_deleted = FALSE
144
+ ORDER BY t.last_modified DESC;
145
+ END;
146
+ $$ LANGUAGE plpgsql SECURITY DEFINER;
147
+
148
+ -- Function to upsert thread with conflict detection
149
+ CREATE OR REPLACE FUNCTION upsert_thread(
150
+ p_id UUID,
151
+ p_agent_id UUID,
152
+ p_user_id UUID,
153
+ p_device_id TEXT,
154
+ p_project_path TEXT,
155
+ p_messages JSONB,
156
+ p_status TEXT,
157
+ p_last_modified BIGINT,
158
+ p_version INTEGER,
159
+ p_is_deleted BOOLEAN
160
+ )
161
+ RETURNS JSONB AS $$
162
+ DECLARE
163
+ existing_version INTEGER;
164
+ result JSONB;
165
+ BEGIN
166
+ -- Check if thread exists and get its version
167
+ SELECT version INTO existing_version
168
+ FROM threads
169
+ WHERE id = p_id;
170
+
171
+ IF existing_version IS NULL THEN
172
+ -- Insert new thread
173
+ INSERT INTO threads (
174
+ id, agent_id, user_id, device_id, project_path,
175
+ messages, status, last_modified, version, is_deleted
176
+ ) VALUES (
177
+ p_id, p_agent_id, p_user_id, p_device_id, p_project_path,
178
+ p_messages, p_status, p_last_modified, p_version, p_is_deleted
179
+ );
180
+
181
+ result := jsonb_build_object(
182
+ 'success', true,
183
+ 'action', 'insert',
184
+ 'conflict', false
185
+ );
186
+ ELSIF p_version > existing_version THEN
187
+ -- Update with newer version
188
+ UPDATE threads SET
189
+ agent_id = p_agent_id,
190
+ device_id = p_device_id,
191
+ project_path = p_project_path,
192
+ messages = p_messages,
193
+ status = p_status,
194
+ last_modified = p_last_modified,
195
+ version = p_version,
196
+ is_deleted = p_is_deleted
197
+ WHERE id = p_id;
198
+
199
+ result := jsonb_build_object(
200
+ 'success', true,
201
+ 'action', 'update',
202
+ 'conflict', false
203
+ );
204
+ ELSE
205
+ -- Version conflict detected
206
+ INSERT INTO sync_conflicts (
207
+ thread_id, user_id, local_version, remote_version
208
+ ) VALUES (
209
+ p_id, p_user_id,
210
+ (SELECT to_jsonb(t.*) FROM threads t WHERE t.id = p_id),
211
+ jsonb_build_object(
212
+ 'id', p_id,
213
+ 'agent_id', p_agent_id,
214
+ 'device_id', p_device_id,
215
+ 'project_path', p_project_path,
216
+ 'messages', p_messages,
217
+ 'status', p_status,
218
+ 'last_modified', p_last_modified,
219
+ 'version', p_version,
220
+ 'is_deleted', p_is_deleted
221
+ )
222
+ );
223
+
224
+ result := jsonb_build_object(
225
+ 'success', false,
226
+ 'action', 'none',
227
+ 'conflict', true,
228
+ 'message', 'Version conflict detected. Manual resolution required.'
229
+ );
230
+ END IF;
231
+
232
+ RETURN result;
233
+ END;
234
+ $$ LANGUAGE plpgsql SECURITY DEFINER;
@@ -0,0 +1,78 @@
1
+ /** @type {import('tailwindcss').Config} */
2
+ module.exports = {
3
+ darkMode: ["class"],
4
+ content: [
5
+ './index.html',
6
+ './src/renderer/**/*.{js,ts,jsx,tsx}',
7
+ ],
8
+ theme: {
9
+ container: {
10
+ center: true,
11
+ padding: "2rem",
12
+ screens: {
13
+ "2xl": "1400px",
14
+ },
15
+ },
16
+ extend: {
17
+ colors: {
18
+ border: "hsl(var(--border))",
19
+ input: "hsl(var(--input))",
20
+ ring: "hsl(var(--ring))",
21
+ background: "hsl(var(--background))",
22
+ foreground: "hsl(var(--foreground))",
23
+ primary: {
24
+ DEFAULT: "hsl(var(--primary))",
25
+ foreground: "hsl(var(--primary-foreground))",
26
+ },
27
+ secondary: {
28
+ DEFAULT: "hsl(var(--secondary))",
29
+ foreground: "hsl(var(--secondary-foreground))",
30
+ },
31
+ destructive: {
32
+ DEFAULT: "hsl(var(--destructive))",
33
+ foreground: "hsl(var(--destructive-foreground))",
34
+ },
35
+ muted: {
36
+ DEFAULT: "hsl(var(--muted))",
37
+ foreground: "hsl(var(--muted-foreground))",
38
+ },
39
+ accent: {
40
+ DEFAULT: "hsl(var(--accent))",
41
+ foreground: "hsl(var(--accent-foreground))",
42
+ },
43
+ popover: {
44
+ DEFAULT: "hsl(var(--popover))",
45
+ foreground: "hsl(var(--popover-foreground))",
46
+ },
47
+ card: {
48
+ DEFAULT: "hsl(var(--card))",
49
+ foreground: "hsl(var(--card-foreground))",
50
+ },
51
+ },
52
+ borderRadius: {
53
+ lg: "var(--radius)",
54
+ md: "calc(var(--radius) - 2px)",
55
+ sm: "calc(var(--radius) - 4px)",
56
+ },
57
+ fontFamily: {
58
+ sans: ['Inter', 'system-ui', '-apple-system', 'BlinkMacSystemFont', 'Segoe UI', 'Roboto', 'sans-serif'],
59
+ mono: ['JetBrains Mono', 'Fira Code', 'Menlo', 'Monaco', 'Consolas', 'monospace'],
60
+ },
61
+ keyframes: {
62
+ "accordion-down": {
63
+ from: { height: "0" },
64
+ to: { height: "var(--radix-accordion-content-height)" },
65
+ },
66
+ "accordion-up": {
67
+ from: { height: "var(--radix-accordion-content-height)" },
68
+ to: { height: "0" },
69
+ },
70
+ },
71
+ animation: {
72
+ "accordion-down": "accordion-down 0.2s ease-out",
73
+ "accordion-up": "accordion-up 0.2s ease-out",
74
+ },
75
+ },
76
+ },
77
+ plugins: [require("tailwindcss-animate")],
78
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "@codex-linux/e2e",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "test": "playwright test",
7
+ "test:ui": "playwright test --ui",
8
+ "test:debug": "playwright test --debug",
9
+ "report": "playwright show-report"
10
+ },
11
+ "devDependencies": {
12
+ "@playwright/test": "^1.40.0",
13
+ "@types/node": "^20.10.0"
14
+ }
15
+ }
@@ -0,0 +1,31 @@
1
+ import { defineConfig, devices } from '@playwright/test';
2
+
3
+ export default defineConfig({
4
+ testDir: './specs',
5
+ fullyParallel: true,
6
+ forbidOnly: !!process.env.CI,
7
+ retries: process.env.CI ? 2 : 0,
8
+ workers: process.env.CI ? 1 : undefined,
9
+ reporter: 'html',
10
+ use: {
11
+ baseURL: 'http://localhost:3000',
12
+ trace: 'on-first-retry',
13
+ screenshot: 'only-on-failure',
14
+ video: 'retain-on-failure',
15
+ },
16
+ projects: [
17
+ {
18
+ name: 'chromium',
19
+ use: { ...devices['Desktop Chrome'] },
20
+ },
21
+ {
22
+ name: 'firefox',
23
+ use: { ...devices['Desktop Firefox'] },
24
+ },
25
+ ],
26
+ webServer: {
27
+ command: 'cd ../.. && npm run dev',
28
+ url: 'http://localhost:3000',
29
+ reuseExistingServer: !process.env.CI,
30
+ },
31
+ });
@@ -0,0 +1,194 @@
1
+ import { test, expect, type Page } from '@playwright/test';
2
+
3
+ test.describe('Codex Linux E2E Tests', () => {
4
+
5
+ test.beforeEach(async ({ page }) => {
6
+ await page.goto('/');
7
+ await page.waitForLoadState('networkidle');
8
+ });
9
+
10
+ describe('Application Launch', () => {
11
+ test('should display loading screen', async ({ page }) => {
12
+ await expect(page.locator('text=Loading')).toBeVisible({ timeout: 10000 });
13
+ });
14
+
15
+ test('should load main interface within timeout', async ({ page }) => {
16
+ await expect(page.locator('nav, aside, [class*="sidebar"]')).toBeVisible({ timeout: 30000 });
17
+ });
18
+
19
+ test('should have correct window title', async ({ page }) => {
20
+ await expect(page).toHaveTitle(/Codex/i, { timeout: 10000 });
21
+ });
22
+
23
+ test('should show sidebar navigation', async ({ page }) => {
24
+ await expect(page.locator('text=Agents')).toBeVisible({ timeout: 30000 });
25
+ });
26
+ });
27
+
28
+ describe('Navigation', () => {
29
+ test.beforeEach(async ({ page }) => {
30
+ await page.waitForSelector('text=Agents', { timeout: 30000 });
31
+ });
32
+
33
+ test('should navigate to all main sections', async ({ page }) => {
34
+ const sections = ['Agents', 'Worktrees', 'Skills', 'Settings'];
35
+
36
+ for (const section of sections) {
37
+ await expect(page.locator(`text=${section}`)).toBeVisible();
38
+ }
39
+ });
40
+
41
+ test('should navigate using keyboard shortcuts', async ({ page }) => {
42
+ await page.keyboard.press('Alt+1');
43
+ await expect(page.locator('[class*="agent"]')).toBeVisible({ timeout: 5000 });
44
+ });
45
+ });
46
+
47
+ describe('Agent Management', () => {
48
+ test.beforeEach(async ({ page }) => {
49
+ await page.goto('/');
50
+ await page.waitForSelector('text=Agents', { timeout: 30000 });
51
+ });
52
+
53
+ test('should open create agent modal', async ({ page }) => {
54
+ const createButton = page.locator('[data-testid="create-agent-button"], button:has-text("Create")').first();
55
+ if (await createButton.isVisible()) {
56
+ await createButton.click();
57
+ await expect(page.locator('text=Create New Agent, text=New Agent')).toBeVisible({ timeout: 5000 });
58
+ }
59
+ });
60
+
61
+ test('should display agent list', async ({ page }) => {
62
+ await page.waitForTimeout(2000);
63
+ const agentCards = page.locator('[class*="card"], [class*="agent"]');
64
+ const count = await agentCards.count();
65
+ expect(count).toBeGreaterThanOrEqual(0);
66
+ });
67
+
68
+ test('should select an agent', async ({ page }) => {
69
+ await page.waitForTimeout(2000);
70
+ const firstAgent = page.locator('[class*="card"], [class*="agent"]').first();
71
+ if (await firstAgent.isVisible()) {
72
+ await firstAgent.click();
73
+ await page.waitForTimeout(1000);
74
+ }
75
+ });
76
+ });
77
+
78
+ describe('Chat Interface', () => {
79
+ test.beforeEach(async ({ page }) => {
80
+ await page.goto('/');
81
+ await page.waitForSelector('text=Agents', { timeout: 30000 });
82
+ });
83
+
84
+ test('should display chat input', async ({ page }) => {
85
+ await page.waitForTimeout(2000);
86
+ const chatInput = page.locator('input[type="text"], textarea, [data-testid="chat-input"]').first();
87
+ await expect(chatInput).toBeVisible({ timeout: 5000 });
88
+ });
89
+
90
+ test('should type and send message', async ({ page }) => {
91
+ await page.waitForTimeout(2000);
92
+ const chatInput = page.locator('input[type="text"], textarea, [data-testid="chat-input"]').first();
93
+
94
+ if (await chatInput.isVisible()) {
95
+ await chatInput.fill('test message');
96
+ await expect(chatInput).toHaveValue('test message');
97
+ }
98
+ });
99
+ });
100
+
101
+ describe('Settings', () => {
102
+ test.beforeEach(async ({ page }) => {
103
+ await page.goto('/');
104
+ await page.waitForSelector('text=Settings', { timeout: 30000 });
105
+ await page.click('text=Settings');
106
+ });
107
+
108
+ test('should display settings page', async ({ page }) => {
109
+ await expect(page.locator('text=Settings, h1:has-text("Settings")')).toBeVisible({ timeout: 5000 });
110
+ });
111
+
112
+ test('should have general settings', async ({ page }) => {
113
+ await expect(page.locator('text=General, text=AI')).toBeVisible({ timeout: 5000 });
114
+ });
115
+ });
116
+
117
+ describe('Accessibility', () => {
118
+ test('should have proper heading structure', async ({ page }) => {
119
+ await page.goto('/');
120
+ await page.waitForSelector('text=Agents', { timeout: 30000 });
121
+
122
+ const h1 = page.locator('h1');
123
+ const count = await h1.count();
124
+ expect(count).toBeGreaterThanOrEqual(0);
125
+ });
126
+
127
+ test('should have focusable elements', async ({ page }) => {
128
+ await page.goto('/');
129
+ await page.waitForSelector('text=Agents', { timeout: 30000 });
130
+
131
+ const buttons = page.locator('button');
132
+ const count = await buttons.count();
133
+ expect(count).toBeGreaterThan(0);
134
+ });
135
+
136
+ test('should support keyboard navigation', async ({ page }) => {
137
+ await page.goto('/');
138
+ await page.waitForSelector('text=Agents', { timeout: 30000 });
139
+
140
+ await page.keyboard.press('Tab');
141
+ const focusedElement = await page.locator(':focus').first();
142
+ await expect(focusedElement).toBeVisible();
143
+ });
144
+ });
145
+
146
+ describe('Error Handling', () => {
147
+ test('should handle network errors gracefully', async ({ page }) => {
148
+ await page.route('**/api/**', route => route.abort('failed'));
149
+ await page.goto('/');
150
+ await page.waitForTimeout(3000);
151
+
152
+ const content = await page.content();
153
+ expect(content.length).toBeGreaterThan(0);
154
+ });
155
+ });
156
+
157
+ describe('Responsive Design', () => {
158
+ test('should work at different viewport sizes', async ({ page }) => {
159
+ await page.setViewportSize({ width: 1920, height: 1080 });
160
+ await page.goto('/');
161
+ await expect(page.locator('text=Agents')).toBeVisible({ timeout: 30000 });
162
+
163
+ await page.setViewportSize({ width: 768, height: 1024 });
164
+ await page.reload();
165
+ await expect(page.locator('text=Agents')).toBeVisible({ timeout: 30000 });
166
+
167
+ await page.setViewportSize({ width: 375, height: 667 });
168
+ await page.reload();
169
+ await page.waitForTimeout(2000);
170
+ });
171
+ });
172
+
173
+ describe('Performance', () => {
174
+ test('should load within acceptable time', async ({ page }) => {
175
+ const startTime = Date.now();
176
+ await page.goto('/');
177
+ await page.waitForSelector('text=Agents', { timeout: 30000 });
178
+ const loadTime = Date.now() - startTime;
179
+
180
+ console.log(`Page load time: ${loadTime}ms`);
181
+ expect(loadTime).toBeLessThan(30000);
182
+ });
183
+
184
+ test('should not have memory leaks on navigation', async ({ page }) => {
185
+ await page.goto('/');
186
+ await page.waitForSelector('text=Agents', { timeout: 30000 });
187
+
188
+ for (let i = 0; i < 3; i++) {
189
+ await page.reload();
190
+ await page.waitForSelector('text=Agents', { timeout: 30000 });
191
+ }
192
+ });
193
+ });
194
+ });
package/tests/setup.ts ADDED
@@ -0,0 +1,99 @@
1
+ // Test setup and utilities
2
+
3
+ // Mock electron modules
4
+ jest.mock('electron', () => ({
5
+ app: {
6
+ getPath: () => '/tmp/test',
7
+ on: () => {},
8
+ whenReady: () => Promise.resolve(),
9
+ },
10
+ BrowserWindow: () => {},
11
+ ipcMain: {
12
+ handle: () => {},
13
+ on: () => {},
14
+ },
15
+ dialog: {
16
+ showOpenDialog: () => Promise.resolve({ filePaths: [] }),
17
+ showSaveDialog: () => Promise.resolve({ filePath: '' }),
18
+ },
19
+ shell: {
20
+ openExternal: () => Promise.resolve(),
21
+ openPath: () => Promise.resolve(''),
22
+ },
23
+ Notification: () => {},
24
+ }));
25
+
26
+ jest.mock('electron-log', () => ({
27
+ info: () => {},
28
+ error: () => {},
29
+ warn: () => {},
30
+ debug: () => {},
31
+ }));
32
+
33
+ jest.mock('electron-store', () => {
34
+ return () => ({
35
+ get: () => {},
36
+ set: () => {},
37
+ clear: () => {},
38
+ });
39
+ });
40
+
41
+ // Global test utilities
42
+ (global as any).testUtils = {
43
+ createMockAgent: (overrides = {}) => ({
44
+ id: 'test-agent-1',
45
+ name: 'Test Agent',
46
+ status: 'idle',
47
+ projectPath: '/tmp/test-project',
48
+ worktreeName: 'test-worktree',
49
+ providerId: 'openai',
50
+ model: 'gpt-4o',
51
+ skills: [],
52
+ createdAt: new Date(),
53
+ updatedAt: new Date(),
54
+ lastActiveAt: null,
55
+ messages: [],
56
+ tasks: [],
57
+ metadata: {},
58
+ ...overrides,
59
+ }),
60
+
61
+ createMockWorktree: (overrides = {}) => ({
62
+ name: 'test-worktree',
63
+ path: '/tmp/test-project/.codex/worktrees/test-worktree',
64
+ commit: 'abc123',
65
+ branch: 'codex/test-agent-1',
66
+ isMain: false,
67
+ agents: [],
68
+ createdAt: new Date(),
69
+ ...overrides,
70
+ }),
71
+
72
+ createMockSkill: (overrides = {}) => ({
73
+ id: 'test-skill-1',
74
+ name: 'Test Skill',
75
+ description: 'A test skill',
76
+ version: '1.0.0',
77
+ author: 'Test Author',
78
+ tags: ['test'],
79
+ files: [],
80
+ config: {
81
+ entryPoint: 'index.md',
82
+ parameters: [],
83
+ dependencies: [],
84
+ permissions: [],
85
+ },
86
+ createdAt: new Date(),
87
+ updatedAt: new Date(),
88
+ ...overrides,
89
+ }),
90
+
91
+ wait: (ms: number) => new Promise(resolve => setTimeout(resolve, ms)),
92
+ };
93
+
94
+ // Console suppression for cleaner test output
95
+ if (process.env.SUPPRESS_CONSOLE) {
96
+ console.log = () => {};
97
+ console.error = () => {};
98
+ console.warn = () => {};
99
+ }