cowork-os 0.3.21

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 (526) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1638 -0
  3. package/bin/cowork.js +42 -0
  4. package/build/entitlements.mac.plist +16 -0
  5. package/build/icon.icns +0 -0
  6. package/build/icon.png +0 -0
  7. package/dist/electron/electron/activity/ActivityRepository.js +190 -0
  8. package/dist/electron/electron/agent/browser/browser-service.js +639 -0
  9. package/dist/electron/electron/agent/context-manager.js +225 -0
  10. package/dist/electron/electron/agent/custom-skill-loader.js +566 -0
  11. package/dist/electron/electron/agent/daemon.js +975 -0
  12. package/dist/electron/electron/agent/executor.js +3561 -0
  13. package/dist/electron/electron/agent/llm/anthropic-provider.js +155 -0
  14. package/dist/electron/electron/agent/llm/bedrock-provider.js +202 -0
  15. package/dist/electron/electron/agent/llm/gemini-provider.js +375 -0
  16. package/dist/electron/electron/agent/llm/index.js +34 -0
  17. package/dist/electron/electron/agent/llm/ollama-provider.js +263 -0
  18. package/dist/electron/electron/agent/llm/openai-oauth.js +101 -0
  19. package/dist/electron/electron/agent/llm/openai-provider.js +657 -0
  20. package/dist/electron/electron/agent/llm/openrouter-provider.js +232 -0
  21. package/dist/electron/electron/agent/llm/pricing.js +160 -0
  22. package/dist/electron/electron/agent/llm/provider-factory.js +880 -0
  23. package/dist/electron/electron/agent/llm/types.js +178 -0
  24. package/dist/electron/electron/agent/queue-manager.js +378 -0
  25. package/dist/electron/electron/agent/sandbox/docker-sandbox.js +402 -0
  26. package/dist/electron/electron/agent/sandbox/macos-sandbox.js +407 -0
  27. package/dist/electron/electron/agent/sandbox/runner.js +410 -0
  28. package/dist/electron/electron/agent/sandbox/sandbox-factory.js +228 -0
  29. package/dist/electron/electron/agent/sandbox/security-utils.js +258 -0
  30. package/dist/electron/electron/agent/search/brave-provider.js +119 -0
  31. package/dist/electron/electron/agent/search/google-provider.js +100 -0
  32. package/dist/electron/electron/agent/search/index.js +28 -0
  33. package/dist/electron/electron/agent/search/provider-factory.js +395 -0
  34. package/dist/electron/electron/agent/search/serpapi-provider.js +112 -0
  35. package/dist/electron/electron/agent/search/tavily-provider.js +90 -0
  36. package/dist/electron/electron/agent/search/types.js +40 -0
  37. package/dist/electron/electron/agent/security/index.js +12 -0
  38. package/dist/electron/electron/agent/security/input-sanitizer.js +303 -0
  39. package/dist/electron/electron/agent/security/output-filter.js +217 -0
  40. package/dist/electron/electron/agent/skill-eligibility.js +281 -0
  41. package/dist/electron/electron/agent/skill-registry.js +396 -0
  42. package/dist/electron/electron/agent/skills/document.js +878 -0
  43. package/dist/electron/electron/agent/skills/image-generator.js +225 -0
  44. package/dist/electron/electron/agent/skills/organizer.js +141 -0
  45. package/dist/electron/electron/agent/skills/presentation.js +367 -0
  46. package/dist/electron/electron/agent/skills/spreadsheet.js +165 -0
  47. package/dist/electron/electron/agent/tools/browser-tools.js +523 -0
  48. package/dist/electron/electron/agent/tools/builtin-settings.js +384 -0
  49. package/dist/electron/electron/agent/tools/canvas-tools.js +530 -0
  50. package/dist/electron/electron/agent/tools/cron-tools.js +577 -0
  51. package/dist/electron/electron/agent/tools/edit-tools.js +194 -0
  52. package/dist/electron/electron/agent/tools/file-tools.js +719 -0
  53. package/dist/electron/electron/agent/tools/glob-tools.js +283 -0
  54. package/dist/electron/electron/agent/tools/grep-tools.js +387 -0
  55. package/dist/electron/electron/agent/tools/image-tools.js +111 -0
  56. package/dist/electron/electron/agent/tools/mention-tools.js +282 -0
  57. package/dist/electron/electron/agent/tools/node-tools.js +476 -0
  58. package/dist/electron/electron/agent/tools/registry.js +2719 -0
  59. package/dist/electron/electron/agent/tools/search-tools.js +91 -0
  60. package/dist/electron/electron/agent/tools/shell-tools.js +574 -0
  61. package/dist/electron/electron/agent/tools/skill-tools.js +274 -0
  62. package/dist/electron/electron/agent/tools/system-tools.js +578 -0
  63. package/dist/electron/electron/agent/tools/web-fetch-tools.js +444 -0
  64. package/dist/electron/electron/agent/tools/x-tools.js +264 -0
  65. package/dist/electron/electron/agents/AgentRoleRepository.js +420 -0
  66. package/dist/electron/electron/agents/HeartbeatService.js +356 -0
  67. package/dist/electron/electron/agents/MentionRepository.js +197 -0
  68. package/dist/electron/electron/agents/TaskSubscriptionRepository.js +168 -0
  69. package/dist/electron/electron/agents/WorkingStateRepository.js +229 -0
  70. package/dist/electron/electron/canvas/canvas-manager.js +714 -0
  71. package/dist/electron/electron/canvas/canvas-preload.js +53 -0
  72. package/dist/electron/electron/canvas/canvas-protocol.js +195 -0
  73. package/dist/electron/electron/canvas/canvas-store.js +174 -0
  74. package/dist/electron/electron/canvas/index.js +13 -0
  75. package/dist/electron/electron/control-plane/client.js +364 -0
  76. package/dist/electron/electron/control-plane/handlers.js +572 -0
  77. package/dist/electron/electron/control-plane/index.js +41 -0
  78. package/dist/electron/electron/control-plane/node-manager.js +264 -0
  79. package/dist/electron/electron/control-plane/protocol.js +194 -0
  80. package/dist/electron/electron/control-plane/remote-client.js +437 -0
  81. package/dist/electron/electron/control-plane/server.js +640 -0
  82. package/dist/electron/electron/control-plane/settings.js +369 -0
  83. package/dist/electron/electron/control-plane/ssh-tunnel.js +549 -0
  84. package/dist/electron/electron/cron/index.js +30 -0
  85. package/dist/electron/electron/cron/schedule.js +190 -0
  86. package/dist/electron/electron/cron/service.js +614 -0
  87. package/dist/electron/electron/cron/store.js +155 -0
  88. package/dist/electron/electron/cron/types.js +82 -0
  89. package/dist/electron/electron/cron/webhook.js +258 -0
  90. package/dist/electron/electron/database/SecureSettingsRepository.js +444 -0
  91. package/dist/electron/electron/database/TaskLabelRepository.js +120 -0
  92. package/dist/electron/electron/database/repositories.js +1781 -0
  93. package/dist/electron/electron/database/schema.js +978 -0
  94. package/dist/electron/electron/extensions/index.js +33 -0
  95. package/dist/electron/electron/extensions/loader.js +313 -0
  96. package/dist/electron/electron/extensions/registry.js +485 -0
  97. package/dist/electron/electron/extensions/types.js +11 -0
  98. package/dist/electron/electron/gateway/channel-registry.js +1102 -0
  99. package/dist/electron/electron/gateway/channels/bluebubbles-client.js +479 -0
  100. package/dist/electron/electron/gateway/channels/bluebubbles.js +432 -0
  101. package/dist/electron/electron/gateway/channels/discord.js +975 -0
  102. package/dist/electron/electron/gateway/channels/email-client.js +593 -0
  103. package/dist/electron/electron/gateway/channels/email.js +443 -0
  104. package/dist/electron/electron/gateway/channels/google-chat.js +631 -0
  105. package/dist/electron/electron/gateway/channels/imessage-client.js +363 -0
  106. package/dist/electron/electron/gateway/channels/imessage.js +465 -0
  107. package/dist/electron/electron/gateway/channels/index.js +36 -0
  108. package/dist/electron/electron/gateway/channels/line-client.js +470 -0
  109. package/dist/electron/electron/gateway/channels/line.js +479 -0
  110. package/dist/electron/electron/gateway/channels/matrix-client.js +432 -0
  111. package/dist/electron/electron/gateway/channels/matrix.js +592 -0
  112. package/dist/electron/electron/gateway/channels/mattermost-client.js +394 -0
  113. package/dist/electron/electron/gateway/channels/mattermost.js +496 -0
  114. package/dist/electron/electron/gateway/channels/signal-client.js +500 -0
  115. package/dist/electron/electron/gateway/channels/signal.js +582 -0
  116. package/dist/electron/electron/gateway/channels/slack.js +415 -0
  117. package/dist/electron/electron/gateway/channels/teams.js +596 -0
  118. package/dist/electron/electron/gateway/channels/telegram.js +1390 -0
  119. package/dist/electron/electron/gateway/channels/twitch-client.js +502 -0
  120. package/dist/electron/electron/gateway/channels/twitch.js +396 -0
  121. package/dist/electron/electron/gateway/channels/types.js +8 -0
  122. package/dist/electron/electron/gateway/channels/whatsapp.js +953 -0
  123. package/dist/electron/electron/gateway/context-policy.js +268 -0
  124. package/dist/electron/electron/gateway/index.js +1063 -0
  125. package/dist/electron/electron/gateway/infrastructure.js +496 -0
  126. package/dist/electron/electron/gateway/router.js +2700 -0
  127. package/dist/electron/electron/gateway/security.js +375 -0
  128. package/dist/electron/electron/gateway/session.js +115 -0
  129. package/dist/electron/electron/gateway/tunnel.js +503 -0
  130. package/dist/electron/electron/guardrails/guardrail-manager.js +348 -0
  131. package/dist/electron/electron/hooks/gmail-watcher.js +300 -0
  132. package/dist/electron/electron/hooks/index.js +46 -0
  133. package/dist/electron/electron/hooks/mappings.js +381 -0
  134. package/dist/electron/electron/hooks/server.js +480 -0
  135. package/dist/electron/electron/hooks/settings.js +447 -0
  136. package/dist/electron/electron/hooks/types.js +41 -0
  137. package/dist/electron/electron/ipc/canvas-handlers.js +158 -0
  138. package/dist/electron/electron/ipc/handlers.js +3138 -0
  139. package/dist/electron/electron/ipc/mission-control-handlers.js +141 -0
  140. package/dist/electron/electron/main.js +448 -0
  141. package/dist/electron/electron/mcp/client/MCPClientManager.js +330 -0
  142. package/dist/electron/electron/mcp/client/MCPServerConnection.js +437 -0
  143. package/dist/electron/electron/mcp/client/transports/SSETransport.js +304 -0
  144. package/dist/electron/electron/mcp/client/transports/StdioTransport.js +307 -0
  145. package/dist/electron/electron/mcp/client/transports/WebSocketTransport.js +329 -0
  146. package/dist/electron/electron/mcp/host/MCPHostServer.js +354 -0
  147. package/dist/electron/electron/mcp/host/ToolAdapter.js +100 -0
  148. package/dist/electron/electron/mcp/registry/MCPRegistryManager.js +497 -0
  149. package/dist/electron/electron/mcp/settings.js +446 -0
  150. package/dist/electron/electron/mcp/types.js +59 -0
  151. package/dist/electron/electron/memory/MemoryService.js +435 -0
  152. package/dist/electron/electron/notifications/index.js +17 -0
  153. package/dist/electron/electron/notifications/service.js +118 -0
  154. package/dist/electron/electron/notifications/store.js +144 -0
  155. package/dist/electron/electron/preload.js +842 -0
  156. package/dist/electron/electron/reports/StandupReportService.js +272 -0
  157. package/dist/electron/electron/security/concurrency.js +293 -0
  158. package/dist/electron/electron/security/index.js +15 -0
  159. package/dist/electron/electron/security/policy-manager.js +435 -0
  160. package/dist/electron/electron/settings/appearance-manager.js +193 -0
  161. package/dist/electron/electron/settings/personality-manager.js +724 -0
  162. package/dist/electron/electron/settings/x-manager.js +58 -0
  163. package/dist/electron/electron/tailscale/exposure.js +188 -0
  164. package/dist/electron/electron/tailscale/index.js +28 -0
  165. package/dist/electron/electron/tailscale/settings.js +205 -0
  166. package/dist/electron/electron/tailscale/tailscale.js +355 -0
  167. package/dist/electron/electron/tray/QuickInputWindow.js +568 -0
  168. package/dist/electron/electron/tray/TrayManager.js +895 -0
  169. package/dist/electron/electron/tray/index.js +9 -0
  170. package/dist/electron/electron/updater/index.js +6 -0
  171. package/dist/electron/electron/updater/update-manager.js +418 -0
  172. package/dist/electron/electron/utils/env-migration.js +209 -0
  173. package/dist/electron/electron/utils/process.js +102 -0
  174. package/dist/electron/electron/utils/rate-limiter.js +104 -0
  175. package/dist/electron/electron/utils/validation.js +419 -0
  176. package/dist/electron/electron/utils/x-cli.js +177 -0
  177. package/dist/electron/electron/voice/VoiceService.js +507 -0
  178. package/dist/electron/electron/voice/index.js +14 -0
  179. package/dist/electron/electron/voice/voice-settings-manager.js +359 -0
  180. package/dist/electron/shared/channelMessages.js +170 -0
  181. package/dist/electron/shared/types.js +1185 -0
  182. package/package.json +159 -0
  183. package/resources/skills/1password.json +10 -0
  184. package/resources/skills/add-documentation.json +31 -0
  185. package/resources/skills/analyze-csv.json +17 -0
  186. package/resources/skills/apple-notes.json +10 -0
  187. package/resources/skills/apple-reminders.json +10 -0
  188. package/resources/skills/auto-commenter.json +10 -0
  189. package/resources/skills/bear-notes.json +10 -0
  190. package/resources/skills/bird.json +35 -0
  191. package/resources/skills/blogwatcher.json +10 -0
  192. package/resources/skills/blucli.json +10 -0
  193. package/resources/skills/bluebubbles.json +10 -0
  194. package/resources/skills/camsnap.json +10 -0
  195. package/resources/skills/clean-imports.json +18 -0
  196. package/resources/skills/code-review.json +18 -0
  197. package/resources/skills/coding-agent.json +10 -0
  198. package/resources/skills/compare-files.json +23 -0
  199. package/resources/skills/convert-code.json +34 -0
  200. package/resources/skills/create-changelog.json +24 -0
  201. package/resources/skills/debug-error.json +17 -0
  202. package/resources/skills/dependency-check.json +10 -0
  203. package/resources/skills/discord.json +10 -0
  204. package/resources/skills/eightctl.json +10 -0
  205. package/resources/skills/explain-code.json +29 -0
  206. package/resources/skills/extract-todos.json +18 -0
  207. package/resources/skills/food-order.json +10 -0
  208. package/resources/skills/gemini.json +10 -0
  209. package/resources/skills/generate-readme.json +10 -0
  210. package/resources/skills/gifgrep.json +10 -0
  211. package/resources/skills/git-commit.json +10 -0
  212. package/resources/skills/github.json +10 -0
  213. package/resources/skills/gog.json +10 -0
  214. package/resources/skills/goplaces.json +10 -0
  215. package/resources/skills/himalaya.json +10 -0
  216. package/resources/skills/imsg.json +10 -0
  217. package/resources/skills/karpathy-guidelines.json +12 -0
  218. package/resources/skills/last30days.json +26 -0
  219. package/resources/skills/local-places.json +10 -0
  220. package/resources/skills/mcporter.json +10 -0
  221. package/resources/skills/model-usage.json +10 -0
  222. package/resources/skills/nano-banana-pro.json +10 -0
  223. package/resources/skills/nano-pdf.json +10 -0
  224. package/resources/skills/notion.json +10 -0
  225. package/resources/skills/obsidian.json +10 -0
  226. package/resources/skills/openai-image-gen.json +10 -0
  227. package/resources/skills/openai-whisper-api.json +10 -0
  228. package/resources/skills/openai-whisper.json +10 -0
  229. package/resources/skills/openhue.json +10 -0
  230. package/resources/skills/oracle.json +10 -0
  231. package/resources/skills/ordercli.json +10 -0
  232. package/resources/skills/peekaboo.json +10 -0
  233. package/resources/skills/project-structure.json +10 -0
  234. package/resources/skills/proofread.json +17 -0
  235. package/resources/skills/refactor-code.json +31 -0
  236. package/resources/skills/rename-symbol.json +23 -0
  237. package/resources/skills/sag.json +10 -0
  238. package/resources/skills/security-audit.json +18 -0
  239. package/resources/skills/session-logs.json +10 -0
  240. package/resources/skills/sherpa-onnx-tts.json +10 -0
  241. package/resources/skills/skill-creator.json +15 -0
  242. package/resources/skills/skill-hub.json +29 -0
  243. package/resources/skills/slack.json +10 -0
  244. package/resources/skills/songsee.json +10 -0
  245. package/resources/skills/sonoscli.json +10 -0
  246. package/resources/skills/spotify-player.json +10 -0
  247. package/resources/skills/startup-cfo.json +55 -0
  248. package/resources/skills/summarize-folder.json +18 -0
  249. package/resources/skills/summarize.json +10 -0
  250. package/resources/skills/things-mac.json +10 -0
  251. package/resources/skills/tmux.json +10 -0
  252. package/resources/skills/translate.json +36 -0
  253. package/resources/skills/trello.json +10 -0
  254. package/resources/skills/video-frames.json +10 -0
  255. package/resources/skills/voice-call.json +10 -0
  256. package/resources/skills/wacli.json +10 -0
  257. package/resources/skills/weather.json +10 -0
  258. package/resources/skills/write-tests.json +31 -0
  259. package/src/electron/activity/ActivityRepository.ts +238 -0
  260. package/src/electron/agent/browser/browser-service.ts +721 -0
  261. package/src/electron/agent/context-manager.ts +257 -0
  262. package/src/electron/agent/custom-skill-loader.ts +634 -0
  263. package/src/electron/agent/daemon.ts +1097 -0
  264. package/src/electron/agent/executor.ts +4017 -0
  265. package/src/electron/agent/llm/anthropic-provider.ts +175 -0
  266. package/src/electron/agent/llm/bedrock-provider.ts +236 -0
  267. package/src/electron/agent/llm/gemini-provider.ts +422 -0
  268. package/src/electron/agent/llm/index.ts +9 -0
  269. package/src/electron/agent/llm/ollama-provider.ts +347 -0
  270. package/src/electron/agent/llm/openai-oauth.ts +127 -0
  271. package/src/electron/agent/llm/openai-provider.ts +686 -0
  272. package/src/electron/agent/llm/openrouter-provider.ts +273 -0
  273. package/src/electron/agent/llm/pricing.ts +180 -0
  274. package/src/electron/agent/llm/provider-factory.ts +971 -0
  275. package/src/electron/agent/llm/types.ts +291 -0
  276. package/src/electron/agent/queue-manager.ts +408 -0
  277. package/src/electron/agent/sandbox/docker-sandbox.ts +453 -0
  278. package/src/electron/agent/sandbox/macos-sandbox.ts +426 -0
  279. package/src/electron/agent/sandbox/runner.ts +453 -0
  280. package/src/electron/agent/sandbox/sandbox-factory.ts +337 -0
  281. package/src/electron/agent/sandbox/security-utils.ts +251 -0
  282. package/src/electron/agent/search/brave-provider.ts +141 -0
  283. package/src/electron/agent/search/google-provider.ts +131 -0
  284. package/src/electron/agent/search/index.ts +6 -0
  285. package/src/electron/agent/search/provider-factory.ts +450 -0
  286. package/src/electron/agent/search/serpapi-provider.ts +138 -0
  287. package/src/electron/agent/search/tavily-provider.ts +108 -0
  288. package/src/electron/agent/search/types.ts +118 -0
  289. package/src/electron/agent/security/index.ts +20 -0
  290. package/src/electron/agent/security/input-sanitizer.ts +380 -0
  291. package/src/electron/agent/security/output-filter.ts +259 -0
  292. package/src/electron/agent/skill-eligibility.ts +334 -0
  293. package/src/electron/agent/skill-registry.ts +457 -0
  294. package/src/electron/agent/skills/document.ts +1070 -0
  295. package/src/electron/agent/skills/image-generator.ts +272 -0
  296. package/src/electron/agent/skills/organizer.ts +131 -0
  297. package/src/electron/agent/skills/presentation.ts +418 -0
  298. package/src/electron/agent/skills/spreadsheet.ts +166 -0
  299. package/src/electron/agent/tools/browser-tools.ts +546 -0
  300. package/src/electron/agent/tools/builtin-settings.ts +422 -0
  301. package/src/electron/agent/tools/canvas-tools.ts +572 -0
  302. package/src/electron/agent/tools/cron-tools.ts +723 -0
  303. package/src/electron/agent/tools/edit-tools.ts +196 -0
  304. package/src/electron/agent/tools/file-tools.ts +811 -0
  305. package/src/electron/agent/tools/glob-tools.ts +303 -0
  306. package/src/electron/agent/tools/grep-tools.ts +432 -0
  307. package/src/electron/agent/tools/image-tools.ts +126 -0
  308. package/src/electron/agent/tools/mention-tools.ts +371 -0
  309. package/src/electron/agent/tools/node-tools.ts +550 -0
  310. package/src/electron/agent/tools/registry.ts +3052 -0
  311. package/src/electron/agent/tools/search-tools.ts +111 -0
  312. package/src/electron/agent/tools/shell-tools.ts +651 -0
  313. package/src/electron/agent/tools/skill-tools.ts +340 -0
  314. package/src/electron/agent/tools/system-tools.ts +665 -0
  315. package/src/electron/agent/tools/web-fetch-tools.ts +528 -0
  316. package/src/electron/agent/tools/x-tools.ts +267 -0
  317. package/src/electron/agents/AgentRoleRepository.ts +557 -0
  318. package/src/electron/agents/HeartbeatService.ts +469 -0
  319. package/src/electron/agents/MentionRepository.ts +242 -0
  320. package/src/electron/agents/TaskSubscriptionRepository.ts +231 -0
  321. package/src/electron/agents/WorkingStateRepository.ts +278 -0
  322. package/src/electron/canvas/canvas-manager.ts +818 -0
  323. package/src/electron/canvas/canvas-preload.ts +102 -0
  324. package/src/electron/canvas/canvas-protocol.ts +174 -0
  325. package/src/electron/canvas/canvas-store.ts +200 -0
  326. package/src/electron/canvas/index.ts +8 -0
  327. package/src/electron/control-plane/client.ts +527 -0
  328. package/src/electron/control-plane/handlers.ts +723 -0
  329. package/src/electron/control-plane/index.ts +51 -0
  330. package/src/electron/control-plane/node-manager.ts +322 -0
  331. package/src/electron/control-plane/protocol.ts +269 -0
  332. package/src/electron/control-plane/remote-client.ts +517 -0
  333. package/src/electron/control-plane/server.ts +853 -0
  334. package/src/electron/control-plane/settings.ts +401 -0
  335. package/src/electron/control-plane/ssh-tunnel.ts +624 -0
  336. package/src/electron/cron/index.ts +9 -0
  337. package/src/electron/cron/schedule.ts +217 -0
  338. package/src/electron/cron/service.ts +743 -0
  339. package/src/electron/cron/store.ts +165 -0
  340. package/src/electron/cron/types.ts +291 -0
  341. package/src/electron/cron/webhook.ts +303 -0
  342. package/src/electron/database/SecureSettingsRepository.ts +514 -0
  343. package/src/electron/database/TaskLabelRepository.ts +148 -0
  344. package/src/electron/database/repositories.ts +2397 -0
  345. package/src/electron/database/schema.ts +1017 -0
  346. package/src/electron/extensions/index.ts +18 -0
  347. package/src/electron/extensions/loader.ts +336 -0
  348. package/src/electron/extensions/registry.ts +546 -0
  349. package/src/electron/extensions/types.ts +372 -0
  350. package/src/electron/gateway/channel-registry.ts +1267 -0
  351. package/src/electron/gateway/channels/bluebubbles-client.ts +641 -0
  352. package/src/electron/gateway/channels/bluebubbles.ts +509 -0
  353. package/src/electron/gateway/channels/discord.ts +1150 -0
  354. package/src/electron/gateway/channels/email-client.ts +708 -0
  355. package/src/electron/gateway/channels/email.ts +516 -0
  356. package/src/electron/gateway/channels/google-chat.ts +760 -0
  357. package/src/electron/gateway/channels/imessage-client.ts +473 -0
  358. package/src/electron/gateway/channels/imessage.ts +520 -0
  359. package/src/electron/gateway/channels/index.ts +21 -0
  360. package/src/electron/gateway/channels/line-client.ts +598 -0
  361. package/src/electron/gateway/channels/line.ts +559 -0
  362. package/src/electron/gateway/channels/matrix-client.ts +632 -0
  363. package/src/electron/gateway/channels/matrix.ts +655 -0
  364. package/src/electron/gateway/channels/mattermost-client.ts +526 -0
  365. package/src/electron/gateway/channels/mattermost.ts +550 -0
  366. package/src/electron/gateway/channels/signal-client.ts +722 -0
  367. package/src/electron/gateway/channels/signal.ts +666 -0
  368. package/src/electron/gateway/channels/slack.ts +458 -0
  369. package/src/electron/gateway/channels/teams.ts +681 -0
  370. package/src/electron/gateway/channels/telegram.ts +1727 -0
  371. package/src/electron/gateway/channels/twitch-client.ts +665 -0
  372. package/src/electron/gateway/channels/twitch.ts +468 -0
  373. package/src/electron/gateway/channels/types.ts +1002 -0
  374. package/src/electron/gateway/channels/whatsapp.ts +1101 -0
  375. package/src/electron/gateway/context-policy.ts +382 -0
  376. package/src/electron/gateway/index.ts +1274 -0
  377. package/src/electron/gateway/infrastructure.ts +645 -0
  378. package/src/electron/gateway/router.ts +3206 -0
  379. package/src/electron/gateway/security.ts +422 -0
  380. package/src/electron/gateway/session.ts +144 -0
  381. package/src/electron/gateway/tunnel.ts +626 -0
  382. package/src/electron/guardrails/guardrail-manager.ts +380 -0
  383. package/src/electron/hooks/gmail-watcher.ts +355 -0
  384. package/src/electron/hooks/index.ts +30 -0
  385. package/src/electron/hooks/mappings.ts +404 -0
  386. package/src/electron/hooks/server.ts +574 -0
  387. package/src/electron/hooks/settings.ts +466 -0
  388. package/src/electron/hooks/types.ts +245 -0
  389. package/src/electron/ipc/canvas-handlers.ts +223 -0
  390. package/src/electron/ipc/handlers.ts +3661 -0
  391. package/src/electron/ipc/mission-control-handlers.ts +182 -0
  392. package/src/electron/main.ts +496 -0
  393. package/src/electron/mcp/client/MCPClientManager.ts +406 -0
  394. package/src/electron/mcp/client/MCPServerConnection.ts +514 -0
  395. package/src/electron/mcp/client/transports/SSETransport.ts +360 -0
  396. package/src/electron/mcp/client/transports/StdioTransport.ts +355 -0
  397. package/src/electron/mcp/client/transports/WebSocketTransport.ts +384 -0
  398. package/src/electron/mcp/host/MCPHostServer.ts +388 -0
  399. package/src/electron/mcp/host/ToolAdapter.ts +140 -0
  400. package/src/electron/mcp/registry/MCPRegistryManager.ts +565 -0
  401. package/src/electron/mcp/settings.ts +468 -0
  402. package/src/electron/mcp/types.ts +371 -0
  403. package/src/electron/memory/MemoryService.ts +523 -0
  404. package/src/electron/notifications/index.ts +16 -0
  405. package/src/electron/notifications/service.ts +161 -0
  406. package/src/electron/notifications/store.ts +163 -0
  407. package/src/electron/preload.ts +2845 -0
  408. package/src/electron/reports/StandupReportService.ts +356 -0
  409. package/src/electron/security/concurrency.ts +333 -0
  410. package/src/electron/security/index.ts +17 -0
  411. package/src/electron/security/policy-manager.ts +539 -0
  412. package/src/electron/settings/appearance-manager.ts +182 -0
  413. package/src/electron/settings/personality-manager.ts +800 -0
  414. package/src/electron/settings/x-manager.ts +62 -0
  415. package/src/electron/tailscale/exposure.ts +262 -0
  416. package/src/electron/tailscale/index.ts +34 -0
  417. package/src/electron/tailscale/settings.ts +218 -0
  418. package/src/electron/tailscale/tailscale.ts +379 -0
  419. package/src/electron/tray/QuickInputWindow.ts +609 -0
  420. package/src/electron/tray/TrayManager.ts +1005 -0
  421. package/src/electron/tray/index.ts +6 -0
  422. package/src/electron/updater/index.ts +1 -0
  423. package/src/electron/updater/update-manager.ts +447 -0
  424. package/src/electron/utils/env-migration.ts +203 -0
  425. package/src/electron/utils/process.ts +124 -0
  426. package/src/electron/utils/rate-limiter.ts +130 -0
  427. package/src/electron/utils/validation.ts +493 -0
  428. package/src/electron/utils/x-cli.ts +198 -0
  429. package/src/electron/voice/VoiceService.ts +583 -0
  430. package/src/electron/voice/index.ts +9 -0
  431. package/src/electron/voice/voice-settings-manager.ts +403 -0
  432. package/src/renderer/App.tsx +775 -0
  433. package/src/renderer/components/ActivityFeed.tsx +407 -0
  434. package/src/renderer/components/ActivityFeedItem.tsx +285 -0
  435. package/src/renderer/components/AgentRoleCard.tsx +343 -0
  436. package/src/renderer/components/AgentRoleEditor.tsx +805 -0
  437. package/src/renderer/components/AgentSquadSettings.tsx +295 -0
  438. package/src/renderer/components/AgentWorkingStatePanel.tsx +411 -0
  439. package/src/renderer/components/AppearanceSettings.tsx +122 -0
  440. package/src/renderer/components/ApprovalDialog.tsx +100 -0
  441. package/src/renderer/components/BlueBubblesSettings.tsx +505 -0
  442. package/src/renderer/components/BuiltinToolsSettings.tsx +307 -0
  443. package/src/renderer/components/CanvasPreview.tsx +1189 -0
  444. package/src/renderer/components/CommandOutput.tsx +202 -0
  445. package/src/renderer/components/ContextPolicySettings.tsx +523 -0
  446. package/src/renderer/components/ControlPlaneSettings.tsx +1134 -0
  447. package/src/renderer/components/DisclaimerModal.tsx +124 -0
  448. package/src/renderer/components/DiscordSettings.tsx +436 -0
  449. package/src/renderer/components/EmailSettings.tsx +606 -0
  450. package/src/renderer/components/ExtensionsSettings.tsx +542 -0
  451. package/src/renderer/components/FileViewer.tsx +224 -0
  452. package/src/renderer/components/GoogleChatSettings.tsx +535 -0
  453. package/src/renderer/components/GuardrailSettings.tsx +487 -0
  454. package/src/renderer/components/HooksSettings.tsx +581 -0
  455. package/src/renderer/components/ImessageSettings.tsx +484 -0
  456. package/src/renderer/components/LineSettings.tsx +483 -0
  457. package/src/renderer/components/MCPRegistryBrowser.tsx +386 -0
  458. package/src/renderer/components/MCPSettings.tsx +943 -0
  459. package/src/renderer/components/MainContent.tsx +2433 -0
  460. package/src/renderer/components/MatrixSettings.tsx +510 -0
  461. package/src/renderer/components/MattermostSettings.tsx +473 -0
  462. package/src/renderer/components/MemorySettings.tsx +247 -0
  463. package/src/renderer/components/MentionBadge.tsx +87 -0
  464. package/src/renderer/components/MentionInput.tsx +409 -0
  465. package/src/renderer/components/MentionList.tsx +476 -0
  466. package/src/renderer/components/MissionControlPanel.tsx +1995 -0
  467. package/src/renderer/components/NodesSettings.tsx +316 -0
  468. package/src/renderer/components/NotificationPanel.tsx +481 -0
  469. package/src/renderer/components/Onboarding/AwakeningOrb.tsx +44 -0
  470. package/src/renderer/components/Onboarding/Onboarding.tsx +443 -0
  471. package/src/renderer/components/Onboarding/TypewriterText.tsx +102 -0
  472. package/src/renderer/components/Onboarding/index.ts +3 -0
  473. package/src/renderer/components/OnboardingModal.tsx +698 -0
  474. package/src/renderer/components/PairingCodeDisplay.tsx +324 -0
  475. package/src/renderer/components/PersonalitySettings.tsx +597 -0
  476. package/src/renderer/components/QueueSettings.tsx +119 -0
  477. package/src/renderer/components/QuickTaskFAB.tsx +71 -0
  478. package/src/renderer/components/RightPanel.tsx +413 -0
  479. package/src/renderer/components/ScheduledTasksSettings.tsx +1328 -0
  480. package/src/renderer/components/SearchSettings.tsx +328 -0
  481. package/src/renderer/components/Settings.tsx +1504 -0
  482. package/src/renderer/components/Sidebar.tsx +344 -0
  483. package/src/renderer/components/SignalSettings.tsx +673 -0
  484. package/src/renderer/components/SkillHubBrowser.tsx +458 -0
  485. package/src/renderer/components/SkillParameterModal.tsx +185 -0
  486. package/src/renderer/components/SkillsSettings.tsx +451 -0
  487. package/src/renderer/components/SlackSettings.tsx +442 -0
  488. package/src/renderer/components/StandupReportViewer.tsx +614 -0
  489. package/src/renderer/components/TaskBoard.tsx +498 -0
  490. package/src/renderer/components/TaskBoardCard.tsx +357 -0
  491. package/src/renderer/components/TaskBoardColumn.tsx +211 -0
  492. package/src/renderer/components/TaskLabelManager.tsx +472 -0
  493. package/src/renderer/components/TaskQueuePanel.tsx +144 -0
  494. package/src/renderer/components/TaskQuickActions.tsx +492 -0
  495. package/src/renderer/components/TaskTimeline.tsx +216 -0
  496. package/src/renderer/components/TaskView.tsx +162 -0
  497. package/src/renderer/components/TeamsSettings.tsx +518 -0
  498. package/src/renderer/components/TelegramSettings.tsx +421 -0
  499. package/src/renderer/components/Toast.tsx +76 -0
  500. package/src/renderer/components/TraySettings.tsx +189 -0
  501. package/src/renderer/components/TwitchSettings.tsx +511 -0
  502. package/src/renderer/components/UpdateSettings.tsx +295 -0
  503. package/src/renderer/components/VoiceIndicator.tsx +270 -0
  504. package/src/renderer/components/VoiceSettings.tsx +867 -0
  505. package/src/renderer/components/WhatsAppSettings.tsx +721 -0
  506. package/src/renderer/components/WorkingStateEditor.tsx +309 -0
  507. package/src/renderer/components/WorkingStateHistory.tsx +481 -0
  508. package/src/renderer/components/WorkspaceSelector.tsx +150 -0
  509. package/src/renderer/components/XSettings.tsx +311 -0
  510. package/src/renderer/global.d.ts +9 -0
  511. package/src/renderer/hooks/useAgentContext.ts +153 -0
  512. package/src/renderer/hooks/useOnboardingFlow.ts +548 -0
  513. package/src/renderer/hooks/useVoiceInput.ts +268 -0
  514. package/src/renderer/index.html +12 -0
  515. package/src/renderer/main.tsx +10 -0
  516. package/src/renderer/public/cowork-os-logo.png +0 -0
  517. package/src/renderer/quick-input.html +164 -0
  518. package/src/renderer/styles/index.css +14504 -0
  519. package/src/renderer/utils/agentMessages.ts +749 -0
  520. package/src/renderer/utils/voice-directives.ts +169 -0
  521. package/src/shared/channelMessages.ts +213 -0
  522. package/src/shared/types.ts +3608 -0
  523. package/tsconfig.electron.json +26 -0
  524. package/tsconfig.json +26 -0
  525. package/tsconfig.node.json +10 -0
  526. package/vite.config.ts +23 -0
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setupMissionControlHandlers = setupMissionControlHandlers;
4
+ const electron_1 = require("electron");
5
+ const types_1 = require("../../shared/types");
6
+ const rate_limiter_1 = require("../utils/rate-limiter");
7
+ const validation_1 = require("../utils/validation");
8
+ // Get main window for event broadcasting
9
+ let mainWindowGetter = null;
10
+ function getMainWindow() {
11
+ return mainWindowGetter?.() ?? null;
12
+ }
13
+ /**
14
+ * Rate limit check helper
15
+ */
16
+ function checkRateLimit(channel) {
17
+ if (!rate_limiter_1.rateLimiter.check(channel)) {
18
+ throw new Error(`Rate limit exceeded for ${channel}`);
19
+ }
20
+ }
21
+ /**
22
+ * Set up Mission Control IPC handlers
23
+ */
24
+ function setupMissionControlHandlers(deps) {
25
+ mainWindowGetter = deps.getMainWindow;
26
+ const { agentRoleRepo, taskSubscriptionRepo, standupService, heartbeatService, } = deps;
27
+ // ============ Heartbeat Handlers ============
28
+ electron_1.ipcMain.handle(types_1.IPC_CHANNELS.HEARTBEAT_GET_CONFIG, async (_, agentRoleId) => {
29
+ const validated = (0, validation_1.validateInput)(validation_1.UUIDSchema, agentRoleId, 'agent role ID');
30
+ const role = agentRoleRepo.findById(validated);
31
+ if (!role) {
32
+ throw new Error('Agent role not found');
33
+ }
34
+ return {
35
+ heartbeatEnabled: role.heartbeatEnabled,
36
+ heartbeatIntervalMinutes: role.heartbeatIntervalMinutes,
37
+ heartbeatStaggerOffset: role.heartbeatStaggerOffset,
38
+ lastHeartbeatAt: role.lastHeartbeatAt,
39
+ heartbeatStatus: role.heartbeatStatus,
40
+ };
41
+ });
42
+ electron_1.ipcMain.handle(types_1.IPC_CHANNELS.HEARTBEAT_UPDATE_CONFIG, async (_, agentRoleId, config) => {
43
+ checkRateLimit(types_1.IPC_CHANNELS.HEARTBEAT_UPDATE_CONFIG);
44
+ const validated = (0, validation_1.validateInput)(validation_1.UUIDSchema, agentRoleId, 'agent role ID');
45
+ const result = agentRoleRepo.updateHeartbeatConfig(validated, config);
46
+ if (result) {
47
+ heartbeatService.updateAgentConfig(validated, config);
48
+ getMainWindow()?.webContents.send(types_1.IPC_CHANNELS.HEARTBEAT_EVENT, {
49
+ type: 'config_updated',
50
+ agentRoleId: validated,
51
+ config,
52
+ });
53
+ }
54
+ return result;
55
+ });
56
+ electron_1.ipcMain.handle(types_1.IPC_CHANNELS.HEARTBEAT_TRIGGER, async (_, agentRoleId) => {
57
+ checkRateLimit(types_1.IPC_CHANNELS.HEARTBEAT_TRIGGER);
58
+ const validated = (0, validation_1.validateInput)(validation_1.UUIDSchema, agentRoleId, 'agent role ID');
59
+ const result = await heartbeatService.triggerHeartbeat(validated);
60
+ getMainWindow()?.webContents.send(types_1.IPC_CHANNELS.HEARTBEAT_EVENT, {
61
+ type: 'triggered',
62
+ agentRoleId: validated,
63
+ result,
64
+ });
65
+ return result;
66
+ });
67
+ electron_1.ipcMain.handle(types_1.IPC_CHANNELS.HEARTBEAT_GET_STATUS, async (_, agentRoleId) => {
68
+ const validated = (0, validation_1.validateInput)(validation_1.UUIDSchema, agentRoleId, 'agent role ID');
69
+ return heartbeatService.getStatus(validated);
70
+ });
71
+ electron_1.ipcMain.handle(types_1.IPC_CHANNELS.HEARTBEAT_GET_ALL_STATUS, async () => {
72
+ return heartbeatService.getAllStatus();
73
+ });
74
+ // Forward heartbeat events to renderer
75
+ heartbeatService.on('heartbeat', (event) => {
76
+ getMainWindow()?.webContents.send(types_1.IPC_CHANNELS.HEARTBEAT_EVENT, event);
77
+ });
78
+ // ============ Task Subscription Handlers ============
79
+ electron_1.ipcMain.handle(types_1.IPC_CHANNELS.SUBSCRIPTION_LIST, async (_, taskId) => {
80
+ const validated = (0, validation_1.validateInput)(validation_1.UUIDSchema, taskId, 'task ID');
81
+ return taskSubscriptionRepo.getSubscribers(validated);
82
+ });
83
+ electron_1.ipcMain.handle(types_1.IPC_CHANNELS.SUBSCRIPTION_ADD, async (_, taskId, agentRoleId, reason) => {
84
+ checkRateLimit(types_1.IPC_CHANNELS.SUBSCRIPTION_ADD);
85
+ const validatedTaskId = (0, validation_1.validateInput)(validation_1.UUIDSchema, taskId, 'task ID');
86
+ const validatedAgentRoleId = (0, validation_1.validateInput)(validation_1.UUIDSchema, agentRoleId, 'agent role ID');
87
+ const subscription = taskSubscriptionRepo.subscribe(validatedTaskId, validatedAgentRoleId, reason);
88
+ getMainWindow()?.webContents.send(types_1.IPC_CHANNELS.SUBSCRIPTION_EVENT, {
89
+ type: 'added',
90
+ subscription,
91
+ });
92
+ return subscription;
93
+ });
94
+ electron_1.ipcMain.handle(types_1.IPC_CHANNELS.SUBSCRIPTION_REMOVE, async (_, taskId, agentRoleId) => {
95
+ checkRateLimit(types_1.IPC_CHANNELS.SUBSCRIPTION_REMOVE);
96
+ const validatedTaskId = (0, validation_1.validateInput)(validation_1.UUIDSchema, taskId, 'task ID');
97
+ const validatedAgentRoleId = (0, validation_1.validateInput)(validation_1.UUIDSchema, agentRoleId, 'agent role ID');
98
+ const success = taskSubscriptionRepo.unsubscribe(validatedTaskId, validatedAgentRoleId);
99
+ if (success) {
100
+ getMainWindow()?.webContents.send(types_1.IPC_CHANNELS.SUBSCRIPTION_EVENT, {
101
+ type: 'removed',
102
+ taskId: validatedTaskId,
103
+ agentRoleId: validatedAgentRoleId,
104
+ });
105
+ }
106
+ return { success };
107
+ });
108
+ electron_1.ipcMain.handle(types_1.IPC_CHANNELS.SUBSCRIPTION_GET_SUBSCRIBERS, async (_, taskId) => {
109
+ const validated = (0, validation_1.validateInput)(validation_1.UUIDSchema, taskId, 'task ID');
110
+ return taskSubscriptionRepo.getSubscribers(validated);
111
+ });
112
+ electron_1.ipcMain.handle(types_1.IPC_CHANNELS.SUBSCRIPTION_GET_FOR_AGENT, async (_, agentRoleId) => {
113
+ const validated = (0, validation_1.validateInput)(validation_1.UUIDSchema, agentRoleId, 'agent role ID');
114
+ return taskSubscriptionRepo.getSubscriptionsForAgent(validated);
115
+ });
116
+ // ============ Standup Report Handlers ============
117
+ electron_1.ipcMain.handle(types_1.IPC_CHANNELS.STANDUP_GENERATE, async (_, workspaceId) => {
118
+ checkRateLimit(types_1.IPC_CHANNELS.STANDUP_GENERATE);
119
+ const validated = (0, validation_1.validateInput)(validation_1.UUIDSchema, workspaceId, 'workspace ID');
120
+ return standupService.generateReport(validated);
121
+ });
122
+ electron_1.ipcMain.handle(types_1.IPC_CHANNELS.STANDUP_GET_LATEST, async (_, workspaceId) => {
123
+ const validated = (0, validation_1.validateInput)(validation_1.UUIDSchema, workspaceId, 'workspace ID');
124
+ return standupService.getLatest(validated);
125
+ });
126
+ electron_1.ipcMain.handle(types_1.IPC_CHANNELS.STANDUP_LIST, async (_, workspaceId, limit) => {
127
+ const validated = (0, validation_1.validateInput)(validation_1.UUIDSchema, workspaceId, 'workspace ID');
128
+ return standupService.list({ workspaceId: validated, limit });
129
+ });
130
+ electron_1.ipcMain.handle(types_1.IPC_CHANNELS.STANDUP_DELIVER, async (_, reportId, channelType, channelId) => {
131
+ checkRateLimit(types_1.IPC_CHANNELS.STANDUP_DELIVER);
132
+ const validatedReportId = (0, validation_1.validateInput)(validation_1.UUIDSchema, reportId, 'report ID');
133
+ const report = standupService.findById(validatedReportId);
134
+ if (!report) {
135
+ throw new Error('Standup report not found');
136
+ }
137
+ await standupService.deliverReport(report, { channelType, channelId });
138
+ return { success: true };
139
+ });
140
+ console.log('[MissionControl] Handlers initialized');
141
+ }
@@ -0,0 +1,448 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const path_1 = __importDefault(require("path"));
7
+ const url_1 = require("url");
8
+ const electron_1 = require("electron");
9
+ const schema_1 = require("./database/schema");
10
+ const SecureSettingsRepository_1 = require("./database/SecureSettingsRepository");
11
+ const handlers_1 = require("./ipc/handlers");
12
+ const mission_control_handlers_1 = require("./ipc/mission-control-handlers");
13
+ const TaskSubscriptionRepository_1 = require("./agents/TaskSubscriptionRepository");
14
+ const StandupReportService_1 = require("./reports/StandupReportService");
15
+ const HeartbeatService_1 = require("./agents/HeartbeatService");
16
+ const AgentRoleRepository_1 = require("./agents/AgentRoleRepository");
17
+ const MentionRepository_1 = require("./agents/MentionRepository");
18
+ const ActivityRepository_1 = require("./activity/ActivityRepository");
19
+ const WorkingStateRepository_1 = require("./agents/WorkingStateRepository");
20
+ const daemon_1 = require("./agent/daemon");
21
+ const repositories_1 = require("./database/repositories");
22
+ const llm_1 = require("./agent/llm");
23
+ const search_1 = require("./agent/search");
24
+ const gateway_1 = require("./gateway");
25
+ const updater_1 = require("./updater");
26
+ const env_migration_1 = require("./utils/env-migration");
27
+ const guardrail_manager_1 = require("./guardrails/guardrail-manager");
28
+ const appearance_manager_1 = require("./settings/appearance-manager");
29
+ const personality_manager_1 = require("./settings/personality-manager");
30
+ const MCPClientManager_1 = require("./mcp/client/MCPClientManager");
31
+ const tray_1 = require("./tray");
32
+ const cron_1 = require("./cron");
33
+ const MemoryService_1 = require("./memory/MemoryService");
34
+ const control_plane_1 = require("./control-plane");
35
+ // Live Canvas feature
36
+ const canvas_1 = require("./canvas");
37
+ const canvas_handlers_1 = require("./ipc/canvas-handlers");
38
+ let mainWindow = null;
39
+ let dbManager;
40
+ let agentDaemon;
41
+ let channelGateway;
42
+ let cronService = null;
43
+ // Suppress GPU-related Chromium errors that occur with transparent windows and vibrancy
44
+ // These are cosmetic errors that don't affect functionality
45
+ electron_1.app.commandLine.appendSwitch('disable-gpu-driver-bug-workarounds');
46
+ electron_1.app.commandLine.appendSwitch('enable-gpu-rasterization');
47
+ electron_1.app.commandLine.appendSwitch('ignore-gpu-blocklist');
48
+ // Register canvas:// protocol scheme (must be called before app.ready)
49
+ (0, canvas_1.registerCanvasScheme)();
50
+ function createWindow() {
51
+ mainWindow = new electron_1.BrowserWindow({
52
+ width: 1600,
53
+ height: 1000,
54
+ minWidth: 1200,
55
+ minHeight: 800,
56
+ center: true,
57
+ titleBarStyle: 'hiddenInset',
58
+ vibrancy: 'under-window',
59
+ visualEffectState: 'active',
60
+ transparent: true,
61
+ backgroundColor: '#00000000',
62
+ webPreferences: {
63
+ nodeIntegration: false,
64
+ contextIsolation: true,
65
+ webviewTag: true, // Enable webview for canvas interactive mode
66
+ preload: path_1.default.join(__dirname, 'preload.js'),
67
+ },
68
+ });
69
+ // Load the app
70
+ if (process.env.NODE_ENV === 'development') {
71
+ mainWindow.loadURL('http://localhost:5173');
72
+ mainWindow.webContents.openDevTools();
73
+ }
74
+ else {
75
+ mainWindow.loadFile(path_1.default.join(__dirname, '../../renderer/index.html'));
76
+ }
77
+ mainWindow.on('closed', () => {
78
+ mainWindow = null;
79
+ });
80
+ // Open external links in the system browser instead of inside the app
81
+ mainWindow.webContents.setWindowOpenHandler(({ url }) => {
82
+ // Open all new window requests in external browser
83
+ electron_1.shell.openExternal(url);
84
+ return { action: 'deny' };
85
+ });
86
+ mainWindow.webContents.on('will-navigate', (event, url) => {
87
+ // Allow navigation to the app itself (dev server or file://), block external URLs
88
+ const appUrl = process.env.NODE_ENV === 'development'
89
+ ? 'http://localhost:5173'
90
+ : `file://${path_1.default.join(__dirname, '../../renderer')}`;
91
+ if (!url.startsWith(appUrl)) {
92
+ event.preventDefault();
93
+ electron_1.shell.openExternal(url);
94
+ }
95
+ });
96
+ }
97
+ electron_1.app.whenReady().then(async () => {
98
+ // Set up Content Security Policy for production builds
99
+ if (process.env.NODE_ENV !== 'development') {
100
+ const appRoot = (0, url_1.pathToFileURL)(path_1.default.join(__dirname, '../../renderer')).toString();
101
+ electron_1.session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
102
+ if (!details.url.startsWith(appRoot)) {
103
+ callback({ responseHeaders: details.responseHeaders });
104
+ return;
105
+ }
106
+ callback({
107
+ responseHeaders: {
108
+ ...details.responseHeaders,
109
+ 'Content-Security-Policy': [
110
+ "default-src 'self'; " +
111
+ "script-src 'self'; " +
112
+ "style-src 'self' 'unsafe-inline'; " + // Allow inline styles for React
113
+ "img-src 'self' data: https:; " + // Allow images from self, data URIs, and HTTPS
114
+ "font-src 'self' data:; " + // Allow fonts from self and data URIs
115
+ "connect-src 'self' https:; " + // Allow API calls to HTTPS endpoints
116
+ "frame-ancestors 'none'; " + // Prevent embedding in iframes
117
+ "form-action 'self';" // Restrict form submissions
118
+ ],
119
+ },
120
+ });
121
+ });
122
+ }
123
+ // Initialize database first - required for SecureSettingsRepository
124
+ dbManager = new schema_1.DatabaseManager();
125
+ // Initialize secure settings repository for encrypted settings storage
126
+ // This MUST be done before provider factories so they can migrate legacy settings
127
+ new SecureSettingsRepository_1.SecureSettingsRepository(dbManager.getDatabase());
128
+ console.log('[Main] SecureSettingsRepository initialized');
129
+ // Initialize provider factories (loads settings from disk, migrates legacy files)
130
+ llm_1.LLMProviderFactory.initialize();
131
+ search_1.SearchProviderFactory.initialize();
132
+ guardrail_manager_1.GuardrailManager.initialize();
133
+ appearance_manager_1.AppearanceManager.initialize();
134
+ personality_manager_1.PersonalityManager.initialize();
135
+ // Migrate .env configuration to Settings (one-time upgrade path)
136
+ const migrationResult = await (0, env_migration_1.migrateEnvToSettings)();
137
+ // Initialize agent daemon
138
+ agentDaemon = new daemon_1.AgentDaemon(dbManager);
139
+ await agentDaemon.initialize();
140
+ // Initialize Memory Service for cross-session context
141
+ try {
142
+ MemoryService_1.MemoryService.initialize(dbManager);
143
+ console.log('[Main] Memory Service initialized');
144
+ }
145
+ catch (error) {
146
+ console.error('[Main] Failed to initialize Memory Service:', error);
147
+ // Don't fail app startup if memory init fails
148
+ }
149
+ // Initialize MCP Client Manager - auto-connects enabled servers on startup
150
+ try {
151
+ const mcpClientManager = MCPClientManager_1.MCPClientManager.getInstance();
152
+ await mcpClientManager.initialize();
153
+ console.log('[Main] MCP Client Manager initialized');
154
+ }
155
+ catch (error) {
156
+ console.error('[Main] Failed to initialize MCP Client Manager:', error);
157
+ // Don't fail app startup if MCP init fails
158
+ }
159
+ // Initialize Cron Service for scheduled task execution
160
+ try {
161
+ cronService = new cron_1.CronService({
162
+ cronEnabled: true,
163
+ storePath: (0, cron_1.getCronStorePath)(),
164
+ maxConcurrentRuns: 3, // Allow up to 3 concurrent jobs
165
+ // Webhook configuration (disabled by default, can be enabled in settings)
166
+ webhook: {
167
+ enabled: false, // Set to true to enable webhook triggers
168
+ port: 9876,
169
+ host: '127.0.0.1',
170
+ // secret: 'your-secret-here', // Uncomment and set for secure webhooks
171
+ },
172
+ createTask: async (params) => {
173
+ const task = await agentDaemon.createTask({
174
+ title: params.title,
175
+ prompt: params.prompt,
176
+ workspaceId: params.workspaceId,
177
+ });
178
+ return { id: task.id };
179
+ },
180
+ // Channel delivery handler - sends job results to messaging platforms
181
+ deliverToChannel: async (params) => {
182
+ if (!channelGateway) {
183
+ console.warn('[Cron] Cannot deliver to channel - gateway not initialized');
184
+ return;
185
+ }
186
+ // Build the message
187
+ const statusEmoji = params.status === 'ok' ? '✅' : params.status === 'error' ? '❌' : '⏱️';
188
+ let message = `${statusEmoji} **Scheduled Task: ${params.jobName}**\n\n`;
189
+ if (params.status === 'ok') {
190
+ message += `Task completed successfully.\n`;
191
+ }
192
+ else if (params.status === 'error') {
193
+ message += `Task failed.\n`;
194
+ }
195
+ else {
196
+ message += `Task timed out.\n`;
197
+ }
198
+ if (params.error) {
199
+ message += `\n**Error:** ${params.error}\n`;
200
+ }
201
+ if (params.taskId && !params.summaryOnly) {
202
+ message += `\n_Task ID: ${params.taskId}_`;
203
+ }
204
+ // Find the channel to verify it exists
205
+ const channels = channelGateway.getChannels();
206
+ const channel = channels.find((ch) => ch.type === params.channelType && ch.id === params.channelId);
207
+ if (!channel) {
208
+ console.warn(`[Cron] Channel not found: ${params.channelType}:${params.channelId}`);
209
+ return;
210
+ }
211
+ try {
212
+ // Send the message via the gateway
213
+ await channelGateway.sendMessage(params.channelType, params.channelId, message, { parseMode: 'markdown' });
214
+ console.log(`[Cron] Delivered to ${params.channelType}:${params.channelId}`);
215
+ }
216
+ catch (err) {
217
+ console.error(`[Cron] Failed to deliver to ${params.channelType}:${params.channelId}:`, err);
218
+ }
219
+ },
220
+ onEvent: async (evt) => {
221
+ // Forward cron events to renderer
222
+ if (mainWindow?.webContents) {
223
+ mainWindow.webContents.send('cron:event', evt);
224
+ }
225
+ console.log('[Cron] Event:', evt.action, evt.jobId);
226
+ // Show desktop notification when scheduled task finishes
227
+ if (evt.action === 'finished') {
228
+ const statusEmoji = evt.status === 'ok' ? '✅' : evt.status === 'error' ? '❌' : '⏱️';
229
+ const statusText = evt.status === 'ok' ? 'completed' : evt.status === 'error' ? 'failed' : 'timed out';
230
+ // Add in-app notification
231
+ const notificationService = (0, handlers_1.getNotificationService)();
232
+ if (notificationService) {
233
+ try {
234
+ // Get job name for the notification
235
+ const job = cronService ? await cronService.get(evt.jobId) : null;
236
+ const jobName = job?.name || 'Scheduled Task';
237
+ await notificationService.add({
238
+ type: evt.status === 'ok' ? 'task_completed' : 'task_failed',
239
+ title: `${statusEmoji} ${jobName} ${statusText}`,
240
+ message: evt.error || (evt.status === 'ok' ? 'Task completed successfully.' : 'Task did not complete.'),
241
+ taskId: evt.taskId,
242
+ cronJobId: evt.jobId,
243
+ workspaceId: job?.workspaceId,
244
+ });
245
+ }
246
+ catch (err) {
247
+ console.error('[Cron] Failed to add in-app notification:', err);
248
+ }
249
+ }
250
+ // Show macOS notification
251
+ if (electron_1.Notification.isSupported()) {
252
+ const notification = new electron_1.Notification({
253
+ title: `${statusEmoji} Scheduled Task ${statusText}`,
254
+ body: evt.error ? `Error: ${evt.error}` : 'Click to view results in the app.',
255
+ silent: false,
256
+ });
257
+ notification.on('click', () => {
258
+ // Bring the main window to focus
259
+ if (mainWindow) {
260
+ if (mainWindow.isMinimized())
261
+ mainWindow.restore();
262
+ mainWindow.focus();
263
+ }
264
+ });
265
+ notification.show();
266
+ }
267
+ }
268
+ },
269
+ log: {
270
+ debug: (msg, data) => console.log(`[Cron] ${msg}`, data ?? ''),
271
+ info: (msg, data) => console.log(`[Cron] ${msg}`, data ?? ''),
272
+ warn: (msg, data) => console.warn(`[Cron] ${msg}`, data ?? ''),
273
+ error: (msg, data) => console.error(`[Cron] ${msg}`, data ?? ''),
274
+ },
275
+ });
276
+ (0, cron_1.setCronService)(cronService);
277
+ await cronService.start();
278
+ console.log('[Main] Cron Service initialized');
279
+ }
280
+ catch (error) {
281
+ console.error('[Main] Failed to initialize Cron Service:', error);
282
+ // Don't fail app startup if cron init fails
283
+ }
284
+ // Initialize channel gateway with agent daemon for task processing
285
+ channelGateway = new gateway_1.ChannelGateway(dbManager.getDatabase(), {
286
+ autoConnect: true, // Auto-connect enabled channels on startup
287
+ agentDaemon,
288
+ });
289
+ // Setup IPC handlers
290
+ await (0, handlers_1.setupIpcHandlers)(dbManager, agentDaemon, channelGateway);
291
+ // Initialize Mission Control services
292
+ try {
293
+ const db = dbManager.getDatabase();
294
+ const agentRoleRepo = new AgentRoleRepository_1.AgentRoleRepository(db);
295
+ // Sync any new default agents to existing workspaces
296
+ const addedAgents = agentRoleRepo.syncNewDefaults();
297
+ if (addedAgents.length > 0) {
298
+ console.log(`[Main] Added ${addedAgents.length} new default agent(s)`);
299
+ }
300
+ const mentionRepo = new MentionRepository_1.MentionRepository(db);
301
+ const activityRepo = new ActivityRepository_1.ActivityRepository(db);
302
+ const workingStateRepo = new WorkingStateRepository_1.WorkingStateRepository(db);
303
+ const taskSubscriptionRepo = new TaskSubscriptionRepository_1.TaskSubscriptionRepository(db);
304
+ const standupService = new StandupReportService_1.StandupReportService(db);
305
+ // Create repositories for heartbeat service
306
+ const taskRepo = new repositories_1.TaskRepository(db);
307
+ const workspaceRepo = new repositories_1.WorkspaceRepository(db);
308
+ // Initialize HeartbeatService with dependencies
309
+ const heartbeatDeps = {
310
+ agentRoleRepo,
311
+ mentionRepo,
312
+ activityRepo,
313
+ workingStateRepo,
314
+ createTask: async (workspaceId, prompt, title, _agentRoleId) => {
315
+ // Create task via agentDaemon (doesn't support assignedAgentRoleId directly)
316
+ const task = await agentDaemon.createTask({
317
+ title,
318
+ prompt,
319
+ workspaceId,
320
+ });
321
+ // Note: Task assignment would need to be done separately if needed
322
+ return task;
323
+ },
324
+ getTasksForAgent: (agentRoleId, workspaceId) => {
325
+ // Get assigned tasks for the agent using the task repository
326
+ const tasks = workspaceId
327
+ ? taskRepo.findByWorkspace(workspaceId)
328
+ : taskRepo.findByStatus(['pending', 'running']);
329
+ return tasks.filter((t) => t.assignedAgentRoleId === agentRoleId);
330
+ },
331
+ getDefaultWorkspaceId: () => {
332
+ // Get the first workspace as default
333
+ const workspaces = workspaceRepo.findAll();
334
+ return workspaces[0]?.id;
335
+ },
336
+ };
337
+ const heartbeatService = new HeartbeatService_1.HeartbeatService(heartbeatDeps);
338
+ await heartbeatService.start();
339
+ // Setup Mission Control IPC handlers
340
+ (0, mission_control_handlers_1.setupMissionControlHandlers)({
341
+ agentRoleRepo,
342
+ taskSubscriptionRepo,
343
+ standupService,
344
+ heartbeatService,
345
+ getMainWindow: () => mainWindow,
346
+ });
347
+ console.log('[Main] Mission Control services initialized');
348
+ }
349
+ catch (error) {
350
+ console.error('[Main] Failed to initialize Mission Control:', error);
351
+ // Don't fail app startup if Mission Control init fails
352
+ }
353
+ // Register canvas:// protocol handler (must be after app.ready)
354
+ (0, canvas_1.registerCanvasProtocol)();
355
+ // Create window
356
+ createWindow();
357
+ // Initialize gateway with main window reference
358
+ if (mainWindow) {
359
+ await channelGateway.initialize(mainWindow);
360
+ // Initialize update manager with main window reference
361
+ updater_1.updateManager.setMainWindow(mainWindow);
362
+ // Initialize Live Canvas handlers and set main window reference
363
+ (0, canvas_handlers_1.setupCanvasHandlers)(mainWindow, agentDaemon);
364
+ canvas_1.CanvasManager.getInstance().setMainWindow(mainWindow);
365
+ // Restore persisted canvas sessions from disk
366
+ await canvas_1.CanvasManager.getInstance().restoreSessions();
367
+ // Initialize control plane (WebSocket gateway)
368
+ (0, control_plane_1.setupControlPlaneHandlers)(mainWindow);
369
+ // Initialize menu bar tray (macOS native companion)
370
+ if (process.platform === 'darwin') {
371
+ await tray_1.trayManager.initialize(mainWindow, channelGateway, dbManager, agentDaemon);
372
+ }
373
+ // Show migration notification after window is ready
374
+ if (migrationResult.migrated && migrationResult.migratedKeys.length > 0) {
375
+ mainWindow.webContents.once('did-finish-load', () => {
376
+ electron_1.dialog.showMessageBox(mainWindow, {
377
+ type: 'info',
378
+ title: 'Configuration Migrated',
379
+ message: 'Your API credentials have been migrated',
380
+ detail: `The following credentials were migrated from your .env file to secure Settings storage:\n\n` +
381
+ `${migrationResult.migratedKeys.map(k => `• ${k}`).join('\n')}\n\n` +
382
+ `Your .env file has been renamed to .env.migrated. ` +
383
+ `You can safely delete it after verifying your settings work correctly.\n\n` +
384
+ `Open Settings (gear icon) to review your configuration.`,
385
+ buttons: ['OK'],
386
+ });
387
+ });
388
+ }
389
+ }
390
+ electron_1.app.on('activate', () => {
391
+ if (electron_1.BrowserWindow.getAllWindows().length === 0) {
392
+ createWindow();
393
+ }
394
+ });
395
+ });
396
+ electron_1.app.on('window-all-closed', () => {
397
+ if (process.platform !== 'darwin') {
398
+ electron_1.app.quit();
399
+ }
400
+ });
401
+ electron_1.app.on('before-quit', async () => {
402
+ // Destroy tray
403
+ tray_1.trayManager.destroy();
404
+ // Stop cron service (async to properly shutdown webhook server)
405
+ if (cronService) {
406
+ await cronService.stop();
407
+ (0, cron_1.setCronService)(null);
408
+ }
409
+ // Cleanup canvas manager (close all windows and watchers)
410
+ await (0, canvas_handlers_1.cleanupCanvasHandlers)();
411
+ // Shutdown control plane (WebSocket gateway and Tailscale)
412
+ await (0, control_plane_1.shutdownControlPlane)();
413
+ if (channelGateway) {
414
+ await channelGateway.shutdown();
415
+ }
416
+ // Disconnect all MCP servers
417
+ try {
418
+ const mcpClientManager = MCPClientManager_1.MCPClientManager.getInstance();
419
+ await mcpClientManager.shutdown();
420
+ }
421
+ catch (error) {
422
+ console.error('[Main] Failed to shutdown MCP servers:', error);
423
+ }
424
+ // Shutdown Memory Service
425
+ try {
426
+ MemoryService_1.MemoryService.shutdown();
427
+ }
428
+ catch (error) {
429
+ console.error('[Main] Failed to shutdown Memory Service:', error);
430
+ }
431
+ if (dbManager) {
432
+ dbManager.close();
433
+ }
434
+ if (agentDaemon) {
435
+ agentDaemon.shutdown();
436
+ }
437
+ });
438
+ // Handle folder selection
439
+ electron_1.ipcMain.handle('dialog:selectFolder', async () => {
440
+ const result = await electron_1.dialog.showOpenDialog({
441
+ properties: ['openDirectory'],
442
+ title: 'Select Workspace Folder',
443
+ });
444
+ if (!result.canceled && result.filePaths.length > 0) {
445
+ return result.filePaths[0];
446
+ }
447
+ return null;
448
+ });