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,102 @@
1
+ /**
2
+ * Canvas Preload Script
3
+ *
4
+ * Exposes a secure bridge between the canvas content and the main process.
5
+ * This preload script is loaded into canvas BrowserWindows and provides:
6
+ * - A2UI (Agent-to-UI) action sending
7
+ * - Session information retrieval
8
+ * - Agent update notifications
9
+ */
10
+
11
+ import { contextBridge, ipcRenderer } from 'electron';
12
+
13
+ // Type definitions for the canvas API
14
+ interface CanvasAPI {
15
+ /**
16
+ * Send an A2UI action to the agent
17
+ * @param actionName - Name of the action (e.g., 'button_click', 'form_submit')
18
+ * @param componentId - Optional ID of the component that triggered the action
19
+ * @param context - Optional context data to send with the action
20
+ */
21
+ sendA2UIAction: (
22
+ actionName: string,
23
+ componentId?: string,
24
+ context?: Record<string, unknown>
25
+ ) => Promise<void>;
26
+
27
+ /**
28
+ * Get information about the current canvas session
29
+ */
30
+ getSessionInfo: () => Promise<{
31
+ id: string;
32
+ taskId: string;
33
+ workspaceId: string;
34
+ title?: string;
35
+ } | null>;
36
+
37
+ /**
38
+ * Register a callback for agent updates
39
+ * @param callback - Function to call when agent sends an update
40
+ */
41
+ onAgentUpdate: (callback: (data: unknown) => void) => void;
42
+
43
+ /**
44
+ * Request a snapshot of the current canvas
45
+ */
46
+ requestSnapshot: () => Promise<{
47
+ imageBase64: string;
48
+ width: number;
49
+ height: number;
50
+ } | null>;
51
+
52
+ /**
53
+ * Log a message to the main process console
54
+ */
55
+ log: (message: string, data?: unknown) => void;
56
+ }
57
+
58
+ // Create the canvas API
59
+ const canvasAPI: CanvasAPI = {
60
+ sendA2UIAction: async (actionName, componentId, context) => {
61
+ await ipcRenderer.invoke('canvas:a2ui-action-from-window', {
62
+ actionName,
63
+ componentId,
64
+ context,
65
+ });
66
+ },
67
+
68
+ getSessionInfo: async () => {
69
+ return ipcRenderer.invoke('canvas:get-session-from-window');
70
+ },
71
+
72
+ onAgentUpdate: (callback) => {
73
+ ipcRenderer.on('canvas:agent-update', (_event, data) => {
74
+ callback(data);
75
+ });
76
+ },
77
+
78
+ requestSnapshot: async () => {
79
+ return ipcRenderer.invoke('canvas:request-snapshot-from-window');
80
+ },
81
+
82
+ log: (message, data) => {
83
+ ipcRenderer.send('canvas:log', { message, data });
84
+ },
85
+ };
86
+
87
+ const shouldExposeCanvasApi = (() => {
88
+ try {
89
+ const location = (globalThis as { location?: { protocol?: string } }).location;
90
+ return location?.protocol === 'canvas:';
91
+ } catch {
92
+ return false;
93
+ }
94
+ })();
95
+
96
+ if (shouldExposeCanvasApi) {
97
+ // Expose the API to trusted canvas:// content only
98
+ contextBridge.exposeInMainWorld('coworkCanvas', canvasAPI);
99
+ console.log('[CanvasPreload] Canvas preload script loaded (canvas://)');
100
+ } else {
101
+ console.log('[CanvasPreload] Canvas preload script loaded (no API exposed)');
102
+ }
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Canvas Protocol Handler
3
+ *
4
+ * Registers a custom 'canvas://' URL scheme that serves files from
5
+ * canvas session directories to the canvas BrowserWindows.
6
+ *
7
+ * URL Format: canvas://{sessionId}/{filename}
8
+ * Example: canvas://abc123-def456/index.html
9
+ */
10
+
11
+ import { protocol } from 'electron';
12
+ import * as path from 'path';
13
+ import * as fs from 'fs';
14
+ import { CanvasManager } from './canvas-manager';
15
+
16
+ // MIME type mapping
17
+ const MIME_TYPES: Record<string, string> = {
18
+ '.html': 'text/html',
19
+ '.htm': 'text/html',
20
+ '.css': 'text/css',
21
+ '.js': 'application/javascript',
22
+ '.mjs': 'application/javascript',
23
+ '.json': 'application/json',
24
+ '.png': 'image/png',
25
+ '.jpg': 'image/jpeg',
26
+ '.jpeg': 'image/jpeg',
27
+ '.gif': 'image/gif',
28
+ '.svg': 'image/svg+xml',
29
+ '.webp': 'image/webp',
30
+ '.ico': 'image/x-icon',
31
+ '.woff': 'font/woff',
32
+ '.woff2': 'font/woff2',
33
+ '.ttf': 'font/ttf',
34
+ '.otf': 'font/otf',
35
+ '.eot': 'application/vnd.ms-fontobject',
36
+ '.wasm': 'application/wasm',
37
+ '.mp3': 'audio/mpeg',
38
+ '.mp4': 'video/mp4',
39
+ '.webm': 'video/webm',
40
+ '.ogg': 'audio/ogg',
41
+ '.wav': 'audio/wav',
42
+ '.pdf': 'application/pdf',
43
+ '.xml': 'application/xml',
44
+ '.txt': 'text/plain',
45
+ '.md': 'text/markdown',
46
+ };
47
+
48
+ /**
49
+ * Get MIME type for a file extension
50
+ */
51
+ function getMimeType(filePath: string): string {
52
+ const ext = path.extname(filePath).toLowerCase();
53
+ return MIME_TYPES[ext] || 'application/octet-stream';
54
+ }
55
+
56
+ /**
57
+ * Create an error response
58
+ */
59
+ function createErrorResponse(statusCode: number, message: string): Response {
60
+ return new Response(message, {
61
+ status: statusCode,
62
+ headers: {
63
+ 'Content-Type': 'text/plain',
64
+ },
65
+ });
66
+ }
67
+
68
+ /**
69
+ * Register the canvas:// protocol scheme as privileged
70
+ * Must be called before app.ready
71
+ */
72
+ export function registerCanvasScheme(): void {
73
+ protocol.registerSchemesAsPrivileged([
74
+ {
75
+ scheme: 'canvas',
76
+ privileges: {
77
+ standard: true,
78
+ secure: true,
79
+ supportFetchAPI: true,
80
+ corsEnabled: true,
81
+ stream: true,
82
+ },
83
+ },
84
+ ]);
85
+ }
86
+
87
+ /**
88
+ * Register the canvas:// protocol handler
89
+ * Must be called after app.ready
90
+ */
91
+ export function registerCanvasProtocol(): void {
92
+ protocol.handle('canvas', async (request) => {
93
+ try {
94
+ const url = new URL(request.url);
95
+ const sessionId = url.hostname;
96
+ let filePath = decodeURIComponent(url.pathname);
97
+
98
+ // Security: prevent path traversal attacks
99
+ if (filePath.includes('..') || filePath.includes('//')) {
100
+ console.warn(`[CanvasProtocol] Blocked path traversal attempt: ${filePath}`);
101
+ return createErrorResponse(403, 'Forbidden: Invalid path');
102
+ }
103
+
104
+ // Get the canvas manager
105
+ const manager = CanvasManager.getInstance();
106
+ const session = manager.getSession(sessionId);
107
+
108
+ if (!session) {
109
+ console.warn(`[CanvasProtocol] Session not found: ${sessionId}`);
110
+ return createErrorResponse(404, 'Session not found');
111
+ }
112
+
113
+ // Default to index.html for root requests
114
+ if (filePath === '/' || filePath === '') {
115
+ filePath = '/index.html';
116
+ }
117
+
118
+ // Remove leading slash
119
+ const relativePath = filePath.startsWith('/') ? filePath.slice(1) : filePath;
120
+ const fullPath = path.join(session.sessionDir, relativePath);
121
+
122
+ // Security: ensure the resolved path is within the session directory
123
+ const resolvedPath = path.resolve(fullPath);
124
+ const resolvedSessionDir = path.resolve(session.sessionDir);
125
+ if (!resolvedPath.startsWith(resolvedSessionDir)) {
126
+ console.warn(`[CanvasProtocol] Path escape attempt: ${fullPath}`);
127
+ return createErrorResponse(403, 'Forbidden: Path outside session');
128
+ }
129
+
130
+ // Check if file exists
131
+ if (!fs.existsSync(fullPath)) {
132
+ console.warn(`[CanvasProtocol] File not found: ${fullPath}`);
133
+ return createErrorResponse(404, 'File not found');
134
+ }
135
+
136
+ // Get file stats
137
+ const stats = fs.statSync(fullPath);
138
+ if (stats.isDirectory()) {
139
+ // Try index.html in directory
140
+ const indexPath = path.join(fullPath, 'index.html');
141
+ if (fs.existsSync(indexPath)) {
142
+ const content = fs.readFileSync(indexPath);
143
+ return new Response(content, {
144
+ status: 200,
145
+ headers: {
146
+ 'Content-Type': 'text/html',
147
+ 'Content-Length': content.length.toString(),
148
+ },
149
+ });
150
+ }
151
+ return createErrorResponse(403, 'Directory listing not allowed');
152
+ }
153
+
154
+ // Read and serve the file
155
+ const content = fs.readFileSync(fullPath);
156
+ const mimeType = getMimeType(fullPath);
157
+
158
+ return new Response(content, {
159
+ status: 200,
160
+ headers: {
161
+ 'Content-Type': mimeType,
162
+ 'Content-Length': content.length.toString(),
163
+ 'Cache-Control': 'no-cache', // Disable caching for development
164
+ },
165
+ });
166
+ } catch (error: unknown) {
167
+ const message = error instanceof Error ? error.message : 'Unknown error';
168
+ console.error('[CanvasProtocol] Error handling request:', error);
169
+ return createErrorResponse(500, `Internal error: ${message}`);
170
+ }
171
+ });
172
+
173
+ console.log('[CanvasProtocol] Registered canvas:// protocol handler');
174
+ }
@@ -0,0 +1,200 @@
1
+ /**
2
+ * Canvas Store - File-based persistence for canvas sessions
3
+ * Uses atomic writes with temporary files for data safety
4
+ */
5
+
6
+ import fs from 'node:fs';
7
+ import path from 'node:path';
8
+ import { app } from 'electron';
9
+ import type { CanvasSession } from '../../shared/types';
10
+
11
+ export interface CanvasStoreFile {
12
+ version: number;
13
+ sessions: CanvasSession[];
14
+ }
15
+
16
+ // Lazy-evaluated paths (app.getPath() is not available until app is ready)
17
+ let _canvasDir: string | null = null;
18
+ let _canvasStorePath: string | null = null;
19
+
20
+ export function getCanvasDir(): string {
21
+ if (!_canvasDir) {
22
+ _canvasDir = path.join(app.getPath('userData'), 'canvas');
23
+ }
24
+ return _canvasDir;
25
+ }
26
+
27
+ export function getCanvasStorePath(): string {
28
+ if (!_canvasStorePath) {
29
+ _canvasStorePath = path.join(getCanvasDir(), 'sessions.json');
30
+ }
31
+ return _canvasStorePath;
32
+ }
33
+
34
+ // Maximum sessions to keep (to prevent unbounded growth)
35
+ const MAX_SESSIONS = 50;
36
+
37
+ /**
38
+ * Validate a single canvas session object
39
+ */
40
+ function isValidSession(s: unknown): s is CanvasSession {
41
+ if (!s || typeof s !== 'object') return false;
42
+ const session = s as Record<string, unknown>;
43
+ const mode = session.mode;
44
+ const isValidMode = mode === undefined || mode === 'html' || mode === 'browser';
45
+ const url = session.url;
46
+ const isValidUrl = url === undefined || typeof url === 'string';
47
+ return (
48
+ typeof session.id === 'string' &&
49
+ typeof session.taskId === 'string' &&
50
+ typeof session.workspaceId === 'string' &&
51
+ typeof session.sessionDir === 'string' &&
52
+ isValidMode &&
53
+ isValidUrl &&
54
+ typeof session.status === 'string' &&
55
+ ['active', 'paused', 'closed'].includes(session.status as string) &&
56
+ typeof session.createdAt === 'number' &&
57
+ typeof session.lastUpdatedAt === 'number'
58
+ );
59
+ }
60
+
61
+ /**
62
+ * Load canvas sessions from the store file
63
+ * Returns empty array if file doesn't exist or is invalid
64
+ */
65
+ export async function loadCanvasStore(storePath?: string): Promise<CanvasStoreFile> {
66
+ const effectivePath = storePath || getCanvasStorePath();
67
+ try {
68
+ const raw = await fs.promises.readFile(effectivePath, 'utf-8');
69
+ const parsed = JSON.parse(raw) as Partial<CanvasStoreFile> | null;
70
+ const sessions = Array.isArray(parsed?.sessions) ? parsed.sessions : [];
71
+
72
+ // Validate and filter sessions
73
+ const validSessions = sessions.filter((s): s is CanvasSession => {
74
+ if (!isValidSession(s)) return false;
75
+
76
+ // Also verify the session directory still exists
77
+ try {
78
+ return fs.existsSync(s.sessionDir);
79
+ } catch {
80
+ return false;
81
+ }
82
+ });
83
+
84
+ return {
85
+ version: 1,
86
+ sessions: validSessions,
87
+ };
88
+ } catch {
89
+ // File doesn't exist or is invalid - return empty store
90
+ return { version: 1, sessions: [] };
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Load canvas store synchronously (for initialization)
96
+ */
97
+ export function loadCanvasStoreSync(storePath?: string): CanvasStoreFile {
98
+ const effectivePath = storePath || getCanvasStorePath();
99
+ try {
100
+ const raw = fs.readFileSync(effectivePath, 'utf-8');
101
+ const parsed = JSON.parse(raw) as Partial<CanvasStoreFile> | null;
102
+ const sessions = Array.isArray(parsed?.sessions) ? parsed.sessions : [];
103
+
104
+ // Validate and filter sessions
105
+ const validSessions = sessions.filter((s): s is CanvasSession => {
106
+ if (!isValidSession(s)) return false;
107
+
108
+ // Also verify the session directory still exists
109
+ try {
110
+ return fs.existsSync(s.sessionDir);
111
+ } catch {
112
+ return false;
113
+ }
114
+ });
115
+
116
+ return {
117
+ version: 1,
118
+ sessions: validSessions,
119
+ };
120
+ } catch {
121
+ return { version: 1, sessions: [] };
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Save canvas sessions to the store file
127
+ * Uses atomic writes to prevent data corruption
128
+ */
129
+ export async function saveCanvasStore(
130
+ store: CanvasStoreFile,
131
+ storePath?: string
132
+ ): Promise<void> {
133
+ const effectivePath = storePath || getCanvasStorePath();
134
+
135
+ // Ensure directory exists
136
+ await fs.promises.mkdir(path.dirname(effectivePath), { recursive: true });
137
+
138
+ // Only keep non-closed sessions, and limit to max
139
+ let sessionsToSave = store.sessions.filter(s => s.status !== 'closed');
140
+
141
+ // Trim to max sessions (keep most recent)
142
+ if (sessionsToSave.length > MAX_SESSIONS) {
143
+ sessionsToSave = sessionsToSave
144
+ .sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt)
145
+ .slice(0, MAX_SESSIONS);
146
+ }
147
+
148
+ const storeToSave: CanvasStoreFile = {
149
+ version: 1,
150
+ sessions: sessionsToSave,
151
+ };
152
+
153
+ // Generate temp file path with process ID and random suffix
154
+ const tmp = `${effectivePath}.${process.pid}.${Math.random().toString(16).slice(2)}.tmp`;
155
+
156
+ // Write to temp file
157
+ const json = JSON.stringify(storeToSave, null, 2);
158
+ await fs.promises.writeFile(tmp, json, 'utf-8');
159
+
160
+ // Atomic rename
161
+ await fs.promises.rename(tmp, effectivePath);
162
+ }
163
+
164
+ /**
165
+ * Save canvas store synchronously
166
+ */
167
+ export function saveCanvasStoreSync(
168
+ store: CanvasStoreFile,
169
+ storePath?: string
170
+ ): void {
171
+ const effectivePath = storePath || getCanvasStorePath();
172
+
173
+ // Ensure directory exists
174
+ fs.mkdirSync(path.dirname(effectivePath), { recursive: true });
175
+
176
+ // Only keep non-closed sessions, and limit to max
177
+ let sessionsToSave = store.sessions.filter(s => s.status !== 'closed');
178
+
179
+ // Trim to max sessions (keep most recent)
180
+ if (sessionsToSave.length > MAX_SESSIONS) {
181
+ sessionsToSave = sessionsToSave
182
+ .sort((a, b) => b.lastUpdatedAt - a.lastUpdatedAt)
183
+ .slice(0, MAX_SESSIONS);
184
+ }
185
+
186
+ const storeToSave: CanvasStoreFile = {
187
+ version: 1,
188
+ sessions: sessionsToSave,
189
+ };
190
+
191
+ // Generate temp file path
192
+ const tmp = `${effectivePath}.${process.pid}.${Math.random().toString(16).slice(2)}.tmp`;
193
+
194
+ // Write to temp file
195
+ const json = JSON.stringify(storeToSave, null, 2);
196
+ fs.writeFileSync(tmp, json, 'utf-8');
197
+
198
+ // Atomic rename
199
+ fs.renameSync(tmp, effectivePath);
200
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Live Canvas Module
3
+ *
4
+ * Agent-driven visual workspace for rendering interactive HTML/CSS/JS content.
5
+ */
6
+
7
+ export { CanvasManager } from './canvas-manager';
8
+ export { registerCanvasScheme, registerCanvasProtocol } from './canvas-protocol';