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,2845 @@
1
+ import { contextBridge, ipcRenderer } from 'electron';
2
+
3
+ // IPC Channel names - inlined to avoid require() issues in sandboxed preload
4
+ const IPC_CHANNELS = {
5
+ TASK_CREATE: 'task:create',
6
+ TASK_GET: 'task:get',
7
+ TASK_LIST: 'task:list',
8
+ TASK_CANCEL: 'task:cancel',
9
+ TASK_PAUSE: 'task:pause',
10
+ TASK_RESUME: 'task:resume',
11
+ TASK_RENAME: 'task:rename',
12
+ TASK_DELETE: 'task:delete',
13
+ TASK_EVENT: 'task:event',
14
+ TASK_EVENTS: 'task:events',
15
+ TASK_SEND_MESSAGE: 'task:sendMessage',
16
+ TASK_SEND_STDIN: 'task:sendStdin',
17
+ TASK_KILL_COMMAND: 'task:killCommand',
18
+ WORKSPACE_SELECT: 'workspace:select',
19
+ WORKSPACE_LIST: 'workspace:list',
20
+ WORKSPACE_CREATE: 'workspace:create',
21
+ WORKSPACE_UPDATE_PERMISSIONS: 'workspace:updatePermissions',
22
+ WORKSPACE_GET_TEMP: 'workspace:getTemp',
23
+ APPROVAL_RESPOND: 'approval:respond',
24
+ ARTIFACT_LIST: 'artifact:list',
25
+ ARTIFACT_PREVIEW: 'artifact:preview',
26
+ SKILL_LIST: 'skill:list',
27
+ SKILL_GET: 'skill:get',
28
+ LLM_GET_SETTINGS: 'llm:getSettings',
29
+ LLM_SAVE_SETTINGS: 'llm:saveSettings',
30
+ LLM_TEST_PROVIDER: 'llm:testProvider',
31
+ LLM_GET_MODELS: 'llm:getModels',
32
+ LLM_GET_CONFIG_STATUS: 'llm:getConfigStatus',
33
+ LLM_SET_MODEL: 'llm:setModel',
34
+ LLM_GET_OLLAMA_MODELS: 'llm:getOllamaModels',
35
+ LLM_GET_GEMINI_MODELS: 'llm:getGeminiModels',
36
+ LLM_GET_OPENROUTER_MODELS: 'llm:getOpenRouterModels',
37
+ LLM_GET_OPENAI_MODELS: 'llm:getOpenAIModels',
38
+ LLM_OPENAI_OAUTH_START: 'llm:openaiOAuthStart',
39
+ LLM_OPENAI_OAUTH_LOGOUT: 'llm:openaiOAuthLogout',
40
+ LLM_GET_BEDROCK_MODELS: 'llm:getBedrockModels',
41
+ // Gateway / Channels
42
+ GATEWAY_GET_CHANNELS: 'gateway:getChannels',
43
+ GATEWAY_ADD_CHANNEL: 'gateway:addChannel',
44
+ GATEWAY_UPDATE_CHANNEL: 'gateway:updateChannel',
45
+ GATEWAY_REMOVE_CHANNEL: 'gateway:removeChannel',
46
+ GATEWAY_ENABLE_CHANNEL: 'gateway:enableChannel',
47
+ GATEWAY_DISABLE_CHANNEL: 'gateway:disableChannel',
48
+ GATEWAY_TEST_CHANNEL: 'gateway:testChannel',
49
+ GATEWAY_GET_USERS: 'gateway:getUsers',
50
+ GATEWAY_GRANT_ACCESS: 'gateway:grantAccess',
51
+ GATEWAY_REVOKE_ACCESS: 'gateway:revokeAccess',
52
+ GATEWAY_GENERATE_PAIRING: 'gateway:generatePairing',
53
+ // Search Settings
54
+ SEARCH_GET_SETTINGS: 'search:getSettings',
55
+ SEARCH_SAVE_SETTINGS: 'search:saveSettings',
56
+ SEARCH_GET_CONFIG_STATUS: 'search:getConfigStatus',
57
+ SEARCH_TEST_PROVIDER: 'search:testProvider',
58
+ // X/Twitter Settings
59
+ X_GET_SETTINGS: 'x:getSettings',
60
+ X_SAVE_SETTINGS: 'x:saveSettings',
61
+ X_TEST_CONNECTION: 'x:testConnection',
62
+ X_GET_STATUS: 'x:getStatus',
63
+ // App Updates
64
+ APP_CHECK_UPDATES: 'app:checkUpdates',
65
+ APP_DOWNLOAD_UPDATE: 'app:downloadUpdate',
66
+ APP_INSTALL_UPDATE: 'app:installUpdate',
67
+ APP_GET_VERSION: 'app:getVersion',
68
+ APP_UPDATE_AVAILABLE: 'app:updateAvailable',
69
+ APP_UPDATE_PROGRESS: 'app:updateProgress',
70
+ APP_UPDATE_DOWNLOADED: 'app:updateDownloaded',
71
+ APP_UPDATE_ERROR: 'app:updateError',
72
+ // Guardrails
73
+ GUARDRAIL_GET_SETTINGS: 'guardrail:getSettings',
74
+ GUARDRAIL_SAVE_SETTINGS: 'guardrail:saveSettings',
75
+ GUARDRAIL_GET_DEFAULTS: 'guardrail:getDefaults',
76
+ // Appearance
77
+ APPEARANCE_GET_SETTINGS: 'appearance:getSettings',
78
+ APPEARANCE_SAVE_SETTINGS: 'appearance:saveSettings',
79
+ // Agent Personality
80
+ PERSONALITY_GET_SETTINGS: 'personality:getSettings',
81
+ PERSONALITY_SAVE_SETTINGS: 'personality:saveSettings',
82
+ PERSONALITY_GET_DEFINITIONS: 'personality:getDefinitions',
83
+ PERSONALITY_GET_PERSONAS: 'personality:getPersonas',
84
+ PERSONALITY_GET_RELATIONSHIP_STATS: 'personality:getRelationshipStats',
85
+ PERSONALITY_SET_ACTIVE: 'personality:setActive',
86
+ PERSONALITY_SET_PERSONA: 'personality:setPersona',
87
+ PERSONALITY_RESET: 'personality:reset',
88
+ PERSONALITY_SETTINGS_CHANGED: 'personality:settingsChanged',
89
+ // Task Queue
90
+ QUEUE_GET_STATUS: 'queue:getStatus',
91
+ QUEUE_GET_SETTINGS: 'queue:getSettings',
92
+ QUEUE_SAVE_SETTINGS: 'queue:saveSettings',
93
+ QUEUE_CLEAR: 'queue:clear',
94
+ QUEUE_UPDATE: 'queue:update',
95
+ // Custom User Skills
96
+ CUSTOM_SKILL_LIST: 'customSkill:list',
97
+ CUSTOM_SKILL_LIST_TASKS: 'customSkill:listTasks',
98
+ CUSTOM_SKILL_LIST_GUIDELINES: 'customSkill:listGuidelines',
99
+ CUSTOM_SKILL_GET: 'customSkill:get',
100
+ CUSTOM_SKILL_CREATE: 'customSkill:create',
101
+ CUSTOM_SKILL_UPDATE: 'customSkill:update',
102
+ CUSTOM_SKILL_DELETE: 'customSkill:delete',
103
+ CUSTOM_SKILL_RELOAD: 'customSkill:reload',
104
+ CUSTOM_SKILL_OPEN_FOLDER: 'customSkill:openFolder',
105
+ // Skill Registry (SkillHub)
106
+ SKILL_REGISTRY_SEARCH: 'skillRegistry:search',
107
+ SKILL_REGISTRY_GET_DETAILS: 'skillRegistry:getDetails',
108
+ SKILL_REGISTRY_INSTALL: 'skillRegistry:install',
109
+ SKILL_REGISTRY_UPDATE: 'skillRegistry:update',
110
+ SKILL_REGISTRY_UPDATE_ALL: 'skillRegistry:updateAll',
111
+ SKILL_REGISTRY_UNINSTALL: 'skillRegistry:uninstall',
112
+ SKILL_REGISTRY_LIST_MANAGED: 'skillRegistry:listManaged',
113
+ SKILL_REGISTRY_CHECK_UPDATES: 'skillRegistry:checkUpdates',
114
+ SKILL_REGISTRY_GET_STATUS: 'skillRegistry:getStatus',
115
+ SKILL_REGISTRY_GET_ELIGIBLE: 'skillRegistry:getEligible',
116
+ // MCP (Model Context Protocol)
117
+ MCP_GET_SETTINGS: 'mcp:getSettings',
118
+ MCP_SAVE_SETTINGS: 'mcp:saveSettings',
119
+ MCP_ADD_SERVER: 'mcp:addServer',
120
+ MCP_UPDATE_SERVER: 'mcp:updateServer',
121
+ MCP_REMOVE_SERVER: 'mcp:removeServer',
122
+ MCP_CONNECT_SERVER: 'mcp:connectServer',
123
+ MCP_DISCONNECT_SERVER: 'mcp:disconnectServer',
124
+ MCP_GET_STATUS: 'mcp:getStatus',
125
+ MCP_GET_SERVER_STATUS: 'mcp:getServerStatus',
126
+ MCP_GET_ALL_TOOLS: 'mcp:getAllTools',
127
+ MCP_GET_SERVER_TOOLS: 'mcp:getServerTools',
128
+ MCP_TEST_SERVER: 'mcp:testServer',
129
+ MCP_SERVER_STATUS_CHANGE: 'mcp:serverStatusChange',
130
+ // MCP Registry
131
+ MCP_REGISTRY_FETCH: 'mcp:registryFetch',
132
+ MCP_REGISTRY_SEARCH: 'mcp:registrySearch',
133
+ MCP_REGISTRY_INSTALL: 'mcp:registryInstall',
134
+ MCP_REGISTRY_UNINSTALL: 'mcp:registryUninstall',
135
+ MCP_REGISTRY_CHECK_UPDATES: 'mcp:registryCheckUpdates',
136
+ MCP_REGISTRY_UPDATE_SERVER: 'mcp:registryUpdateServer',
137
+ // MCP Host
138
+ MCP_HOST_START: 'mcp:hostStart',
139
+ MCP_HOST_STOP: 'mcp:hostStop',
140
+ MCP_HOST_GET_STATUS: 'mcp:hostGetStatus',
141
+ // Built-in Tools Settings
142
+ BUILTIN_TOOLS_GET_SETTINGS: 'builtinTools:getSettings',
143
+ BUILTIN_TOOLS_SAVE_SETTINGS: 'builtinTools:saveSettings',
144
+ BUILTIN_TOOLS_GET_CATEGORIES: 'builtinTools:getCategories',
145
+ // Tray (Menu Bar)
146
+ TRAY_GET_SETTINGS: 'tray:getSettings',
147
+ TRAY_SAVE_SETTINGS: 'tray:saveSettings',
148
+ TRAY_NEW_TASK: 'tray:newTask',
149
+ TRAY_SELECT_WORKSPACE: 'tray:selectWorkspace',
150
+ TRAY_OPEN_SETTINGS: 'tray:openSettings',
151
+ TRAY_OPEN_ABOUT: 'tray:openAbout',
152
+ TRAY_CHECK_UPDATES: 'tray:checkUpdates',
153
+ TRAY_QUICK_TASK: 'tray:quick-task',
154
+ // Quick Input
155
+ QUICK_INPUT_SUBMIT: 'quick-input:submit',
156
+ QUICK_INPUT_CLOSE: 'quick-input:close',
157
+ // Cron (Scheduled Tasks)
158
+ CRON_GET_STATUS: 'cron:getStatus',
159
+ CRON_LIST_JOBS: 'cron:listJobs',
160
+ CRON_GET_JOB: 'cron:getJob',
161
+ CRON_ADD_JOB: 'cron:addJob',
162
+ CRON_UPDATE_JOB: 'cron:updateJob',
163
+ CRON_REMOVE_JOB: 'cron:removeJob',
164
+ CRON_RUN_JOB: 'cron:runJob',
165
+ CRON_EVENT: 'cron:event',
166
+ // Notifications
167
+ NOTIFICATION_LIST: 'notification:list',
168
+ NOTIFICATION_ADD: 'notification:add',
169
+ NOTIFICATION_MARK_READ: 'notification:markRead',
170
+ NOTIFICATION_MARK_ALL_READ: 'notification:markAllRead',
171
+ NOTIFICATION_DELETE: 'notification:delete',
172
+ NOTIFICATION_DELETE_ALL: 'notification:deleteAll',
173
+ NOTIFICATION_EVENT: 'notification:event',
174
+ // Hooks (Webhooks & Gmail Pub/Sub)
175
+ HOOKS_GET_SETTINGS: 'hooks:getSettings',
176
+ HOOKS_SAVE_SETTINGS: 'hooks:saveSettings',
177
+ HOOKS_ENABLE: 'hooks:enable',
178
+ HOOKS_DISABLE: 'hooks:disable',
179
+ HOOKS_REGENERATE_TOKEN: 'hooks:regenerateToken',
180
+ HOOKS_GET_STATUS: 'hooks:getStatus',
181
+ HOOKS_ADD_MAPPING: 'hooks:addMapping',
182
+ HOOKS_REMOVE_MAPPING: 'hooks:removeMapping',
183
+ HOOKS_CONFIGURE_GMAIL: 'hooks:configureGmail',
184
+ HOOKS_GET_GMAIL_STATUS: 'hooks:getGmailStatus',
185
+ HOOKS_START_GMAIL_WATCHER: 'hooks:startGmailWatcher',
186
+ HOOKS_STOP_GMAIL_WATCHER: 'hooks:stopGmailWatcher',
187
+ HOOKS_EVENT: 'hooks:event',
188
+ // Control Plane (WebSocket Gateway)
189
+ CONTROL_PLANE_GET_SETTINGS: 'controlPlane:getSettings',
190
+ CONTROL_PLANE_SAVE_SETTINGS: 'controlPlane:saveSettings',
191
+ CONTROL_PLANE_ENABLE: 'controlPlane:enable',
192
+ CONTROL_PLANE_DISABLE: 'controlPlane:disable',
193
+ CONTROL_PLANE_START: 'controlPlane:start',
194
+ CONTROL_PLANE_STOP: 'controlPlane:stop',
195
+ CONTROL_PLANE_GET_STATUS: 'controlPlane:getStatus',
196
+ CONTROL_PLANE_REGENERATE_TOKEN: 'controlPlane:regenerateToken',
197
+ CONTROL_PLANE_EVENT: 'controlPlane:event',
198
+ // Tailscale
199
+ TAILSCALE_GET_STATUS: 'tailscale:getStatus',
200
+ TAILSCALE_CHECK_AVAILABILITY: 'tailscale:checkAvailability',
201
+ TAILSCALE_SET_MODE: 'tailscale:setMode',
202
+ // Remote Gateway (connecting to external Control Plane)
203
+ REMOTE_GATEWAY_CONNECT: 'remoteGateway:connect',
204
+ REMOTE_GATEWAY_DISCONNECT: 'remoteGateway:disconnect',
205
+ REMOTE_GATEWAY_GET_STATUS: 'remoteGateway:getStatus',
206
+ REMOTE_GATEWAY_SAVE_CONFIG: 'remoteGateway:saveConfig',
207
+ REMOTE_GATEWAY_TEST_CONNECTION: 'remoteGateway:testConnection',
208
+ REMOTE_GATEWAY_EVENT: 'remoteGateway:event',
209
+ // SSH Tunnel (for Remote Gateway connection)
210
+ SSH_TUNNEL_CONNECT: 'sshTunnel:connect',
211
+ SSH_TUNNEL_DISCONNECT: 'sshTunnel:disconnect',
212
+ SSH_TUNNEL_GET_STATUS: 'sshTunnel:getStatus',
213
+ SSH_TUNNEL_SAVE_CONFIG: 'sshTunnel:saveConfig',
214
+ SSH_TUNNEL_TEST_CONNECTION: 'sshTunnel:testConnection',
215
+ SSH_TUNNEL_EVENT: 'sshTunnel:event',
216
+ // Live Canvas (Agent-driven visual workspace)
217
+ CANVAS_CREATE: 'canvas:create',
218
+ CANVAS_GET_SESSION: 'canvas:getSession',
219
+ CANVAS_LIST_SESSIONS: 'canvas:listSessions',
220
+ CANVAS_SHOW: 'canvas:show',
221
+ CANVAS_HIDE: 'canvas:hide',
222
+ CANVAS_CLOSE: 'canvas:close',
223
+ CANVAS_PUSH: 'canvas:push',
224
+ CANVAS_EVAL: 'canvas:eval',
225
+ CANVAS_SNAPSHOT: 'canvas:snapshot',
226
+ CANVAS_A2UI_ACTION: 'canvas:a2uiAction',
227
+ CANVAS_EVENT: 'canvas:event',
228
+ CANVAS_EXPORT_HTML: 'canvas:exportHTML',
229
+ CANVAS_EXPORT_TO_FOLDER: 'canvas:exportToFolder',
230
+ CANVAS_OPEN_IN_BROWSER: 'canvas:openInBrowser',
231
+ CANVAS_GET_SESSION_DIR: 'canvas:getSessionDir',
232
+ // Mobile Companion Nodes
233
+ NODE_LIST: 'node:list',
234
+ NODE_GET: 'node:get',
235
+ NODE_INVOKE: 'node:invoke',
236
+ NODE_EVENT: 'node:event',
237
+ // Memory System
238
+ MEMORY_GET_SETTINGS: 'memory:getSettings',
239
+ MEMORY_SAVE_SETTINGS: 'memory:saveSettings',
240
+ MEMORY_SEARCH: 'memory:search',
241
+ MEMORY_GET_TIMELINE: 'memory:getTimeline',
242
+ MEMORY_GET_DETAILS: 'memory:getDetails',
243
+ MEMORY_GET_RECENT: 'memory:getRecent',
244
+ MEMORY_GET_STATS: 'memory:getStats',
245
+ MEMORY_CLEAR: 'memory:clear',
246
+ MEMORY_EVENT: 'memory:event',
247
+
248
+ // Migration Status (for showing one-time notifications after app rename)
249
+ MIGRATION_GET_STATUS: 'migration:getStatus',
250
+ MIGRATION_DISMISS_NOTIFICATION: 'migration:dismissNotification',
251
+
252
+ // Extensions / Plugins
253
+ EXTENSIONS_LIST: 'extensions:list',
254
+ EXTENSIONS_GET: 'extensions:get',
255
+ EXTENSIONS_ENABLE: 'extensions:enable',
256
+ EXTENSIONS_DISABLE: 'extensions:disable',
257
+ EXTENSIONS_RELOAD: 'extensions:reload',
258
+ EXTENSIONS_GET_CONFIG: 'extensions:getConfig',
259
+ EXTENSIONS_SET_CONFIG: 'extensions:setConfig',
260
+ EXTENSIONS_DISCOVER: 'extensions:discover',
261
+
262
+ // Webhook Tunnel
263
+ TUNNEL_GET_STATUS: 'tunnel:getStatus',
264
+ TUNNEL_START: 'tunnel:start',
265
+ TUNNEL_STOP: 'tunnel:stop',
266
+ // Agent Roles (Agent Squad)
267
+ AGENT_ROLE_LIST: 'agentRole:list',
268
+ AGENT_ROLE_GET: 'agentRole:get',
269
+ AGENT_ROLE_CREATE: 'agentRole:create',
270
+ AGENT_ROLE_UPDATE: 'agentRole:update',
271
+ AGENT_ROLE_DELETE: 'agentRole:delete',
272
+ AGENT_ROLE_ASSIGN_TO_TASK: 'agentRole:assignToTask',
273
+ AGENT_ROLE_GET_DEFAULTS: 'agentRole:getDefaults',
274
+ AGENT_ROLE_SEED_DEFAULTS: 'agentRole:seedDefaults',
275
+ AGENT_ROLE_SYNC_DEFAULTS: 'agentRole:syncDefaults',
276
+ // Activity Feed
277
+ ACTIVITY_LIST: 'activity:list',
278
+ ACTIVITY_CREATE: 'activity:create',
279
+ ACTIVITY_MARK_READ: 'activity:markRead',
280
+ ACTIVITY_MARK_ALL_READ: 'activity:markAllRead',
281
+ ACTIVITY_PIN: 'activity:pin',
282
+ ACTIVITY_DELETE: 'activity:delete',
283
+ ACTIVITY_EVENT: 'activity:event',
284
+ // @Mention System
285
+ MENTION_CREATE: 'mention:create',
286
+ MENTION_LIST: 'mention:list',
287
+ MENTION_ACKNOWLEDGE: 'mention:acknowledge',
288
+ MENTION_COMPLETE: 'mention:complete',
289
+ MENTION_DISMISS: 'mention:dismiss',
290
+ MENTION_EVENT: 'mention:event',
291
+ // Task Board
292
+ TASK_MOVE_COLUMN: 'task:moveColumn',
293
+ TASK_SET_PRIORITY: 'task:setPriority',
294
+ TASK_SET_DUE_DATE: 'task:setDueDate',
295
+ TASK_SET_ESTIMATE: 'task:setEstimate',
296
+ TASK_ADD_LABEL: 'task:addLabel',
297
+ TASK_REMOVE_LABEL: 'task:removeLabel',
298
+ TASK_BOARD_EVENT: 'taskBoard:event',
299
+ // Task Labels
300
+ TASK_LABEL_LIST: 'taskLabel:list',
301
+ TASK_LABEL_CREATE: 'taskLabel:create',
302
+ TASK_LABEL_UPDATE: 'taskLabel:update',
303
+ TASK_LABEL_DELETE: 'taskLabel:delete',
304
+ // Agent Working State
305
+ WORKING_STATE_GET: 'workingState:get',
306
+ WORKING_STATE_GET_CURRENT: 'workingState:getCurrent',
307
+ WORKING_STATE_UPDATE: 'workingState:update',
308
+ WORKING_STATE_HISTORY: 'workingState:history',
309
+ WORKING_STATE_RESTORE: 'workingState:restore',
310
+ WORKING_STATE_DELETE: 'workingState:delete',
311
+ WORKING_STATE_LIST_FOR_TASK: 'workingState:listForTask',
312
+ // Context Policy (per-context security DM vs group)
313
+ CONTEXT_POLICY_GET: 'contextPolicy:get',
314
+ CONTEXT_POLICY_GET_FOR_CHAT: 'contextPolicy:getForChat',
315
+ CONTEXT_POLICY_LIST: 'contextPolicy:list',
316
+ CONTEXT_POLICY_UPDATE: 'contextPolicy:update',
317
+ CONTEXT_POLICY_DELETE: 'contextPolicy:delete',
318
+ CONTEXT_POLICY_CREATE_DEFAULTS: 'contextPolicy:createDefaults',
319
+ CONTEXT_POLICY_IS_TOOL_ALLOWED: 'contextPolicy:isToolAllowed',
320
+ // Voice Mode
321
+ VOICE_GET_SETTINGS: 'voice:getSettings',
322
+ VOICE_SAVE_SETTINGS: 'voice:saveSettings',
323
+ VOICE_GET_STATE: 'voice:getState',
324
+ VOICE_SPEAK: 'voice:speak',
325
+ VOICE_STOP_SPEAKING: 'voice:stopSpeaking',
326
+ VOICE_TRANSCRIBE: 'voice:transcribe',
327
+ VOICE_GET_ELEVENLABS_VOICES: 'voice:getElevenLabsVoices',
328
+ VOICE_TEST_ELEVENLABS: 'voice:testElevenLabs',
329
+ VOICE_TEST_OPENAI: 'voice:testOpenAI',
330
+ VOICE_TEST_AZURE: 'voice:testAzure',
331
+ VOICE_EVENT: 'voice:event',
332
+ // Mission Control - Heartbeat
333
+ HEARTBEAT_GET_CONFIG: 'heartbeat:getConfig',
334
+ HEARTBEAT_UPDATE_CONFIG: 'heartbeat:updateConfig',
335
+ HEARTBEAT_TRIGGER: 'heartbeat:trigger',
336
+ HEARTBEAT_GET_STATUS: 'heartbeat:getStatus',
337
+ HEARTBEAT_GET_ALL_STATUS: 'heartbeat:getAllStatus',
338
+ HEARTBEAT_EVENT: 'heartbeat:event',
339
+ // Mission Control - Task Subscriptions
340
+ SUBSCRIPTION_LIST: 'subscription:list',
341
+ SUBSCRIPTION_ADD: 'subscription:add',
342
+ SUBSCRIPTION_REMOVE: 'subscription:remove',
343
+ SUBSCRIPTION_GET_SUBSCRIBERS: 'subscription:getSubscribers',
344
+ SUBSCRIPTION_GET_FOR_AGENT: 'subscription:getForAgent',
345
+ SUBSCRIPTION_EVENT: 'subscription:event',
346
+ // Mission Control - Standup Reports
347
+ STANDUP_GENERATE: 'standup:generate',
348
+ STANDUP_GET_LATEST: 'standup:getLatest',
349
+ STANDUP_LIST: 'standup:list',
350
+ STANDUP_DELIVER: 'standup:deliver',
351
+ } as const;
352
+
353
+ // Mobile Companion Node types (inlined for sandboxed preload)
354
+ type NodePlatform = 'ios' | 'android' | 'macos';
355
+ type NodeCapabilityType = 'camera' | 'location' | 'screen' | 'sms' | 'voice' | 'canvas' | 'system';
356
+
357
+ interface NodeInfo {
358
+ id: string;
359
+ displayName: string;
360
+ platform: NodePlatform;
361
+ version: string;
362
+ deviceId?: string;
363
+ modelIdentifier?: string;
364
+ capabilities: NodeCapabilityType[];
365
+ commands: string[];
366
+ permissions: Record<string, boolean>;
367
+ connectedAt: number;
368
+ lastActivityAt: number;
369
+ isForeground?: boolean;
370
+ }
371
+
372
+ interface NodeEvent {
373
+ type: 'connected' | 'disconnected' | 'capabilities_changed' | 'foreground_changed';
374
+ nodeId: string;
375
+ node?: NodeInfo;
376
+ timestamp: number;
377
+ }
378
+
379
+ // Custom Skill types (inlined for sandboxed preload)
380
+ interface SkillParameter {
381
+ name: string;
382
+ type: 'string' | 'number' | 'boolean' | 'select';
383
+ description: string;
384
+ required?: boolean;
385
+ default?: string | number | boolean;
386
+ options?: string[];
387
+ }
388
+
389
+ type SkillSource = 'bundled' | 'managed' | 'workspace';
390
+
391
+ interface SkillRequirements {
392
+ bins?: string[];
393
+ anyBins?: string[];
394
+ env?: string[];
395
+ config?: string[];
396
+ os?: ('darwin' | 'linux' | 'win32')[];
397
+ }
398
+
399
+ interface SkillMetadata {
400
+ version?: string;
401
+ author?: string;
402
+ homepage?: string;
403
+ repository?: string;
404
+ license?: string;
405
+ tags?: string[];
406
+ primaryEnv?: string;
407
+ }
408
+
409
+ interface CustomSkill {
410
+ id: string;
411
+ name: string;
412
+ description: string;
413
+ icon: string;
414
+ prompt: string;
415
+ parameters?: SkillParameter[];
416
+ category?: string;
417
+ enabled?: boolean;
418
+ filePath?: string;
419
+ source?: SkillSource;
420
+ requires?: SkillRequirements;
421
+ metadata?: SkillMetadata;
422
+ }
423
+
424
+ // Skill Registry types (inlined for sandboxed preload)
425
+ interface SkillRegistryEntry {
426
+ id: string;
427
+ name: string;
428
+ description: string;
429
+ version: string;
430
+ author?: string;
431
+ downloads?: number;
432
+ rating?: number;
433
+ tags?: string[];
434
+ icon?: string;
435
+ category?: string;
436
+ updatedAt?: string;
437
+ homepage?: string;
438
+ }
439
+
440
+ interface SkillSearchResult {
441
+ query: string;
442
+ total: number;
443
+ page: number;
444
+ pageSize: number;
445
+ results: SkillRegistryEntry[];
446
+ }
447
+
448
+ interface SkillStatusEntry extends CustomSkill {
449
+ eligible: boolean;
450
+ disabled: boolean;
451
+ blockedByAllowlist: boolean;
452
+ requirements: {
453
+ bins: string[];
454
+ anyBins: string[];
455
+ env: string[];
456
+ config: string[];
457
+ os: string[];
458
+ };
459
+ missing: {
460
+ bins: string[];
461
+ anyBins: string[];
462
+ env: string[];
463
+ config: string[];
464
+ os: string[];
465
+ };
466
+ }
467
+
468
+ interface SkillStatusReport {
469
+ workspaceDir: string;
470
+ managedSkillsDir: string;
471
+ bundledSkillsDir: string;
472
+ skills: SkillStatusEntry[];
473
+ summary: {
474
+ total: number;
475
+ eligible: number;
476
+ disabled: number;
477
+ missingRequirements: number;
478
+ };
479
+ }
480
+
481
+ // MCP types (inlined for sandboxed preload)
482
+ type MCPTransportType = 'stdio' | 'sse' | 'websocket';
483
+ type MCPConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'error';
484
+
485
+ interface MCPServerConfig {
486
+ id: string;
487
+ name: string;
488
+ description?: string;
489
+ enabled: boolean;
490
+ transport: MCPTransportType;
491
+ command?: string;
492
+ args?: string[];
493
+ env?: Record<string, string>;
494
+ cwd?: string;
495
+ url?: string;
496
+ headers?: Record<string, string>;
497
+ connectionTimeout?: number;
498
+ requestTimeout?: number;
499
+ }
500
+
501
+ interface MCPTool {
502
+ name: string;
503
+ description?: string;
504
+ inputSchema: {
505
+ type: 'object';
506
+ properties?: Record<string, any>;
507
+ required?: string[];
508
+ };
509
+ }
510
+
511
+ interface MCPServerStatus {
512
+ id: string;
513
+ name: string;
514
+ status: MCPConnectionStatus;
515
+ error?: string;
516
+ tools: MCPTool[];
517
+ lastPing?: number;
518
+ }
519
+
520
+ interface MCPSettings {
521
+ servers: MCPServerConfig[];
522
+ autoConnect: boolean;
523
+ toolNamePrefix: string;
524
+ maxReconnectAttempts: number;
525
+ reconnectDelayMs: number;
526
+ registryEnabled: boolean;
527
+ registryUrl?: string;
528
+ hostEnabled: boolean;
529
+ hostPort?: number;
530
+ }
531
+
532
+ interface MCPRegistryEntry {
533
+ id: string;
534
+ name: string;
535
+ description: string;
536
+ version: string;
537
+ author: string;
538
+ installMethod: 'npm' | 'pip' | 'binary' | 'docker';
539
+ installCommand?: string;
540
+ transport: MCPTransportType;
541
+ defaultCommand?: string;
542
+ tools: Array<{ name: string; description: string }>;
543
+ tags: string[];
544
+ verified: boolean;
545
+ }
546
+
547
+ interface MCPRegistry {
548
+ version: string;
549
+ lastUpdated: string;
550
+ servers: MCPRegistryEntry[];
551
+ }
552
+
553
+ interface MCPUpdateInfo {
554
+ serverId: string;
555
+ currentVersion: string;
556
+ latestVersion: string;
557
+ registryEntry: MCPRegistryEntry;
558
+ }
559
+
560
+ // Canvas types (inlined for sandboxed preload)
561
+ type CanvasSessionStatus = 'active' | 'paused' | 'closed';
562
+
563
+ interface CanvasSession {
564
+ id: string;
565
+ taskId: string;
566
+ workspaceId: string;
567
+ sessionDir: string;
568
+ status: CanvasSessionStatus;
569
+ title?: string;
570
+ createdAt: number;
571
+ lastUpdatedAt: number;
572
+ }
573
+
574
+ interface CanvasA2UIAction {
575
+ actionName: string;
576
+ sessionId: string;
577
+ componentId?: string;
578
+ context?: Record<string, unknown>;
579
+ timestamp: number;
580
+ }
581
+
582
+ interface CanvasEvent {
583
+ type: 'session_created' | 'session_updated' | 'session_closed' | 'content_pushed' | 'a2ui_action';
584
+ sessionId: string;
585
+ taskId: string;
586
+ session?: CanvasSession;
587
+ action?: CanvasA2UIAction;
588
+ timestamp: number;
589
+ }
590
+
591
+ // Built-in Tools Settings types (inlined for sandboxed preload)
592
+ interface ToolCategoryConfig {
593
+ enabled: boolean;
594
+ priority: 'high' | 'normal' | 'low';
595
+ description?: string;
596
+ }
597
+
598
+ interface BuiltinToolsSettings {
599
+ categories: {
600
+ browser: ToolCategoryConfig;
601
+ search: ToolCategoryConfig;
602
+ system: ToolCategoryConfig;
603
+ file: ToolCategoryConfig;
604
+ skill: ToolCategoryConfig;
605
+ shell: ToolCategoryConfig;
606
+ image: ToolCategoryConfig;
607
+ };
608
+ toolOverrides: Record<string, { enabled: boolean; priority?: 'high' | 'normal' | 'low' }>;
609
+ version: string;
610
+ }
611
+
612
+ // Tray (Menu Bar) Settings (inlined for sandboxed preload)
613
+ interface TraySettings {
614
+ enabled: boolean;
615
+ showDockIcon: boolean;
616
+ startMinimized: boolean;
617
+ closeToTray: boolean;
618
+ showNotifications: boolean;
619
+ }
620
+
621
+ // Cron (Scheduled Tasks) Types (inlined for sandboxed preload)
622
+ type CronSchedule =
623
+ | { kind: 'at'; atMs: number }
624
+ | { kind: 'every'; everyMs: number; anchorMs?: number }
625
+ | { kind: 'cron'; expr: string; tz?: string };
626
+
627
+ type CronJobStatus = 'ok' | 'error' | 'skipped';
628
+
629
+ interface CronRunHistoryEntry {
630
+ runAtMs: number;
631
+ durationMs: number;
632
+ status: CronJobStatus;
633
+ error?: string;
634
+ taskId?: string;
635
+ }
636
+
637
+ interface CronJobState {
638
+ nextRunAtMs?: number;
639
+ runningAtMs?: number;
640
+ lastRunAtMs?: number;
641
+ lastStatus?: CronJobStatus;
642
+ lastError?: string;
643
+ lastDurationMs?: number;
644
+ lastTaskId?: string;
645
+ runHistory?: CronRunHistoryEntry[];
646
+ totalRuns?: number;
647
+ successfulRuns?: number;
648
+ failedRuns?: number;
649
+ }
650
+
651
+ interface CronDeliveryConfig {
652
+ enabled: boolean;
653
+ channelType?: 'telegram' | 'discord' | 'slack' | 'whatsapp';
654
+ channelId?: string;
655
+ deliverOnSuccess?: boolean;
656
+ deliverOnError?: boolean;
657
+ summaryOnly?: boolean;
658
+ }
659
+
660
+ interface CronJob {
661
+ id: string;
662
+ name: string;
663
+ description?: string;
664
+ enabled: boolean;
665
+ deleteAfterRun?: boolean;
666
+ createdAtMs: number;
667
+ updatedAtMs: number;
668
+ schedule: CronSchedule;
669
+ workspaceId: string;
670
+ taskPrompt: string;
671
+ taskTitle?: string;
672
+ timeoutMs?: number;
673
+ modelKey?: string;
674
+ maxHistoryEntries?: number;
675
+ delivery?: CronDeliveryConfig;
676
+ state: CronJobState;
677
+ }
678
+
679
+ interface CronJobCreate {
680
+ name: string;
681
+ description?: string;
682
+ enabled: boolean;
683
+ deleteAfterRun?: boolean;
684
+ schedule: CronSchedule;
685
+ workspaceId: string;
686
+ taskPrompt: string;
687
+ taskTitle?: string;
688
+ timeoutMs?: number;
689
+ modelKey?: string;
690
+ maxHistoryEntries?: number;
691
+ delivery?: CronDeliveryConfig;
692
+ }
693
+
694
+ interface CronJobPatch {
695
+ name?: string;
696
+ description?: string;
697
+ enabled?: boolean;
698
+ deleteAfterRun?: boolean;
699
+ schedule?: CronSchedule;
700
+ workspaceId?: string;
701
+ taskPrompt?: string;
702
+ taskTitle?: string;
703
+ timeoutMs?: number;
704
+ modelKey?: string;
705
+ maxHistoryEntries?: number;
706
+ delivery?: CronDeliveryConfig;
707
+ }
708
+
709
+ interface CronRunHistoryResult {
710
+ jobId: string;
711
+ jobName: string;
712
+ entries: CronRunHistoryEntry[];
713
+ totalRuns: number;
714
+ successfulRuns: number;
715
+ failedRuns: number;
716
+ }
717
+
718
+ interface CronWebhookStatus {
719
+ enabled: boolean;
720
+ host?: string;
721
+ port?: number;
722
+ }
723
+
724
+ interface CronStatusSummary {
725
+ enabled: boolean;
726
+ storePath: string;
727
+ jobCount: number;
728
+ enabledJobCount: number;
729
+ runningJobCount: number;
730
+ maxConcurrentRuns: number;
731
+ nextWakeAtMs: number | null;
732
+ webhook?: CronWebhookStatus;
733
+ }
734
+
735
+ interface CronEvent {
736
+ jobId: string;
737
+ action: 'added' | 'updated' | 'removed' | 'started' | 'finished';
738
+ runAtMs?: number;
739
+ durationMs?: number;
740
+ status?: CronJobStatus;
741
+ error?: string;
742
+ taskId?: string;
743
+ nextRunAtMs?: number;
744
+ }
745
+
746
+ // Notification Types (inlined for sandboxed preload)
747
+ type NotificationType = 'task_completed' | 'task_failed' | 'scheduled_task' | 'info' | 'warning' | 'error';
748
+
749
+ interface AppNotification {
750
+ id: string;
751
+ type: NotificationType;
752
+ title: string;
753
+ message: string;
754
+ read: boolean;
755
+ createdAt: number;
756
+ taskId?: string;
757
+ cronJobId?: string;
758
+ workspaceId?: string;
759
+ }
760
+
761
+ interface NotificationEvent {
762
+ type: 'added' | 'updated' | 'removed' | 'cleared';
763
+ notification?: AppNotification;
764
+ notifications?: AppNotification[];
765
+ }
766
+
767
+ // Memory System Types (inlined for sandboxed preload)
768
+ type MemoryType = 'observation' | 'decision' | 'error' | 'insight' | 'summary';
769
+ type PrivacyMode = 'normal' | 'strict' | 'disabled';
770
+
771
+ interface MemorySettings {
772
+ workspaceId: string;
773
+ enabled: boolean;
774
+ autoCapture: boolean;
775
+ compressionEnabled: boolean;
776
+ retentionDays: number;
777
+ maxStorageMb: number;
778
+ privacyMode: PrivacyMode;
779
+ excludedPatterns?: string[];
780
+ }
781
+
782
+ interface Memory {
783
+ id: string;
784
+ workspaceId: string;
785
+ taskId?: string;
786
+ type: MemoryType;
787
+ content: string;
788
+ summary?: string;
789
+ tokens: number;
790
+ isCompressed: boolean;
791
+ isPrivate: boolean;
792
+ createdAt: number;
793
+ updatedAt: number;
794
+ }
795
+
796
+ interface MemorySearchResult {
797
+ id: string;
798
+ snippet: string;
799
+ type: MemoryType;
800
+ relevanceScore: number;
801
+ createdAt: number;
802
+ taskId?: string;
803
+ }
804
+
805
+ interface MemoryTimelineEntry {
806
+ id: string;
807
+ content: string;
808
+ type: MemoryType;
809
+ createdAt: number;
810
+ taskId?: string;
811
+ }
812
+
813
+ interface MemoryStats {
814
+ count: number;
815
+ totalTokens: number;
816
+ compressedCount: number;
817
+ compressionRatio: number;
818
+ }
819
+
820
+ // Hooks types (inlined for sandboxed preload)
821
+ interface HooksSettings {
822
+ enabled: boolean;
823
+ token: string;
824
+ path: string;
825
+ maxBodyBytes: number;
826
+ port: number;
827
+ host: string;
828
+ presets: string[];
829
+ mappings: HookMapping[];
830
+ gmail?: GmailHooksConfig;
831
+ }
832
+
833
+ interface HookMapping {
834
+ id?: string;
835
+ match?: {
836
+ path?: string;
837
+ source?: string;
838
+ };
839
+ action?: 'wake' | 'agent';
840
+ wakeMode?: 'now' | 'next-heartbeat';
841
+ name?: string;
842
+ sessionKey?: string;
843
+ messageTemplate?: string;
844
+ textTemplate?: string;
845
+ deliver?: boolean;
846
+ channel?: 'telegram' | 'discord' | 'slack' | 'whatsapp' | 'imessage' | 'last';
847
+ to?: string;
848
+ model?: string;
849
+ thinking?: string;
850
+ timeoutSeconds?: number;
851
+ }
852
+
853
+ interface GmailHooksConfig {
854
+ account?: string;
855
+ label?: string;
856
+ topic?: string;
857
+ subscription?: string;
858
+ pushToken?: string;
859
+ hookUrl?: string;
860
+ includeBody?: boolean;
861
+ maxBytes?: number;
862
+ renewEveryMinutes?: number;
863
+ model?: string;
864
+ thinking?: string;
865
+ serve?: {
866
+ bind?: string;
867
+ port?: number;
868
+ path?: string;
869
+ };
870
+ tailscale?: {
871
+ mode?: 'off' | 'serve' | 'funnel';
872
+ path?: string;
873
+ target?: string;
874
+ };
875
+ }
876
+
877
+ interface HooksStatus {
878
+ enabled: boolean;
879
+ serverRunning: boolean;
880
+ serverAddress?: { host: string; port: number };
881
+ gmailWatcherRunning: boolean;
882
+ gmailAccount?: string;
883
+ gogAvailable: boolean;
884
+ }
885
+
886
+ interface GmailHooksStatus {
887
+ configured: boolean;
888
+ running: boolean;
889
+ account?: string;
890
+ topic?: string;
891
+ gogAvailable: boolean;
892
+ }
893
+
894
+ interface HooksEvent {
895
+ action: 'started' | 'stopped' | 'request' | 'error';
896
+ timestamp: number;
897
+ path?: string;
898
+ method?: string;
899
+ statusCode?: number;
900
+ error?: string;
901
+ }
902
+
903
+ // Control Plane types (inlined for sandboxed preload)
904
+ // NOTE: These types are intentionally duplicated from shared/types.ts because
905
+ // the preload script runs in a sandboxed context and cannot import from other modules.
906
+ // When updating these types, ensure shared/types.ts is also updated to stay in sync.
907
+ type TailscaleMode = 'off' | 'serve' | 'funnel';
908
+ type ControlPlaneConnectionMode = 'local' | 'remote';
909
+
910
+ interface ControlPlaneSettingsData {
911
+ enabled: boolean;
912
+ port: number;
913
+ host: string;
914
+ token: string;
915
+ handshakeTimeoutMs: number;
916
+ heartbeatIntervalMs: number;
917
+ maxPayloadBytes: number;
918
+ tailscale: {
919
+ mode: TailscaleMode;
920
+ resetOnExit: boolean;
921
+ };
922
+ connectionMode?: ControlPlaneConnectionMode;
923
+ remote?: RemoteGatewayConfig;
924
+ }
925
+
926
+ interface ControlPlaneClientInfo {
927
+ id: string;
928
+ remoteAddress: string;
929
+ deviceName?: string;
930
+ authenticated: boolean;
931
+ scopes: string[];
932
+ connectedAt: number;
933
+ lastActivityAt: number;
934
+ }
935
+
936
+ interface ControlPlaneStatus {
937
+ enabled: boolean;
938
+ running: boolean;
939
+ address?: {
940
+ host: string;
941
+ port: number;
942
+ wsUrl: string;
943
+ };
944
+ clients: {
945
+ total: number;
946
+ authenticated: number;
947
+ pending: number;
948
+ list: ControlPlaneClientInfo[];
949
+ };
950
+ tailscale: {
951
+ active: boolean;
952
+ mode?: TailscaleMode;
953
+ hostname?: string;
954
+ httpsUrl?: string;
955
+ wssUrl?: string;
956
+ };
957
+ }
958
+
959
+ interface ControlPlaneEvent {
960
+ action: 'started' | 'stopped' | 'client_connected' | 'client_disconnected' | 'client_authenticated' | 'request' | 'error';
961
+ timestamp: number;
962
+ clientId?: string;
963
+ method?: string;
964
+ error?: string;
965
+ details?: unknown;
966
+ }
967
+
968
+ interface TailscaleAvailability {
969
+ installed: boolean;
970
+ funnelAvailable: boolean;
971
+ hostname: string | null;
972
+ }
973
+
974
+ // Remote Gateway types
975
+ interface RemoteGatewayConfig {
976
+ url: string;
977
+ token: string;
978
+ tlsFingerprint?: string;
979
+ deviceName?: string;
980
+ autoReconnect?: boolean;
981
+ reconnectIntervalMs?: number;
982
+ maxReconnectAttempts?: number;
983
+ sshTunnel?: SSHTunnelConfig;
984
+ }
985
+
986
+ type RemoteGatewayConnectionState =
987
+ | 'disconnected'
988
+ | 'connecting'
989
+ | 'authenticating'
990
+ | 'connected'
991
+ | 'reconnecting'
992
+ | 'error';
993
+
994
+ interface RemoteGatewayStatus {
995
+ state: RemoteGatewayConnectionState;
996
+ url?: string;
997
+ connectedAt?: number;
998
+ clientId?: string;
999
+ scopes?: string[];
1000
+ error?: string;
1001
+ reconnectAttempts?: number;
1002
+ lastActivityAt?: number;
1003
+ }
1004
+
1005
+ interface RemoteGatewayEvent {
1006
+ type: 'stateChange' | 'event';
1007
+ state?: RemoteGatewayConnectionState;
1008
+ event?: string;
1009
+ payload?: unknown;
1010
+ error?: string;
1011
+ }
1012
+
1013
+ // SSH Tunnel types
1014
+ type SSHTunnelState =
1015
+ | 'disconnected'
1016
+ | 'connecting'
1017
+ | 'connected'
1018
+ | 'reconnecting'
1019
+ | 'error';
1020
+
1021
+ interface SSHTunnelConfig {
1022
+ enabled: boolean;
1023
+ host: string;
1024
+ sshPort: number;
1025
+ username: string;
1026
+ keyPath?: string;
1027
+ localPort: number;
1028
+ remotePort: number;
1029
+ remoteBindAddress?: string;
1030
+ autoReconnect?: boolean;
1031
+ reconnectDelayMs?: number;
1032
+ maxReconnectAttempts?: number;
1033
+ connectionTimeoutMs?: number;
1034
+ }
1035
+
1036
+ interface SSHTunnelStatus {
1037
+ state: SSHTunnelState;
1038
+ config?: Partial<SSHTunnelConfig>;
1039
+ connectedAt?: number;
1040
+ error?: string;
1041
+ reconnectAttempts?: number;
1042
+ pid?: number;
1043
+ localEndpoint?: string;
1044
+ }
1045
+
1046
+ interface SSHTunnelEvent {
1047
+ type: 'stateChange' | 'connected' | 'disconnected' | 'error';
1048
+ state?: SSHTunnelState;
1049
+ reason?: string;
1050
+ error?: string;
1051
+ }
1052
+
1053
+ // Agent Role (Agent Squad) types (inlined for sandboxed preload)
1054
+ type AgentCapability = 'code' | 'review' | 'research' | 'test' | 'document' | 'plan' | 'design' | 'analyze';
1055
+
1056
+ interface AgentToolRestrictions {
1057
+ allowedTools?: string[];
1058
+ deniedTools?: string[];
1059
+ }
1060
+
1061
+ type AgentAutonomyLevel = 'intern' | 'specialist' | 'lead';
1062
+
1063
+ interface AgentRoleData {
1064
+ id: string;
1065
+ name: string;
1066
+ displayName: string;
1067
+ description?: string;
1068
+ icon: string;
1069
+ color: string;
1070
+ personalityId?: string;
1071
+ modelKey?: string;
1072
+ providerType?: string;
1073
+ systemPrompt?: string;
1074
+ capabilities: AgentCapability[];
1075
+ toolRestrictions?: AgentToolRestrictions;
1076
+ isSystem: boolean;
1077
+ isActive: boolean;
1078
+ sortOrder: number;
1079
+ createdAt: number;
1080
+ updatedAt: number;
1081
+ // Mission Control fields
1082
+ autonomyLevel?: AgentAutonomyLevel;
1083
+ soul?: string;
1084
+ heartbeatEnabled?: boolean;
1085
+ heartbeatIntervalMinutes?: number;
1086
+ heartbeatStaggerOffset?: number;
1087
+ lastHeartbeatAt?: number;
1088
+ heartbeatStatus?: HeartbeatStatus;
1089
+ }
1090
+
1091
+ interface CreateAgentRoleRequest {
1092
+ name: string;
1093
+ displayName: string;
1094
+ description?: string;
1095
+ icon?: string;
1096
+ color?: string;
1097
+ personalityId?: string;
1098
+ modelKey?: string;
1099
+ providerType?: string;
1100
+ systemPrompt?: string;
1101
+ capabilities: AgentCapability[];
1102
+ toolRestrictions?: AgentToolRestrictions;
1103
+ // Mission Control fields
1104
+ autonomyLevel?: AgentAutonomyLevel;
1105
+ soul?: string;
1106
+ heartbeatEnabled?: boolean;
1107
+ heartbeatIntervalMinutes?: number;
1108
+ heartbeatStaggerOffset?: number;
1109
+ }
1110
+
1111
+ interface UpdateAgentRoleRequest {
1112
+ id: string;
1113
+ displayName?: string;
1114
+ description?: string;
1115
+ icon?: string;
1116
+ color?: string;
1117
+ personalityId?: string;
1118
+ modelKey?: string;
1119
+ providerType?: string;
1120
+ systemPrompt?: string;
1121
+ capabilities?: AgentCapability[];
1122
+ toolRestrictions?: AgentToolRestrictions;
1123
+ isActive?: boolean;
1124
+ sortOrder?: number;
1125
+ // Mission Control fields
1126
+ autonomyLevel?: AgentAutonomyLevel;
1127
+ soul?: string;
1128
+ heartbeatEnabled?: boolean;
1129
+ heartbeatIntervalMinutes?: number;
1130
+ heartbeatStaggerOffset?: number;
1131
+ }
1132
+
1133
+ // Activity Feed types (inlined for sandboxed preload)
1134
+ type ActivityActorType = 'agent' | 'user' | 'system';
1135
+ type ActivityType =
1136
+ | 'task_created'
1137
+ | 'task_started'
1138
+ | 'task_completed'
1139
+ | 'task_failed'
1140
+ | 'task_paused'
1141
+ | 'task_resumed'
1142
+ | 'comment'
1143
+ | 'file_created'
1144
+ | 'file_modified'
1145
+ | 'file_deleted'
1146
+ | 'command_executed'
1147
+ | 'tool_used'
1148
+ | 'mention'
1149
+ | 'agent_assigned'
1150
+ | 'error'
1151
+ | 'info';
1152
+
1153
+ interface ActivityData {
1154
+ id: string;
1155
+ workspaceId: string;
1156
+ taskId?: string;
1157
+ agentRoleId?: string;
1158
+ actorType: ActivityActorType;
1159
+ activityType: ActivityType;
1160
+ title: string;
1161
+ description?: string;
1162
+ metadata?: Record<string, unknown>;
1163
+ isRead: boolean;
1164
+ isPinned: boolean;
1165
+ createdAt: number;
1166
+ }
1167
+
1168
+ interface CreateActivityRequest {
1169
+ workspaceId: string;
1170
+ taskId?: string;
1171
+ agentRoleId?: string;
1172
+ actorType: ActivityActorType;
1173
+ activityType: ActivityType;
1174
+ title: string;
1175
+ description?: string;
1176
+ metadata?: Record<string, unknown>;
1177
+ }
1178
+
1179
+ interface ActivityListQuery {
1180
+ workspaceId: string;
1181
+ taskId?: string;
1182
+ agentRoleId?: string;
1183
+ activityType?: ActivityType | ActivityType[];
1184
+ actorType?: ActivityActorType;
1185
+ isRead?: boolean;
1186
+ isPinned?: boolean;
1187
+ limit?: number;
1188
+ offset?: number;
1189
+ }
1190
+
1191
+ interface ActivityEvent {
1192
+ type: 'created' | 'read' | 'all_read' | 'pinned' | 'deleted';
1193
+ activity?: ActivityData;
1194
+ id?: string;
1195
+ workspaceId?: string;
1196
+ }
1197
+
1198
+ // @Mention System types (inlined for sandboxed preload)
1199
+ type MentionType = 'request' | 'handoff' | 'review' | 'fyi';
1200
+ type MentionStatus = 'pending' | 'acknowledged' | 'completed' | 'dismissed';
1201
+
1202
+ interface MentionData {
1203
+ id: string;
1204
+ workspaceId: string;
1205
+ taskId: string;
1206
+ fromAgentRoleId?: string;
1207
+ toAgentRoleId: string;
1208
+ mentionType: MentionType;
1209
+ context?: string;
1210
+ status: MentionStatus;
1211
+ createdAt: number;
1212
+ acknowledgedAt?: number;
1213
+ completedAt?: number;
1214
+ }
1215
+
1216
+ interface CreateMentionRequest {
1217
+ workspaceId: string;
1218
+ taskId: string;
1219
+ fromAgentRoleId?: string;
1220
+ toAgentRoleId: string;
1221
+ mentionType: MentionType;
1222
+ context?: string;
1223
+ }
1224
+
1225
+ interface MentionListQuery {
1226
+ workspaceId?: string;
1227
+ taskId?: string;
1228
+ toAgentRoleId?: string;
1229
+ fromAgentRoleId?: string;
1230
+ status?: MentionStatus | MentionStatus[];
1231
+ limit?: number;
1232
+ offset?: number;
1233
+ }
1234
+
1235
+ interface MentionEvent {
1236
+ type: 'created' | 'acknowledged' | 'completed' | 'dismissed';
1237
+ mention?: MentionData;
1238
+ }
1239
+
1240
+ // Mission Control types (inlined for sandboxed preload)
1241
+ type HeartbeatStatus = 'idle' | 'running' | 'sleeping' | 'error';
1242
+
1243
+ interface HeartbeatResult {
1244
+ agentRoleId: string;
1245
+ status: 'ok' | 'work_done' | 'error';
1246
+ pendingMentions: number;
1247
+ assignedTasks: number;
1248
+ relevantActivities: number;
1249
+ taskCreated?: string;
1250
+ error?: string;
1251
+ }
1252
+
1253
+ interface HeartbeatEvent {
1254
+ type: 'started' | 'completed' | 'work_found' | 'no_work' | 'error';
1255
+ agentRoleId: string;
1256
+ agentName: string;
1257
+ timestamp: number;
1258
+ result?: HeartbeatResult;
1259
+ error?: string;
1260
+ }
1261
+
1262
+ type SubscriptionReason = 'assigned' | 'mentioned' | 'commented' | 'manual';
1263
+
1264
+ interface TaskSubscription {
1265
+ id: string;
1266
+ taskId: string;
1267
+ agentRoleId: string;
1268
+ subscriptionReason: SubscriptionReason;
1269
+ subscribedAt: number;
1270
+ }
1271
+
1272
+ interface SubscriptionEvent {
1273
+ type: 'subscribed' | 'unsubscribed';
1274
+ taskId: string;
1275
+ agentRoleId: string;
1276
+ subscription?: TaskSubscription;
1277
+ }
1278
+
1279
+ interface StandupReport {
1280
+ id: string;
1281
+ workspaceId: string;
1282
+ reportDate: string;
1283
+ completedTaskIds: string[];
1284
+ inProgressTaskIds: string[];
1285
+ blockedTaskIds: string[];
1286
+ summary: string;
1287
+ deliveredToChannel?: string;
1288
+ createdAt: number;
1289
+ }
1290
+
1291
+ // Task Board types (inlined for sandboxed preload)
1292
+ type TaskBoardColumn = 'backlog' | 'todo' | 'in_progress' | 'review' | 'done';
1293
+
1294
+ interface TaskLabelData {
1295
+ id: string;
1296
+ workspaceId: string;
1297
+ name: string;
1298
+ color: string;
1299
+ createdAt: number;
1300
+ }
1301
+
1302
+ interface CreateTaskLabelRequest {
1303
+ workspaceId: string;
1304
+ name: string;
1305
+ color?: string;
1306
+ }
1307
+
1308
+ interface UpdateTaskLabelRequest {
1309
+ name?: string;
1310
+ color?: string;
1311
+ }
1312
+
1313
+ interface TaskLabelListQuery {
1314
+ workspaceId: string;
1315
+ }
1316
+
1317
+ interface TaskBoardEvent {
1318
+ type: 'moved' | 'priorityChanged' | 'labelAdded' | 'labelRemoved' | 'dueDateChanged' | 'estimateChanged';
1319
+ taskId: string;
1320
+ data?: {
1321
+ column?: TaskBoardColumn;
1322
+ priority?: number;
1323
+ labelId?: string;
1324
+ dueDate?: number | null;
1325
+ estimatedMinutes?: number | null;
1326
+ };
1327
+ }
1328
+
1329
+ // Agent Working State types (inlined for sandboxed preload)
1330
+ type WorkingStateType = 'context' | 'progress' | 'notes' | 'plan';
1331
+
1332
+ interface AgentWorkingStateData {
1333
+ id: string;
1334
+ agentRoleId: string;
1335
+ workspaceId: string;
1336
+ taskId?: string;
1337
+ stateType: WorkingStateType;
1338
+ content: string;
1339
+ fileReferences?: string[];
1340
+ isCurrent: boolean;
1341
+ createdAt: number;
1342
+ updatedAt: number;
1343
+ }
1344
+
1345
+ interface UpdateWorkingStateRequest {
1346
+ agentRoleId: string;
1347
+ workspaceId: string;
1348
+ taskId?: string;
1349
+ stateType: WorkingStateType;
1350
+ content: string;
1351
+ fileReferences?: string[];
1352
+ }
1353
+
1354
+ interface WorkingStateQuery {
1355
+ agentRoleId: string;
1356
+ workspaceId: string;
1357
+ taskId?: string;
1358
+ stateType?: WorkingStateType;
1359
+ }
1360
+
1361
+ interface WorkingStateHistoryQuery {
1362
+ agentRoleId: string;
1363
+ workspaceId: string;
1364
+ limit?: number;
1365
+ offset?: number;
1366
+ }
1367
+
1368
+ // Context Policy types (inlined for sandboxed preload)
1369
+ type SecurityModeType = 'open' | 'allowlist' | 'pairing';
1370
+ type ContextTypeValue = 'dm' | 'group';
1371
+
1372
+ interface ContextPolicyData {
1373
+ id: string;
1374
+ channelId: string;
1375
+ contextType: ContextTypeValue;
1376
+ securityMode: SecurityModeType;
1377
+ toolRestrictions: string[];
1378
+ createdAt: number;
1379
+ updatedAt: number;
1380
+ }
1381
+
1382
+ interface UpdateContextPolicyOptions {
1383
+ securityMode?: SecurityModeType;
1384
+ toolRestrictions?: string[];
1385
+ }
1386
+
1387
+ // Expose protected methods that allow the renderer process to use ipcRenderer
1388
+ contextBridge.exposeInMainWorld('electronAPI', {
1389
+ // Dialog APIs
1390
+ selectFolder: () => ipcRenderer.invoke('dialog:selectFolder'),
1391
+
1392
+ // File APIs
1393
+ openFile: (filePath: string, workspacePath?: string) => ipcRenderer.invoke('file:open', filePath, workspacePath),
1394
+ showInFinder: (filePath: string, workspacePath?: string) => ipcRenderer.invoke('file:showInFinder', filePath, workspacePath),
1395
+ readFileForViewer: (filePath: string, workspacePath?: string) => ipcRenderer.invoke('file:readForViewer', { filePath, workspacePath }),
1396
+
1397
+ // Shell APIs
1398
+ openExternal: (url: string) => ipcRenderer.invoke('shell:openExternal', url),
1399
+
1400
+ // Task APIs
1401
+ createTask: (data: any) => ipcRenderer.invoke(IPC_CHANNELS.TASK_CREATE, data),
1402
+ getTask: (id: string) => ipcRenderer.invoke(IPC_CHANNELS.TASK_GET, id),
1403
+ listTasks: () => ipcRenderer.invoke(IPC_CHANNELS.TASK_LIST),
1404
+ cancelTask: (id: string) => ipcRenderer.invoke(IPC_CHANNELS.TASK_CANCEL, id),
1405
+ pauseTask: (id: string) => ipcRenderer.invoke(IPC_CHANNELS.TASK_PAUSE, id),
1406
+ resumeTask: (id: string) => ipcRenderer.invoke(IPC_CHANNELS.TASK_RESUME, id),
1407
+ sendStdin: (taskId: string, input: string) => ipcRenderer.invoke(IPC_CHANNELS.TASK_SEND_STDIN, { taskId, input }),
1408
+ killCommand: (taskId: string, force?: boolean) => ipcRenderer.invoke(IPC_CHANNELS.TASK_KILL_COMMAND, { taskId, force }),
1409
+ renameTask: (id: string, title: string) => ipcRenderer.invoke(IPC_CHANNELS.TASK_RENAME, { id, title }),
1410
+ deleteTask: (id: string) => ipcRenderer.invoke(IPC_CHANNELS.TASK_DELETE, id),
1411
+
1412
+ // Task event streaming
1413
+ onTaskEvent: (callback: (event: any) => void) => {
1414
+ const subscription = (_: any, data: any) => callback(data);
1415
+ ipcRenderer.on(IPC_CHANNELS.TASK_EVENT, subscription);
1416
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.TASK_EVENT, subscription);
1417
+ },
1418
+
1419
+ // Task event history (load from DB)
1420
+ getTaskEvents: (taskId: string) => ipcRenderer.invoke(IPC_CHANNELS.TASK_EVENTS, taskId),
1421
+
1422
+ // Send follow-up message to a task
1423
+ sendMessage: (taskId: string, message: string) =>
1424
+ ipcRenderer.invoke(IPC_CHANNELS.TASK_SEND_MESSAGE, { taskId, message }),
1425
+
1426
+ // Workspace APIs
1427
+ createWorkspace: (data: any) => ipcRenderer.invoke(IPC_CHANNELS.WORKSPACE_CREATE, data),
1428
+ listWorkspaces: () => ipcRenderer.invoke(IPC_CHANNELS.WORKSPACE_LIST),
1429
+ selectWorkspace: (id: string) => ipcRenderer.invoke(IPC_CHANNELS.WORKSPACE_SELECT, id),
1430
+ getTempWorkspace: () => ipcRenderer.invoke(IPC_CHANNELS.WORKSPACE_GET_TEMP),
1431
+ updateWorkspacePermissions: (id: string, permissions: { shell?: boolean; network?: boolean }) =>
1432
+ ipcRenderer.invoke(IPC_CHANNELS.WORKSPACE_UPDATE_PERMISSIONS, id, permissions),
1433
+
1434
+ // Approval APIs
1435
+ respondToApproval: (data: any) => ipcRenderer.invoke(IPC_CHANNELS.APPROVAL_RESPOND, data),
1436
+
1437
+ // Artifact APIs
1438
+ listArtifacts: (taskId: string) => ipcRenderer.invoke(IPC_CHANNELS.ARTIFACT_LIST, taskId),
1439
+ previewArtifact: (id: string) => ipcRenderer.invoke(IPC_CHANNELS.ARTIFACT_PREVIEW, id),
1440
+
1441
+ // Skill APIs
1442
+ listSkills: () => ipcRenderer.invoke(IPC_CHANNELS.SKILL_LIST),
1443
+ getSkill: (id: string) => ipcRenderer.invoke(IPC_CHANNELS.SKILL_GET, id),
1444
+
1445
+ // LLM Settings APIs
1446
+ getLLMSettings: () => ipcRenderer.invoke(IPC_CHANNELS.LLM_GET_SETTINGS),
1447
+ saveLLMSettings: (settings: any) => ipcRenderer.invoke(IPC_CHANNELS.LLM_SAVE_SETTINGS, settings),
1448
+ testLLMProvider: (config: any) => ipcRenderer.invoke(IPC_CHANNELS.LLM_TEST_PROVIDER, config),
1449
+ getLLMModels: () => ipcRenderer.invoke(IPC_CHANNELS.LLM_GET_MODELS),
1450
+ getLLMConfigStatus: () => ipcRenderer.invoke(IPC_CHANNELS.LLM_GET_CONFIG_STATUS),
1451
+ setLLMModel: (modelKey: string) => ipcRenderer.invoke(IPC_CHANNELS.LLM_SET_MODEL, modelKey),
1452
+ getOllamaModels: (baseUrl?: string) => ipcRenderer.invoke(IPC_CHANNELS.LLM_GET_OLLAMA_MODELS, baseUrl),
1453
+ getGeminiModels: (apiKey?: string) => ipcRenderer.invoke(IPC_CHANNELS.LLM_GET_GEMINI_MODELS, apiKey),
1454
+ getOpenRouterModels: (apiKey?: string) => ipcRenderer.invoke(IPC_CHANNELS.LLM_GET_OPENROUTER_MODELS, apiKey),
1455
+ getOpenAIModels: (apiKey?: string) => ipcRenderer.invoke(IPC_CHANNELS.LLM_GET_OPENAI_MODELS, apiKey),
1456
+ openaiOAuthStart: () => ipcRenderer.invoke(IPC_CHANNELS.LLM_OPENAI_OAUTH_START),
1457
+ openaiOAuthLogout: () => ipcRenderer.invoke(IPC_CHANNELS.LLM_OPENAI_OAUTH_LOGOUT),
1458
+ getBedrockModels: (config?: { region?: string; accessKeyId?: string; secretAccessKey?: string; profile?: string }) =>
1459
+ ipcRenderer.invoke(IPC_CHANNELS.LLM_GET_BEDROCK_MODELS, config),
1460
+
1461
+ // Gateway / Channel APIs
1462
+ getGatewayChannels: () => ipcRenderer.invoke(IPC_CHANNELS.GATEWAY_GET_CHANNELS),
1463
+ addGatewayChannel: (data: any) => ipcRenderer.invoke(IPC_CHANNELS.GATEWAY_ADD_CHANNEL, data),
1464
+ updateGatewayChannel: (data: any) => ipcRenderer.invoke(IPC_CHANNELS.GATEWAY_UPDATE_CHANNEL, data),
1465
+ removeGatewayChannel: (id: string) => ipcRenderer.invoke(IPC_CHANNELS.GATEWAY_REMOVE_CHANNEL, id),
1466
+ enableGatewayChannel: (id: string) => ipcRenderer.invoke(IPC_CHANNELS.GATEWAY_ENABLE_CHANNEL, id),
1467
+ disableGatewayChannel: (id: string) => ipcRenderer.invoke(IPC_CHANNELS.GATEWAY_DISABLE_CHANNEL, id),
1468
+ testGatewayChannel: (id: string) => ipcRenderer.invoke(IPC_CHANNELS.GATEWAY_TEST_CHANNEL, id),
1469
+ getGatewayUsers: (channelId: string) => ipcRenderer.invoke(IPC_CHANNELS.GATEWAY_GET_USERS, channelId),
1470
+ grantGatewayAccess: (channelId: string, userId: string, displayName?: string) =>
1471
+ ipcRenderer.invoke(IPC_CHANNELS.GATEWAY_GRANT_ACCESS, { channelId, userId, displayName }),
1472
+ revokeGatewayAccess: (channelId: string, userId: string) =>
1473
+ ipcRenderer.invoke(IPC_CHANNELS.GATEWAY_REVOKE_ACCESS, { channelId, userId }),
1474
+ generateGatewayPairing: (channelId: string, userId: string, displayName?: string) =>
1475
+ ipcRenderer.invoke(IPC_CHANNELS.GATEWAY_GENERATE_PAIRING, { channelId, userId, displayName }),
1476
+
1477
+ // Gateway event listener
1478
+ onGatewayMessage: (callback: (data: any) => void) => {
1479
+ const subscription = (_: any, data: any) => callback(data);
1480
+ ipcRenderer.on('gateway:message', subscription);
1481
+ return () => ipcRenderer.removeListener('gateway:message', subscription);
1482
+ },
1483
+
1484
+ // WhatsApp-specific APIs
1485
+ getWhatsAppInfo: () => ipcRenderer.invoke('whatsapp:get-info'),
1486
+ whatsAppLogout: () => ipcRenderer.invoke('whatsapp:logout'),
1487
+
1488
+ // WhatsApp event listeners
1489
+ onWhatsAppQRCode: (callback: (event: any, qr: string) => void) => {
1490
+ ipcRenderer.on('whatsapp:qr-code', callback);
1491
+ },
1492
+ onWhatsAppConnected: (callback: () => void) => {
1493
+ ipcRenderer.on('whatsapp:connected', callback);
1494
+ },
1495
+ onWhatsAppStatus: (callback: (event: any, data: { status: string; error?: string }) => void) => {
1496
+ ipcRenderer.on('whatsapp:status', callback);
1497
+ },
1498
+
1499
+ // Search Settings APIs
1500
+ getSearchSettings: () => ipcRenderer.invoke(IPC_CHANNELS.SEARCH_GET_SETTINGS),
1501
+ saveSearchSettings: (settings: any) => ipcRenderer.invoke(IPC_CHANNELS.SEARCH_SAVE_SETTINGS, settings),
1502
+ getSearchConfigStatus: () => ipcRenderer.invoke(IPC_CHANNELS.SEARCH_GET_CONFIG_STATUS),
1503
+ testSearchProvider: (providerType: string) => ipcRenderer.invoke(IPC_CHANNELS.SEARCH_TEST_PROVIDER, providerType),
1504
+
1505
+ // X/Twitter Settings APIs
1506
+ getXSettings: () => ipcRenderer.invoke(IPC_CHANNELS.X_GET_SETTINGS),
1507
+ saveXSettings: (settings: any) => ipcRenderer.invoke(IPC_CHANNELS.X_SAVE_SETTINGS, settings),
1508
+ testXConnection: () => ipcRenderer.invoke(IPC_CHANNELS.X_TEST_CONNECTION),
1509
+ getXStatus: () => ipcRenderer.invoke(IPC_CHANNELS.X_GET_STATUS),
1510
+
1511
+ // App Update APIs
1512
+ getAppVersion: () => ipcRenderer.invoke(IPC_CHANNELS.APP_GET_VERSION),
1513
+ checkForUpdates: () => ipcRenderer.invoke(IPC_CHANNELS.APP_CHECK_UPDATES),
1514
+ downloadUpdate: (updateInfo: any) => ipcRenderer.invoke(IPC_CHANNELS.APP_DOWNLOAD_UPDATE, updateInfo),
1515
+ installUpdate: () => ipcRenderer.invoke(IPC_CHANNELS.APP_INSTALL_UPDATE),
1516
+
1517
+ // Update event listeners
1518
+ onUpdateProgress: (callback: (progress: any) => void) => {
1519
+ const subscription = (_: any, data: any) => callback(data);
1520
+ ipcRenderer.on(IPC_CHANNELS.APP_UPDATE_PROGRESS, subscription);
1521
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.APP_UPDATE_PROGRESS, subscription);
1522
+ },
1523
+ onUpdateDownloaded: (callback: (info: any) => void) => {
1524
+ const subscription = (_: any, data: any) => callback(data);
1525
+ ipcRenderer.on(IPC_CHANNELS.APP_UPDATE_DOWNLOADED, subscription);
1526
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.APP_UPDATE_DOWNLOADED, subscription);
1527
+ },
1528
+ onUpdateError: (callback: (error: any) => void) => {
1529
+ const subscription = (_: any, data: any) => callback(data);
1530
+ ipcRenderer.on(IPC_CHANNELS.APP_UPDATE_ERROR, subscription);
1531
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.APP_UPDATE_ERROR, subscription);
1532
+ },
1533
+
1534
+ // Guardrail Settings APIs
1535
+ getGuardrailSettings: () => ipcRenderer.invoke(IPC_CHANNELS.GUARDRAIL_GET_SETTINGS),
1536
+ saveGuardrailSettings: (settings: any) => ipcRenderer.invoke(IPC_CHANNELS.GUARDRAIL_SAVE_SETTINGS, settings),
1537
+ getGuardrailDefaults: () => ipcRenderer.invoke(IPC_CHANNELS.GUARDRAIL_GET_DEFAULTS),
1538
+
1539
+ // Appearance Settings APIs
1540
+ getAppearanceSettings: () => ipcRenderer.invoke(IPC_CHANNELS.APPEARANCE_GET_SETTINGS),
1541
+ saveAppearanceSettings: (settings: any) => ipcRenderer.invoke(IPC_CHANNELS.APPEARANCE_SAVE_SETTINGS, settings),
1542
+
1543
+ // Personality Settings APIs
1544
+ getPersonalitySettings: () => ipcRenderer.invoke(IPC_CHANNELS.PERSONALITY_GET_SETTINGS),
1545
+ savePersonalitySettings: (settings: any) => ipcRenderer.invoke(IPC_CHANNELS.PERSONALITY_SAVE_SETTINGS, settings),
1546
+ getPersonalityDefinitions: () => ipcRenderer.invoke(IPC_CHANNELS.PERSONALITY_GET_DEFINITIONS),
1547
+ getPersonaDefinitions: () => ipcRenderer.invoke(IPC_CHANNELS.PERSONALITY_GET_PERSONAS),
1548
+ getRelationshipStats: () => ipcRenderer.invoke(IPC_CHANNELS.PERSONALITY_GET_RELATIONSHIP_STATS),
1549
+ setActivePersonality: (personalityId: string) => ipcRenderer.invoke(IPC_CHANNELS.PERSONALITY_SET_ACTIVE, personalityId),
1550
+ setActivePersona: (personaId: string) => ipcRenderer.invoke(IPC_CHANNELS.PERSONALITY_SET_PERSONA, personaId),
1551
+ resetPersonalitySettings: (preserveRelationship?: boolean) => ipcRenderer.invoke(IPC_CHANNELS.PERSONALITY_RESET, preserveRelationship),
1552
+ onPersonalitySettingsChanged: (callback: (settings: any) => void) => {
1553
+ const subscription = (_: any, data: any) => callback(data);
1554
+ ipcRenderer.on(IPC_CHANNELS.PERSONALITY_SETTINGS_CHANGED, subscription);
1555
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.PERSONALITY_SETTINGS_CHANGED, subscription);
1556
+ },
1557
+
1558
+ // Queue APIs
1559
+ getQueueStatus: () => ipcRenderer.invoke(IPC_CHANNELS.QUEUE_GET_STATUS),
1560
+ getQueueSettings: () => ipcRenderer.invoke(IPC_CHANNELS.QUEUE_GET_SETTINGS),
1561
+ saveQueueSettings: (settings: any) => ipcRenderer.invoke(IPC_CHANNELS.QUEUE_SAVE_SETTINGS, settings),
1562
+ clearQueue: () => ipcRenderer.invoke(IPC_CHANNELS.QUEUE_CLEAR),
1563
+ onQueueUpdate: (callback: (status: any) => void) => {
1564
+ const subscription = (_: any, data: any) => callback(data);
1565
+ ipcRenderer.on(IPC_CHANNELS.QUEUE_UPDATE, subscription);
1566
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.QUEUE_UPDATE, subscription);
1567
+ },
1568
+
1569
+ // Custom Skills APIs
1570
+ listCustomSkills: () => ipcRenderer.invoke(IPC_CHANNELS.CUSTOM_SKILL_LIST),
1571
+ listTaskSkills: () => ipcRenderer.invoke(IPC_CHANNELS.CUSTOM_SKILL_LIST_TASKS),
1572
+ listGuidelineSkills: () => ipcRenderer.invoke(IPC_CHANNELS.CUSTOM_SKILL_LIST_GUIDELINES),
1573
+ getCustomSkill: (id: string) => ipcRenderer.invoke(IPC_CHANNELS.CUSTOM_SKILL_GET, id),
1574
+ createCustomSkill: (skill: any) => ipcRenderer.invoke(IPC_CHANNELS.CUSTOM_SKILL_CREATE, skill),
1575
+ updateCustomSkill: (id: string, updates: any) => ipcRenderer.invoke(IPC_CHANNELS.CUSTOM_SKILL_UPDATE, id, updates),
1576
+ deleteCustomSkill: (id: string) => ipcRenderer.invoke(IPC_CHANNELS.CUSTOM_SKILL_DELETE, id),
1577
+ reloadCustomSkills: () => ipcRenderer.invoke(IPC_CHANNELS.CUSTOM_SKILL_RELOAD),
1578
+ openCustomSkillsFolder: () => ipcRenderer.invoke(IPC_CHANNELS.CUSTOM_SKILL_OPEN_FOLDER),
1579
+
1580
+ // Skill Registry (SkillHub) APIs
1581
+ searchSkillRegistry: (query: string, options?: { page?: number; pageSize?: number }) =>
1582
+ ipcRenderer.invoke(IPC_CHANNELS.SKILL_REGISTRY_SEARCH, query, options),
1583
+ getSkillDetails: (skillId: string) =>
1584
+ ipcRenderer.invoke(IPC_CHANNELS.SKILL_REGISTRY_GET_DETAILS, skillId),
1585
+ installSkillFromRegistry: (skillId: string, version?: string) =>
1586
+ ipcRenderer.invoke(IPC_CHANNELS.SKILL_REGISTRY_INSTALL, skillId, version),
1587
+ updateSkillFromRegistry: (skillId: string, version?: string) =>
1588
+ ipcRenderer.invoke(IPC_CHANNELS.SKILL_REGISTRY_UPDATE, skillId, version),
1589
+ updateAllSkills: () => ipcRenderer.invoke(IPC_CHANNELS.SKILL_REGISTRY_UPDATE_ALL),
1590
+ uninstallSkill: (skillId: string) =>
1591
+ ipcRenderer.invoke(IPC_CHANNELS.SKILL_REGISTRY_UNINSTALL, skillId),
1592
+ listManagedSkills: () => ipcRenderer.invoke(IPC_CHANNELS.SKILL_REGISTRY_LIST_MANAGED),
1593
+ checkSkillUpdates: (skillId: string) =>
1594
+ ipcRenderer.invoke(IPC_CHANNELS.SKILL_REGISTRY_CHECK_UPDATES, skillId),
1595
+ getSkillStatus: () => ipcRenderer.invoke(IPC_CHANNELS.SKILL_REGISTRY_GET_STATUS),
1596
+ getEligibleSkills: () => ipcRenderer.invoke(IPC_CHANNELS.SKILL_REGISTRY_GET_ELIGIBLE),
1597
+
1598
+ // MCP (Model Context Protocol) APIs
1599
+ getMCPSettings: () => ipcRenderer.invoke(IPC_CHANNELS.MCP_GET_SETTINGS),
1600
+ saveMCPSettings: (settings: any) => ipcRenderer.invoke(IPC_CHANNELS.MCP_SAVE_SETTINGS, settings),
1601
+ addMCPServer: (config: any) => ipcRenderer.invoke(IPC_CHANNELS.MCP_ADD_SERVER, config),
1602
+ updateMCPServer: (id: string, updates: any) => ipcRenderer.invoke(IPC_CHANNELS.MCP_UPDATE_SERVER, id, updates),
1603
+ removeMCPServer: (id: string) => ipcRenderer.invoke(IPC_CHANNELS.MCP_REMOVE_SERVER, id),
1604
+ connectMCPServer: (serverId: string) => ipcRenderer.invoke(IPC_CHANNELS.MCP_CONNECT_SERVER, serverId),
1605
+ disconnectMCPServer: (serverId: string) => ipcRenderer.invoke(IPC_CHANNELS.MCP_DISCONNECT_SERVER, serverId),
1606
+ getMCPStatus: () => ipcRenderer.invoke(IPC_CHANNELS.MCP_GET_STATUS),
1607
+ getMCPServerStatus: (serverId: string) => ipcRenderer.invoke(IPC_CHANNELS.MCP_GET_SERVER_STATUS, serverId),
1608
+ getMCPAllTools: () => ipcRenderer.invoke(IPC_CHANNELS.MCP_GET_ALL_TOOLS),
1609
+ getMCPServerTools: (serverId: string) => ipcRenderer.invoke(IPC_CHANNELS.MCP_GET_SERVER_TOOLS, serverId),
1610
+ testMCPServer: (serverId: string) => ipcRenderer.invoke(IPC_CHANNELS.MCP_TEST_SERVER, serverId),
1611
+
1612
+ // MCP Status change event listener
1613
+ onMCPStatusChange: (callback: (status: any[]) => void) => {
1614
+ const subscription = (_: any, data: any) => callback(data);
1615
+ ipcRenderer.on(IPC_CHANNELS.MCP_SERVER_STATUS_CHANGE, subscription);
1616
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.MCP_SERVER_STATUS_CHANGE, subscription);
1617
+ },
1618
+
1619
+ // MCP Registry APIs
1620
+ fetchMCPRegistry: () => ipcRenderer.invoke(IPC_CHANNELS.MCP_REGISTRY_FETCH),
1621
+ searchMCPRegistry: (query: string, tags?: string[]) =>
1622
+ ipcRenderer.invoke(IPC_CHANNELS.MCP_REGISTRY_SEARCH, { query, tags }),
1623
+ installMCPServer: (entryId: string) => ipcRenderer.invoke(IPC_CHANNELS.MCP_REGISTRY_INSTALL, entryId),
1624
+ uninstallMCPServer: (serverId: string) => ipcRenderer.invoke(IPC_CHANNELS.MCP_REGISTRY_UNINSTALL, serverId),
1625
+ checkMCPUpdates: () => ipcRenderer.invoke(IPC_CHANNELS.MCP_REGISTRY_CHECK_UPDATES),
1626
+ updateMCPServerFromRegistry: (serverId: string) => ipcRenderer.invoke(IPC_CHANNELS.MCP_REGISTRY_UPDATE_SERVER, serverId),
1627
+
1628
+ // MCP Host APIs
1629
+ startMCPHost: (port?: number) => ipcRenderer.invoke(IPC_CHANNELS.MCP_HOST_START, port),
1630
+ stopMCPHost: () => ipcRenderer.invoke(IPC_CHANNELS.MCP_HOST_STOP),
1631
+ getMCPHostStatus: () => ipcRenderer.invoke(IPC_CHANNELS.MCP_HOST_GET_STATUS),
1632
+
1633
+ // Built-in Tools Settings APIs
1634
+ getBuiltinToolsSettings: () => ipcRenderer.invoke(IPC_CHANNELS.BUILTIN_TOOLS_GET_SETTINGS),
1635
+ saveBuiltinToolsSettings: (settings: BuiltinToolsSettings) => ipcRenderer.invoke(IPC_CHANNELS.BUILTIN_TOOLS_SAVE_SETTINGS, settings),
1636
+ getBuiltinToolsCategories: () => ipcRenderer.invoke(IPC_CHANNELS.BUILTIN_TOOLS_GET_CATEGORIES),
1637
+
1638
+ // Tray (Menu Bar) APIs
1639
+ getTraySettings: () => ipcRenderer.invoke(IPC_CHANNELS.TRAY_GET_SETTINGS),
1640
+ saveTraySettings: (settings: TraySettings) => ipcRenderer.invoke(IPC_CHANNELS.TRAY_SAVE_SETTINGS, settings),
1641
+
1642
+ // Tray event listeners (for renderer to respond to tray actions)
1643
+ onTrayNewTask: (callback: () => void) => {
1644
+ ipcRenderer.on(IPC_CHANNELS.TRAY_NEW_TASK, callback);
1645
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.TRAY_NEW_TASK, callback);
1646
+ },
1647
+ onTraySelectWorkspace: (callback: (event: any, workspaceId: string) => void) => {
1648
+ ipcRenderer.on(IPC_CHANNELS.TRAY_SELECT_WORKSPACE, callback);
1649
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.TRAY_SELECT_WORKSPACE, callback);
1650
+ },
1651
+ onTrayOpenSettings: (callback: () => void) => {
1652
+ ipcRenderer.on(IPC_CHANNELS.TRAY_OPEN_SETTINGS, callback);
1653
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.TRAY_OPEN_SETTINGS, callback);
1654
+ },
1655
+ onTrayOpenAbout: (callback: () => void) => {
1656
+ ipcRenderer.on(IPC_CHANNELS.TRAY_OPEN_ABOUT, callback);
1657
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.TRAY_OPEN_ABOUT, callback);
1658
+ },
1659
+ onTrayCheckUpdates: (callback: () => void) => {
1660
+ ipcRenderer.on(IPC_CHANNELS.TRAY_CHECK_UPDATES, callback);
1661
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.TRAY_CHECK_UPDATES, callback);
1662
+ },
1663
+ onTrayQuickTask: (callback: (event: any, data: { task: string; workspaceId?: string }) => void) => {
1664
+ ipcRenderer.on(IPC_CHANNELS.TRAY_QUICK_TASK, callback);
1665
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.TRAY_QUICK_TASK, callback);
1666
+ },
1667
+
1668
+ // Quick Input APIs (for the floating quick input window)
1669
+ quickInputSubmit: (task: string, workspaceId?: string) =>
1670
+ ipcRenderer.invoke(IPC_CHANNELS.QUICK_INPUT_SUBMIT, task, workspaceId),
1671
+ quickInputClose: () => ipcRenderer.invoke(IPC_CHANNELS.QUICK_INPUT_CLOSE),
1672
+
1673
+ // Cron (Scheduled Tasks) APIs
1674
+ getCronStatus: () => ipcRenderer.invoke(IPC_CHANNELS.CRON_GET_STATUS),
1675
+ listCronJobs: (opts?: { includeDisabled?: boolean }) =>
1676
+ ipcRenderer.invoke(IPC_CHANNELS.CRON_LIST_JOBS, opts),
1677
+ getCronJob: (id: string) => ipcRenderer.invoke(IPC_CHANNELS.CRON_GET_JOB, id),
1678
+ addCronJob: (job: CronJobCreate) => ipcRenderer.invoke(IPC_CHANNELS.CRON_ADD_JOB, job),
1679
+ updateCronJob: (id: string, patch: CronJobPatch) =>
1680
+ ipcRenderer.invoke(IPC_CHANNELS.CRON_UPDATE_JOB, id, patch),
1681
+ removeCronJob: (id: string) => ipcRenderer.invoke(IPC_CHANNELS.CRON_REMOVE_JOB, id),
1682
+ runCronJob: (id: string, mode?: 'due' | 'force') =>
1683
+ ipcRenderer.invoke(IPC_CHANNELS.CRON_RUN_JOB, id, mode),
1684
+ onCronEvent: (callback: (event: CronEvent) => void) => {
1685
+ const subscription = (_: any, data: CronEvent) => callback(data);
1686
+ ipcRenderer.on(IPC_CHANNELS.CRON_EVENT, subscription);
1687
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.CRON_EVENT, subscription);
1688
+ },
1689
+ getCronRunHistory: (id: string) => ipcRenderer.invoke('cron:getRunHistory', id),
1690
+ clearCronRunHistory: (id: string) => ipcRenderer.invoke('cron:clearRunHistory', id),
1691
+ getCronWebhookStatus: () => ipcRenderer.invoke('cron:getWebhookStatus'),
1692
+
1693
+ // Notification APIs
1694
+ listNotifications: () => ipcRenderer.invoke(IPC_CHANNELS.NOTIFICATION_LIST),
1695
+ getUnreadNotificationCount: () => ipcRenderer.invoke('notification:unreadCount'),
1696
+ markNotificationRead: (id: string) => ipcRenderer.invoke(IPC_CHANNELS.NOTIFICATION_MARK_READ, id),
1697
+ markAllNotificationsRead: () => ipcRenderer.invoke(IPC_CHANNELS.NOTIFICATION_MARK_ALL_READ),
1698
+ deleteNotification: (id: string) => ipcRenderer.invoke(IPC_CHANNELS.NOTIFICATION_DELETE, id),
1699
+ deleteAllNotifications: () => ipcRenderer.invoke(IPC_CHANNELS.NOTIFICATION_DELETE_ALL),
1700
+ onNotificationEvent: (callback: (event: NotificationEvent) => void) => {
1701
+ const subscription = (_: any, data: NotificationEvent) => callback(data);
1702
+ ipcRenderer.on(IPC_CHANNELS.NOTIFICATION_EVENT, subscription);
1703
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.NOTIFICATION_EVENT, subscription);
1704
+ },
1705
+
1706
+ // Hooks (Webhooks & Gmail Pub/Sub) APIs
1707
+ getHooksSettings: () => ipcRenderer.invoke(IPC_CHANNELS.HOOKS_GET_SETTINGS),
1708
+ saveHooksSettings: (settings: Partial<HooksSettings>) => ipcRenderer.invoke(IPC_CHANNELS.HOOKS_SAVE_SETTINGS, settings),
1709
+ enableHooks: () => ipcRenderer.invoke(IPC_CHANNELS.HOOKS_ENABLE),
1710
+ disableHooks: () => ipcRenderer.invoke(IPC_CHANNELS.HOOKS_DISABLE),
1711
+ regenerateHookToken: () => ipcRenderer.invoke(IPC_CHANNELS.HOOKS_REGENERATE_TOKEN),
1712
+ getHooksStatus: () => ipcRenderer.invoke(IPC_CHANNELS.HOOKS_GET_STATUS),
1713
+ addHookMapping: (mapping: HookMapping) => ipcRenderer.invoke(IPC_CHANNELS.HOOKS_ADD_MAPPING, mapping),
1714
+ removeHookMapping: (id: string) => ipcRenderer.invoke(IPC_CHANNELS.HOOKS_REMOVE_MAPPING, id),
1715
+ configureGmailHooks: (config: GmailHooksConfig) => ipcRenderer.invoke(IPC_CHANNELS.HOOKS_CONFIGURE_GMAIL, config),
1716
+ getGmailHooksStatus: () => ipcRenderer.invoke(IPC_CHANNELS.HOOKS_GET_GMAIL_STATUS),
1717
+ startGmailWatcher: () => ipcRenderer.invoke(IPC_CHANNELS.HOOKS_START_GMAIL_WATCHER),
1718
+ stopGmailWatcher: () => ipcRenderer.invoke(IPC_CHANNELS.HOOKS_STOP_GMAIL_WATCHER),
1719
+ onHooksEvent: (callback: (event: HooksEvent) => void) => {
1720
+ const subscription = (_: Electron.IpcRendererEvent, data: HooksEvent) => callback(data);
1721
+ ipcRenderer.on(IPC_CHANNELS.HOOKS_EVENT, subscription);
1722
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.HOOKS_EVENT, subscription);
1723
+ },
1724
+
1725
+ // Control Plane (WebSocket Gateway)
1726
+ getControlPlaneSettings: () => ipcRenderer.invoke(IPC_CHANNELS.CONTROL_PLANE_GET_SETTINGS),
1727
+ saveControlPlaneSettings: (settings: ControlPlaneSettingsData) => ipcRenderer.invoke(IPC_CHANNELS.CONTROL_PLANE_SAVE_SETTINGS, settings),
1728
+ enableControlPlane: () => ipcRenderer.invoke(IPC_CHANNELS.CONTROL_PLANE_ENABLE),
1729
+ disableControlPlane: () => ipcRenderer.invoke(IPC_CHANNELS.CONTROL_PLANE_DISABLE),
1730
+ startControlPlane: () => ipcRenderer.invoke(IPC_CHANNELS.CONTROL_PLANE_START),
1731
+ stopControlPlane: () => ipcRenderer.invoke(IPC_CHANNELS.CONTROL_PLANE_STOP),
1732
+ getControlPlaneStatus: () => ipcRenderer.invoke(IPC_CHANNELS.CONTROL_PLANE_GET_STATUS),
1733
+ regenerateControlPlaneToken: () => ipcRenderer.invoke(IPC_CHANNELS.CONTROL_PLANE_REGENERATE_TOKEN),
1734
+ onControlPlaneEvent: (callback: (event: ControlPlaneEvent) => void) => {
1735
+ const subscription = (_: Electron.IpcRendererEvent, data: ControlPlaneEvent) => callback(data);
1736
+ ipcRenderer.on(IPC_CHANNELS.CONTROL_PLANE_EVENT, subscription);
1737
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.CONTROL_PLANE_EVENT, subscription);
1738
+ },
1739
+
1740
+ // Tailscale
1741
+ checkTailscaleAvailability: () => ipcRenderer.invoke(IPC_CHANNELS.TAILSCALE_CHECK_AVAILABILITY),
1742
+ getTailscaleStatus: () => ipcRenderer.invoke(IPC_CHANNELS.TAILSCALE_GET_STATUS),
1743
+ setTailscaleMode: (mode: TailscaleMode) => ipcRenderer.invoke(IPC_CHANNELS.TAILSCALE_SET_MODE, mode),
1744
+
1745
+ // Remote Gateway
1746
+ connectRemoteGateway: (config?: RemoteGatewayConfig) => ipcRenderer.invoke(IPC_CHANNELS.REMOTE_GATEWAY_CONNECT, config),
1747
+ disconnectRemoteGateway: () => ipcRenderer.invoke(IPC_CHANNELS.REMOTE_GATEWAY_DISCONNECT),
1748
+ getRemoteGatewayStatus: () => ipcRenderer.invoke(IPC_CHANNELS.REMOTE_GATEWAY_GET_STATUS),
1749
+ saveRemoteGatewayConfig: (config: RemoteGatewayConfig) => ipcRenderer.invoke(IPC_CHANNELS.REMOTE_GATEWAY_SAVE_CONFIG, config),
1750
+ testRemoteGatewayConnection: (config: RemoteGatewayConfig) => ipcRenderer.invoke(IPC_CHANNELS.REMOTE_GATEWAY_TEST_CONNECTION, config),
1751
+ onRemoteGatewayEvent: (callback: (event: RemoteGatewayEvent) => void) => {
1752
+ const subscription = (_: Electron.IpcRendererEvent, data: RemoteGatewayEvent) => callback(data);
1753
+ ipcRenderer.on(IPC_CHANNELS.REMOTE_GATEWAY_EVENT, subscription);
1754
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.REMOTE_GATEWAY_EVENT, subscription);
1755
+ },
1756
+
1757
+ // SSH Tunnel
1758
+ connectSSHTunnel: (config: SSHTunnelConfig) => ipcRenderer.invoke(IPC_CHANNELS.SSH_TUNNEL_CONNECT, config),
1759
+ disconnectSSHTunnel: () => ipcRenderer.invoke(IPC_CHANNELS.SSH_TUNNEL_DISCONNECT),
1760
+ getSSHTunnelStatus: () => ipcRenderer.invoke(IPC_CHANNELS.SSH_TUNNEL_GET_STATUS),
1761
+ saveSSHTunnelConfig: (config: SSHTunnelConfig) => ipcRenderer.invoke(IPC_CHANNELS.SSH_TUNNEL_SAVE_CONFIG, config),
1762
+ testSSHTunnelConnection: (config: SSHTunnelConfig) => ipcRenderer.invoke(IPC_CHANNELS.SSH_TUNNEL_TEST_CONNECTION, config),
1763
+ onSSHTunnelEvent: (callback: (event: SSHTunnelEvent) => void) => {
1764
+ const subscription = (_: Electron.IpcRendererEvent, data: SSHTunnelEvent) => callback(data);
1765
+ ipcRenderer.on(IPC_CHANNELS.SSH_TUNNEL_EVENT, subscription);
1766
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.SSH_TUNNEL_EVENT, subscription);
1767
+ },
1768
+
1769
+ // Live Canvas APIs
1770
+ canvasCreate: (data: { taskId: string; workspaceId: string; title?: string }) =>
1771
+ ipcRenderer.invoke(IPC_CHANNELS.CANVAS_CREATE, data),
1772
+ canvasGetSession: (sessionId: string) =>
1773
+ ipcRenderer.invoke(IPC_CHANNELS.CANVAS_GET_SESSION, sessionId),
1774
+ canvasListSessions: (taskId?: string) =>
1775
+ ipcRenderer.invoke(IPC_CHANNELS.CANVAS_LIST_SESSIONS, taskId),
1776
+ canvasShow: (sessionId: string) =>
1777
+ ipcRenderer.invoke(IPC_CHANNELS.CANVAS_SHOW, sessionId),
1778
+ canvasHide: (sessionId: string) =>
1779
+ ipcRenderer.invoke(IPC_CHANNELS.CANVAS_HIDE, sessionId),
1780
+ canvasClose: (sessionId: string) =>
1781
+ ipcRenderer.invoke(IPC_CHANNELS.CANVAS_CLOSE, sessionId),
1782
+ canvasPush: (data: { sessionId: string; content: string; filename?: string }) =>
1783
+ ipcRenderer.invoke(IPC_CHANNELS.CANVAS_PUSH, data),
1784
+ canvasEval: (data: { sessionId: string; script: string }) =>
1785
+ ipcRenderer.invoke(IPC_CHANNELS.CANVAS_EVAL, data),
1786
+ canvasSnapshot: (sessionId: string) =>
1787
+ ipcRenderer.invoke(IPC_CHANNELS.CANVAS_SNAPSHOT, sessionId),
1788
+ canvasExportHTML: (sessionId: string) =>
1789
+ ipcRenderer.invoke(IPC_CHANNELS.CANVAS_EXPORT_HTML, sessionId),
1790
+ canvasExportToFolder: (data: { sessionId: string; targetDir: string }) =>
1791
+ ipcRenderer.invoke(IPC_CHANNELS.CANVAS_EXPORT_TO_FOLDER, data),
1792
+ canvasOpenInBrowser: (sessionId: string) =>
1793
+ ipcRenderer.invoke(IPC_CHANNELS.CANVAS_OPEN_IN_BROWSER, sessionId),
1794
+ canvasGetSessionDir: (sessionId: string) =>
1795
+ ipcRenderer.invoke(IPC_CHANNELS.CANVAS_GET_SESSION_DIR, sessionId),
1796
+ onCanvasEvent: (callback: (event: CanvasEvent) => void) => {
1797
+ const subscription = (_: Electron.IpcRendererEvent, data: CanvasEvent) => callback(data);
1798
+ ipcRenderer.on(IPC_CHANNELS.CANVAS_EVENT, subscription);
1799
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.CANVAS_EVENT, subscription);
1800
+ },
1801
+
1802
+ // Mobile Companion Nodes
1803
+ nodeList: () => ipcRenderer.invoke(IPC_CHANNELS.NODE_LIST),
1804
+ nodeGet: (nodeId: string) => ipcRenderer.invoke(IPC_CHANNELS.NODE_GET, nodeId),
1805
+ nodeInvoke: (params: { nodeId: string; command: string; params?: Record<string, unknown>; timeoutMs?: number }) =>
1806
+ ipcRenderer.invoke(IPC_CHANNELS.NODE_INVOKE, params),
1807
+ onNodeEvent: (callback: (event: { type: string; nodeId: string; node?: any; timestamp: number }) => void) => {
1808
+ const subscription = (_: Electron.IpcRendererEvent, data: any) => callback(data);
1809
+ ipcRenderer.on(IPC_CHANNELS.NODE_EVENT, subscription);
1810
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.NODE_EVENT, subscription);
1811
+ },
1812
+
1813
+ // Memory System APIs
1814
+ getMemorySettings: (workspaceId: string) =>
1815
+ ipcRenderer.invoke(IPC_CHANNELS.MEMORY_GET_SETTINGS, workspaceId),
1816
+ saveMemorySettings: (data: { workspaceId: string; settings: Partial<MemorySettings> }) =>
1817
+ ipcRenderer.invoke(IPC_CHANNELS.MEMORY_SAVE_SETTINGS, data),
1818
+ searchMemories: (data: { workspaceId: string; query: string; limit?: number }) =>
1819
+ ipcRenderer.invoke(IPC_CHANNELS.MEMORY_SEARCH, data),
1820
+ getMemoryTimeline: (data: { memoryId: string; windowSize?: number }) =>
1821
+ ipcRenderer.invoke(IPC_CHANNELS.MEMORY_GET_TIMELINE, data),
1822
+ getMemoryDetails: (ids: string[]) =>
1823
+ ipcRenderer.invoke(IPC_CHANNELS.MEMORY_GET_DETAILS, ids),
1824
+ getRecentMemories: (data: { workspaceId: string; limit?: number }) =>
1825
+ ipcRenderer.invoke(IPC_CHANNELS.MEMORY_GET_RECENT, data),
1826
+ getMemoryStats: (workspaceId: string) =>
1827
+ ipcRenderer.invoke(IPC_CHANNELS.MEMORY_GET_STATS, workspaceId),
1828
+ clearMemory: (workspaceId: string) =>
1829
+ ipcRenderer.invoke(IPC_CHANNELS.MEMORY_CLEAR, workspaceId),
1830
+ onMemoryEvent: (callback: (event: { type: string; workspaceId: string }) => void) => {
1831
+ const subscription = (_: Electron.IpcRendererEvent, data: any) => callback(data);
1832
+ ipcRenderer.on(IPC_CHANNELS.MEMORY_EVENT, subscription);
1833
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.MEMORY_EVENT, subscription);
1834
+ },
1835
+
1836
+ // Migration Status APIs
1837
+ getMigrationStatus: () => ipcRenderer.invoke(IPC_CHANNELS.MIGRATION_GET_STATUS),
1838
+ dismissMigrationNotification: () => ipcRenderer.invoke(IPC_CHANNELS.MIGRATION_DISMISS_NOTIFICATION),
1839
+
1840
+ // Extensions / Plugin APIs
1841
+ getExtensions: () => ipcRenderer.invoke(IPC_CHANNELS.EXTENSIONS_LIST),
1842
+ getExtension: (name: string) => ipcRenderer.invoke(IPC_CHANNELS.EXTENSIONS_GET, name),
1843
+ enableExtension: (name: string) => ipcRenderer.invoke(IPC_CHANNELS.EXTENSIONS_ENABLE, name),
1844
+ disableExtension: (name: string) => ipcRenderer.invoke(IPC_CHANNELS.EXTENSIONS_DISABLE, name),
1845
+ reloadExtension: (name: string) => ipcRenderer.invoke(IPC_CHANNELS.EXTENSIONS_RELOAD, name),
1846
+ getExtensionConfig: (name: string) => ipcRenderer.invoke(IPC_CHANNELS.EXTENSIONS_GET_CONFIG, name),
1847
+ setExtensionConfig: (name: string, config: Record<string, unknown>) =>
1848
+ ipcRenderer.invoke(IPC_CHANNELS.EXTENSIONS_SET_CONFIG, { name, config }),
1849
+ discoverExtensions: () => ipcRenderer.invoke(IPC_CHANNELS.EXTENSIONS_DISCOVER),
1850
+
1851
+ // Webhook Tunnel APIs
1852
+ getTunnelStatus: () => ipcRenderer.invoke(IPC_CHANNELS.TUNNEL_GET_STATUS),
1853
+ startTunnel: (config: { provider: string; port: number; ngrokAuthToken?: string; ngrokRegion?: string }) =>
1854
+ ipcRenderer.invoke(IPC_CHANNELS.TUNNEL_START, config),
1855
+ stopTunnel: () => ipcRenderer.invoke(IPC_CHANNELS.TUNNEL_STOP),
1856
+
1857
+ // Agent Role (Agent Squad) APIs
1858
+ getAgentRoles: (includeInactive?: boolean) =>
1859
+ ipcRenderer.invoke(IPC_CHANNELS.AGENT_ROLE_LIST, includeInactive),
1860
+ getAgentRole: (id: string) =>
1861
+ ipcRenderer.invoke(IPC_CHANNELS.AGENT_ROLE_GET, id),
1862
+ createAgentRole: (request: {
1863
+ name: string;
1864
+ displayName: string;
1865
+ description?: string;
1866
+ icon?: string;
1867
+ color?: string;
1868
+ personalityId?: string;
1869
+ modelKey?: string;
1870
+ providerType?: string;
1871
+ systemPrompt?: string;
1872
+ capabilities: string[];
1873
+ toolRestrictions?: { allowedTools?: string[]; deniedTools?: string[] };
1874
+ }) => ipcRenderer.invoke(IPC_CHANNELS.AGENT_ROLE_CREATE, request),
1875
+ updateAgentRole: (request: {
1876
+ id: string;
1877
+ displayName?: string;
1878
+ description?: string;
1879
+ icon?: string;
1880
+ color?: string;
1881
+ personalityId?: string;
1882
+ modelKey?: string;
1883
+ providerType?: string;
1884
+ systemPrompt?: string;
1885
+ capabilities?: string[];
1886
+ toolRestrictions?: { allowedTools?: string[]; deniedTools?: string[] };
1887
+ isActive?: boolean;
1888
+ sortOrder?: number;
1889
+ }) => ipcRenderer.invoke(IPC_CHANNELS.AGENT_ROLE_UPDATE, request),
1890
+ deleteAgentRole: (id: string) =>
1891
+ ipcRenderer.invoke(IPC_CHANNELS.AGENT_ROLE_DELETE, id),
1892
+ assignAgentRoleToTask: (taskId: string, agentRoleId: string | null) =>
1893
+ ipcRenderer.invoke(IPC_CHANNELS.AGENT_ROLE_ASSIGN_TO_TASK, taskId, agentRoleId),
1894
+ getDefaultAgentRoles: () =>
1895
+ ipcRenderer.invoke(IPC_CHANNELS.AGENT_ROLE_GET_DEFAULTS),
1896
+ seedDefaultAgentRoles: () =>
1897
+ ipcRenderer.invoke(IPC_CHANNELS.AGENT_ROLE_SEED_DEFAULTS),
1898
+ syncDefaultAgentRoles: () =>
1899
+ ipcRenderer.invoke(IPC_CHANNELS.AGENT_ROLE_SYNC_DEFAULTS),
1900
+
1901
+ // Activity Feed APIs
1902
+ listActivities: (query: ActivityListQuery) =>
1903
+ ipcRenderer.invoke(IPC_CHANNELS.ACTIVITY_LIST, query),
1904
+ createActivity: (request: CreateActivityRequest) =>
1905
+ ipcRenderer.invoke(IPC_CHANNELS.ACTIVITY_CREATE, request),
1906
+ markActivityRead: (id: string) =>
1907
+ ipcRenderer.invoke(IPC_CHANNELS.ACTIVITY_MARK_READ, id),
1908
+ markAllActivitiesRead: (workspaceId: string) =>
1909
+ ipcRenderer.invoke(IPC_CHANNELS.ACTIVITY_MARK_ALL_READ, workspaceId),
1910
+ pinActivity: (id: string) =>
1911
+ ipcRenderer.invoke(IPC_CHANNELS.ACTIVITY_PIN, id),
1912
+ deleteActivity: (id: string) =>
1913
+ ipcRenderer.invoke(IPC_CHANNELS.ACTIVITY_DELETE, id),
1914
+ onActivityEvent: (callback: (event: ActivityEvent) => void) => {
1915
+ const subscription = (_: any, data: ActivityEvent) => callback(data);
1916
+ ipcRenderer.on(IPC_CHANNELS.ACTIVITY_EVENT, subscription);
1917
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.ACTIVITY_EVENT, subscription);
1918
+ },
1919
+
1920
+ // @Mention System APIs
1921
+ listMentions: (query: MentionListQuery) =>
1922
+ ipcRenderer.invoke(IPC_CHANNELS.MENTION_LIST, query),
1923
+ createMention: (request: CreateMentionRequest) =>
1924
+ ipcRenderer.invoke(IPC_CHANNELS.MENTION_CREATE, request),
1925
+ acknowledgeMention: (id: string) =>
1926
+ ipcRenderer.invoke(IPC_CHANNELS.MENTION_ACKNOWLEDGE, id),
1927
+ completeMention: (id: string) =>
1928
+ ipcRenderer.invoke(IPC_CHANNELS.MENTION_COMPLETE, id),
1929
+ dismissMention: (id: string) =>
1930
+ ipcRenderer.invoke(IPC_CHANNELS.MENTION_DISMISS, id),
1931
+ onMentionEvent: (callback: (event: MentionEvent) => void) => {
1932
+ const subscription = (_: any, data: MentionEvent) => callback(data);
1933
+ ipcRenderer.on(IPC_CHANNELS.MENTION_EVENT, subscription);
1934
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.MENTION_EVENT, subscription);
1935
+ },
1936
+
1937
+ // ============ Mission Control APIs ============
1938
+
1939
+ // Heartbeat System
1940
+ getHeartbeatConfig: (agentRoleId: string) =>
1941
+ ipcRenderer.invoke(IPC_CHANNELS.HEARTBEAT_GET_CONFIG, agentRoleId),
1942
+ updateHeartbeatConfig: (agentRoleId: string, config: {
1943
+ heartbeatEnabled?: boolean;
1944
+ heartbeatIntervalMinutes?: number;
1945
+ heartbeatStaggerOffset?: number;
1946
+ }) => ipcRenderer.invoke(IPC_CHANNELS.HEARTBEAT_UPDATE_CONFIG, agentRoleId, config),
1947
+ triggerHeartbeat: (agentRoleId: string) =>
1948
+ ipcRenderer.invoke(IPC_CHANNELS.HEARTBEAT_TRIGGER, agentRoleId),
1949
+ getHeartbeatStatus: (agentRoleId: string) =>
1950
+ ipcRenderer.invoke(IPC_CHANNELS.HEARTBEAT_GET_STATUS, agentRoleId),
1951
+ getAllHeartbeatStatus: () =>
1952
+ ipcRenderer.invoke(IPC_CHANNELS.HEARTBEAT_GET_ALL_STATUS),
1953
+ onHeartbeatEvent: (callback: (event: HeartbeatEvent) => void) => {
1954
+ const subscription = (_: any, data: HeartbeatEvent) => callback(data);
1955
+ ipcRenderer.on(IPC_CHANNELS.HEARTBEAT_EVENT, subscription);
1956
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.HEARTBEAT_EVENT, subscription);
1957
+ },
1958
+
1959
+ // Task Subscriptions
1960
+ listSubscriptions: (taskId: string) =>
1961
+ ipcRenderer.invoke(IPC_CHANNELS.SUBSCRIPTION_LIST, taskId),
1962
+ addSubscription: (taskId: string, agentRoleId: string, reason: SubscriptionReason) =>
1963
+ ipcRenderer.invoke(IPC_CHANNELS.SUBSCRIPTION_ADD, taskId, agentRoleId, reason),
1964
+ removeSubscription: (taskId: string, agentRoleId: string) =>
1965
+ ipcRenderer.invoke(IPC_CHANNELS.SUBSCRIPTION_REMOVE, taskId, agentRoleId),
1966
+ getTaskSubscribers: (taskId: string) =>
1967
+ ipcRenderer.invoke(IPC_CHANNELS.SUBSCRIPTION_GET_SUBSCRIBERS, taskId),
1968
+ getAgentSubscriptions: (agentRoleId: string) =>
1969
+ ipcRenderer.invoke(IPC_CHANNELS.SUBSCRIPTION_GET_FOR_AGENT, agentRoleId),
1970
+ onSubscriptionEvent: (callback: (event: SubscriptionEvent) => void) => {
1971
+ const subscription = (_: any, data: SubscriptionEvent) => callback(data);
1972
+ ipcRenderer.on(IPC_CHANNELS.SUBSCRIPTION_EVENT, subscription);
1973
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.SUBSCRIPTION_EVENT, subscription);
1974
+ },
1975
+
1976
+ // Standup Reports
1977
+ generateStandupReport: (workspaceId: string) =>
1978
+ ipcRenderer.invoke(IPC_CHANNELS.STANDUP_GENERATE, workspaceId),
1979
+ getLatestStandupReport: (workspaceId: string) =>
1980
+ ipcRenderer.invoke(IPC_CHANNELS.STANDUP_GET_LATEST, workspaceId),
1981
+ listStandupReports: (workspaceId: string, limit?: number) =>
1982
+ ipcRenderer.invoke(IPC_CHANNELS.STANDUP_LIST, workspaceId, limit),
1983
+ deliverStandupReport: (reportId: string, channelType: string, channelId: string) =>
1984
+ ipcRenderer.invoke(IPC_CHANNELS.STANDUP_DELIVER, reportId, channelType, channelId),
1985
+
1986
+ // Task Board APIs
1987
+ moveTaskToColumn: (taskId: string, column: TaskBoardColumn) =>
1988
+ ipcRenderer.invoke(IPC_CHANNELS.TASK_MOVE_COLUMN, taskId, column),
1989
+ setTaskPriority: (taskId: string, priority: number) =>
1990
+ ipcRenderer.invoke(IPC_CHANNELS.TASK_SET_PRIORITY, taskId, priority),
1991
+ setTaskDueDate: (taskId: string, dueDate: number | null) =>
1992
+ ipcRenderer.invoke(IPC_CHANNELS.TASK_SET_DUE_DATE, taskId, dueDate),
1993
+ setTaskEstimate: (taskId: string, estimatedMinutes: number | null) =>
1994
+ ipcRenderer.invoke(IPC_CHANNELS.TASK_SET_ESTIMATE, taskId, estimatedMinutes),
1995
+ addTaskLabel: (taskId: string, labelId: string) =>
1996
+ ipcRenderer.invoke(IPC_CHANNELS.TASK_ADD_LABEL, taskId, labelId),
1997
+ removeTaskLabel: (taskId: string, labelId: string) =>
1998
+ ipcRenderer.invoke(IPC_CHANNELS.TASK_REMOVE_LABEL, taskId, labelId),
1999
+ onTaskBoardEvent: (callback: (event: TaskBoardEvent) => void) => {
2000
+ const subscription = (_: any, data: TaskBoardEvent) => callback(data);
2001
+ ipcRenderer.on(IPC_CHANNELS.TASK_BOARD_EVENT, subscription);
2002
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.TASK_BOARD_EVENT, subscription);
2003
+ },
2004
+
2005
+ // Task Label APIs
2006
+ listTaskLabels: (query: TaskLabelListQuery) =>
2007
+ ipcRenderer.invoke(IPC_CHANNELS.TASK_LABEL_LIST, query),
2008
+ createTaskLabel: (request: CreateTaskLabelRequest) =>
2009
+ ipcRenderer.invoke(IPC_CHANNELS.TASK_LABEL_CREATE, request),
2010
+ updateTaskLabel: (id: string, request: UpdateTaskLabelRequest) =>
2011
+ ipcRenderer.invoke(IPC_CHANNELS.TASK_LABEL_UPDATE, id, request),
2012
+ deleteTaskLabel: (id: string) =>
2013
+ ipcRenderer.invoke(IPC_CHANNELS.TASK_LABEL_DELETE, id),
2014
+
2015
+ // Agent Working State APIs
2016
+ getWorkingState: (id: string) =>
2017
+ ipcRenderer.invoke(IPC_CHANNELS.WORKING_STATE_GET, id),
2018
+ getCurrentWorkingState: (query: WorkingStateQuery) =>
2019
+ ipcRenderer.invoke(IPC_CHANNELS.WORKING_STATE_GET_CURRENT, query),
2020
+ updateWorkingState: (request: UpdateWorkingStateRequest) =>
2021
+ ipcRenderer.invoke(IPC_CHANNELS.WORKING_STATE_UPDATE, request),
2022
+ getWorkingStateHistory: (query: WorkingStateHistoryQuery) =>
2023
+ ipcRenderer.invoke(IPC_CHANNELS.WORKING_STATE_HISTORY, query),
2024
+ restoreWorkingState: (id: string) =>
2025
+ ipcRenderer.invoke(IPC_CHANNELS.WORKING_STATE_RESTORE, id),
2026
+ deleteWorkingState: (id: string) =>
2027
+ ipcRenderer.invoke(IPC_CHANNELS.WORKING_STATE_DELETE, id),
2028
+ listWorkingStatesForTask: (taskId: string) =>
2029
+ ipcRenderer.invoke(IPC_CHANNELS.WORKING_STATE_LIST_FOR_TASK, taskId),
2030
+
2031
+ // Context Policy APIs (per-context security DM vs group)
2032
+ getContextPolicy: (channelId: string, contextType: ContextTypeValue) =>
2033
+ ipcRenderer.invoke(IPC_CHANNELS.CONTEXT_POLICY_GET, channelId, contextType),
2034
+ getContextPolicyForChat: (channelId: string, chatId: string, isGroup: boolean) =>
2035
+ ipcRenderer.invoke(IPC_CHANNELS.CONTEXT_POLICY_GET_FOR_CHAT, channelId, chatId, isGroup),
2036
+ listContextPolicies: (channelId: string) =>
2037
+ ipcRenderer.invoke(IPC_CHANNELS.CONTEXT_POLICY_LIST, channelId),
2038
+ updateContextPolicy: (channelId: string, contextType: ContextTypeValue, options: UpdateContextPolicyOptions) =>
2039
+ ipcRenderer.invoke(IPC_CHANNELS.CONTEXT_POLICY_UPDATE, channelId, contextType, options),
2040
+ deleteContextPolicies: (channelId: string) =>
2041
+ ipcRenderer.invoke(IPC_CHANNELS.CONTEXT_POLICY_DELETE, channelId),
2042
+ createDefaultContextPolicies: (channelId: string) =>
2043
+ ipcRenderer.invoke(IPC_CHANNELS.CONTEXT_POLICY_CREATE_DEFAULTS, channelId),
2044
+ isToolAllowedInContext: (channelId: string, contextType: ContextTypeValue, toolName: string, toolGroups: string[]) =>
2045
+ ipcRenderer.invoke(IPC_CHANNELS.CONTEXT_POLICY_IS_TOOL_ALLOWED, channelId, contextType, toolName, toolGroups),
2046
+
2047
+ // Voice Mode
2048
+ getVoiceSettings: () => ipcRenderer.invoke(IPC_CHANNELS.VOICE_GET_SETTINGS),
2049
+ saveVoiceSettings: (settings: Partial<VoiceSettingsData>) =>
2050
+ ipcRenderer.invoke(IPC_CHANNELS.VOICE_SAVE_SETTINGS, settings),
2051
+ getVoiceState: () => ipcRenderer.invoke(IPC_CHANNELS.VOICE_GET_STATE),
2052
+ voiceSpeak: (text: string) => ipcRenderer.invoke(IPC_CHANNELS.VOICE_SPEAK, text),
2053
+ voiceStopSpeaking: () => ipcRenderer.invoke(IPC_CHANNELS.VOICE_STOP_SPEAKING),
2054
+ voiceTranscribe: (audioData: ArrayBuffer) =>
2055
+ ipcRenderer.invoke(IPC_CHANNELS.VOICE_TRANSCRIBE, Array.from(new Uint8Array(audioData))),
2056
+ getElevenLabsVoices: () => ipcRenderer.invoke(IPC_CHANNELS.VOICE_GET_ELEVENLABS_VOICES),
2057
+ testElevenLabsConnection: () => ipcRenderer.invoke(IPC_CHANNELS.VOICE_TEST_ELEVENLABS),
2058
+ testOpenAIVoiceConnection: () => ipcRenderer.invoke(IPC_CHANNELS.VOICE_TEST_OPENAI),
2059
+ testAzureVoiceConnection: () => ipcRenderer.invoke(IPC_CHANNELS.VOICE_TEST_AZURE),
2060
+ onVoiceEvent: (callback: (event: VoiceEventData) => void) => {
2061
+ const handler = (_event: Electron.IpcRendererEvent, data: VoiceEventData) => callback(data);
2062
+ ipcRenderer.on(IPC_CHANNELS.VOICE_EVENT, handler);
2063
+ return () => ipcRenderer.removeListener(IPC_CHANNELS.VOICE_EVENT, handler);
2064
+ },
2065
+ });
2066
+
2067
+ // Type declarations for TypeScript
2068
+ export interface FileViewerResult {
2069
+ success: boolean;
2070
+ data?: {
2071
+ path: string;
2072
+ fileName: string;
2073
+ fileType: 'markdown' | 'code' | 'text' | 'docx' | 'pdf' | 'image' | 'pptx' | 'html' | 'unsupported';
2074
+ content: string | null;
2075
+ htmlContent?: string;
2076
+ size: number;
2077
+ };
2078
+ error?: string;
2079
+ }
2080
+
2081
+ export type { TraySettings };
2082
+
2083
+ // Export Agent Role types
2084
+ export type {
2085
+ AgentCapability,
2086
+ AgentToolRestrictions,
2087
+ AgentRoleData,
2088
+ CreateAgentRoleRequest,
2089
+ UpdateAgentRoleRequest,
2090
+ };
2091
+
2092
+ // Export Activity Feed types
2093
+ export type {
2094
+ ActivityActorType,
2095
+ ActivityType,
2096
+ ActivityData,
2097
+ ActivityListQuery,
2098
+ ActivityEvent,
2099
+ };
2100
+
2101
+ // Export @Mention System types
2102
+ export type {
2103
+ MentionType,
2104
+ MentionStatus,
2105
+ MentionData,
2106
+ CreateMentionRequest,
2107
+ MentionListQuery,
2108
+ MentionEvent,
2109
+ };
2110
+
2111
+ // Export Task Board types
2112
+ export type {
2113
+ TaskBoardColumn,
2114
+ TaskLabelData,
2115
+ CreateTaskLabelRequest,
2116
+ UpdateTaskLabelRequest,
2117
+ TaskLabelListQuery,
2118
+ TaskBoardEvent,
2119
+ };
2120
+
2121
+ // Export Agent Working State types
2122
+ export type {
2123
+ WorkingStateType,
2124
+ AgentWorkingStateData,
2125
+ UpdateWorkingStateRequest,
2126
+ WorkingStateQuery,
2127
+ WorkingStateHistoryQuery,
2128
+ };
2129
+
2130
+ // Export Context Policy types
2131
+ export type {
2132
+ SecurityModeType,
2133
+ ContextTypeValue,
2134
+ ContextPolicyData,
2135
+ UpdateContextPolicyOptions,
2136
+ };
2137
+
2138
+ // Export Mission Control types
2139
+ export type {
2140
+ HeartbeatStatus,
2141
+ HeartbeatResult,
2142
+ HeartbeatEvent,
2143
+ SubscriptionReason,
2144
+ TaskSubscription,
2145
+ SubscriptionEvent,
2146
+ StandupReport,
2147
+ AgentAutonomyLevel,
2148
+ };
2149
+
2150
+ export interface ElectronAPI {
2151
+ selectFolder: () => Promise<string | null>;
2152
+ openFile: (filePath: string, workspacePath?: string) => Promise<string>;
2153
+ showInFinder: (filePath: string, workspacePath?: string) => Promise<void>;
2154
+ readFileForViewer: (filePath: string, workspacePath?: string) => Promise<FileViewerResult>;
2155
+ openExternal: (url: string) => Promise<void>;
2156
+ createTask: (data: any) => Promise<any>;
2157
+ getTask: (id: string) => Promise<any>;
2158
+ listTasks: () => Promise<any[]>;
2159
+ cancelTask: (id: string) => Promise<void>;
2160
+ pauseTask: (id: string) => Promise<void>;
2161
+ resumeTask: (id: string) => Promise<void>;
2162
+ sendStdin: (taskId: string, input: string) => Promise<boolean>;
2163
+ killCommand: (taskId: string, force?: boolean) => Promise<boolean>;
2164
+ renameTask: (id: string, title: string) => Promise<void>;
2165
+ deleteTask: (id: string) => Promise<void>;
2166
+ onTaskEvent: (callback: (event: any) => void) => () => void;
2167
+ getTaskEvents: (taskId: string) => Promise<any[]>;
2168
+ sendMessage: (taskId: string, message: string) => Promise<void>;
2169
+ createWorkspace: (data: any) => Promise<any>;
2170
+ listWorkspaces: () => Promise<any[]>;
2171
+ selectWorkspace: (id: string) => Promise<any>;
2172
+ getTempWorkspace: () => Promise<any>;
2173
+ updateWorkspacePermissions: (id: string, permissions: { shell?: boolean; network?: boolean }) => Promise<any>;
2174
+ respondToApproval: (data: any) => Promise<void>;
2175
+ listArtifacts: (taskId: string) => Promise<any[]>;
2176
+ previewArtifact: (id: string) => Promise<any>;
2177
+ listSkills: () => Promise<any[]>;
2178
+ getSkill: (id: string) => Promise<any>;
2179
+ // LLM Settings
2180
+ getLLMSettings: () => Promise<any>;
2181
+ saveLLMSettings: (settings: any) => Promise<{ success: boolean }>;
2182
+ testLLMProvider: (config: any) => Promise<{ success: boolean; error?: string }>;
2183
+ getLLMModels: () => Promise<Array<{ key: string; displayName: string; description: string }>>;
2184
+ getLLMConfigStatus: () => Promise<{
2185
+ currentProvider: 'anthropic' | 'bedrock' | 'ollama';
2186
+ currentModel: string;
2187
+ providers: Array<{ type: 'anthropic' | 'bedrock' | 'ollama'; name: string; configured: boolean; source?: string }>;
2188
+ models: Array<{ key: string; displayName: string; description: string }>;
2189
+ }>;
2190
+ setLLMModel: (modelKey: string) => Promise<{ success: boolean }>;
2191
+ getOllamaModels: (baseUrl?: string) => Promise<Array<{ name: string; size: number; modified: string }>>;
2192
+ getGeminiModels: (apiKey?: string) => Promise<Array<{ name: string; displayName: string; description: string }>>;
2193
+ getOpenRouterModels: (apiKey?: string) => Promise<Array<{ id: string; name: string; context_length: number }>>;
2194
+ getOpenAIModels: (apiKey?: string) => Promise<Array<{ id: string; name: string; description: string }>>;
2195
+ openaiOAuthStart: () => Promise<{ success: boolean; error?: string }>;
2196
+ openaiOAuthLogout: () => Promise<{ success: boolean }>;
2197
+ getBedrockModels: (config?: { region?: string; accessKeyId?: string; secretAccessKey?: string; profile?: string }) => Promise<Array<{ id: string; name: string; provider: string; description: string }>>;
2198
+ // Gateway / Channel APIs
2199
+ getGatewayChannels: () => Promise<any[]>;
2200
+ addGatewayChannel: (data: { type: string; name: string; botToken?: string; securityMode?: string; applicationId?: string; guildIds?: string[]; appToken?: string; signingSecret?: string; allowedNumbers?: string[]; selfChatMode?: boolean; responsePrefix?: string; cliPath?: string; dbPath?: string; allowedContacts?: string[]; dmPolicy?: string; groupPolicy?: string; phoneNumber?: string; dataDir?: string; mode?: string; trustMode?: string; sendReadReceipts?: boolean; sendTypingIndicators?: boolean; mattermostServerUrl?: string; mattermostToken?: string; mattermostTeamId?: string; matrixHomeserver?: string; matrixUserId?: string; matrixAccessToken?: string; matrixDeviceId?: string; matrixRoomIds?: string[]; twitchUsername?: string; twitchOauthToken?: string; twitchChannels?: string[]; twitchAllowWhispers?: boolean; lineChannelAccessToken?: string; lineChannelSecret?: string; lineWebhookPort?: number; lineWebhookPath?: string; blueBubblesServerUrl?: string; blueBubblesPassword?: string; blueBubblesWebhookPort?: number; blueBubblesAllowedContacts?: string[]; emailAddress?: string; emailPassword?: string; emailImapHost?: string; emailImapPort?: number; emailSmtpHost?: string; emailSmtpPort?: number; emailDisplayName?: string; emailAllowedSenders?: string[]; emailSubjectFilter?: string; appId?: string; appPassword?: string; tenantId?: string; webhookPort?: number; serviceAccountKeyPath?: string; projectId?: string; webhookPath?: string }) => Promise<any>;
2201
+ updateGatewayChannel: (data: { id: string; name?: string; securityMode?: string; config?: { selfChatMode?: boolean; responsePrefix?: string; [key: string]: unknown } }) => Promise<void>;
2202
+ removeGatewayChannel: (id: string) => Promise<void>;
2203
+ enableGatewayChannel: (id: string) => Promise<void>;
2204
+ disableGatewayChannel: (id: string) => Promise<void>;
2205
+ testGatewayChannel: (id: string) => Promise<{ success: boolean; error?: string; botUsername?: string }>;
2206
+ getGatewayUsers: (channelId: string) => Promise<any[]>;
2207
+ grantGatewayAccess: (channelId: string, userId: string, displayName?: string) => Promise<void>;
2208
+ revokeGatewayAccess: (channelId: string, userId: string) => Promise<void>;
2209
+ generateGatewayPairing: (channelId: string, userId: string, displayName?: string) => Promise<string>;
2210
+ onGatewayMessage: (callback: (data: any) => void) => () => void;
2211
+ // WhatsApp-specific APIs
2212
+ getWhatsAppInfo: () => Promise<{ qrCode?: string; phoneNumber?: string; status?: string }>;
2213
+ whatsAppLogout: () => Promise<void>;
2214
+ onWhatsAppQRCode: (callback: (event: any, qr: string) => void) => void;
2215
+ onWhatsAppConnected: (callback: () => void) => void;
2216
+ onWhatsAppStatus: (callback: (event: any, data: { status: string; error?: string }) => void) => void;
2217
+ // Search Settings
2218
+ getSearchSettings: () => Promise<{
2219
+ primaryProvider: 'tavily' | 'brave' | 'serpapi' | 'google' | null;
2220
+ fallbackProvider: 'tavily' | 'brave' | 'serpapi' | 'google' | null;
2221
+ }>;
2222
+ saveSearchSettings: (settings: any) => Promise<{ success: boolean }>;
2223
+ getSearchConfigStatus: () => Promise<{
2224
+ primaryProvider: 'tavily' | 'brave' | 'serpapi' | 'google' | null;
2225
+ fallbackProvider: 'tavily' | 'brave' | 'serpapi' | 'google' | null;
2226
+ providers: Array<{
2227
+ type: 'tavily' | 'brave' | 'serpapi' | 'google';
2228
+ name: string;
2229
+ description: string;
2230
+ configured: boolean;
2231
+ supportedTypes: Array<'web' | 'news' | 'images'>;
2232
+ }>;
2233
+ isConfigured: boolean;
2234
+ }>;
2235
+ testSearchProvider: (providerType: string) => Promise<{ success: boolean; error?: string }>;
2236
+ // X/Twitter Settings
2237
+ getXSettings: () => Promise<{
2238
+ enabled: boolean;
2239
+ authMethod: 'browser' | 'manual';
2240
+ authToken?: string;
2241
+ ct0?: string;
2242
+ cookieSource?: string[];
2243
+ chromeProfile?: string;
2244
+ chromeProfileDir?: string;
2245
+ firefoxProfile?: string;
2246
+ timeoutMs?: number;
2247
+ cookieTimeoutMs?: number;
2248
+ quoteDepth?: number;
2249
+ }>;
2250
+ saveXSettings: (settings: any) => Promise<{ success: boolean }>;
2251
+ testXConnection: () => Promise<{ success: boolean; error?: string; username?: string; userId?: string }>;
2252
+ getXStatus: () => Promise<{ installed: boolean; connected: boolean; username?: string; error?: string }>;
2253
+ // App Updates
2254
+ getAppVersion: () => Promise<{
2255
+ version: string;
2256
+ isDev: boolean;
2257
+ isGitRepo: boolean;
2258
+ isNpmGlobal: boolean;
2259
+ gitBranch?: string;
2260
+ gitCommit?: string;
2261
+ }>;
2262
+ checkForUpdates: () => Promise<{
2263
+ available: boolean;
2264
+ currentVersion: string;
2265
+ latestVersion: string;
2266
+ releaseNotes?: string;
2267
+ releaseUrl?: string;
2268
+ publishedAt?: string;
2269
+ updateMode: 'git' | 'npm' | 'electron-updater';
2270
+ }>;
2271
+ downloadUpdate: (updateInfo: any) => Promise<{ success: boolean }>;
2272
+ installUpdate: () => Promise<{ success: boolean }>;
2273
+ onUpdateProgress: (callback: (progress: {
2274
+ phase: 'checking' | 'downloading' | 'extracting' | 'installing' | 'complete' | 'error';
2275
+ percent?: number;
2276
+ message: string;
2277
+ bytesDownloaded?: number;
2278
+ bytesTotal?: number;
2279
+ }) => void) => () => void;
2280
+ onUpdateDownloaded: (callback: (info: { requiresRestart: boolean; message: string }) => void) => () => void;
2281
+ onUpdateError: (callback: (error: { error: string }) => void) => () => void;
2282
+ // Guardrail Settings
2283
+ getGuardrailSettings: () => Promise<{
2284
+ maxTokensPerTask: number;
2285
+ tokenBudgetEnabled: boolean;
2286
+ maxCostPerTask: number;
2287
+ costBudgetEnabled: boolean;
2288
+ blockDangerousCommands: boolean;
2289
+ customBlockedPatterns: string[];
2290
+ autoApproveTrustedCommands: boolean;
2291
+ trustedCommandPatterns: string[];
2292
+ maxFileSizeMB: number;
2293
+ fileSizeLimitEnabled: boolean;
2294
+ enforceAllowedDomains: boolean;
2295
+ allowedDomains: string[];
2296
+ maxIterationsPerTask: number;
2297
+ iterationLimitEnabled: boolean;
2298
+ }>;
2299
+ saveGuardrailSettings: (settings: any) => Promise<{ success: boolean }>;
2300
+ getGuardrailDefaults: () => Promise<{
2301
+ maxTokensPerTask: number;
2302
+ tokenBudgetEnabled: boolean;
2303
+ maxCostPerTask: number;
2304
+ costBudgetEnabled: boolean;
2305
+ blockDangerousCommands: boolean;
2306
+ customBlockedPatterns: string[];
2307
+ autoApproveTrustedCommands: boolean;
2308
+ trustedCommandPatterns: string[];
2309
+ maxFileSizeMB: number;
2310
+ fileSizeLimitEnabled: boolean;
2311
+ enforceAllowedDomains: boolean;
2312
+ allowedDomains: string[];
2313
+ maxIterationsPerTask: number;
2314
+ iterationLimitEnabled: boolean;
2315
+ }>;
2316
+ // Appearance Settings
2317
+ getAppearanceSettings: () => Promise<{
2318
+ themeMode: 'light' | 'dark' | 'system';
2319
+ accentColor: 'cyan' | 'blue' | 'purple' | 'pink' | 'rose' | 'orange' | 'green' | 'teal' | 'coral';
2320
+ disclaimerAccepted?: boolean;
2321
+ onboardingCompleted?: boolean;
2322
+ onboardingCompletedAt?: string;
2323
+ assistantName?: string;
2324
+ }>;
2325
+ saveAppearanceSettings: (settings: {
2326
+ themeMode?: 'light' | 'dark' | 'system';
2327
+ accentColor?: 'cyan' | 'blue' | 'purple' | 'pink' | 'rose' | 'orange' | 'green' | 'teal' | 'coral';
2328
+ disclaimerAccepted?: boolean;
2329
+ onboardingCompleted?: boolean;
2330
+ onboardingCompletedAt?: string;
2331
+ assistantName?: string;
2332
+ }) => Promise<{ success: boolean }>;
2333
+ // Personality Settings
2334
+ getPersonalitySettings: () => Promise<{
2335
+ activePersonality: 'professional' | 'friendly' | 'concise' | 'creative' | 'technical' | 'casual' | 'custom';
2336
+ customPrompt?: string;
2337
+ customName?: string;
2338
+ agentName?: string;
2339
+ activePersona?: 'none' | 'jarvis' | 'friday' | 'hal' | 'computer' | 'alfred' | 'intern' | 'sensei' | 'pirate' | 'noir' | 'companion';
2340
+ responseStyle?: {
2341
+ emojiUsage: 'none' | 'minimal' | 'moderate' | 'expressive';
2342
+ responseLength: 'terse' | 'balanced' | 'detailed';
2343
+ codeCommentStyle: 'minimal' | 'moderate' | 'verbose';
2344
+ explanationDepth: 'expert' | 'balanced' | 'teaching';
2345
+ };
2346
+ quirks?: {
2347
+ catchphrase?: string;
2348
+ signOff?: string;
2349
+ analogyDomain: 'none' | 'cooking' | 'sports' | 'space' | 'music' | 'nature' | 'gaming' | 'movies' | 'construction';
2350
+ };
2351
+ relationship?: {
2352
+ userName?: string;
2353
+ tasksCompleted: number;
2354
+ firstInteraction?: number;
2355
+ lastMilestoneCelebrated: number;
2356
+ projectsWorkedOn: string[];
2357
+ };
2358
+ workStyle?: 'planner' | 'flexible';
2359
+ }>;
2360
+ savePersonalitySettings: (settings: {
2361
+ activePersonality?: 'professional' | 'friendly' | 'concise' | 'creative' | 'technical' | 'casual' | 'custom';
2362
+ customPrompt?: string;
2363
+ customName?: string;
2364
+ agentName?: string;
2365
+ activePersona?: 'none' | 'jarvis' | 'friday' | 'hal' | 'computer' | 'alfred' | 'intern' | 'sensei' | 'pirate' | 'noir' | 'companion';
2366
+ responseStyle?: {
2367
+ emojiUsage?: 'none' | 'minimal' | 'moderate' | 'expressive';
2368
+ responseLength?: 'terse' | 'balanced' | 'detailed';
2369
+ codeCommentStyle?: 'minimal' | 'moderate' | 'verbose';
2370
+ explanationDepth?: 'expert' | 'balanced' | 'teaching';
2371
+ };
2372
+ quirks?: {
2373
+ catchphrase?: string;
2374
+ signOff?: string;
2375
+ analogyDomain?: 'none' | 'cooking' | 'sports' | 'space' | 'music' | 'nature' | 'gaming' | 'movies' | 'construction';
2376
+ };
2377
+ relationship?: {
2378
+ userName?: string;
2379
+ tasksCompleted?: number;
2380
+ firstInteraction?: number;
2381
+ lastMilestoneCelebrated?: number;
2382
+ projectsWorkedOn?: string[];
2383
+ };
2384
+ workStyle?: 'planner' | 'flexible';
2385
+ }) => Promise<{ success: boolean }>;
2386
+ getPersonalityDefinitions: () => Promise<Array<{
2387
+ id: 'professional' | 'friendly' | 'concise' | 'creative' | 'technical' | 'casual' | 'custom';
2388
+ name: string;
2389
+ description: string;
2390
+ icon: string;
2391
+ traits: string[];
2392
+ promptTemplate: string;
2393
+ }>>;
2394
+ getPersonaDefinitions: () => Promise<Array<{
2395
+ id: 'none' | 'jarvis' | 'friday' | 'hal' | 'computer' | 'alfred' | 'intern' | 'sensei' | 'pirate' | 'noir' | 'companion';
2396
+ name: string;
2397
+ description: string;
2398
+ icon: string;
2399
+ promptTemplate: string;
2400
+ suggestedName?: string;
2401
+ sampleCatchphrase?: string;
2402
+ sampleSignOff?: string;
2403
+ }>>;
2404
+ getRelationshipStats: () => Promise<{
2405
+ tasksCompleted: number;
2406
+ projectsCount: number;
2407
+ daysTogether: number;
2408
+ nextMilestone: number | null;
2409
+ }>;
2410
+ setActivePersonality: (personalityId: string) => Promise<{ success: boolean }>;
2411
+ setActivePersona: (personaId: string) => Promise<{ success: boolean }>;
2412
+ resetPersonalitySettings: (preserveRelationship?: boolean) => Promise<{ success: boolean }>;
2413
+ onPersonalitySettingsChanged: (callback: (settings: any) => void) => () => void;
2414
+ // Queue APIs
2415
+ getQueueStatus: () => Promise<{
2416
+ runningCount: number;
2417
+ queuedCount: number;
2418
+ runningTaskIds: string[];
2419
+ queuedTaskIds: string[];
2420
+ maxConcurrent: number;
2421
+ }>;
2422
+ getQueueSettings: () => Promise<{
2423
+ maxConcurrentTasks: number;
2424
+ taskTimeoutMinutes: number;
2425
+ }>;
2426
+ saveQueueSettings: (settings: { maxConcurrentTasks?: number; taskTimeoutMinutes?: number }) => Promise<{ success: boolean }>;
2427
+ clearQueue: () => Promise<{ success: boolean; clearedRunning: number; clearedQueued: number }>;
2428
+ onQueueUpdate: (callback: (status: {
2429
+ runningCount: number;
2430
+ queuedCount: number;
2431
+ runningTaskIds: string[];
2432
+ queuedTaskIds: string[];
2433
+ maxConcurrent: number;
2434
+ }) => void) => () => void;
2435
+ // Custom Skills APIs
2436
+ listCustomSkills: () => Promise<CustomSkill[]>;
2437
+ listTaskSkills: () => Promise<CustomSkill[]>;
2438
+ listGuidelineSkills: () => Promise<CustomSkill[]>;
2439
+ getCustomSkill: (id: string) => Promise<CustomSkill | undefined>;
2440
+ createCustomSkill: (skill: Omit<CustomSkill, 'filePath'>) => Promise<CustomSkill>;
2441
+ updateCustomSkill: (id: string, updates: Partial<CustomSkill>) => Promise<CustomSkill>;
2442
+ deleteCustomSkill: (id: string) => Promise<boolean>;
2443
+ reloadCustomSkills: () => Promise<CustomSkill[]>;
2444
+ openCustomSkillsFolder: () => Promise<void>;
2445
+ // Skill Registry (SkillHub) APIs
2446
+ searchSkillRegistry: (query: string, options?: { page?: number; pageSize?: number }) => Promise<SkillSearchResult>;
2447
+ getSkillDetails: (skillId: string) => Promise<SkillRegistryEntry | null>;
2448
+ installSkillFromRegistry: (skillId: string, version?: string) => Promise<{ success: boolean; skill?: CustomSkill; error?: string }>;
2449
+ updateSkillFromRegistry: (skillId: string, version?: string) => Promise<{ success: boolean; skill?: CustomSkill; error?: string }>;
2450
+ updateAllSkills: () => Promise<{ updated: string[]; failed: string[] }>;
2451
+ uninstallSkill: (skillId: string) => Promise<{ success: boolean; error?: string }>;
2452
+ listManagedSkills: () => Promise<CustomSkill[]>;
2453
+ checkSkillUpdates: (skillId: string) => Promise<{ hasUpdate: boolean; currentVersion: string | null; latestVersion: string | null }>;
2454
+ getSkillStatus: () => Promise<SkillStatusReport>;
2455
+ getEligibleSkills: () => Promise<CustomSkill[]>;
2456
+ // MCP (Model Context Protocol)
2457
+ getMCPSettings: () => Promise<MCPSettings>;
2458
+ saveMCPSettings: (settings: MCPSettings) => Promise<{ success: boolean }>;
2459
+ addMCPServer: (config: Omit<MCPServerConfig, 'id'>) => Promise<MCPServerConfig>;
2460
+ updateMCPServer: (id: string, updates: Partial<MCPServerConfig>) => Promise<MCPServerConfig>;
2461
+ removeMCPServer: (id: string) => Promise<void>;
2462
+ connectMCPServer: (serverId: string) => Promise<void>;
2463
+ disconnectMCPServer: (serverId: string) => Promise<void>;
2464
+ getMCPStatus: () => Promise<MCPServerStatus[]>;
2465
+ getMCPServerStatus: (serverId: string) => Promise<MCPServerStatus | null>;
2466
+ getMCPAllTools: () => Promise<MCPTool[]>;
2467
+ getMCPServerTools: (serverId: string) => Promise<MCPTool[]>;
2468
+ testMCPServer: (serverId: string) => Promise<{ success: boolean; error?: string; tools?: number }>;
2469
+ onMCPStatusChange: (callback: (status: MCPServerStatus[]) => void) => () => void;
2470
+ // MCP Registry
2471
+ fetchMCPRegistry: () => Promise<MCPRegistry>;
2472
+ searchMCPRegistry: (query: string, tags?: string[]) => Promise<MCPRegistryEntry[]>;
2473
+ installMCPServer: (entryId: string) => Promise<MCPServerConfig>;
2474
+ uninstallMCPServer: (serverId: string) => Promise<void>;
2475
+ checkMCPUpdates: () => Promise<MCPUpdateInfo[]>;
2476
+ updateMCPServerFromRegistry: (serverId: string) => Promise<MCPServerConfig>;
2477
+ // MCP Host
2478
+ startMCPHost: (port?: number) => Promise<{ success: boolean; port?: number }>;
2479
+ stopMCPHost: () => Promise<void>;
2480
+ getMCPHostStatus: () => Promise<{ running: boolean; port?: number }>;
2481
+ // Built-in Tools Settings
2482
+ getBuiltinToolsSettings: () => Promise<BuiltinToolsSettings>;
2483
+ saveBuiltinToolsSettings: (settings: BuiltinToolsSettings) => Promise<{ success: boolean }>;
2484
+ getBuiltinToolsCategories: () => Promise<Record<string, string[]>>;
2485
+ // Tray (Menu Bar)
2486
+ getTraySettings: () => Promise<TraySettings>;
2487
+ saveTraySettings: (settings: Partial<TraySettings>) => Promise<{ success: boolean }>;
2488
+ onTrayNewTask: (callback: () => void) => () => void;
2489
+ onTraySelectWorkspace: (callback: (event: any, workspaceId: string) => void) => () => void;
2490
+ onTrayOpenSettings: (callback: () => void) => () => void;
2491
+ onTrayOpenAbout: (callback: () => void) => () => void;
2492
+ onTrayCheckUpdates: (callback: () => void) => () => void;
2493
+ // Cron (Scheduled Tasks)
2494
+ getCronStatus: () => Promise<CronStatusSummary>;
2495
+ listCronJobs: (opts?: { includeDisabled?: boolean }) => Promise<CronJob[]>;
2496
+ getCronJob: (id: string) => Promise<CronJob | null>;
2497
+ addCronJob: (job: CronJobCreate) => Promise<{ ok: true; job: CronJob } | { ok: false; error: string }>;
2498
+ updateCronJob: (id: string, patch: CronJobPatch) => Promise<{ ok: true; job: CronJob } | { ok: false; error: string }>;
2499
+ removeCronJob: (id: string) => Promise<{ ok: true; removed: boolean } | { ok: false; removed: false; error: string }>;
2500
+ runCronJob: (id: string, mode?: 'due' | 'force') => Promise<
2501
+ | { ok: true; ran: true; taskId: string }
2502
+ | { ok: true; ran: false; reason: 'not-due' | 'disabled' | 'not-found' }
2503
+ | { ok: false; error: string }
2504
+ >;
2505
+ onCronEvent: (callback: (event: CronEvent) => void) => () => void;
2506
+ getCronRunHistory: (id: string) => Promise<CronRunHistoryResult | null>;
2507
+ clearCronRunHistory: (id: string) => Promise<boolean>;
2508
+ getCronWebhookStatus: () => Promise<CronWebhookStatus>;
2509
+ // Notifications
2510
+ listNotifications: () => Promise<AppNotification[]>;
2511
+ getUnreadNotificationCount: () => Promise<number>;
2512
+ markNotificationRead: (id: string) => Promise<AppNotification | null>;
2513
+ markAllNotificationsRead: () => Promise<void>;
2514
+ deleteNotification: (id: string) => Promise<boolean>;
2515
+ deleteAllNotifications: () => Promise<void>;
2516
+ onNotificationEvent: (callback: (event: NotificationEvent) => void) => () => void;
2517
+ // Hooks (Webhooks & Gmail Pub/Sub)
2518
+ getHooksSettings: () => Promise<HooksSettings>;
2519
+ saveHooksSettings: (settings: Partial<HooksSettings>) => Promise<HooksSettings>;
2520
+ enableHooks: () => Promise<{ enabled: boolean; gmailWatcherError?: string }>;
2521
+ disableHooks: () => Promise<{ enabled: boolean }>;
2522
+ regenerateHookToken: () => Promise<{ token: string }>;
2523
+ getHooksStatus: () => Promise<HooksStatus>;
2524
+ addHookMapping: (mapping: HookMapping) => Promise<{ ok: boolean }>;
2525
+ removeHookMapping: (id: string) => Promise<{ ok: boolean }>;
2526
+ configureGmailHooks: (config: GmailHooksConfig) => Promise<{ ok: boolean; gmail?: GmailHooksConfig }>;
2527
+ getGmailHooksStatus: () => Promise<GmailHooksStatus>;
2528
+ startGmailWatcher: () => Promise<{ ok: boolean; error?: string }>;
2529
+ stopGmailWatcher: () => Promise<{ ok: boolean }>;
2530
+ onHooksEvent: (callback: (event: HooksEvent) => void) => () => void;
2531
+
2532
+ // Control Plane (WebSocket Gateway)
2533
+ getControlPlaneSettings: () => Promise<ControlPlaneSettingsData>;
2534
+ saveControlPlaneSettings: (settings: Partial<ControlPlaneSettingsData>) => Promise<{ ok: boolean; error?: string }>;
2535
+ enableControlPlane: () => Promise<{ ok: boolean; token?: string; error?: string }>;
2536
+ disableControlPlane: () => Promise<{ ok: boolean; error?: string }>;
2537
+ startControlPlane: () => Promise<{
2538
+ ok: boolean;
2539
+ address?: { host: string; port: number; wsUrl: string };
2540
+ tailscale?: { httpsUrl?: string; wssUrl?: string };
2541
+ error?: string;
2542
+ }>;
2543
+ stopControlPlane: () => Promise<{ ok: boolean; error?: string }>;
2544
+ getControlPlaneStatus: () => Promise<ControlPlaneStatus>;
2545
+ regenerateControlPlaneToken: () => Promise<{ ok: boolean; token?: string; error?: string }>;
2546
+ onControlPlaneEvent: (callback: (event: ControlPlaneEvent) => void) => () => void;
2547
+
2548
+ // Tailscale
2549
+ checkTailscaleAvailability: () => Promise<TailscaleAvailability>;
2550
+ getTailscaleStatus: () => Promise<{ settings: any; exposure: any }>;
2551
+ setTailscaleMode: (mode: TailscaleMode) => Promise<{ ok: boolean; error?: string }>;
2552
+
2553
+ // Remote Gateway
2554
+ connectRemoteGateway: (config?: RemoteGatewayConfig) => Promise<{ ok: boolean; error?: string }>;
2555
+ disconnectRemoteGateway: () => Promise<{ ok: boolean; error?: string }>;
2556
+ getRemoteGatewayStatus: () => Promise<RemoteGatewayStatus>;
2557
+ saveRemoteGatewayConfig: (config: RemoteGatewayConfig) => Promise<{ ok: boolean; error?: string }>;
2558
+ testRemoteGatewayConnection: (config: RemoteGatewayConfig) => Promise<{ ok: boolean; latencyMs?: number; error?: string }>;
2559
+ onRemoteGatewayEvent: (callback: (event: RemoteGatewayEvent) => void) => () => void;
2560
+
2561
+ // SSH Tunnel
2562
+ connectSSHTunnel: (config: SSHTunnelConfig) => Promise<{ ok: boolean; error?: string }>;
2563
+ disconnectSSHTunnel: () => Promise<{ ok: boolean; error?: string }>;
2564
+ getSSHTunnelStatus: () => Promise<SSHTunnelStatus>;
2565
+ saveSSHTunnelConfig: (config: SSHTunnelConfig) => Promise<{ ok: boolean; error?: string }>;
2566
+ testSSHTunnelConnection: (config: SSHTunnelConfig) => Promise<{ ok: boolean; latencyMs?: number; error?: string }>;
2567
+ onSSHTunnelEvent: (callback: (event: SSHTunnelEvent) => void) => () => void;
2568
+
2569
+ // Live Canvas APIs
2570
+ canvasCreate: (data: { taskId: string; workspaceId: string; title?: string }) => Promise<CanvasSession>;
2571
+ canvasGetSession: (sessionId: string) => Promise<CanvasSession | null>;
2572
+ canvasListSessions: (taskId?: string) => Promise<CanvasSession[]>;
2573
+ canvasShow: (sessionId: string) => Promise<{ success: boolean }>;
2574
+ canvasHide: (sessionId: string) => Promise<{ success: boolean }>;
2575
+ canvasClose: (sessionId: string) => Promise<{ success: boolean }>;
2576
+ canvasPush: (data: { sessionId: string; content: string; filename?: string }) => Promise<{ success: boolean }>;
2577
+ canvasEval: (data: { sessionId: string; script: string }) => Promise<{ result: unknown }>;
2578
+ canvasSnapshot: (sessionId: string) => Promise<{ imageBase64: string; width: number; height: number }>;
2579
+ canvasExportHTML: (sessionId: string) => Promise<{ content: string; filename: string }>;
2580
+ canvasExportToFolder: (data: { sessionId: string; targetDir: string }) => Promise<{ files: string[]; targetDir: string }>;
2581
+ canvasOpenInBrowser: (sessionId: string) => Promise<{ success: boolean; path: string }>;
2582
+ canvasGetSessionDir: (sessionId: string) => Promise<string | null>;
2583
+ onCanvasEvent: (callback: (event: CanvasEvent) => void) => () => void;
2584
+
2585
+ // Mobile Companion Nodes
2586
+ nodeList: () => Promise<{ ok: boolean; nodes?: NodeInfo[]; error?: string }>;
2587
+ nodeGet: (nodeId: string) => Promise<{ ok: boolean; node?: NodeInfo; error?: string }>;
2588
+ nodeInvoke: (params: { nodeId: string; command: string; params?: Record<string, unknown>; timeoutMs?: number }) =>
2589
+ Promise<{ ok: boolean; payload?: unknown; error?: { code: string; message: string } }>;
2590
+ onNodeEvent: (callback: (event: NodeEvent) => void) => () => void;
2591
+
2592
+ // Memory System
2593
+ getMemorySettings: (workspaceId: string) => Promise<MemorySettings>;
2594
+ saveMemorySettings: (data: { workspaceId: string; settings: Partial<MemorySettings> }) => Promise<{ success: boolean }>;
2595
+ searchMemories: (data: { workspaceId: string; query: string; limit?: number }) => Promise<MemorySearchResult[]>;
2596
+ getMemoryTimeline: (data: { memoryId: string; windowSize?: number }) => Promise<MemoryTimelineEntry[]>;
2597
+ getMemoryDetails: (ids: string[]) => Promise<Memory[]>;
2598
+ getRecentMemories: (data: { workspaceId: string; limit?: number }) => Promise<Memory[]>;
2599
+ getMemoryStats: (workspaceId: string) => Promise<MemoryStats>;
2600
+ clearMemory: (workspaceId: string) => Promise<{ success: boolean }>;
2601
+ onMemoryEvent: (callback: (event: { type: string; workspaceId: string }) => void) => () => void;
2602
+
2603
+ // Migration Status
2604
+ getMigrationStatus: () => Promise<MigrationStatus>;
2605
+ dismissMigrationNotification: () => Promise<{ success: boolean }>;
2606
+
2607
+ // Extensions / Plugins
2608
+ getExtensions: () => Promise<ExtensionData[]>;
2609
+ getExtension: (name: string) => Promise<ExtensionData | null>;
2610
+ enableExtension: (name: string) => Promise<{ success: boolean; error?: string }>;
2611
+ disableExtension: (name: string) => Promise<{ success: boolean; error?: string }>;
2612
+ reloadExtension: (name: string) => Promise<{ success: boolean; error?: string }>;
2613
+ getExtensionConfig: (name: string) => Promise<Record<string, unknown>>;
2614
+ setExtensionConfig: (name: string, config: Record<string, unknown>) => Promise<{ success: boolean; error?: string }>;
2615
+ discoverExtensions: () => Promise<ExtensionData[]>;
2616
+
2617
+ // Webhook Tunnel
2618
+ getTunnelStatus: () => Promise<TunnelStatusData>;
2619
+ startTunnel: (config: { provider: string; port: number; ngrokAuthToken?: string; ngrokRegion?: string }) => Promise<{ success: boolean; url?: string; error?: string }>;
2620
+ stopTunnel: () => Promise<{ success: boolean; error?: string }>;
2621
+
2622
+ // Agent Role (Agent Squad)
2623
+ getAgentRoles: (includeInactive?: boolean) => Promise<AgentRoleData[]>;
2624
+ getAgentRole: (id: string) => Promise<AgentRoleData | undefined>;
2625
+ createAgentRole: (request: CreateAgentRoleRequest) => Promise<AgentRoleData>;
2626
+ updateAgentRole: (request: UpdateAgentRoleRequest) => Promise<AgentRoleData | undefined>;
2627
+ deleteAgentRole: (id: string) => Promise<boolean>;
2628
+ assignAgentRoleToTask: (taskId: string, agentRoleId: string | null) => Promise<boolean>;
2629
+ getDefaultAgentRoles: () => Promise<Omit<AgentRoleData, 'id' | 'createdAt' | 'updatedAt'>[]>;
2630
+ seedDefaultAgentRoles: () => Promise<AgentRoleData[]>;
2631
+
2632
+ // Activity Feed
2633
+ listActivities: (query: ActivityListQuery) => Promise<ActivityData[]>;
2634
+ createActivity: (request: CreateActivityRequest) => Promise<ActivityData>;
2635
+ markActivityRead: (id: string) => Promise<{ success: boolean }>;
2636
+ markAllActivitiesRead: (workspaceId: string) => Promise<{ count: number }>;
2637
+ pinActivity: (id: string) => Promise<ActivityData | undefined>;
2638
+ deleteActivity: (id: string) => Promise<{ success: boolean }>;
2639
+ onActivityEvent: (callback: (event: ActivityEvent) => void) => () => void;
2640
+
2641
+ // @Mention System
2642
+ listMentions: (query: MentionListQuery) => Promise<MentionData[]>;
2643
+ createMention: (request: CreateMentionRequest) => Promise<MentionData>;
2644
+ acknowledgeMention: (id: string) => Promise<MentionData | undefined>;
2645
+ completeMention: (id: string) => Promise<MentionData | undefined>;
2646
+ dismissMention: (id: string) => Promise<MentionData | undefined>;
2647
+ onMentionEvent: (callback: (event: MentionEvent) => void) => () => void;
2648
+ // Mission Control - Heartbeat APIs
2649
+ getHeartbeatConfig: (agentRoleId: string) => Promise<{
2650
+ heartbeatEnabled: boolean;
2651
+ heartbeatIntervalMinutes: number;
2652
+ heartbeatStaggerOffset: number;
2653
+ heartbeatStatus: HeartbeatStatus;
2654
+ lastHeartbeatAt?: number;
2655
+ } | undefined>;
2656
+ updateHeartbeatConfig: (agentRoleId: string, config: {
2657
+ heartbeatEnabled?: boolean;
2658
+ heartbeatIntervalMinutes?: number;
2659
+ heartbeatStaggerOffset?: number;
2660
+ }) => Promise<any>;
2661
+ triggerHeartbeat: (agentRoleId: string) => Promise<HeartbeatResult>;
2662
+ getHeartbeatStatus: (agentRoleId: string) => Promise<{
2663
+ heartbeatEnabled: boolean;
2664
+ heartbeatStatus: HeartbeatStatus;
2665
+ lastHeartbeatAt?: number;
2666
+ nextHeartbeatAt?: number;
2667
+ isRunning: boolean;
2668
+ } | undefined>;
2669
+ getAllHeartbeatStatus: () => Promise<Array<{
2670
+ agentRoleId: string;
2671
+ agentName: string;
2672
+ heartbeatEnabled: boolean;
2673
+ heartbeatStatus: HeartbeatStatus;
2674
+ lastHeartbeatAt?: number;
2675
+ nextHeartbeatAt?: number;
2676
+ }>>;
2677
+ onHeartbeatEvent: (callback: (event: HeartbeatEvent) => void) => () => void;
2678
+ // Mission Control - Task Subscription APIs
2679
+ listSubscriptions: (taskId: string) => Promise<TaskSubscription[]>;
2680
+ addSubscription: (taskId: string, agentRoleId: string, reason: SubscriptionReason) => Promise<TaskSubscription>;
2681
+ removeSubscription: (taskId: string, agentRoleId: string) => Promise<boolean>;
2682
+ getTaskSubscribers: (taskId: string) => Promise<TaskSubscription[]>;
2683
+ getAgentSubscriptions: (agentRoleId: string) => Promise<TaskSubscription[]>;
2684
+ onSubscriptionEvent: (callback: (event: SubscriptionEvent) => void) => () => void;
2685
+ // Mission Control - Standup Report APIs
2686
+ generateStandupReport: (workspaceId: string) => Promise<StandupReport>;
2687
+ getLatestStandupReport: (workspaceId: string) => Promise<StandupReport | undefined>;
2688
+ listStandupReports: (workspaceId: string, limit?: number) => Promise<StandupReport[]>;
2689
+ deliverStandupReport: (reportId: string, channelType: string, channelId: string) => Promise<void>;
2690
+ // Task Board APIs
2691
+ moveTaskToColumn: (taskId: string, column: TaskBoardColumn) => Promise<any>;
2692
+ setTaskPriority: (taskId: string, priority: number) => Promise<any>;
2693
+ setTaskDueDate: (taskId: string, dueDate: number | null) => Promise<any>;
2694
+ setTaskEstimate: (taskId: string, estimatedMinutes: number | null) => Promise<any>;
2695
+ addTaskLabel: (taskId: string, labelId: string) => Promise<any>;
2696
+ removeTaskLabel: (taskId: string, labelId: string) => Promise<any>;
2697
+ onTaskBoardEvent: (callback: (event: TaskBoardEvent) => void) => () => void;
2698
+ // Task Label APIs
2699
+ listTaskLabels: (query: TaskLabelListQuery) => Promise<TaskLabelData[]>;
2700
+ createTaskLabel: (request: CreateTaskLabelRequest) => Promise<TaskLabelData>;
2701
+ updateTaskLabel: (id: string, request: UpdateTaskLabelRequest) => Promise<TaskLabelData>;
2702
+ deleteTaskLabel: (id: string) => Promise<boolean>;
2703
+ // Agent Working State APIs
2704
+ getWorkingState: (id: string) => Promise<AgentWorkingStateData | undefined>;
2705
+ getCurrentWorkingState: (query: WorkingStateQuery) => Promise<AgentWorkingStateData | undefined>;
2706
+ updateWorkingState: (request: UpdateWorkingStateRequest) => Promise<AgentWorkingStateData>;
2707
+ getWorkingStateHistory: (query: WorkingStateHistoryQuery) => Promise<AgentWorkingStateData[]>;
2708
+ restoreWorkingState: (id: string) => Promise<AgentWorkingStateData | undefined>;
2709
+ deleteWorkingState: (id: string) => Promise<{ success: boolean }>;
2710
+ listWorkingStatesForTask: (taskId: string) => Promise<AgentWorkingStateData[]>;
2711
+ // Context Policy APIs
2712
+ getContextPolicy: (channelId: string, contextType: ContextTypeValue) => Promise<ContextPolicyData>;
2713
+ getContextPolicyForChat: (channelId: string, chatId: string, isGroup: boolean) => Promise<ContextPolicyData>;
2714
+ listContextPolicies: (channelId: string) => Promise<ContextPolicyData[]>;
2715
+ updateContextPolicy: (channelId: string, contextType: ContextTypeValue, options: UpdateContextPolicyOptions) => Promise<ContextPolicyData>;
2716
+ deleteContextPolicies: (channelId: string) => Promise<{ count: number }>;
2717
+ createDefaultContextPolicies: (channelId: string) => Promise<{ success: boolean }>;
2718
+ isToolAllowedInContext: (channelId: string, contextType: ContextTypeValue, toolName: string, toolGroups: string[]) => Promise<{ allowed: boolean }>;
2719
+ // Voice Mode APIs
2720
+ getVoiceSettings: () => Promise<VoiceSettingsData>;
2721
+ saveVoiceSettings: (settings: Partial<VoiceSettingsData>) => Promise<VoiceSettingsData>;
2722
+ getVoiceState: () => Promise<VoiceStateData>;
2723
+ voiceSpeak: (text: string) => Promise<{ success: boolean; audioData?: number[] | null; error?: string }>;
2724
+ voiceStopSpeaking: () => Promise<{ success: boolean }>;
2725
+ voiceTranscribe: (audioData: ArrayBuffer) => Promise<{ text: string; error?: string }>;
2726
+ getElevenLabsVoices: () => Promise<ElevenLabsVoiceData[]>;
2727
+ testElevenLabsConnection: () => Promise<{ success: boolean; voiceCount?: number; error?: string }>;
2728
+ testOpenAIVoiceConnection: () => Promise<{ success: boolean; error?: string }>;
2729
+ testAzureVoiceConnection: () => Promise<{ success: boolean; error?: string }>;
2730
+ onVoiceEvent: (callback: (event: VoiceEventData) => void) => () => void;
2731
+ }
2732
+
2733
+ // Migration status type (for showing one-time notifications after app rename)
2734
+ export interface MigrationStatus {
2735
+ migrated: boolean;
2736
+ notificationDismissed: boolean;
2737
+ timestamp?: string;
2738
+ }
2739
+
2740
+ // Extension / Plugin types (duplicated from shared/types since preload is sandboxed)
2741
+ export type ExtensionType = 'channel' | 'tool' | 'provider' | 'integration';
2742
+ export type ExtensionState = 'loading' | 'loaded' | 'registered' | 'active' | 'error' | 'disabled';
2743
+
2744
+ export interface ExtensionData {
2745
+ name: string;
2746
+ displayName: string;
2747
+ version: string;
2748
+ description: string;
2749
+ author?: string;
2750
+ type: ExtensionType;
2751
+ state: ExtensionState;
2752
+ path: string;
2753
+ loadedAt: number;
2754
+ error?: string;
2755
+ capabilities?: Record<string, boolean>;
2756
+ configSchema?: Record<string, unknown>;
2757
+ }
2758
+
2759
+ // Webhook Tunnel types
2760
+ export type TunnelProvider = 'ngrok' | 'tailscale' | 'cloudflare' | 'localtunnel';
2761
+ export type TunnelStatus = 'stopped' | 'starting' | 'running' | 'error';
2762
+
2763
+ export interface TunnelStatusData {
2764
+ status: TunnelStatus;
2765
+ provider?: TunnelProvider;
2766
+ url?: string;
2767
+ error?: string;
2768
+ startedAt?: number;
2769
+ }
2770
+
2771
+ // Voice Mode types (inlined for sandboxed preload)
2772
+ export type VoiceProvider = 'elevenlabs' | 'openai' | 'azure' | 'local';
2773
+ export type VoiceInputMode = 'push_to_talk' | 'voice_activity' | 'disabled';
2774
+ export type VoiceResponseMode = 'auto' | 'manual' | 'smart';
2775
+
2776
+ export interface VoiceSettingsData {
2777
+ enabled: boolean;
2778
+ ttsProvider: VoiceProvider;
2779
+ sttProvider: VoiceProvider;
2780
+ elevenLabsApiKey?: string;
2781
+ openaiApiKey?: string;
2782
+ elevenLabsVoiceId?: string;
2783
+ openaiVoice?: 'alloy' | 'echo' | 'fable' | 'onyx' | 'nova' | 'shimmer';
2784
+ /** Azure OpenAI endpoint URL */
2785
+ azureEndpoint?: string;
2786
+ /** Azure OpenAI API key */
2787
+ azureApiKey?: string;
2788
+ /** Azure OpenAI TTS deployment name */
2789
+ azureTtsDeploymentName?: string;
2790
+ /** Azure OpenAI STT deployment name */
2791
+ azureSttDeploymentName?: string;
2792
+ /** Azure OpenAI API version */
2793
+ azureApiVersion?: string;
2794
+ /** Selected Azure voice */
2795
+ azureVoice?: 'alloy' | 'echo' | 'fable' | 'onyx' | 'nova' | 'shimmer';
2796
+ inputMode: VoiceInputMode;
2797
+ responseMode: VoiceResponseMode;
2798
+ pushToTalkKey: string;
2799
+ volume: number;
2800
+ speechRate: number;
2801
+ language: string;
2802
+ wakeWordEnabled: boolean;
2803
+ wakeWord?: string;
2804
+ silenceTimeout: number;
2805
+ audioFeedback: boolean;
2806
+ }
2807
+
2808
+ export interface VoiceStateData {
2809
+ isActive: boolean;
2810
+ isListening: boolean;
2811
+ isSpeaking: boolean;
2812
+ isProcessing: boolean;
2813
+ audioLevel: number;
2814
+ partialTranscript?: string;
2815
+ error?: string;
2816
+ }
2817
+
2818
+ export interface ElevenLabsVoiceData {
2819
+ voice_id: string;
2820
+ name: string;
2821
+ category?: string;
2822
+ description?: string;
2823
+ preview_url?: string;
2824
+ labels?: Record<string, string>;
2825
+ }
2826
+
2827
+ export type VoiceEventType =
2828
+ | 'voice:state-changed'
2829
+ | 'voice:transcript'
2830
+ | 'voice:partial-transcript'
2831
+ | 'voice:speaking-start'
2832
+ | 'voice:speaking-end'
2833
+ | 'voice:error'
2834
+ | 'voice:audio-level';
2835
+
2836
+ export interface VoiceEventData {
2837
+ type: VoiceEventType;
2838
+ data: VoiceStateData | string | number | { message: string };
2839
+ }
2840
+
2841
+ declare global {
2842
+ interface Window {
2843
+ electronAPI: ElectronAPI;
2844
+ }
2845
+ }