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,248 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { Brain, Gauge, ChevronDown, ChevronUp, Info, AlertTriangle, CheckCircle } from 'lucide-react';
3
+
4
+ export interface ContextUsage {
5
+ inputTokens: number;
6
+ outputTokens: number;
7
+ totalTokens: number;
8
+ maxTokens: number;
9
+ messagesCount: number;
10
+ filesInContext: number;
11
+ }
12
+
13
+ export interface ThinkingConfig {
14
+ enabled: boolean;
15
+ maxThinkingTokens: number;
16
+ adaptiveThinking: boolean;
17
+ currentThinkingTokens: number;
18
+ }
19
+
20
+ interface ContextUsageDisplayProps {
21
+ usage: ContextUsage;
22
+ thinking?: ThinkingConfig;
23
+ compact?: boolean;
24
+ onThinkingToggle?: (enabled: boolean) => void;
25
+ onThinkingTokensChange?: (tokens: number) => void;
26
+ }
27
+
28
+ function cn(...inputs: (string | undefined | null | boolean)[]): string {
29
+ return inputs.filter(Boolean).join(' ');
30
+ }
31
+
32
+ const formatNumber = (num: number): string => {
33
+ if (num >= 1000000) {
34
+ return `${(num / 1000000).toFixed(1)}M`;
35
+ }
36
+ if (num >= 1000) {
37
+ return `${(num / 1000).toFixed(1)}K`;
38
+ }
39
+ return num.toString();
40
+ };
41
+
42
+ const getUsagePercentage = (current: number, max: number): number => {
43
+ return Math.min(100, Math.round((current / max) * 100));
44
+ };
45
+
46
+ const getUsageColor = (percentage: number): string => {
47
+ if (percentage >= 90) return 'bg-red-500';
48
+ if (percentage >= 70) return 'bg-yellow-500';
49
+ return 'bg-green-500';
50
+ };
51
+
52
+ export const ContextUsageDisplay: React.FC<ContextUsageDisplayProps> = ({
53
+ usage,
54
+ thinking,
55
+ compact = false,
56
+ onThinkingToggle,
57
+ onThinkingTokensChange,
58
+ }) => {
59
+ const [expanded, setExpanded] = useState(!compact);
60
+ const [thinkingExpanded, setThinkingExpanded] = useState(false);
61
+
62
+ const usagePercentage = getUsagePercentage(usage.totalTokens, usage.maxTokens);
63
+ const usageColor = getUsageColor(usagePercentage);
64
+
65
+ if (compact) {
66
+ return (
67
+ <div
68
+ className="flex items-center gap-2 text-xs text-muted-foreground cursor-pointer"
69
+ onClick={() => setExpanded(!expanded)}
70
+ >
71
+ <Brain className="w-3.5 h-3.5" />
72
+ <span>{formatNumber(usage.totalTokens)}</span>
73
+ <span className="text-muted-foreground/60">/</span>
74
+ <span>{formatNumber(usage.maxTokens)}</span>
75
+
76
+ <div className="w-16 h-1.5 bg-muted rounded-full overflow-hidden">
77
+ <div
78
+ className={cn('h-full rounded-full transition-all', usageColor)}
79
+ style={{ width: `${usagePercentage}%` }}
80
+ />
81
+ </div>
82
+
83
+ {expanded ? (
84
+ <ChevronUp className="w-3.5 h-3.5" />
85
+ ) : (
86
+ <ChevronDown className="w-3.5 h-3.5" />
87
+ )}
88
+ </div>
89
+ );
90
+ }
91
+
92
+ return (
93
+ <div className="bg-card border border-border rounded-lg overflow-hidden">
94
+ {/* Header - Always visible */}
95
+ <div
96
+ className="flex items-center justify-between px-4 py-3 cursor-pointer hover:bg-muted/50"
97
+ onClick={() => setExpanded(!expanded)}
98
+ >
99
+ <div className="flex items-center gap-3">
100
+ <Brain className="w-5 h-5 text-primary" />
101
+ <span className="font-medium">Context Usage</span>
102
+ </div>
103
+
104
+ <div className="flex items-center gap-4">
105
+ <div className="flex items-center gap-2">
106
+ <div className="w-32 h-2 bg-muted rounded-full overflow-hidden">
107
+ <div
108
+ className={cn('h-full rounded-full transition-all', usageColor)}
109
+ style={{ width: `${usagePercentage}%` }}
110
+ />
111
+ </div>
112
+ <span className="text-sm text-muted-foreground">
113
+ {usagePercentage}%
114
+ </span>
115
+ </div>
116
+
117
+ {expanded ? (
118
+ <ChevronUp className="w-4 h-4" />
119
+ ) : (
120
+ <ChevronDown className="w-4 h-4" />
121
+ )}
122
+ </div>
123
+ </div>
124
+
125
+ {/* Expanded content */}
126
+ {expanded && (
127
+ <div className="px-4 py-3 border-t border-border space-y-4">
128
+ {/* Token breakdown */}
129
+ <div className="grid grid-cols-3 gap-4">
130
+ <div className="bg-muted/50 rounded-lg p-3">
131
+ <div className="text-xs text-muted-foreground mb-1">Input</div>
132
+ <div className="text-lg font-semibold">{formatNumber(usage.inputTokens)}</div>
133
+ <div className="text-xs text-muted-foreground">
134
+ {Math.round((usage.inputTokens / usage.maxTokens) * 100)}% of limit
135
+ </div>
136
+ </div>
137
+
138
+ <div className="bg-muted/50 rounded-lg p-3">
139
+ <div className="text-xs text-muted-foreground mb-1">Output</div>
140
+ <div className="text-lg font-semibold">{formatNumber(usage.outputTokens)}</div>
141
+ <div className="text-xs text-muted-foreground">
142
+ {Math.round((usage.outputTokens / usage.maxTokens) * 100)}% of limit
143
+ </div>
144
+ </div>
145
+
146
+ <div className="bg-muted/50 rounded-lg p-3">
147
+ <div className="text-xs text-muted-foreground mb-1">Total</div>
148
+ <div className="text-lg font-semibold">{formatNumber(usage.totalTokens)}</div>
149
+ <div className="text-xs text-muted-foreground">
150
+ / {formatNumber(usage.maxTokens)}
151
+ </div>
152
+ </div>
153
+ </div>
154
+
155
+ {/* Additional stats */}
156
+ <div className="flex items-center gap-6 text-sm">
157
+ <div className="flex items-center gap-2">
158
+ <Info className="w-4 h-4 text-muted-foreground" />
159
+ <span className="text-muted-foreground">{usage.messagesCount} messages</span>
160
+ </div>
161
+ <div className="flex items-center gap-2">
162
+ <CheckCircle className="w-4 h-4 text-muted-foreground" />
163
+ <span className="text-muted-foreground">{usage.filesInContext} files in context</span>
164
+ </div>
165
+ </div>
166
+
167
+ {/* Thinking config */}
168
+ {thinking && (
169
+ <div className="border-t border-border pt-4">
170
+ <div
171
+ className="flex items-center justify-between cursor-pointer"
172
+ onClick={() => setThinkingExpanded(!thinkingExpanded)}
173
+ >
174
+ <div className="flex items-center gap-2">
175
+ <Gauge className="w-4 h-4 text-primary" />
176
+ <span className="font-medium">Extended Thinking</span>
177
+ {thinking.adaptiveThinking && (
178
+ <span className="px-1.5 py-0.5 text-xs bg-primary/10 text-primary rounded">
179
+ Adaptive
180
+ </span>
181
+ )}
182
+ </div>
183
+
184
+ <div className="flex items-center gap-3">
185
+ <label className="relative inline-flex items-center cursor-pointer">
186
+ <input
187
+ type="checkbox"
188
+ checked={thinking.enabled}
189
+ onChange={(e) => onThinkingToggle?.(e.target.checked)}
190
+ className="sr-only peer"
191
+ />
192
+ <div className="w-9 h-5 bg-muted peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:bg-primary"></div>
193
+ </label>
194
+
195
+ {thinkingExpanded ? (
196
+ <ChevronUp className="w-4 h-4" />
197
+ ) : (
198
+ <ChevronDown className="w-4 h-4" />
199
+ )}
200
+ </div>
201
+ </div>
202
+
203
+ {thinkingExpanded && (
204
+ <div className="mt-3 space-y-3">
205
+ <div className="flex items-center justify-between text-sm">
206
+ <span className="text-muted-foreground">Current thinking tokens</span>
207
+ <span className="font-medium">{formatNumber(thinking.currentThinkingTokens)}</span>
208
+ </div>
209
+
210
+ <div>
211
+ <div className="flex items-center justify-between text-sm mb-1">
212
+ <span className="text-muted-foreground">Max thinking tokens</span>
213
+ <span className="font-medium">{formatNumber(thinking.maxThinkingTokens)}</span>
214
+ </div>
215
+ <input
216
+ type="range"
217
+ min="0"
218
+ max={thinking.maxThinkingTokens}
219
+ value={thinking.maxThinkingTokens}
220
+ onChange={(e) => onThinkingTokensChange?.(parseInt(e.target.value))}
221
+ className="w-full h-2 bg-muted rounded-lg appearance-none cursor-pointer"
222
+ />
223
+ <div className="flex justify-between text-xs text-muted-foreground mt-1">
224
+ <span>0</span>
225
+ <span>{formatNumber(thinking.maxThinkingTokens)}</span>
226
+ </div>
227
+ </div>
228
+
229
+ {!thinking.adaptiveThinking && thinking.enabled && (
230
+ <div className="flex items-start gap-2 p-2 bg-yellow-500/10 rounded-lg">
231
+ <AlertTriangle className="w-4 h-4 text-yellow-500 flex-shrink-0 mt-0.5" />
232
+ <p className="text-xs text-yellow-500">
233
+ Extended thinking uses additional tokens for reasoning.
234
+ This may increase costs on paid plans.
235
+ </p>
236
+ </div>
237
+ )}
238
+ </div>
239
+ )}
240
+ </div>
241
+ )}
242
+ </div>
243
+ )}
244
+ </div>
245
+ );
246
+ };
247
+
248
+ export default ContextUsageDisplay;
@@ -0,0 +1,415 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { CoworkSession } from '../../shared/types';
3
+ import {
4
+ Users,
5
+ Plus,
6
+ Play,
7
+ Pause,
8
+ Square,
9
+ Trash2,
10
+ Clock,
11
+ CheckCircle,
12
+ AlertCircle,
13
+ Loader2,
14
+ FileText,
15
+ ChevronRight
16
+ } from 'lucide-react';
17
+
18
+ interface CoworkPanelProps {
19
+ sessions: CoworkSession[];
20
+ onCreateSession: (name: string, objective: string, projectPath: string, options: {
21
+ autoApprove?: boolean;
22
+ skills?: string[];
23
+ }) => Promise<void>;
24
+ onStartSession: (sessionId: string) => Promise<void>;
25
+ onPauseSession: (sessionId: string) => Promise<void>;
26
+ onStopSession: (sessionId: string) => Promise<void>;
27
+ onDeleteSession: (sessionId: string) => Promise<void>;
28
+ onViewSession: (sessionId: string) => void;
29
+ }
30
+
31
+ export const CoworkPanel: React.FC<CoworkPanelProps> = ({
32
+ sessions,
33
+ onCreateSession,
34
+ onStartSession,
35
+ onPauseSession,
36
+ onStopSession,
37
+ onDeleteSession,
38
+ onViewSession
39
+ }) => {
40
+ const [showCreateModal, setShowCreateModal] = useState(false);
41
+ const [selectedSession, setSelectedSession] = useState<CoworkSession | null>(null);
42
+ const [newSessionConfig, setNewSessionConfig] = useState({
43
+ name: '',
44
+ objective: '',
45
+ projectPath: '',
46
+ autoApprove: false
47
+ });
48
+
49
+ const handleCreateSession = async () => {
50
+ try {
51
+ await onCreateSession(
52
+ newSessionConfig.name,
53
+ newSessionConfig.objective,
54
+ newSessionConfig.projectPath,
55
+ { autoApprove: newSessionConfig.autoApprove }
56
+ );
57
+ setShowCreateModal(false);
58
+ setNewSessionConfig({
59
+ name: '',
60
+ objective: '',
61
+ projectPath: '',
62
+ autoApprove: false
63
+ });
64
+ } catch (error) {
65
+ console.error('Failed to create session:', error);
66
+ }
67
+ };
68
+
69
+ const getStatusIcon = (status: string) => {
70
+ switch (status) {
71
+ case 'running':
72
+ return <Loader2 className="w-4 h-4 animate-spin text-green-500" />;
73
+ case 'paused':
74
+ return <Pause className="w-4 h-4 text-yellow-500" />;
75
+ case 'completed':
76
+ return <CheckCircle className="w-4 h-4 text-green-500" />;
77
+ case 'error':
78
+ return <AlertCircle className="w-4 h-4 text-red-500" />;
79
+ default:
80
+ return <Clock className="w-4 h-4 text-gray-400" />;
81
+ }
82
+ };
83
+
84
+ const getStatusColor = (status: string) => {
85
+ switch (status) {
86
+ case 'running':
87
+ return 'bg-green-500/10 text-green-500 border-green-500/30';
88
+ case 'paused':
89
+ return 'bg-yellow-500/10 text-yellow-500 border-yellow-500/30';
90
+ case 'completed':
91
+ return 'bg-blue-500/10 text-blue-500 border-blue-500/30';
92
+ case 'error':
93
+ return 'bg-red-500/10 text-red-500 border-red-500/30';
94
+ default:
95
+ return 'bg-gray-500/10 text-gray-500 border-gray-500/30';
96
+ }
97
+ };
98
+
99
+ return (
100
+ <div className="h-full flex">
101
+ {/* Sessions List */}
102
+ <div className="w-96 border-r border-border bg-card flex flex-col">
103
+ <div className="p-4 border-b border-border flex items-center justify-between">
104
+ <div className="flex items-center gap-2">
105
+ <Users className="w-5 h-5" />
106
+ <h2 className="font-semibold">Cowork Sessions</h2>
107
+ </div>
108
+ <button
109
+ onClick={() => setShowCreateModal(true)}
110
+ className="p-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90"
111
+ >
112
+ <Plus className="w-4 h-4" />
113
+ </button>
114
+ </div>
115
+
116
+ <div className="flex-1 overflow-auto p-3 space-y-2">
117
+ {sessions.map(session => (
118
+ <div
119
+ key={session.id}
120
+ onClick={() => setSelectedSession(session)}
121
+ className={`p-3 rounded-lg cursor-pointer transition-colors border ${
122
+ selectedSession?.id === session.id
123
+ ? 'bg-primary/10 border-primary/30'
124
+ : 'hover:bg-muted border-transparent'
125
+ }`}
126
+ >
127
+ <div className="flex items-start justify-between mb-2">
128
+ <div className="flex items-center gap-2">
129
+ {getStatusIcon(session.status)}
130
+ <span className="font-medium text-sm truncate max-w-[180px]">
131
+ {session.name}
132
+ </span>
133
+ </div>
134
+ <span className={`text-xs px-2 py-0.5 rounded-full border ${getStatusColor(session.status)}`}>
135
+ {session.status}
136
+ </span>
137
+ </div>
138
+
139
+ <p className="text-xs text-muted-foreground truncate mb-2">
140
+ {session.objective}
141
+ </p>
142
+
143
+ <div className="flex items-center justify-between text-xs text-muted-foreground">
144
+ <span>{session.progress}% complete</span>
145
+ <span>{new Date(session.createdAt).toLocaleDateString()}</span>
146
+ </div>
147
+
148
+ {/* Progress bar */}
149
+ <div className="mt-2 h-1.5 bg-muted rounded-full overflow-hidden">
150
+ <div
151
+ className={`h-full rounded-full transition-all ${
152
+ session.status === 'error' ? 'bg-red-500' :
153
+ session.status === 'completed' ? 'bg-green-500' :
154
+ 'bg-primary'
155
+ }`}
156
+ style={{ width: `${session.progress}%` }}
157
+ />
158
+ </div>
159
+ </div>
160
+ ))}
161
+
162
+ {sessions.length === 0 && (
163
+ <div className="text-center py-8 text-muted-foreground">
164
+ <Users className="w-12 h-12 mx-auto mb-2 opacity-50" />
165
+ <p className="text-sm">No sessions yet</p>
166
+ <p className="text-xs mt-1">Create your first cowork session</p>
167
+ </div>
168
+ )}
169
+ </div>
170
+ </div>
171
+
172
+ {/* Session Detail View */}
173
+ <div className="flex-1 flex flex-col bg-background">
174
+ {selectedSession ? (
175
+ <>
176
+ {/* Header */}
177
+ <div className="p-4 border-b border-border flex items-center justify-between">
178
+ <div className="flex-1 min-w-0">
179
+ <div className="flex items-center gap-3">
180
+ <h2 className="text-lg font-semibold truncate">{selectedSession.name}</h2>
181
+ <span className={`text-xs px-2 py-0.5 rounded-full border ${getStatusColor(selectedSession.status)}`}>
182
+ {selectedSession.status}
183
+ </span>
184
+ </div>
185
+ <p className="text-sm text-muted-foreground mt-1">
186
+ Created {new Date(selectedSession.createdAt).toLocaleString()}
187
+ </p>
188
+ </div>
189
+
190
+ <div className="flex items-center gap-2">
191
+ {selectedSession.status === 'idle' && (
192
+ <button
193
+ onClick={() => onStartSession(selectedSession.id)}
194
+ className="flex items-center gap-1.5 px-3 py-1.5 bg-green-500 text-white rounded-lg hover:bg-green-600"
195
+ >
196
+ <Play className="w-4 h-4" />
197
+ Start
198
+ </button>
199
+ )}
200
+
201
+ {selectedSession.status === 'running' && (
202
+ <>
203
+ <button
204
+ onClick={() => onPauseSession(selectedSession.id)}
205
+ className="flex items-center gap-1.5 px-3 py-1.5 bg-yellow-500 text-white rounded-lg hover:bg-yellow-600"
206
+ >
207
+ <Pause className="w-4 h-4" />
208
+ Pause
209
+ </button>
210
+ <button
211
+ onClick={() => onStopSession(selectedSession.id)}
212
+ className="flex items-center gap-1.5 px-3 py-1.5 bg-red-500 text-white rounded-lg hover:bg-red-600"
213
+ >
214
+ <Square className="w-4 h-4" />
215
+ Stop
216
+ </button>
217
+ </>
218
+ )}
219
+
220
+ {selectedSession.status === 'paused' && (
221
+ <>
222
+ <button
223
+ onClick={() => onStartSession(selectedSession.id)}
224
+ className="flex items-center gap-1.5 px-3 py-1.5 bg-green-500 text-white rounded-lg hover:bg-green-600"
225
+ >
226
+ <Play className="w-4 h-4" />
227
+ Resume
228
+ </button>
229
+ <button
230
+ onClick={() => onStopSession(selectedSession.id)}
231
+ className="flex items-center gap-1.5 px-3 py-1.5 bg-red-500 text-white rounded-lg hover:bg-red-600"
232
+ >
233
+ <Square className="w-4 h-4" />
234
+ Stop
235
+ </button>
236
+ </>
237
+ )}
238
+
239
+ <button
240
+ onClick={() => onDeleteSession(selectedSession.id)}
241
+ className="p-2 text-destructive hover:bg-destructive/10 rounded-lg"
242
+ >
243
+ <Trash2 className="w-4 h-4" />
244
+ </button>
245
+ </div>
246
+ </div>
247
+
248
+ {/* Content */}
249
+ <div className="flex-1 overflow-auto p-6">
250
+ <div className="max-w-3xl space-y-6">
251
+ {/* Objective */}
252
+ <div className="bg-card border border-border rounded-lg p-4">
253
+ <h3 className="text-sm font-medium mb-2">Objective</h3>
254
+ <p className="text-muted-foreground">{selectedSession.objective}</p>
255
+ </div>
256
+
257
+ {/* Progress */}
258
+ <div className="bg-card border border-border rounded-lg p-4">
259
+ <div className="flex items-center justify-between mb-3">
260
+ <h3 className="text-sm font-medium">Progress</h3>
261
+ <span className="text-2xl font-bold">{selectedSession.progress}%</span>
262
+ </div>
263
+ <div className="h-2 bg-muted rounded-full overflow-hidden">
264
+ <div
265
+ className={`h-full rounded-full transition-all ${
266
+ selectedSession.status === 'error' ? 'bg-red-500' :
267
+ selectedSession.status === 'completed' ? 'bg-green-500' :
268
+ 'bg-primary'
269
+ }`}
270
+ style={{ width: `${selectedSession.progress}%` }}
271
+ />
272
+ </div>
273
+ </div>
274
+
275
+ {/* Logs */}
276
+ {selectedSession.logs.length > 0 && (
277
+ <div className="bg-card border border-border rounded-lg p-4">
278
+ <h3 className="text-sm font-medium mb-3">Activity Log</h3>
279
+ <div className="space-y-2 max-h-64 overflow-auto">
280
+ {selectedSession.logs.map((log, index) => (
281
+ <div key={index} className="text-xs font-mono text-muted-foreground">
282
+ {log}
283
+ </div>
284
+ ))}
285
+ </div>
286
+ </div>
287
+ )}
288
+
289
+ {/* Deliverables */}
290
+ {selectedSession.deliverables.length > 0 && (
291
+ <div className="bg-card border border-border rounded-lg p-4">
292
+ <h3 className="text-sm font-medium mb-3">Deliverables</h3>
293
+ <div className="space-y-2">
294
+ {selectedSession.deliverables.map((deliverable, index) => (
295
+ <div key={index} className="flex items-center gap-2 text-sm">
296
+ <FileText className="w-4 h-4 text-muted-foreground" />
297
+ <span>{deliverable}</span>
298
+ </div>
299
+ ))}
300
+ </div>
301
+ </div>
302
+ )}
303
+
304
+ {/* Completed info */}
305
+ {selectedSession.completedAt && (
306
+ <div className="bg-green-500/10 border border-green-500/30 rounded-lg p-4">
307
+ <div className="flex items-center gap-2 text-green-500">
308
+ <CheckCircle className="w-5 h-5" />
309
+ <span className="font-medium">
310
+ Completed on {new Date(selectedSession.completedAt).toLocaleString()}
311
+ </span>
312
+ </div>
313
+ </div>
314
+ )}
315
+ </div>
316
+ </div>
317
+ </>
318
+ ) : (
319
+ <div className="flex-1 flex items-center justify-center text-muted-foreground">
320
+ <div className="text-center">
321
+ <Users className="w-16 h-16 mx-auto mb-4 opacity-30" />
322
+ <p className="text-lg font-medium">Select a session</p>
323
+ <p className="text-sm mt-2">Choose a cowork session to view details</p>
324
+ </div>
325
+ </div>
326
+ )}
327
+ </div>
328
+
329
+ {/* Create Session Modal */}
330
+ {showCreateModal && (
331
+ <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
332
+ <div className="bg-card border border-border rounded-lg p-6 w-[500px] max-w-[90vw]">
333
+ <h2 className="text-lg font-semibold mb-4">Create New Cowork Session</h2>
334
+
335
+ <div className="space-y-4">
336
+ <div>
337
+ <label className="block text-sm font-medium mb-1">Session Name</label>
338
+ <input
339
+ type="text"
340
+ value={newSessionConfig.name}
341
+ onChange={e => setNewSessionConfig({ ...newSessionConfig, name: e.target.value })}
342
+ className="w-full px-3 py-2 bg-background border border-input rounded-md"
343
+ placeholder="e.g., Refactor Authentication Module"
344
+ />
345
+ </div>
346
+
347
+ <div>
348
+ <label className="block text-sm font-medium mb-1">Objective</label>
349
+ <textarea
350
+ value={newSessionConfig.objective}
351
+ onChange={e => setNewSessionConfig({ ...newSessionConfig, objective: e.target.value })}
352
+ className="w-full px-3 py-2 bg-background border border-input rounded-md min-h-[100px] resize-none"
353
+ placeholder="Describe what you want the agent to accomplish..."
354
+ />
355
+ </div>
356
+
357
+ <div>
358
+ <label className="block text-sm font-medium mb-1">Project Path</label>
359
+ <div className="flex gap-2">
360
+ <input
361
+ type="text"
362
+ value={newSessionConfig.projectPath}
363
+ onChange={e => setNewSessionConfig({ ...newSessionConfig, projectPath: e.target.value })}
364
+ className="flex-1 px-3 py-2 bg-background border border-input rounded-md"
365
+ placeholder="/path/to/project"
366
+ />
367
+ <button
368
+ onClick={async () => {
369
+ const path = await window.electronAPI.dialog.selectFolder();
370
+ if (path) setNewSessionConfig({ ...newSessionConfig, projectPath: path });
371
+ }}
372
+ className="px-3 py-2 bg-muted rounded-md hover:bg-muted/80"
373
+ >
374
+ Browse
375
+ </button>
376
+ </div>
377
+ </div>
378
+
379
+ <div className="flex items-center gap-2">
380
+ <input
381
+ type="checkbox"
382
+ id="autoApprove"
383
+ checked={newSessionConfig.autoApprove}
384
+ onChange={e => setNewSessionConfig({ ...newSessionConfig, autoApprove: e.target.checked })}
385
+ className="rounded"
386
+ />
387
+ <label htmlFor="autoApprove" className="text-sm">
388
+ Auto-approve changes (runs autonomously)
389
+ </label>
390
+ </div>
391
+ </div>
392
+
393
+ <div className="flex justify-end gap-2 mt-6">
394
+ <button
395
+ onClick={() => setShowCreateModal(false)}
396
+ className="px-4 py-2 text-muted-foreground hover:text-foreground"
397
+ >
398
+ Cancel
399
+ </button>
400
+ <button
401
+ onClick={handleCreateSession}
402
+ disabled={!newSessionConfig.name || !newSessionConfig.objective || !newSessionConfig.projectPath}
403
+ className="px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 disabled:opacity-50"
404
+ >
405
+ Create Session
406
+ </button>
407
+ </div>
408
+ </div>
409
+ </div>
410
+ )}
411
+ </div>
412
+ );
413
+ };
414
+
415
+ export default CoworkPanel;