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,746 @@
1
+ import { EventEmitter } from 'events';
2
+ import log from 'electron-log';
3
+ import { AIProviderManager } from '../providers/AIProviderManager';
4
+ import {
5
+ PromptAnalysis,
6
+ PromptImprovement,
7
+ PromptTemplate,
8
+ PromptOptimizationOptions,
9
+ PromptTestResult,
10
+ PromptVersion
11
+ } from '../../shared/types';
12
+
13
+ const PROMPT_TEMPLATES: PromptTemplate[] = [
14
+ {
15
+ id: 'code-review',
16
+ name: 'Code Review',
17
+ description: 'Comprehensive code review with best practices',
18
+ category: 'Development',
19
+ template: `Review the following code for the {{language}} project:
20
+
21
+ Context: {{context}}
22
+ Code to review:
23
+ \`\`\`
24
+ {{code}}
25
+ \`\`\`
26
+
27
+ Please evaluate:
28
+ 1. Code quality and readability
29
+ 2. Performance considerations
30
+ 3. Security vulnerabilities
31
+ 4. Best practices adherence
32
+ 5. Potential bugs or edge cases
33
+ 6. Documentation quality
34
+
35
+ Provide specific, actionable feedback with line numbers where applicable.`,
36
+ variables: ['language', 'context', 'code'],
37
+ tags: ['code-review', 'development', 'quality'],
38
+ },
39
+ {
40
+ id: 'refactor',
41
+ name: 'Code Refactoring',
42
+ description: 'Suggest improvements and refactoring options',
43
+ category: 'Development',
44
+ template: `Refactor the following {{language}} code:
45
+
46
+ Current implementation:
47
+ \`\`\`
48
+ {{code}}
49
+ \`\`\`
50
+
51
+ Goals:
52
+ {{goals}}
53
+
54
+ Provide:
55
+ 1. Explanation of current issues
56
+ 2. Refactored code with improvements
57
+ 3. Explanation of changes made
58
+ 4. Trade-offs considered`,
59
+ variables: ['language', 'code', 'goals'],
60
+ tags: ['refactoring', 'development', 'improvement'],
61
+ },
62
+ {
63
+ id: 'test-generation',
64
+ name: 'Test Generation',
65
+ description: 'Generate comprehensive test cases',
66
+ category: 'Testing',
67
+ template: `Generate tests for the following {{language}} code:
68
+
69
+ Code to test:
70
+ \`\`\`
71
+ {{code}}
72
+ \`\`\`
73
+
74
+ Requirements:
75
+ - Test framework: {{framework}}
76
+ - Coverage goal: {{coverage}}
77
+
78
+ Include:
79
+ 1. Unit tests for main functions
80
+ 2. Edge case tests
81
+ 3. Error handling tests
82
+ 4. Integration tests if applicable`,
83
+ variables: ['language', 'code', 'framework', 'coverage'],
84
+ tags: ['testing', 'development', 'quality'],
85
+ },
86
+ {
87
+ id: 'bug-fix',
88
+ name: 'Bug Fix',
89
+ description: 'Analyze and fix bugs with root cause analysis',
90
+ category: 'Development',
91
+ template: `Analyze and fix the following bug:
92
+
93
+ Error message:
94
+ {{error}}
95
+
96
+ Problematic code:
97
+ \`\`\`
98
+ {{code}}
99
+ \`\`\`
100
+
101
+ Stack trace:
102
+ \`\`\`
103
+ {{stackTrace}}
104
+ \`\`\`
105
+
106
+ Provide:
107
+ 1. Root cause analysis
108
+ 2. Fixed code
109
+ 3. Explanation of the fix
110
+ 4. Prevention recommendations`,
111
+ variables: ['error', 'code', 'stackTrace'],
112
+ tags: ['bug', 'debugging', 'fix'],
113
+ },
114
+ {
115
+ id: 'documentation',
116
+ name: 'Documentation Generation',
117
+ description: 'Generate comprehensive documentation',
118
+ category: 'Documentation',
119
+ template: `Generate documentation for:
120
+
121
+ Code to document:
122
+ \`\`\`
123
+ {{code}}
124
+ \`\`\`
125
+
126
+ Documentation type: {{docType}}
127
+ Audience: {{audience}}
128
+
129
+ Include:
130
+ 1. Overview/purpose
131
+ 2. Function/class descriptions
132
+ 3. Parameter descriptions
133
+ 4. Return values
134
+ 5. Usage examples
135
+ 6. Edge cases and limitations`,
136
+ variables: ['code', 'docType', 'audience'],
137
+ tags: ['documentation', 'api', 'reference'],
138
+ },
139
+ {
140
+ id: 'architecture',
141
+ name: 'Architecture Design',
142
+ description: 'Design system architecture',
143
+ category: 'Architecture',
144
+ template: `Design architecture for: {{system}}
145
+
146
+ Requirements:
147
+ {{requirements}}
148
+
149
+ Constraints:
150
+ {{constraints}}
151
+
152
+ Provide:
153
+ 1. High-level architecture diagram (text-based)
154
+ 2. Component breakdown
155
+ 3. Data flow
156
+ 4. Technology recommendations
157
+ 5. Scalability considerations`,
158
+ variables: ['system', 'requirements', 'constraints'],
159
+ tags: ['architecture', 'design', 'system'],
160
+ },
161
+ ];
162
+
163
+ interface PromptVariant {
164
+ id: string;
165
+ name: string;
166
+ prompt: string;
167
+ usage: number;
168
+ success: number;
169
+ avgResponseLength: number;
170
+ }
171
+
172
+ interface PromptTest {
173
+ id: string;
174
+ originalPrompt: string;
175
+ variants: PromptVariant[];
176
+ testCases: string[];
177
+ winner?: string;
178
+ }
179
+
180
+ export class PromptOptimizer extends EventEmitter {
181
+ private aiProviderManager: AIProviderManager | null = null;
182
+ private tests: Map<string, PromptTest> = new Map();
183
+ private promptHistory: Map<string, PromptVersion[]> = new Map();
184
+ private testResults: Map<string, PromptTestResult[]> = new Map();
185
+
186
+ constructor(aiProviderManager?: AIProviderManager) {
187
+ super();
188
+ this.aiProviderManager = aiProviderManager || null;
189
+ }
190
+
191
+ setAIProvider(aiProviderManager: AIProviderManager): void {
192
+ this.aiProviderManager = aiProviderManager;
193
+ }
194
+
195
+ async suggestImprovements(prompt: string): Promise<string[]> {
196
+ // If AI provider available, use it for advanced analysis
197
+ if (this.aiProviderManager) {
198
+ try {
199
+ const analysis = await this.analyzeWithAI(prompt);
200
+ return analysis.suggestions;
201
+ } catch (error) {
202
+ log.warn('PromptOptimizer: AI analysis failed, using basic suggestions');
203
+ }
204
+ }
205
+
206
+ // Fallback to basic suggestions
207
+ const suggestions: string[] = [];
208
+
209
+ if (prompt.length < 50) {
210
+ suggestions.push('Add more context to get better results');
211
+ }
212
+
213
+ if (!prompt.includes('example') && !prompt.includes('Example')) {
214
+ suggestions.push('Consider adding examples to clarify expectations');
215
+ }
216
+
217
+ if (!prompt.includes('step') && !prompt.includes('Step')) {
218
+ suggestions.push('Break complex tasks into numbered steps');
219
+ }
220
+
221
+ const vagueTerms = ['some', 'thing', 'stuff', 'good', 'bad', 'nice'];
222
+ const hasVagueTerms = vagueTerms.some(term =>
223
+ prompt.toLowerCase().includes(term)
224
+ );
225
+ if (hasVagueTerms) {
226
+ suggestions.push('Replace vague terms with specific descriptions');
227
+ }
228
+
229
+ if (!prompt.includes('format') && !prompt.includes('output')) {
230
+ suggestions.push('Specify desired output format (JSON, markdown, etc.)');
231
+ }
232
+
233
+ return suggestions;
234
+ }
235
+
236
+ async analyzePrompt(prompt: string): Promise<PromptAnalysis> {
237
+ if (!this.aiProviderManager) {
238
+ return this.basicAnalysis(prompt);
239
+ }
240
+
241
+ return this.analyzeWithAI(prompt);
242
+ }
243
+
244
+ private async analyzeWithAI(prompt: string): Promise<PromptAnalysis> {
245
+ const provider = this.aiProviderManager!.getActiveProviderInstance();
246
+ if (!provider) {
247
+ throw new Error('No AI provider available');
248
+ }
249
+
250
+ const analysisPrompt = `Analyze the following prompt and provide a detailed analysis:
251
+
252
+ Prompt: "${prompt}"
253
+
254
+ Respond in JSON format:
255
+ {
256
+ "clarity": <score 0-100>,
257
+ "specificity": <score 0-100>,
258
+ "context": <score 0-100>,
259
+ "structure": <score 0-100>,
260
+ "overall": <score 0-100>,
261
+ "improvements": [
262
+ {
263
+ "type": "clarity|specificity|context|structure|examples|constraints",
264
+ "description": "<description>",
265
+ "before": "<original text>",
266
+ "after": "<improved text>",
267
+ "impact": "high|medium|low"
268
+ }
269
+ ],
270
+ "suggestions": ["<suggestion1>", "<suggestion2>"],
271
+ "estimatedTokens": <estimated token count>
272
+ }`;
273
+
274
+ try {
275
+ const response = await provider.sendMessage('gpt-4o', [
276
+ { role: 'system', content: 'You are a prompt engineering expert. Analyze prompts and provide structured feedback in JSON format.' },
277
+ { role: 'user', content: analysisPrompt }
278
+ ] as Array<{ role: string; content: string }>);
279
+
280
+ const jsonMatch = response.content.match(/\{[\s\S]*\}/);
281
+ if (jsonMatch) {
282
+ const analysis = JSON.parse(jsonMatch[0]);
283
+
284
+ return {
285
+ originalPrompt: prompt,
286
+ optimizedPrompt: prompt,
287
+ improvements: analysis.improvements || [],
288
+ metrics: {
289
+ clarity: analysis.clarity || 50,
290
+ specificity: analysis.specificity || 50,
291
+ context: analysis.context || 50,
292
+ structure: analysis.structure || 50,
293
+ overall: analysis.overall || 50,
294
+ },
295
+ estimatedTokens: analysis.estimatedTokens || this.estimateTokens(prompt),
296
+ suggestions: analysis.suggestions || [],
297
+ };
298
+ }
299
+ } catch (error) {
300
+ log.error('PromptOptimizer: Analysis failed:', error);
301
+ }
302
+
303
+ return this.basicAnalysis(prompt);
304
+ }
305
+
306
+ async optimizePrompt(
307
+ prompt: string,
308
+ options: PromptOptimizationOptions = {}
309
+ ): Promise<PromptAnalysis> {
310
+ if (!this.aiProviderManager) {
311
+ return this.basicAnalysis(prompt);
312
+ }
313
+
314
+ const provider = this.aiProviderManager.getActiveProviderInstance();
315
+ if (!provider) {
316
+ throw new Error('No AI provider available');
317
+ }
318
+
319
+ const styleInstructions: Record<string, string> = {
320
+ concise: 'Be extremely concise. Use minimal words.',
321
+ detailed: 'Provide maximum detail and thoroughness.',
322
+ technical: 'Use technical terminology and precise language.',
323
+ conversational: 'Write in a friendly, conversational tone.',
324
+ };
325
+
326
+ const optimizationPrompt = `Optimize the following prompt for better results from an AI.
327
+
328
+ Original prompt: "${prompt}"
329
+
330
+ ${options.goal ? `Goal: ${options.goal}` : ''}
331
+ ${options.targetModel ? `Target model: ${options.targetModel}` : ''}
332
+ ${options.style ? `Style: ${styleInstructions[options.style]}` : ''}
333
+ ${options.maxLength ? `Maximum length: ${options.maxLength} characters` : ''}
334
+
335
+ Requirements:
336
+ ${options.addExamples ? '- Add relevant examples to clarify expectations' : ''}
337
+ ${options.addConstraints ? '- Add specific constraints and requirements' : ''}
338
+ ${options.improveStructure ? '- Improve the structure and organization' : ''}
339
+
340
+ Respond in JSON format:
341
+ {
342
+ "optimizedPrompt": "<the optimized prompt>",
343
+ "improvements": [
344
+ {
345
+ "type": "clarity|specificity|context|structure|examples|constraints",
346
+ "description": "<what was improved>",
347
+ "before": "<original text>",
348
+ "after": "<improved text>",
349
+ "impact": "high|medium|low"
350
+ }
351
+ ],
352
+ "metrics": {
353
+ "clarity": <0-100>,
354
+ "specificity": <0-100>,
355
+ "context": <0-100>,
356
+ "structure": <0-100>,
357
+ "overall": <0-100>
358
+ },
359
+ "suggestions": ["<additional suggestion>"]
360
+ }`;
361
+
362
+ try {
363
+ const response = await provider.sendMessage('gpt-4o', [
364
+ { role: 'system', content: 'You are a prompt engineering expert. Optimize prompts to get better results from AI models.' },
365
+ { role: 'user', content: optimizationPrompt }
366
+ ] as Array<{ role: string; content: string }>);
367
+
368
+ const jsonMatch = response.content.match(/\{[\s\S]*\}/);
369
+ if (jsonMatch) {
370
+ const result = JSON.parse(jsonMatch[0]);
371
+
372
+ return {
373
+ originalPrompt: prompt,
374
+ optimizedPrompt: result.optimizedPrompt || prompt,
375
+ improvements: result.improvements || [],
376
+ metrics: result.metrics || {
377
+ clarity: 70,
378
+ specificity: 70,
379
+ context: 70,
380
+ structure: 70,
381
+ overall: 70,
382
+ },
383
+ estimatedTokens: this.estimateTokens(result.optimizedPrompt || prompt),
384
+ suggestions: result.suggestions || [],
385
+ };
386
+ }
387
+ } catch (error) {
388
+ log.error('PromptOptimizer: Optimization failed:', error);
389
+ }
390
+
391
+ return this.basicAnalysis(prompt);
392
+ }
393
+
394
+ async generatePrompt(
395
+ templateId: string,
396
+ variables: Record<string, string>
397
+ ): Promise<string> {
398
+ const template = PROMPT_TEMPLATES.find(t => t.id === templateId);
399
+ if (!template) {
400
+ throw new Error(`Template ${templateId} not found`);
401
+ }
402
+
403
+ let prompt = template.template;
404
+ for (const [key, value] of Object.entries(variables)) {
405
+ prompt = prompt.replace(new RegExp(`{{${key}}}`, 'g'), value);
406
+ }
407
+
408
+ return prompt;
409
+ }
410
+
411
+ getTemplates(category?: string): PromptTemplate[] {
412
+ if (category) {
413
+ return PROMPT_TEMPLATES.filter(t => t.category === category);
414
+ }
415
+ return PROMPT_TEMPLATES;
416
+ }
417
+
418
+ getTemplateCategories(): string[] {
419
+ return [...new Set(PROMPT_TEMPLATES.map(t => t.category))];
420
+ }
421
+
422
+ async savePromptVersion(
423
+ promptId: string,
424
+ prompt: string,
425
+ tags: string[] = [],
426
+ notes?: string
427
+ ): Promise<PromptVersion> {
428
+ const version: PromptVersion = {
429
+ id: `${promptId}_${Date.now()}`,
430
+ prompt,
431
+ version: (this.promptHistory.get(promptId)?.length || 0) + 1,
432
+ timestamp: new Date(),
433
+ tags,
434
+ notes,
435
+ };
436
+
437
+ if (!this.promptHistory.has(promptId)) {
438
+ this.promptHistory.set(promptId, []);
439
+ }
440
+ this.promptHistory.get(promptId)!.push(version);
441
+
442
+ log.info(`PromptOptimizer: Saved version ${version.version} for prompt ${promptId}`);
443
+ return version;
444
+ }
445
+
446
+ getPromptHistory(promptId: string): PromptVersion[] {
447
+ return this.promptHistory.get(promptId) || [];
448
+ }
449
+
450
+ async testPrompt(
451
+ prompt: string,
452
+ testInput?: string
453
+ ): Promise<PromptTestResult> {
454
+ if (!this.aiProviderManager) {
455
+ throw new Error('AI provider not available for testing');
456
+ }
457
+
458
+ log.info('PromptOptimizer: Testing prompt...');
459
+
460
+ const provider = this.aiProviderManager.getActiveProviderInstance();
461
+ if (!provider) {
462
+ throw new Error('No AI provider available');
463
+ }
464
+
465
+ const startTime = Date.now();
466
+
467
+ try {
468
+ const messages = testInput
469
+ ? [
470
+ { role: 'user' as const, content: prompt },
471
+ { role: 'user' as const, content: testInput }
472
+ ]
473
+ : [{ role: 'user' as const, content: prompt }];
474
+
475
+ const response = await provider.sendMessage('gpt-4o', messages as Array<{ role: string; content: string }>);
476
+
477
+ const latency = Date.now() - startTime;
478
+ const responseText = response.content;
479
+ const tokenUsage = this.estimateTokens(prompt) + this.estimateTokens(responseText);
480
+
481
+ const result: PromptTestResult = {
482
+ prompt,
483
+ response: responseText,
484
+ metrics: {
485
+ responseQuality: this.evaluateQuality(responseText),
486
+ relevance: this.evaluateRelevance(prompt, responseText),
487
+ completeness: this.evaluateCompleteness(prompt, responseText),
488
+ tokenUsage,
489
+ latency,
490
+ },
491
+ timestamp: new Date(),
492
+ };
493
+
494
+ const promptKey = this.hashString(prompt);
495
+ if (!this.testResults.has(promptKey)) {
496
+ this.testResults.set(promptKey, []);
497
+ }
498
+ this.testResults.get(promptKey)!.push(result);
499
+
500
+ return result;
501
+ } catch (error) {
502
+ log.error('PromptOptimizer: Test failed:', error);
503
+ throw error;
504
+ }
505
+ }
506
+
507
+ getTestResults(prompt: string): PromptTestResult[] {
508
+ const promptKey = this.hashString(prompt);
509
+ return this.testResults.get(promptKey) || [];
510
+ }
511
+
512
+ comparePrompts(promptA: string, promptB: string): {
513
+ winner: 'A' | 'B' | 'tie';
514
+ metricsComparison: Record<string, number>;
515
+ } {
516
+ const resultsA = this.getTestResults(promptA);
517
+ const resultsB = this.getTestResults(promptB);
518
+
519
+ if (resultsA.length === 0 && resultsB.length === 0) {
520
+ return { winner: 'tie', metricsComparison: {} };
521
+ }
522
+
523
+ const avgMetricsA = this.averageMetrics(resultsA);
524
+ const avgMetricsB = this.averageMetrics(resultsB);
525
+
526
+ const scores = {
527
+ A: avgMetricsA.responseQuality + avgMetricsA.relevance + avgMetricsA.completeness - (avgMetricsA.latency / 1000),
528
+ B: avgMetricsB.responseQuality + avgMetricsB.relevance + avgMetricsB.completeness - (avgMetricsB.latency / 1000),
529
+ };
530
+
531
+ return {
532
+ winner: scores.A > scores.B ? 'A' : scores.B > scores.A ? 'B' : 'tie',
533
+ metricsComparison: {
534
+ responseQuality: avgMetricsA.responseQuality - avgMetricsB.responseQuality,
535
+ relevance: avgMetricsA.relevance - avgMetricsB.relevance,
536
+ completeness: avgMetricsA.completeness - avgMetricsB.completeness,
537
+ latency: avgMetricsA.latency - avgMetricsB.latency,
538
+ tokenUsage: avgMetricsA.tokenUsage - avgMetricsB.tokenUsage,
539
+ },
540
+ };
541
+ }
542
+
543
+ createABTest(originalPrompt: string, variants: string[]): string {
544
+ const testId = `ab-test-${Date.now()}`;
545
+
546
+ const test: PromptTest = {
547
+ id: testId,
548
+ originalPrompt,
549
+ variants: [
550
+ {
551
+ id: 'original',
552
+ name: 'Original',
553
+ prompt: originalPrompt,
554
+ usage: 0,
555
+ success: 0,
556
+ avgResponseLength: 0
557
+ },
558
+ ...variants.map((variant, index) => ({
559
+ id: `variant-${index}`,
560
+ name: `Variant ${index + 1}`,
561
+ prompt: variant,
562
+ usage: 0,
563
+ success: 0,
564
+ avgResponseLength: 0
565
+ }))
566
+ ],
567
+ testCases: []
568
+ };
569
+
570
+ this.tests.set(testId, test);
571
+ log.info(`Created A/B test: ${testId}`);
572
+
573
+ return testId;
574
+ }
575
+
576
+ recordUsage(testId: string, variantId: string, success: boolean, responseLength: number): void {
577
+ const test = this.tests.get(testId);
578
+ if (!test) return;
579
+
580
+ const variant = test.variants.find(v => v.id === variantId);
581
+ if (!variant) return;
582
+
583
+ variant.usage++;
584
+ if (success) variant.success++;
585
+
586
+ variant.avgResponseLength =
587
+ ((variant.avgResponseLength * (variant.usage - 1)) + responseLength) / variant.usage;
588
+ }
589
+
590
+ getABTestResults(testId: string): {
591
+ winner?: PromptVariant;
592
+ variants: PromptVariant[];
593
+ confidence: number;
594
+ } | null {
595
+ const test = this.tests.get(testId);
596
+ if (!test) return null;
597
+
598
+ const variantsWithRates = test.variants.map(v => ({
599
+ ...v,
600
+ successRate: v.usage > 0 ? v.success / v.usage : 0
601
+ }));
602
+
603
+ const winner = variantsWithRates.reduce((best, current) =>
604
+ current.successRate > best.successRate ? current : best
605
+ );
606
+
607
+ const totalUsage = test.variants.reduce((sum, v) => sum + v.usage, 0);
608
+ const confidence = Math.min(1, totalUsage / 100);
609
+
610
+ return {
611
+ winner: winner.successRate > 0 ? winner : undefined,
612
+ variants: variantsWithRates,
613
+ confidence
614
+ };
615
+ }
616
+
617
+ generateOptimizedPrompt(prompt: string): string {
618
+ let optimized = prompt;
619
+
620
+ if (!optimized.includes('#') && optimized.length > 200) {
621
+ optimized = `# Task\n${optimized}`;
622
+ }
623
+
624
+ if (!optimized.toLowerCase().includes('output format')) {
625
+ optimized += '\n\n# Output Format\nPlease provide your response in a clear, structured format.';
626
+ }
627
+
628
+ return optimized;
629
+ }
630
+
631
+ private basicAnalysis(prompt: string): PromptAnalysis {
632
+ const words = prompt.split(/\s+/);
633
+ const hasExamples = prompt.includes('example') || prompt.includes('e.g.');
634
+ const hasContext = prompt.includes('context') || prompt.length > 200;
635
+ const hasStructure = prompt.includes('\n') || prompt.includes('1.') || prompt.includes('•');
636
+
637
+ const improvements: PromptImprovement[] = [];
638
+
639
+ if (!hasExamples) {
640
+ improvements.push({
641
+ type: 'examples',
642
+ description: 'Add examples to clarify expectations',
643
+ before: prompt,
644
+ after: prompt + '\n\nExample: [add relevant example]',
645
+ impact: 'medium',
646
+ });
647
+ }
648
+
649
+ if (!hasContext) {
650
+ improvements.push({
651
+ type: 'context',
652
+ description: 'Add more context about the task',
653
+ before: prompt,
654
+ after: 'Context: [describe background]\n\n' + prompt,
655
+ impact: 'high',
656
+ });
657
+ }
658
+
659
+ if (!hasStructure) {
660
+ improvements.push({
661
+ type: 'structure',
662
+ description: 'Structure the prompt with clear sections',
663
+ before: prompt,
664
+ after: `Task: ${prompt}\n\nRequirements:\n- [requirement 1]\n- [requirement 2]`,
665
+ impact: 'medium',
666
+ });
667
+ }
668
+
669
+ return {
670
+ originalPrompt: prompt,
671
+ optimizedPrompt: improvements.length > 0 ? improvements[0].after : prompt,
672
+ improvements,
673
+ metrics: {
674
+ clarity: hasStructure ? 70 : 50,
675
+ specificity: words.length > 10 ? 70 : 40,
676
+ context: hasContext ? 70 : 40,
677
+ structure: hasStructure ? 80 : 30,
678
+ overall: 60,
679
+ },
680
+ estimatedTokens: this.estimateTokens(prompt),
681
+ suggestions: improvements.map(i => i.description),
682
+ };
683
+ }
684
+
685
+ private estimateTokens(text: string): number {
686
+ return Math.ceil(text.length / 4);
687
+ }
688
+
689
+ private evaluateQuality(response: string): number {
690
+ const hasStructure = response.includes('\n') || response.includes(':');
691
+ const isSubstantial = response.length > 100;
692
+ return Math.min(100, (hasStructure ? 40 : 20) + (isSubstantial ? 40 : 20) + 20);
693
+ }
694
+
695
+ private evaluateRelevance(prompt: string, response: string): number {
696
+ const promptWords = prompt.toLowerCase().split(/\s+/).filter(w => w.length > 4);
697
+ const responseLower = response.toLowerCase();
698
+ const matchedWords = promptWords.filter(w => responseLower.includes(w));
699
+ return Math.min(100, (matchedWords.length / promptWords.length) * 100);
700
+ }
701
+
702
+ private evaluateCompleteness(_prompt: string, response: string): number {
703
+ const hasExplanation = response.includes('because') || response.includes('reason');
704
+ const hasDetails = response.length > 200;
705
+ return Math.min(100, (hasExplanation ? 40 : 0) + (hasDetails ? 50 : 30) + 10);
706
+ }
707
+
708
+ private averageMetrics(results: PromptTestResult[]): PromptTestResult['metrics'] {
709
+ if (results.length === 0) {
710
+ return {
711
+ responseQuality: 0,
712
+ relevance: 0,
713
+ completeness: 0,
714
+ tokenUsage: 0,
715
+ latency: 0,
716
+ };
717
+ }
718
+
719
+ return {
720
+ responseQuality: results.reduce((sum, r) => sum + r.metrics.responseQuality, 0) / results.length,
721
+ relevance: results.reduce((sum, r) => sum + r.metrics.relevance, 0) / results.length,
722
+ completeness: results.reduce((sum, r) => sum + r.metrics.completeness, 0) / results.length,
723
+ tokenUsage: results.reduce((sum, r) => sum + r.metrics.tokenUsage, 0) / results.length,
724
+ latency: results.reduce((sum, r) => sum + r.metrics.latency, 0) / results.length,
725
+ };
726
+ }
727
+
728
+ private hashString(str: string): string {
729
+ let hash = 0;
730
+ for (let i = 0; i < str.length; i++) {
731
+ const char = str.charCodeAt(i);
732
+ hash = ((hash << 5) - hash) + char;
733
+ hash = hash & hash;
734
+ }
735
+ return hash.toString(36);
736
+ }
737
+
738
+ cleanup(): void {
739
+ this.tests.clear();
740
+ this.promptHistory.clear();
741
+ this.testResults.clear();
742
+ this.removeAllListeners();
743
+ }
744
+ }
745
+
746
+ export default PromptOptimizer;