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,375 @@
1
+ "use strict";
2
+ /**
3
+ * Security Manager
4
+ *
5
+ * Handles user authorization for channel access.
6
+ * Supports three modes:
7
+ * - open: Anyone can use the bot
8
+ * - allowlist: Only pre-approved users
9
+ * - pairing: Users must enter a pairing code generated in the desktop app
10
+ *
11
+ * Implements concurrent access safety using mutex locks to prevent race conditions
12
+ * in pairing operations.
13
+ */
14
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ var desc = Object.getOwnPropertyDescriptor(m, k);
17
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
18
+ desc = { enumerable: true, get: function() { return m[k]; } };
19
+ }
20
+ Object.defineProperty(o, k2, desc);
21
+ }) : (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ }));
25
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
26
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
27
+ }) : function(o, v) {
28
+ o["default"] = v;
29
+ });
30
+ var __importStar = (this && this.__importStar) || (function () {
31
+ var ownKeys = function(o) {
32
+ ownKeys = Object.getOwnPropertyNames || function (o) {
33
+ var ar = [];
34
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
35
+ return ar;
36
+ };
37
+ return ownKeys(o);
38
+ };
39
+ return function (mod) {
40
+ if (mod && mod.__esModule) return mod;
41
+ var result = {};
42
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
43
+ __setModuleDefault(result, mod);
44
+ return result;
45
+ };
46
+ })();
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.SecurityManager = void 0;
49
+ const crypto = __importStar(require("crypto"));
50
+ const repositories_1 = require("../database/repositories");
51
+ const concurrency_1 = require("../security/concurrency");
52
+ const context_policy_1 = require("./context-policy");
53
+ class SecurityManager {
54
+ constructor(db) {
55
+ this.userRepo = new repositories_1.ChannelUserRepository(db);
56
+ this.pairingIdempotency = new concurrency_1.IdempotencyManager(5 * 60 * 1000); // 5 min TTL
57
+ this.contextPolicyManager = new context_policy_1.ContextPolicyManager(db);
58
+ }
59
+ /**
60
+ * Get the context policy manager for direct access to context policies
61
+ */
62
+ getContextPolicyManager() {
63
+ return this.contextPolicyManager;
64
+ }
65
+ /**
66
+ * Check if a message sender is allowed to interact
67
+ * Supports per-context (DM vs group) security policies
68
+ */
69
+ async checkAccess(channel, message, isGroup) {
70
+ const securityConfig = channel.securityConfig;
71
+ // Determine context type
72
+ // Priority: 1) Explicit isGroup parameter, 2) Channel type check, 3) Inference from IDs
73
+ let contextType;
74
+ if (isGroup !== undefined) {
75
+ // Explicit parameter takes precedence
76
+ contextType = isGroup ? 'group' : 'dm';
77
+ }
78
+ else if (SecurityManager.DM_ONLY_CHANNELS.includes(channel.type)) {
79
+ // Channels that don't support groups always use DM context
80
+ contextType = 'dm';
81
+ }
82
+ else {
83
+ // Infer from message - chatId different from userId typically means group
84
+ // This works for Telegram, Discord, Slack, etc.
85
+ contextType = message.chatId !== message.userId ? 'group' : 'dm';
86
+ }
87
+ // Get context-specific policy (creates default if doesn't exist)
88
+ const contextPolicy = this.contextPolicyManager.getPolicy(channel.id, contextType);
89
+ // Use context policy's security mode, falling back to channel default
90
+ const mode = contextPolicy.securityMode || securityConfig.mode;
91
+ // Get denied tools for this context
92
+ const deniedTools = contextPolicy.toolRestrictions || [];
93
+ // Get or create user record
94
+ let user = this.userRepo.findByChannelUserId(channel.id, message.userId);
95
+ if (!user) {
96
+ // Create new user record
97
+ user = this.userRepo.create({
98
+ channelId: channel.id,
99
+ channelUserId: message.userId,
100
+ displayName: message.userName,
101
+ allowed: mode === 'open', // Auto-allow in open mode
102
+ });
103
+ }
104
+ else {
105
+ // Update display name if changed
106
+ if (user.displayName !== message.userName) {
107
+ this.userRepo.update(user.id, { displayName: message.userName });
108
+ }
109
+ }
110
+ // Check based on security mode
111
+ switch (mode) {
112
+ case 'open':
113
+ // Everyone is allowed
114
+ return { allowed: true, user, contextType, deniedTools };
115
+ case 'allowlist': {
116
+ // Check if user is in allowlist
117
+ if (user.allowed) {
118
+ return { allowed: true, user, contextType, deniedTools };
119
+ }
120
+ // Check if user ID is in config allowlist
121
+ const allowedUsers = securityConfig.allowedUsers || [];
122
+ if (allowedUsers.includes(message.userId)) {
123
+ // Add to allowed users
124
+ this.userRepo.update(user.id, { allowed: true });
125
+ return {
126
+ allowed: true,
127
+ user: { ...user, allowed: true },
128
+ contextType,
129
+ deniedTools,
130
+ };
131
+ }
132
+ return {
133
+ allowed: false,
134
+ user,
135
+ reason: 'User not in allowlist',
136
+ contextType,
137
+ deniedTools,
138
+ };
139
+ }
140
+ case 'pairing':
141
+ // Check if user has been paired
142
+ if (user.allowed) {
143
+ return { allowed: true, user, contextType, deniedTools };
144
+ }
145
+ return {
146
+ allowed: false,
147
+ user,
148
+ reason: 'Pairing required',
149
+ pairingRequired: true,
150
+ contextType,
151
+ deniedTools,
152
+ };
153
+ default:
154
+ return {
155
+ allowed: false,
156
+ reason: `Unknown security mode: ${mode}`,
157
+ contextType,
158
+ deniedTools,
159
+ };
160
+ }
161
+ }
162
+ /**
163
+ * Generate a pairing code for a channel
164
+ * Creates a placeholder entry that can be claimed by any user who enters the code
165
+ * Uses mutex to prevent race conditions in concurrent code generation
166
+ */
167
+ generatePairingCode(channel, _userId, _displayName) {
168
+ // Use synchronous mutex key for this channel to prevent concurrent generation issues
169
+ const mutexKey = `pairing:generate:${channel.id}`;
170
+ // Generate code (synchronous operation, but we track idempotency)
171
+ const code = this.createPairingCode();
172
+ const ttl = channel.securityConfig.pairingCodeTTL || 300; // 5 minutes default
173
+ const expiresAt = Date.now() + ttl * 1000;
174
+ // Create a placeholder user entry with the pairing code
175
+ // Use a unique placeholder ID so multiple codes can exist
176
+ const placeholderId = `pending_${code}_${Date.now()}`;
177
+ this.userRepo.create({
178
+ channelId: channel.id,
179
+ channelUserId: placeholderId,
180
+ displayName: 'Pending User',
181
+ allowed: false,
182
+ pairingCode: code,
183
+ pairingExpiresAt: expiresAt,
184
+ });
185
+ return code;
186
+ }
187
+ /**
188
+ * Verify a pairing code
189
+ * Looks up the code across all users in the channel and grants access to the caller
190
+ * Uses idempotency to prevent double-verification race conditions
191
+ */
192
+ async verifyPairingCode(channel, userId, code) {
193
+ // Generate idempotency key for this verification attempt
194
+ const idempotencyKey = concurrency_1.IdempotencyManager.generateKey('pairing:verify', channel.id, userId, code.toUpperCase());
195
+ // Check if this exact verification is already in progress or completed
196
+ const existing = this.pairingIdempotency.check(idempotencyKey);
197
+ if (existing.exists && existing.status === 'completed') {
198
+ return existing.result;
199
+ }
200
+ // Use mutex to ensure only one verification happens at a time per channel
201
+ const mutexKey = `pairing:verify:${channel.id}`;
202
+ return await concurrency_1.pairingMutex.withLock(mutexKey, async () => {
203
+ // Double-check idempotency after acquiring lock
204
+ const recheck = this.pairingIdempotency.check(idempotencyKey);
205
+ if (recheck.exists && recheck.status === 'completed') {
206
+ return recheck.result;
207
+ }
208
+ // Start tracking this operation
209
+ this.pairingIdempotency.start(idempotencyKey);
210
+ try {
211
+ const result = await this.doVerifyPairingCode(channel, userId, code);
212
+ this.pairingIdempotency.complete(idempotencyKey, result);
213
+ return result;
214
+ }
215
+ catch (error) {
216
+ this.pairingIdempotency.fail(idempotencyKey, error);
217
+ throw error;
218
+ }
219
+ });
220
+ }
221
+ async doVerifyPairingCode(channel, userId, code) {
222
+ // First check if user is already allowed
223
+ const existingUser = this.userRepo.findByChannelUserId(channel.id, userId);
224
+ if (existingUser?.allowed) {
225
+ return { success: true, user: existingUser };
226
+ }
227
+ // Brute-force protection: Check if user is locked out due to too many failed attempts
228
+ if (existingUser && existingUser.pairingAttempts >= SecurityManager.MAX_PAIRING_ATTEMPTS) {
229
+ // Check if lockout period has passed (use dedicated lockoutUntil field)
230
+ const lockoutUntil = existingUser.lockoutUntil;
231
+ if (lockoutUntil && Date.now() < lockoutUntil) {
232
+ const remainingMinutes = Math.ceil((lockoutUntil - Date.now()) / 60000);
233
+ return {
234
+ success: false,
235
+ error: `Too many failed attempts. Please wait ${remainingMinutes} minute(s) before trying again.`,
236
+ };
237
+ }
238
+ // Lockout expired - reset attempts (keep pairingExpiresAt unchanged)
239
+ this.userRepo.update(existingUser.id, {
240
+ pairingAttempts: 0,
241
+ lockoutUntil: undefined,
242
+ });
243
+ }
244
+ // Look up the pairing code across all users in the channel
245
+ const codeOwner = this.userRepo.findByPairingCode(channel.id, code.toUpperCase());
246
+ if (!codeOwner) {
247
+ // Code not found - increment attempts on the requesting user if they exist
248
+ if (existingUser) {
249
+ const newAttempts = existingUser.pairingAttempts + 1;
250
+ const updates = {
251
+ pairingAttempts: newAttempts,
252
+ };
253
+ // Set lockout timestamp if max attempts reached (uses dedicated lockoutUntil field)
254
+ if (newAttempts >= SecurityManager.MAX_PAIRING_ATTEMPTS) {
255
+ updates.lockoutUntil = Date.now() + SecurityManager.PAIRING_LOCKOUT_MS;
256
+ }
257
+ this.userRepo.update(existingUser.id, updates);
258
+ // Warn user about remaining attempts
259
+ const remaining = SecurityManager.MAX_PAIRING_ATTEMPTS - newAttempts;
260
+ if (remaining > 0) {
261
+ return { success: false, error: `Invalid pairing code. ${remaining} attempt(s) remaining.` };
262
+ }
263
+ else {
264
+ return { success: false, error: 'Too many failed attempts. Please wait 15 minutes before trying again.' };
265
+ }
266
+ }
267
+ return { success: false, error: 'Invalid pairing code' };
268
+ }
269
+ // Check expiration
270
+ if (codeOwner.pairingExpiresAt && Date.now() > codeOwner.pairingExpiresAt) {
271
+ // Clear expired code
272
+ this.userRepo.update(codeOwner.id, {
273
+ pairingCode: undefined,
274
+ pairingExpiresAt: undefined,
275
+ });
276
+ return { success: false, error: 'Pairing code has expired. Please request a new one.' };
277
+ }
278
+ // Code is valid! Grant access to the requesting user
279
+ if (existingUser) {
280
+ // Update existing user to be allowed
281
+ this.userRepo.update(existingUser.id, {
282
+ allowed: true,
283
+ pairingCode: undefined,
284
+ pairingExpiresAt: undefined,
285
+ pairingAttempts: 0,
286
+ lockoutUntil: undefined,
287
+ });
288
+ // Clear the code from wherever it was stored
289
+ if (codeOwner.id !== existingUser.id) {
290
+ this.userRepo.update(codeOwner.id, {
291
+ pairingCode: undefined,
292
+ pairingExpiresAt: undefined,
293
+ });
294
+ }
295
+ return { success: true, user: { ...existingUser, allowed: true } };
296
+ }
297
+ else {
298
+ // This shouldn't happen since checkAccess creates the user, but handle it
299
+ return { success: false, error: 'User record not found' };
300
+ }
301
+ }
302
+ /**
303
+ * Revoke a user's access
304
+ */
305
+ revokeAccess(channelId, userId) {
306
+ const user = this.userRepo.findByChannelUserId(channelId, userId);
307
+ if (user) {
308
+ this.userRepo.update(user.id, { allowed: false });
309
+ }
310
+ }
311
+ /**
312
+ * Grant a user access directly (for allowlist management)
313
+ */
314
+ grantAccess(channelId, userId, displayName) {
315
+ let user = this.userRepo.findByChannelUserId(channelId, userId);
316
+ if (user) {
317
+ this.userRepo.update(user.id, { allowed: true });
318
+ }
319
+ else if (displayName) {
320
+ this.userRepo.create({
321
+ channelId,
322
+ channelUserId: userId,
323
+ displayName,
324
+ allowed: true,
325
+ });
326
+ }
327
+ }
328
+ /**
329
+ * Get all users for a channel
330
+ * Automatically cleans up expired pending pairing entries before returning
331
+ */
332
+ getChannelUsers(channelId) {
333
+ // Cleanup expired pending entries first
334
+ this.cleanupExpiredPending(channelId);
335
+ return this.userRepo.findByChannelId(channelId);
336
+ }
337
+ /**
338
+ * Cleanup expired pending pairing entries for a channel
339
+ * These are placeholder entries created when generating pairing codes that have expired
340
+ * Returns the number of deleted entries
341
+ */
342
+ cleanupExpiredPending(channelId) {
343
+ return this.userRepo.deleteExpiredPending(channelId);
344
+ }
345
+ /**
346
+ * Get allowed users for a channel
347
+ */
348
+ getAllowedUsers(channelId) {
349
+ return this.userRepo.findAllowedByChannelId(channelId);
350
+ }
351
+ // Private methods
352
+ /**
353
+ * Create a random pairing code
354
+ */
355
+ createPairingCode() {
356
+ // Generate 6-character alphanumeric code
357
+ const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'; // Exclude similar chars (I, O, 1, 0)
358
+ let code = '';
359
+ const randomBytes = crypto.randomBytes(6);
360
+ for (let i = 0; i < 6; i++) {
361
+ code += chars[randomBytes[i] % chars.length];
362
+ }
363
+ return code;
364
+ }
365
+ }
366
+ exports.SecurityManager = SecurityManager;
367
+ // Channels that don't support group chats - always use DM context
368
+ SecurityManager.DM_ONLY_CHANNELS = ['email', 'imessage', 'bluebubbles'];
369
+ /**
370
+ * Internal pairing verification logic (called within mutex)
371
+ */
372
+ // Maximum pairing attempts before lockout (brute-force protection)
373
+ SecurityManager.MAX_PAIRING_ATTEMPTS = 5;
374
+ // Lockout duration in milliseconds (15 minutes)
375
+ SecurityManager.PAIRING_LOCKOUT_MS = 15 * 60 * 1000;
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ /**
3
+ * Session Manager
4
+ *
5
+ * Manages channel sessions linking chats to CoWork tasks.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.SessionManager = void 0;
9
+ const repositories_1 = require("../database/repositories");
10
+ class SessionManager {
11
+ constructor(db) {
12
+ this.sessionRepo = new repositories_1.ChannelSessionRepository(db);
13
+ }
14
+ /**
15
+ * Get or create a session for a chat
16
+ */
17
+ async getOrCreateSession(channel, chatId, userId, defaultWorkspaceId) {
18
+ // Look for existing session
19
+ let session = this.sessionRepo.findByChatId(channel.id, chatId);
20
+ if (session) {
21
+ // Update last activity
22
+ this.sessionRepo.update(session.id, {
23
+ lastActivityAt: Date.now(),
24
+ });
25
+ return { ...session, lastActivityAt: Date.now() };
26
+ }
27
+ // Create new session
28
+ session = this.sessionRepo.create({
29
+ channelId: channel.id,
30
+ chatId,
31
+ userId,
32
+ workspaceId: defaultWorkspaceId,
33
+ state: 'idle',
34
+ });
35
+ return session;
36
+ }
37
+ /**
38
+ * Get session by ID
39
+ */
40
+ getSession(sessionId) {
41
+ return this.sessionRepo.findById(sessionId);
42
+ }
43
+ /**
44
+ * Get session by task ID
45
+ */
46
+ getSessionByTaskId(taskId) {
47
+ return this.sessionRepo.findByTaskId(taskId);
48
+ }
49
+ /**
50
+ * Update session state
51
+ */
52
+ updateSessionState(sessionId, state) {
53
+ this.sessionRepo.update(sessionId, {
54
+ state,
55
+ lastActivityAt: Date.now(),
56
+ });
57
+ }
58
+ /**
59
+ * Link a session to a task
60
+ */
61
+ linkSessionToTask(sessionId, taskId) {
62
+ this.sessionRepo.update(sessionId, {
63
+ taskId,
64
+ state: 'active',
65
+ lastActivityAt: Date.now(),
66
+ });
67
+ }
68
+ /**
69
+ * Unlink session from task
70
+ */
71
+ unlinkSessionFromTask(sessionId) {
72
+ this.sessionRepo.update(sessionId, {
73
+ taskId: undefined,
74
+ state: 'idle',
75
+ lastActivityAt: Date.now(),
76
+ });
77
+ }
78
+ /**
79
+ * Set session workspace
80
+ */
81
+ setSessionWorkspace(sessionId, workspaceId) {
82
+ this.sessionRepo.update(sessionId, {
83
+ workspaceId,
84
+ lastActivityAt: Date.now(),
85
+ });
86
+ }
87
+ /**
88
+ * Update session context
89
+ */
90
+ updateSessionContext(sessionId, context) {
91
+ const session = this.sessionRepo.findById(sessionId);
92
+ if (session) {
93
+ const mergedContext = { ...session.context, ...context };
94
+ this.sessionRepo.update(sessionId, {
95
+ context: mergedContext,
96
+ lastActivityAt: Date.now(),
97
+ });
98
+ }
99
+ }
100
+ /**
101
+ * Get active sessions for a channel
102
+ */
103
+ getActiveSessions(channelId) {
104
+ return this.sessionRepo.findActiveByChannelId(channelId);
105
+ }
106
+ /**
107
+ * Clean up old idle sessions
108
+ */
109
+ cleanupOldSessions(maxAgeMs = 24 * 60 * 60 * 1000) {
110
+ // This would require a new method in the repository
111
+ // For now, we'll skip automated cleanup
112
+ console.log('Session cleanup not yet implemented');
113
+ }
114
+ }
115
+ exports.SessionManager = SessionManager;