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,631 @@
1
+ "use strict";
2
+ /**
3
+ * Google Chat Channel Adapter
4
+ *
5
+ * Implements the ChannelAdapter interface using Google Chat API.
6
+ * Supports direct messages, spaces, and threaded conversations.
7
+ *
8
+ * Authentication: Service Account with Domain-Wide Delegation
9
+ * Message reception: HTTP webhook or Pub/Sub subscription
10
+ * Message sending: Google Chat REST API
11
+ */
12
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ var desc = Object.getOwnPropertyDescriptor(m, k);
15
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
+ desc = { enumerable: true, get: function() { return m[k]; } };
17
+ }
18
+ Object.defineProperty(o, k2, desc);
19
+ }) : (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ o[k2] = m[k];
22
+ }));
23
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
25
+ }) : function(o, v) {
26
+ o["default"] = v;
27
+ });
28
+ var __importStar = (this && this.__importStar) || (function () {
29
+ var ownKeys = function(o) {
30
+ ownKeys = Object.getOwnPropertyNames || function (o) {
31
+ var ar = [];
32
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
33
+ return ar;
34
+ };
35
+ return ownKeys(o);
36
+ };
37
+ return function (mod) {
38
+ if (mod && mod.__esModule) return mod;
39
+ var result = {};
40
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
41
+ __setModuleDefault(result, mod);
42
+ return result;
43
+ };
44
+ })();
45
+ Object.defineProperty(exports, "__esModule", { value: true });
46
+ exports.GoogleChatAdapter = void 0;
47
+ exports.createGoogleChatAdapter = createGoogleChatAdapter;
48
+ const http = __importStar(require("http"));
49
+ const https = __importStar(require("https"));
50
+ const fs = __importStar(require("fs"));
51
+ const path = __importStar(require("path"));
52
+ const crypto = __importStar(require("crypto"));
53
+ /**
54
+ * Simple TTL cache for message deduplication
55
+ */
56
+ class MessageDeduplicationCache {
57
+ constructor(ttlMs = 60000) {
58
+ this.cache = new Map();
59
+ this.ttlMs = ttlMs;
60
+ this.cleanupInterval = setInterval(() => this.cleanup(), 60000);
61
+ }
62
+ has(messageId) {
63
+ const timestamp = this.cache.get(messageId);
64
+ if (!timestamp)
65
+ return false;
66
+ if (Date.now() - timestamp > this.ttlMs) {
67
+ this.cache.delete(messageId);
68
+ return false;
69
+ }
70
+ return true;
71
+ }
72
+ add(messageId) {
73
+ this.cache.set(messageId, Date.now());
74
+ }
75
+ cleanup() {
76
+ const now = Date.now();
77
+ for (const [key, timestamp] of this.cache.entries()) {
78
+ if (now - timestamp > this.ttlMs) {
79
+ this.cache.delete(key);
80
+ }
81
+ }
82
+ }
83
+ destroy() {
84
+ clearInterval(this.cleanupInterval);
85
+ this.cache.clear();
86
+ }
87
+ }
88
+ /**
89
+ * Google OAuth2 token manager for service account
90
+ */
91
+ class GoogleAuthManager {
92
+ constructor(credentials) {
93
+ this.accessToken = null;
94
+ this.tokenExpiry = 0;
95
+ this.credentials = credentials;
96
+ }
97
+ async getAccessToken() {
98
+ if (this.accessToken && Date.now() < this.tokenExpiry - 60000) {
99
+ return this.accessToken;
100
+ }
101
+ const jwt = this.createJWT();
102
+ const token = await this.exchangeJWTForToken(jwt);
103
+ this.accessToken = token.access_token;
104
+ this.tokenExpiry = Date.now() + (token.expires_in * 1000);
105
+ return this.accessToken;
106
+ }
107
+ createJWT() {
108
+ const header = {
109
+ alg: 'RS256',
110
+ typ: 'JWT',
111
+ };
112
+ const now = Math.floor(Date.now() / 1000);
113
+ const payload = {
114
+ iss: this.credentials.client_email,
115
+ scope: 'https://www.googleapis.com/auth/chat.bot',
116
+ aud: 'https://oauth2.googleapis.com/token',
117
+ iat: now,
118
+ exp: now + 3600,
119
+ };
120
+ const encodedHeader = Buffer.from(JSON.stringify(header)).toString('base64url');
121
+ const encodedPayload = Buffer.from(JSON.stringify(payload)).toString('base64url');
122
+ const signatureInput = `${encodedHeader}.${encodedPayload}`;
123
+ const sign = crypto.createSign('RSA-SHA256');
124
+ sign.update(signatureInput);
125
+ const signature = sign.sign(this.credentials.private_key, 'base64url');
126
+ return `${signatureInput}.${signature}`;
127
+ }
128
+ async exchangeJWTForToken(jwt) {
129
+ return new Promise((resolve, reject) => {
130
+ const postData = new URLSearchParams({
131
+ grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
132
+ assertion: jwt,
133
+ }).toString();
134
+ const options = {
135
+ hostname: 'oauth2.googleapis.com',
136
+ port: 443,
137
+ path: '/token',
138
+ method: 'POST',
139
+ headers: {
140
+ 'Content-Type': 'application/x-www-form-urlencoded',
141
+ 'Content-Length': Buffer.byteLength(postData),
142
+ },
143
+ };
144
+ const req = https.request(options, (res) => {
145
+ let data = '';
146
+ res.on('data', (chunk) => { data += chunk; });
147
+ res.on('end', () => {
148
+ try {
149
+ const parsed = JSON.parse(data);
150
+ if (parsed.error) {
151
+ reject(new Error(`Token exchange failed: ${parsed.error_description || parsed.error}`));
152
+ }
153
+ else {
154
+ resolve(parsed);
155
+ }
156
+ }
157
+ catch (e) {
158
+ reject(new Error(`Failed to parse token response: ${data}`));
159
+ }
160
+ });
161
+ });
162
+ req.on('error', reject);
163
+ req.write(postData);
164
+ req.end();
165
+ });
166
+ }
167
+ }
168
+ class GoogleChatAdapter {
169
+ constructor(config) {
170
+ this.type = 'googlechat';
171
+ this.server = null;
172
+ this.authManager = null;
173
+ this._status = 'disconnected';
174
+ this.messageHandlers = [];
175
+ this.errorHandlers = [];
176
+ this.statusHandlers = [];
177
+ this.reconnectAttempts = 0;
178
+ this.reconnectTimer = null;
179
+ this.config = config;
180
+ this.deduplicationCache = new MessageDeduplicationCache();
181
+ }
182
+ get status() {
183
+ return this._status;
184
+ }
185
+ get botUsername() {
186
+ return this._botUsername;
187
+ }
188
+ /**
189
+ * Connect to Google Chat via webhook server
190
+ */
191
+ async connect() {
192
+ if (this._status === 'connected' || this._status === 'connecting') {
193
+ return;
194
+ }
195
+ this.setStatus('connecting');
196
+ try {
197
+ // Load service account credentials
198
+ const credentials = await this.loadCredentials();
199
+ this.authManager = new GoogleAuthManager(credentials);
200
+ // Verify credentials by getting a token
201
+ await this.authManager.getAccessToken();
202
+ // Set bot info from config
203
+ this._botUsername = this.config.displayName || 'Google Chat Bot';
204
+ // Start the HTTP server for receiving webhooks
205
+ await this.startWebhookServer();
206
+ console.log(`Google Chat bot "${this._botUsername}" is connected on port ${this.config.webhookPort || 3979}`);
207
+ this.setStatus('connected');
208
+ this.reconnectAttempts = 0;
209
+ }
210
+ catch (error) {
211
+ const err = error instanceof Error ? error : new Error(String(error));
212
+ this.setStatus('error', err);
213
+ this.scheduleReconnect();
214
+ throw err;
215
+ }
216
+ }
217
+ /**
218
+ * Load service account credentials
219
+ */
220
+ async loadCredentials() {
221
+ // Check for inline credentials first
222
+ if (this.config.serviceAccountKey) {
223
+ return this.config.serviceAccountKey;
224
+ }
225
+ // Check for key file path
226
+ if (this.config.serviceAccountKeyPath) {
227
+ const keyPath = this.config.serviceAccountKeyPath;
228
+ if (!fs.existsSync(keyPath)) {
229
+ throw new Error(`Service account key file not found: ${keyPath}`);
230
+ }
231
+ const keyContent = fs.readFileSync(keyPath, 'utf-8');
232
+ const key = JSON.parse(keyContent);
233
+ return {
234
+ client_email: key.client_email,
235
+ private_key: key.private_key,
236
+ project_id: key.project_id,
237
+ };
238
+ }
239
+ // Check for GOOGLE_APPLICATION_CREDENTIALS environment variable
240
+ const envPath = process.env.GOOGLE_APPLICATION_CREDENTIALS;
241
+ if (envPath && fs.existsSync(envPath)) {
242
+ const keyContent = fs.readFileSync(envPath, 'utf-8');
243
+ const key = JSON.parse(keyContent);
244
+ return {
245
+ client_email: key.client_email,
246
+ private_key: key.private_key,
247
+ project_id: key.project_id,
248
+ };
249
+ }
250
+ throw new Error('Google Chat credentials not configured. Provide serviceAccountKey or serviceAccountKeyPath.');
251
+ }
252
+ /**
253
+ * Start the webhook server to receive messages from Google Chat
254
+ */
255
+ async startWebhookServer() {
256
+ const port = this.config.webhookPort || 3979;
257
+ const webhookPath = this.config.webhookPath || '/googlechat/webhook';
258
+ return new Promise((resolve, reject) => {
259
+ this.server = http.createServer(async (req, res) => {
260
+ if (req.method === 'POST' && req.url === webhookPath) {
261
+ let body = '';
262
+ req.on('data', chunk => {
263
+ body += chunk.toString();
264
+ });
265
+ req.on('end', async () => {
266
+ try {
267
+ await this.processIncomingEvent(req, res, body);
268
+ }
269
+ catch (error) {
270
+ console.error('Error processing Google Chat event:', error);
271
+ res.writeHead(500);
272
+ res.end(JSON.stringify({ error: 'Internal Server Error' }));
273
+ }
274
+ });
275
+ }
276
+ else if (req.method === 'GET' && req.url === '/health') {
277
+ // Health check endpoint
278
+ res.writeHead(200, { 'Content-Type': 'application/json' });
279
+ res.end(JSON.stringify({ status: 'ok', bot: this._botUsername }));
280
+ }
281
+ else {
282
+ res.writeHead(404);
283
+ res.end('Not Found');
284
+ }
285
+ });
286
+ this.server.on('error', (error) => {
287
+ if (error.code === 'EADDRINUSE') {
288
+ reject(new Error(`Port ${port} is already in use. Please choose a different webhook port.`));
289
+ }
290
+ else if (error.code === 'EACCES') {
291
+ reject(new Error(`Permission denied to use port ${port}. Try a port above 1024.`));
292
+ }
293
+ else {
294
+ reject(error);
295
+ }
296
+ });
297
+ this.server.listen(port, () => {
298
+ console.log(`Google Chat webhook server listening on port ${port} at ${webhookPath}`);
299
+ resolve();
300
+ });
301
+ });
302
+ }
303
+ /**
304
+ * Process incoming event from Google Chat
305
+ */
306
+ async processIncomingEvent(req, res, body) {
307
+ try {
308
+ const event = JSON.parse(body);
309
+ // Handle different event types
310
+ switch (event.type) {
311
+ case 'MESSAGE':
312
+ await this.handleMessage(event);
313
+ // Respond with empty JSON to acknowledge
314
+ res.writeHead(200, { 'Content-Type': 'application/json' });
315
+ res.end('{}');
316
+ break;
317
+ case 'ADDED_TO_SPACE':
318
+ console.log(`Bot added to space: ${event.space?.displayName || event.space?.name}`);
319
+ res.writeHead(200, { 'Content-Type': 'application/json' });
320
+ res.end(JSON.stringify({
321
+ text: `Hello! I'm ${this._botUsername}. How can I help you today?`,
322
+ }));
323
+ break;
324
+ case 'REMOVED_FROM_SPACE':
325
+ console.log(`Bot removed from space: ${event.space?.displayName || event.space?.name}`);
326
+ res.writeHead(200, { 'Content-Type': 'application/json' });
327
+ res.end('{}');
328
+ break;
329
+ case 'CARD_CLICKED':
330
+ // Handle interactive card clicks
331
+ console.log(`Card clicked: ${event.action?.actionMethodName}`);
332
+ res.writeHead(200, { 'Content-Type': 'application/json' });
333
+ res.end('{}');
334
+ break;
335
+ default:
336
+ console.log(`Unhandled Google Chat event type: ${event.type}`);
337
+ res.writeHead(200, { 'Content-Type': 'application/json' });
338
+ res.end('{}');
339
+ }
340
+ }
341
+ catch (error) {
342
+ console.error('Error parsing Google Chat event:', error);
343
+ res.writeHead(400);
344
+ res.end(JSON.stringify({ error: 'Bad Request' }));
345
+ }
346
+ }
347
+ /**
348
+ * Handle incoming message event
349
+ */
350
+ async handleMessage(event) {
351
+ const message = event.message;
352
+ if (!message) {
353
+ return;
354
+ }
355
+ // Skip bot's own messages
356
+ if (message.sender?.type === 'BOT') {
357
+ return;
358
+ }
359
+ // Get message text (use argumentText for @mentions, otherwise use text)
360
+ const text = message.argumentText?.trim() || message.text?.trim();
361
+ if (!text) {
362
+ return;
363
+ }
364
+ // Extract message ID from name (format: spaces/{space}/messages/{message})
365
+ const messageId = message.name.split('/').pop() || message.name;
366
+ // Deduplication check
367
+ if (this.config.deduplicationEnabled !== false && this.deduplicationCache.has(messageId)) {
368
+ console.log(`Skipping duplicate Google Chat message: ${messageId}`);
369
+ return;
370
+ }
371
+ this.deduplicationCache.add(messageId);
372
+ // Extract space ID (format: spaces/{space})
373
+ const spaceId = message.space.name;
374
+ // Get user info
375
+ const userName = message.sender?.displayName || 'Unknown User';
376
+ const userId = message.sender?.name || '';
377
+ // Map to IncomingMessage format
378
+ const incomingMessage = {
379
+ messageId: messageId,
380
+ channel: 'googlechat',
381
+ userId: userId,
382
+ userName: userName,
383
+ chatId: spaceId,
384
+ text: text,
385
+ timestamp: message.createTime ? new Date(message.createTime) : new Date(),
386
+ threadId: message.thread?.name,
387
+ raw: event,
388
+ };
389
+ console.log(`Processing Google Chat message from ${userName}: ${text.slice(0, 50)}...`);
390
+ await this.handleIncomingMessage(incomingMessage);
391
+ }
392
+ /**
393
+ * Schedule reconnection with exponential backoff
394
+ */
395
+ scheduleReconnect() {
396
+ if (!this.config.autoReconnect)
397
+ return;
398
+ const maxAttempts = this.config.maxReconnectAttempts || 5;
399
+ if (this.reconnectAttempts >= maxAttempts) {
400
+ console.error(`Google Chat: Max reconnection attempts (${maxAttempts}) reached`);
401
+ return;
402
+ }
403
+ const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);
404
+ this.reconnectAttempts++;
405
+ console.log(`Google Chat: Scheduling reconnection attempt ${this.reconnectAttempts} in ${delay}ms`);
406
+ if (this.reconnectTimer) {
407
+ clearTimeout(this.reconnectTimer);
408
+ }
409
+ this.reconnectTimer = setTimeout(async () => {
410
+ try {
411
+ await this.connect();
412
+ }
413
+ catch (error) {
414
+ console.error('Google Chat reconnection failed:', error);
415
+ }
416
+ }, delay);
417
+ }
418
+ /**
419
+ * Disconnect from Google Chat
420
+ */
421
+ async disconnect() {
422
+ if (this.reconnectTimer) {
423
+ clearTimeout(this.reconnectTimer);
424
+ this.reconnectTimer = null;
425
+ }
426
+ if (this.server) {
427
+ await new Promise((resolve) => {
428
+ this.server.close(() => resolve());
429
+ });
430
+ this.server = null;
431
+ }
432
+ this.deduplicationCache.destroy();
433
+ this.authManager = null;
434
+ this._botUsername = undefined;
435
+ this.setStatus('disconnected');
436
+ }
437
+ /**
438
+ * Send a message to a Google Chat space
439
+ */
440
+ async sendMessage(message) {
441
+ if (!this.authManager || this._status !== 'connected') {
442
+ throw new Error('Google Chat bot is not connected');
443
+ }
444
+ const accessToken = await this.authManager.getAccessToken();
445
+ // Prepare message payload
446
+ const payload = {
447
+ text: message.text,
448
+ };
449
+ // Add thread if specified
450
+ if (message.threadId) {
451
+ payload.thread = { name: message.threadId };
452
+ }
453
+ // Build the API URL
454
+ // Format: spaces/{space}/messages
455
+ const apiUrl = `https://chat.googleapis.com/v1/${message.chatId}/messages`;
456
+ try {
457
+ const response = await this.makeApiRequest('POST', apiUrl, accessToken, payload);
458
+ return response.name || '';
459
+ }
460
+ catch (error) {
461
+ const errorMessage = error instanceof Error ? error.message : String(error);
462
+ console.error('Error sending Google Chat message:', errorMessage);
463
+ throw error;
464
+ }
465
+ }
466
+ /**
467
+ * Make an authenticated API request to Google Chat
468
+ */
469
+ async makeApiRequest(method, url, accessToken, body) {
470
+ return new Promise((resolve, reject) => {
471
+ const urlObj = new URL(url);
472
+ const postData = body ? JSON.stringify(body) : undefined;
473
+ const options = {
474
+ hostname: urlObj.hostname,
475
+ port: 443,
476
+ path: urlObj.pathname + urlObj.search,
477
+ method: method,
478
+ headers: {
479
+ 'Authorization': `Bearer ${accessToken}`,
480
+ 'Content-Type': 'application/json',
481
+ },
482
+ };
483
+ if (postData) {
484
+ options.headers['Content-Length'] = Buffer.byteLength(postData);
485
+ }
486
+ const req = https.request(options, (res) => {
487
+ let data = '';
488
+ res.on('data', (chunk) => { data += chunk; });
489
+ res.on('end', () => {
490
+ try {
491
+ const parsed = JSON.parse(data);
492
+ if (res.statusCode && res.statusCode >= 400) {
493
+ reject(new Error(`API error ${res.statusCode}: ${parsed.error?.message || data}`));
494
+ }
495
+ else {
496
+ resolve(parsed);
497
+ }
498
+ }
499
+ catch (e) {
500
+ if (res.statusCode && res.statusCode >= 400) {
501
+ reject(new Error(`API error ${res.statusCode}: ${data}`));
502
+ }
503
+ else {
504
+ resolve({});
505
+ }
506
+ }
507
+ });
508
+ });
509
+ req.on('error', reject);
510
+ if (postData) {
511
+ req.write(postData);
512
+ }
513
+ req.end();
514
+ });
515
+ }
516
+ /**
517
+ * Edit an existing message
518
+ */
519
+ async editMessage(chatId, messageId, text) {
520
+ if (!this.authManager || this._status !== 'connected') {
521
+ throw new Error('Google Chat bot is not connected');
522
+ }
523
+ const accessToken = await this.authManager.getAccessToken();
524
+ // Build the message name (format: spaces/{space}/messages/{message})
525
+ const messageName = messageId.includes('/') ? messageId : `${chatId}/messages/${messageId}`;
526
+ const apiUrl = `https://chat.googleapis.com/v1/${messageName}?updateMask=text`;
527
+ const payload = { text };
528
+ await this.makeApiRequest('PATCH', apiUrl, accessToken, payload);
529
+ }
530
+ /**
531
+ * Delete a message
532
+ */
533
+ async deleteMessage(chatId, messageId) {
534
+ if (!this.authManager || this._status !== 'connected') {
535
+ throw new Error('Google Chat bot is not connected');
536
+ }
537
+ const accessToken = await this.authManager.getAccessToken();
538
+ // Build the message name
539
+ const messageName = messageId.includes('/') ? messageId : `${chatId}/messages/${messageId}`;
540
+ const apiUrl = `https://chat.googleapis.com/v1/${messageName}`;
541
+ await this.makeApiRequest('DELETE', apiUrl, accessToken);
542
+ }
543
+ /**
544
+ * Send a document/file to a space
545
+ * Note: Google Chat has limited file attachment support via API
546
+ */
547
+ async sendDocument(chatId, filePath, caption) {
548
+ // Google Chat API doesn't support direct file uploads
549
+ // Files must be uploaded to Google Drive first
550
+ // For now, send a message with the file path/name
551
+ const fileName = path.basename(filePath);
552
+ const message = caption ? `${caption}\nšŸ“Ž ${fileName}` : `šŸ“Ž ${fileName}`;
553
+ return this.sendMessage({
554
+ chatId,
555
+ text: message,
556
+ });
557
+ }
558
+ /**
559
+ * Register a message handler
560
+ */
561
+ onMessage(handler) {
562
+ this.messageHandlers.push(handler);
563
+ }
564
+ /**
565
+ * Register an error handler
566
+ */
567
+ onError(handler) {
568
+ this.errorHandlers.push(handler);
569
+ }
570
+ /**
571
+ * Register a status change handler
572
+ */
573
+ onStatusChange(handler) {
574
+ this.statusHandlers.push(handler);
575
+ }
576
+ /**
577
+ * Get channel info
578
+ */
579
+ async getInfo() {
580
+ return {
581
+ type: 'googlechat',
582
+ status: this._status,
583
+ botUsername: this._botUsername,
584
+ botDisplayName: this._botUsername,
585
+ };
586
+ }
587
+ // Private helper methods
588
+ async handleIncomingMessage(message) {
589
+ for (const handler of this.messageHandlers) {
590
+ try {
591
+ await handler(message);
592
+ }
593
+ catch (error) {
594
+ console.error('Error in message handler:', error);
595
+ this.handleError(error instanceof Error ? error : new Error(String(error)), 'messageHandler');
596
+ }
597
+ }
598
+ }
599
+ handleError(error, context) {
600
+ for (const handler of this.errorHandlers) {
601
+ try {
602
+ handler(error, context);
603
+ }
604
+ catch (e) {
605
+ console.error('Error in error handler:', e);
606
+ }
607
+ }
608
+ }
609
+ setStatus(status, error) {
610
+ this._status = status;
611
+ for (const handler of this.statusHandlers) {
612
+ try {
613
+ handler(status, error);
614
+ }
615
+ catch (e) {
616
+ console.error('Error in status handler:', e);
617
+ }
618
+ }
619
+ }
620
+ }
621
+ exports.GoogleChatAdapter = GoogleChatAdapter;
622
+ /**
623
+ * Create a Google Chat adapter from configuration
624
+ */
625
+ function createGoogleChatAdapter(config) {
626
+ // At least one credential source must be provided
627
+ if (!config.serviceAccountKey && !config.serviceAccountKeyPath && !process.env.GOOGLE_APPLICATION_CREDENTIALS) {
628
+ throw new Error('Google Chat requires service account credentials (serviceAccountKey, serviceAccountKeyPath, or GOOGLE_APPLICATION_CREDENTIALS)');
629
+ }
630
+ return new GoogleChatAdapter(config);
631
+ }