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,582 @@
1
+ "use strict";
2
+ /**
3
+ * Signal Channel Adapter
4
+ *
5
+ * Implements the ChannelAdapter interface for Signal messaging.
6
+ * Uses signal-cli under the hood for communication.
7
+ *
8
+ * Features:
9
+ * - End-to-end encrypted messaging
10
+ * - Message deduplication
11
+ * - Read receipts and typing indicators
12
+ * - Group messaging support
13
+ * - Attachment support
14
+ * - Reaction support
15
+ *
16
+ * Requirements:
17
+ * - signal-cli installed and configured
18
+ * - Phone number registered with Signal
19
+ */
20
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ var desc = Object.getOwnPropertyDescriptor(m, k);
23
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
24
+ desc = { enumerable: true, get: function() { return m[k]; } };
25
+ }
26
+ Object.defineProperty(o, k2, desc);
27
+ }) : (function(o, m, k, k2) {
28
+ if (k2 === undefined) k2 = k;
29
+ o[k2] = m[k];
30
+ }));
31
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
32
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
33
+ }) : function(o, v) {
34
+ o["default"] = v;
35
+ });
36
+ var __importStar = (this && this.__importStar) || (function () {
37
+ var ownKeys = function(o) {
38
+ ownKeys = Object.getOwnPropertyNames || function (o) {
39
+ var ar = [];
40
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
41
+ return ar;
42
+ };
43
+ return ownKeys(o);
44
+ };
45
+ return function (mod) {
46
+ if (mod && mod.__esModule) return mod;
47
+ var result = {};
48
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
49
+ __setModuleDefault(result, mod);
50
+ return result;
51
+ };
52
+ })();
53
+ Object.defineProperty(exports, "__esModule", { value: true });
54
+ exports.SignalAdapter = void 0;
55
+ exports.createSignalAdapter = createSignalAdapter;
56
+ const signal_client_1 = require("./signal-client");
57
+ const fs = __importStar(require("fs"));
58
+ const path = __importStar(require("path"));
59
+ const os = __importStar(require("os"));
60
+ class SignalAdapter {
61
+ constructor(config) {
62
+ this.type = 'signal';
63
+ this.client = null;
64
+ this._status = 'disconnected';
65
+ this.messageHandlers = [];
66
+ this.errorHandlers = [];
67
+ this.statusHandlers = [];
68
+ this.callbackQueryHandlers = [];
69
+ // Message deduplication
70
+ this.processedMessages = new Map();
71
+ this.DEDUP_CACHE_TTL = 60000; // 1 minute
72
+ this.DEDUP_CACHE_MAX_SIZE = 1000;
73
+ this.config = {
74
+ deduplicationEnabled: true,
75
+ sendReadReceipts: true,
76
+ sendTypingIndicators: true,
77
+ maxAttachmentMb: 100,
78
+ pollInterval: 1000,
79
+ trustMode: 'tofu',
80
+ ...config,
81
+ };
82
+ // Set up attachments directory
83
+ this.attachmentsDir = path.join(os.tmpdir(), 'cowork-signal-attachments');
84
+ if (!fs.existsSync(this.attachmentsDir)) {
85
+ fs.mkdirSync(this.attachmentsDir, { recursive: true });
86
+ }
87
+ }
88
+ get status() {
89
+ return this._status;
90
+ }
91
+ get botUsername() {
92
+ return this._botUsername;
93
+ }
94
+ /**
95
+ * Connect to Signal
96
+ */
97
+ async connect() {
98
+ if (this._status === 'connected' || this._status === 'connecting') {
99
+ return;
100
+ }
101
+ this.setStatus('connecting');
102
+ try {
103
+ // Create Signal client
104
+ this.client = new signal_client_1.SignalClient({
105
+ phoneNumber: this.config.phoneNumber,
106
+ cliPath: this.config.cliPath,
107
+ dataDir: this.config.dataDir,
108
+ mode: this.config.mode,
109
+ socketPath: this.config.socketPath,
110
+ verbose: process.env.NODE_ENV === 'development',
111
+ });
112
+ // Check installation
113
+ const installCheck = await this.client.checkInstallation();
114
+ if (!installCheck.installed) {
115
+ throw new Error(installCheck.error || 'signal-cli not installed');
116
+ }
117
+ console.log(`signal-cli version: ${installCheck.version}`);
118
+ // Check registration
119
+ const regCheck = await this.client.checkRegistration();
120
+ if (!regCheck.registered) {
121
+ throw new Error(regCheck.error || 'Phone number not registered');
122
+ }
123
+ // Set up event handlers
124
+ this.client.on('message', (message) => {
125
+ this.handleIncomingMessage(message);
126
+ });
127
+ this.client.on('error', (error) => {
128
+ this.handleError(error, 'client');
129
+ });
130
+ this.client.on('connected', () => {
131
+ console.log('Signal client connected');
132
+ });
133
+ this.client.on('disconnected', () => {
134
+ console.log('Signal client disconnected');
135
+ if (this._status === 'connected') {
136
+ this.setStatus('disconnected');
137
+ }
138
+ });
139
+ // Start receiving messages
140
+ await this.client.startReceiving();
141
+ // Set bot username to phone number
142
+ this._botUsername = this.config.phoneNumber;
143
+ // Start deduplication cleanup
144
+ if (this.config.deduplicationEnabled) {
145
+ this.startDedupCleanup();
146
+ }
147
+ this.setStatus('connected');
148
+ console.log(`Signal adapter connected for ${this.config.phoneNumber}`);
149
+ }
150
+ catch (error) {
151
+ const err = error instanceof Error ? error : new Error(String(error));
152
+ this.setStatus('error', err);
153
+ throw err;
154
+ }
155
+ }
156
+ /**
157
+ * Disconnect from Signal
158
+ */
159
+ async disconnect() {
160
+ // Stop dedup cleanup
161
+ if (this.dedupCleanupTimer) {
162
+ clearInterval(this.dedupCleanupTimer);
163
+ this.dedupCleanupTimer = undefined;
164
+ }
165
+ // Clear caches
166
+ this.processedMessages.clear();
167
+ // Stop client
168
+ if (this.client) {
169
+ await this.client.stopReceiving();
170
+ this.client = null;
171
+ }
172
+ this._botUsername = undefined;
173
+ this.setStatus('disconnected');
174
+ }
175
+ /**
176
+ * Send a message
177
+ */
178
+ async sendMessage(message) {
179
+ if (!this.client || this._status !== 'connected') {
180
+ throw new Error('Signal client is not connected');
181
+ }
182
+ // Prepare attachments
183
+ const attachmentPaths = [];
184
+ if (message.attachments) {
185
+ for (const attachment of message.attachments) {
186
+ const filePath = await this.prepareAttachment(attachment);
187
+ if (filePath) {
188
+ attachmentPaths.push(filePath);
189
+ }
190
+ }
191
+ }
192
+ // Add response prefix if configured
193
+ let text = message.text;
194
+ if (this.config.responsePrefix) {
195
+ text = `${this.config.responsePrefix} ${text}`;
196
+ }
197
+ // Send the message
198
+ const result = await this.client.sendMessage(message.chatId, text, {
199
+ attachments: attachmentPaths.length > 0 ? attachmentPaths : undefined,
200
+ quote: message.replyTo ? {
201
+ timestamp: parseInt(message.replyTo, 10),
202
+ author: message.chatId,
203
+ } : undefined,
204
+ });
205
+ return result.timestamp.toString();
206
+ }
207
+ /**
208
+ * Prepare an attachment for sending
209
+ */
210
+ async prepareAttachment(attachment) {
211
+ if (attachment.url && fs.existsSync(attachment.url)) {
212
+ return attachment.url;
213
+ }
214
+ if (attachment.data) {
215
+ const fileName = attachment.fileName || `attachment_${Date.now()}`;
216
+ const filePath = path.join(this.attachmentsDir, fileName);
217
+ fs.writeFileSync(filePath, attachment.data);
218
+ return filePath;
219
+ }
220
+ return null;
221
+ }
222
+ /**
223
+ * Edit a message (not supported by Signal)
224
+ */
225
+ async editMessage(chatId, messageId, text) {
226
+ throw new Error('Signal does not support message editing');
227
+ }
228
+ /**
229
+ * Delete a message
230
+ */
231
+ async deleteMessage(chatId, messageId) {
232
+ // Signal supports remote delete but it's complex
233
+ // For now, just log a warning
234
+ console.warn('Signal message deletion not fully implemented');
235
+ }
236
+ /**
237
+ * Send a document/file
238
+ */
239
+ async sendDocument(chatId, filePath, caption) {
240
+ if (!this.client || this._status !== 'connected') {
241
+ throw new Error('Signal client is not connected');
242
+ }
243
+ const text = caption || path.basename(filePath);
244
+ const result = await this.client.sendMessage(chatId, text, {
245
+ attachments: [filePath],
246
+ });
247
+ return result.timestamp.toString();
248
+ }
249
+ /**
250
+ * Send a photo/image
251
+ */
252
+ async sendPhoto(chatId, filePath, caption) {
253
+ return this.sendDocument(chatId, filePath, caption);
254
+ }
255
+ /**
256
+ * Register a message handler
257
+ */
258
+ onMessage(handler) {
259
+ this.messageHandlers.push(handler);
260
+ }
261
+ /**
262
+ * Register a callback query handler (not supported by Signal)
263
+ */
264
+ onCallbackQuery(handler) {
265
+ this.callbackQueryHandlers.push(handler);
266
+ }
267
+ /**
268
+ * Answer callback query (not supported by Signal)
269
+ */
270
+ async answerCallbackQuery(queryId, text, showAlert) {
271
+ // Signal doesn't have inline keyboards
272
+ console.warn('Signal does not support callback queries');
273
+ }
274
+ /**
275
+ * Register an error handler
276
+ */
277
+ onError(handler) {
278
+ this.errorHandlers.push(handler);
279
+ }
280
+ /**
281
+ * Register a status change handler
282
+ */
283
+ onStatusChange(handler) {
284
+ this.statusHandlers.push(handler);
285
+ }
286
+ /**
287
+ * Get channel info
288
+ */
289
+ async getInfo() {
290
+ return {
291
+ type: 'signal',
292
+ status: this._status,
293
+ botId: this.config.phoneNumber,
294
+ botUsername: this.config.phoneNumber,
295
+ botDisplayName: `Signal (${this.config.phoneNumber})`,
296
+ extra: {
297
+ mode: this.config.mode,
298
+ trustMode: this.config.trustMode,
299
+ },
300
+ };
301
+ }
302
+ // ============================================================================
303
+ // Extended Features
304
+ // ============================================================================
305
+ /**
306
+ * Send typing indicator
307
+ */
308
+ async sendTyping(chatId) {
309
+ if (!this.client || !this.config.sendTypingIndicators) {
310
+ return;
311
+ }
312
+ try {
313
+ await this.client.sendTyping(chatId);
314
+ }
315
+ catch (error) {
316
+ // Ignore typing indicator errors
317
+ }
318
+ }
319
+ /**
320
+ * Stop typing indicator
321
+ */
322
+ async stopTyping(chatId) {
323
+ if (!this.client || !this.config.sendTypingIndicators) {
324
+ return;
325
+ }
326
+ try {
327
+ await this.client.sendTyping(chatId, true);
328
+ }
329
+ catch (error) {
330
+ // Ignore typing indicator errors
331
+ }
332
+ }
333
+ /**
334
+ * Add reaction to a message
335
+ */
336
+ async addReaction(chatId, messageId, emoji) {
337
+ if (!this.client || this._status !== 'connected') {
338
+ throw new Error('Signal client is not connected');
339
+ }
340
+ await this.client.sendReaction(chatId, emoji, chatId, // targetAuthor
341
+ parseInt(messageId, 10));
342
+ }
343
+ /**
344
+ * Remove reaction from a message
345
+ */
346
+ async removeReaction(chatId, messageId, emoji) {
347
+ if (!this.client || this._status !== 'connected') {
348
+ throw new Error('Signal client is not connected');
349
+ }
350
+ await this.client.sendReaction(chatId, emoji, chatId, // targetAuthor
351
+ parseInt(messageId, 10), true // remove
352
+ );
353
+ }
354
+ /**
355
+ * Send read receipt
356
+ */
357
+ async sendReadReceipt(sender, messageTimestamp) {
358
+ if (!this.client || !this.config.sendReadReceipts) {
359
+ return;
360
+ }
361
+ try {
362
+ await this.client.sendReadReceipt(sender, [messageTimestamp]);
363
+ }
364
+ catch (error) {
365
+ // Ignore read receipt errors
366
+ }
367
+ }
368
+ /**
369
+ * Get contacts
370
+ */
371
+ async getContacts() {
372
+ if (!this.client || this._status !== 'connected') {
373
+ throw new Error('Signal client is not connected');
374
+ }
375
+ return this.client.getContacts();
376
+ }
377
+ /**
378
+ * Get groups
379
+ */
380
+ async getGroups() {
381
+ if (!this.client || this._status !== 'connected') {
382
+ throw new Error('Signal client is not connected');
383
+ }
384
+ return this.client.getGroups();
385
+ }
386
+ /**
387
+ * Trust a contact's identity
388
+ */
389
+ async trustIdentity(phoneNumber) {
390
+ if (!this.client || this._status !== 'connected') {
391
+ throw new Error('Signal client is not connected');
392
+ }
393
+ await this.client.trustIdentity(phoneNumber, this.config.trustMode === 'always');
394
+ }
395
+ // ============================================================================
396
+ // Private Methods
397
+ // ============================================================================
398
+ /**
399
+ * Handle incoming Signal message
400
+ */
401
+ async handleIncomingMessage(signalMessage) {
402
+ const envelope = signalMessage.envelope;
403
+ const dataMessage = envelope.dataMessage;
404
+ // Skip non-data messages
405
+ if (!dataMessage?.message) {
406
+ return;
407
+ }
408
+ // Generate message ID from timestamp
409
+ const messageId = envelope.timestamp.toString();
410
+ // Check for duplicates
411
+ if (this.config.deduplicationEnabled && this.isMessageProcessed(messageId)) {
412
+ console.log(`Skipping duplicate Signal message ${messageId}`);
413
+ return;
414
+ }
415
+ // Mark as processed
416
+ if (this.config.deduplicationEnabled) {
417
+ this.markMessageProcessed(messageId);
418
+ }
419
+ // Check access policy
420
+ if (!this.isAllowedSender(envelope.source)) {
421
+ console.log(`Ignoring message from unauthorized sender: ${envelope.source}`);
422
+ return;
423
+ }
424
+ // Convert to IncomingMessage
425
+ const message = {
426
+ messageId,
427
+ channel: 'signal',
428
+ userId: envelope.source,
429
+ userName: envelope.source, // Signal doesn't provide names in messages
430
+ chatId: dataMessage.groupInfo?.groupId || envelope.source,
431
+ text: dataMessage.message,
432
+ timestamp: new Date(envelope.timestamp),
433
+ replyTo: dataMessage.quote?.id?.toString(),
434
+ attachments: this.convertAttachments(dataMessage.attachments),
435
+ raw: signalMessage,
436
+ };
437
+ // Send read receipt
438
+ if (this.config.sendReadReceipts) {
439
+ await this.sendReadReceipt(envelope.source, envelope.timestamp);
440
+ }
441
+ // Notify handlers
442
+ for (const handler of this.messageHandlers) {
443
+ try {
444
+ await handler(message);
445
+ }
446
+ catch (error) {
447
+ console.error('Error in Signal message handler:', error);
448
+ this.handleError(error instanceof Error ? error : new Error(String(error)), 'messageHandler');
449
+ }
450
+ }
451
+ }
452
+ /**
453
+ * Convert Signal attachments to MessageAttachment format
454
+ */
455
+ convertAttachments(attachments) {
456
+ if (!attachments || attachments.length === 0) {
457
+ return undefined;
458
+ }
459
+ return attachments.map(att => {
460
+ let type = 'file';
461
+ if (att.contentType.startsWith('image/')) {
462
+ type = 'image';
463
+ }
464
+ else if (att.contentType.startsWith('audio/')) {
465
+ type = 'audio';
466
+ }
467
+ else if (att.contentType.startsWith('video/')) {
468
+ type = 'video';
469
+ }
470
+ return {
471
+ type,
472
+ url: att.localPath,
473
+ mimeType: att.contentType,
474
+ fileName: att.filename,
475
+ size: att.size,
476
+ };
477
+ });
478
+ }
479
+ /**
480
+ * Check if sender is allowed
481
+ */
482
+ isAllowedSender(sender) {
483
+ // Skip messages from self
484
+ if (sender === this.config.phoneNumber) {
485
+ return false;
486
+ }
487
+ // Check allowlist if configured
488
+ if (this.config.allowedNumbers && this.config.allowedNumbers.length > 0) {
489
+ // Normalize phone numbers for comparison
490
+ const normalizedSender = sender.replace(/[^+\d]/g, '');
491
+ return this.config.allowedNumbers.some(num => {
492
+ const normalizedNum = num.replace(/[^+\d]/g, '');
493
+ return normalizedSender === normalizedNum || normalizedSender.endsWith(normalizedNum);
494
+ });
495
+ }
496
+ // Check DM policy
497
+ switch (this.config.dmPolicy) {
498
+ case 'disabled':
499
+ return false;
500
+ case 'allowlist':
501
+ return false; // No allowlist configured
502
+ case 'pairing':
503
+ // TODO: Implement pairing code system
504
+ return true;
505
+ case 'open':
506
+ default:
507
+ return true;
508
+ }
509
+ }
510
+ /**
511
+ * Check if message was already processed
512
+ */
513
+ isMessageProcessed(messageId) {
514
+ return this.processedMessages.has(messageId);
515
+ }
516
+ /**
517
+ * Mark message as processed
518
+ */
519
+ markMessageProcessed(messageId) {
520
+ this.processedMessages.set(messageId, Date.now());
521
+ // Prevent unbounded growth
522
+ if (this.processedMessages.size > this.DEDUP_CACHE_MAX_SIZE) {
523
+ this.cleanupDedupCache();
524
+ }
525
+ }
526
+ /**
527
+ * Start periodic dedup cache cleanup
528
+ */
529
+ startDedupCleanup() {
530
+ this.dedupCleanupTimer = setInterval(() => {
531
+ this.cleanupDedupCache();
532
+ }, this.DEDUP_CACHE_TTL);
533
+ }
534
+ /**
535
+ * Clean up old entries from dedup cache
536
+ */
537
+ cleanupDedupCache() {
538
+ const now = Date.now();
539
+ for (const [messageId, timestamp] of this.processedMessages) {
540
+ if (now - timestamp > this.DEDUP_CACHE_TTL) {
541
+ this.processedMessages.delete(messageId);
542
+ }
543
+ }
544
+ }
545
+ /**
546
+ * Handle errors
547
+ */
548
+ handleError(error, context) {
549
+ for (const handler of this.errorHandlers) {
550
+ try {
551
+ handler(error, context);
552
+ }
553
+ catch (e) {
554
+ console.error('Error in error handler:', e);
555
+ }
556
+ }
557
+ }
558
+ /**
559
+ * Set status and notify handlers
560
+ */
561
+ setStatus(status, error) {
562
+ this._status = status;
563
+ for (const handler of this.statusHandlers) {
564
+ try {
565
+ handler(status, error);
566
+ }
567
+ catch (e) {
568
+ console.error('Error in status handler:', e);
569
+ }
570
+ }
571
+ }
572
+ }
573
+ exports.SignalAdapter = SignalAdapter;
574
+ /**
575
+ * Create a Signal adapter from configuration
576
+ */
577
+ function createSignalAdapter(config) {
578
+ if (!config.phoneNumber) {
579
+ throw new Error('Signal phone number is required');
580
+ }
581
+ return new SignalAdapter(config);
582
+ }