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,444 @@
1
+ "use strict";
2
+ /**
3
+ * SecureSettingsRepository
4
+ *
5
+ * Stores all application settings in an encrypted format in the database.
6
+ * Uses Electron's safeStorage API which leverages the OS keychain:
7
+ * - macOS: Keychain
8
+ * - Windows: DPAPI (Data Protection API)
9
+ * - Linux: libsecret
10
+ *
11
+ * This ensures settings can ONLY be accessed by this app.
12
+ */
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
26
+ }) : function(o, v) {
27
+ o["default"] = v;
28
+ });
29
+ var __importStar = (this && this.__importStar) || (function () {
30
+ var ownKeys = function(o) {
31
+ ownKeys = Object.getOwnPropertyNames || function (o) {
32
+ var ar = [];
33
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
34
+ return ar;
35
+ };
36
+ return ownKeys(o);
37
+ };
38
+ return function (mod) {
39
+ if (mod && mod.__esModule) return mod;
40
+ var result = {};
41
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
42
+ __setModuleDefault(result, mod);
43
+ return result;
44
+ };
45
+ })();
46
+ Object.defineProperty(exports, "__esModule", { value: true });
47
+ exports.SecureSettingsRepository = void 0;
48
+ const electron_1 = require("electron");
49
+ const uuid_1 = require("uuid");
50
+ const crypto = __importStar(require("crypto"));
51
+ const fs = __importStar(require("fs"));
52
+ const path = __importStar(require("path"));
53
+ /** Machine ID file name - persisted for stable key derivation */
54
+ const MACHINE_ID_FILE = '.cowork-machine-id';
55
+ /**
56
+ * Repository for securely storing encrypted settings in the database
57
+ */
58
+ class SecureSettingsRepository {
59
+ constructor(db) {
60
+ this.db = db;
61
+ this.machineId = null;
62
+ this.encryptionAvailable = electron_1.safeStorage.isEncryptionAvailable();
63
+ if (!this.encryptionAvailable) {
64
+ console.warn('[SecureSettingsRepository] OS encryption not available. Settings will be stored with app-level encryption only.');
65
+ }
66
+ // Initialize stable machine ID for fallback encryption
67
+ this.initializeMachineId();
68
+ // Set as singleton instance
69
+ SecureSettingsRepository.instance = this;
70
+ }
71
+ /**
72
+ * Initialize or load the stable machine ID
73
+ * This ID persists across hostname changes, making fallback encryption stable
74
+ */
75
+ initializeMachineId() {
76
+ try {
77
+ const userDataPath = electron_1.app.getPath('userData');
78
+ const machineIdPath = path.join(userDataPath, MACHINE_ID_FILE);
79
+ if (fs.existsSync(machineIdPath)) {
80
+ this.machineId = fs.readFileSync(machineIdPath, 'utf-8').trim();
81
+ console.log('[SecureSettingsRepository] Loaded existing machine ID');
82
+ }
83
+ else {
84
+ // Generate a new stable machine ID
85
+ this.machineId = (0, uuid_1.v4)();
86
+ // Write with restrictive permissions (owner read/write only)
87
+ fs.writeFileSync(machineIdPath, this.machineId, { mode: 0o600 });
88
+ console.log('[SecureSettingsRepository] Generated new machine ID');
89
+ }
90
+ }
91
+ catch (error) {
92
+ console.warn('[SecureSettingsRepository] Failed to initialize machine ID, using fallback:', error);
93
+ // Fallback to old method if file operations fail
94
+ this.machineId = null;
95
+ }
96
+ }
97
+ /**
98
+ * Get the singleton instance of SecureSettingsRepository.
99
+ * Must be called after the instance has been created.
100
+ */
101
+ static getInstance() {
102
+ if (!SecureSettingsRepository.instance) {
103
+ throw new Error('SecureSettingsRepository has not been initialized. Initialize it in main.ts first.');
104
+ }
105
+ return SecureSettingsRepository.instance;
106
+ }
107
+ /**
108
+ * Check if the repository has been initialized
109
+ */
110
+ static isInitialized() {
111
+ return SecureSettingsRepository.instance !== null;
112
+ }
113
+ /**
114
+ * Save settings for a category (creates or updates)
115
+ */
116
+ save(category, settings) {
117
+ const now = Date.now();
118
+ const jsonData = JSON.stringify(settings);
119
+ const encryptedData = this.encrypt(jsonData);
120
+ const checksum = this.computeChecksum(jsonData);
121
+ const existing = this.findByCategory(category);
122
+ if (existing) {
123
+ // Update existing
124
+ const stmt = this.db.prepare(`
125
+ UPDATE secure_settings
126
+ SET encrypted_data = ?, checksum = ?, updated_at = ?
127
+ WHERE category = ?
128
+ `);
129
+ stmt.run(encryptedData, checksum, now, category);
130
+ }
131
+ else {
132
+ // Insert new
133
+ const stmt = this.db.prepare(`
134
+ INSERT INTO secure_settings (id, category, encrypted_data, checksum, created_at, updated_at)
135
+ VALUES (?, ?, ?, ?, ?, ?)
136
+ `);
137
+ stmt.run((0, uuid_1.v4)(), category, encryptedData, checksum, now, now);
138
+ }
139
+ console.log(`[SecureSettingsRepository] Saved settings for category: ${category}`);
140
+ }
141
+ /**
142
+ * Load settings for a category
143
+ * Returns undefined if no settings exist or if decryption fails
144
+ */
145
+ load(category) {
146
+ const result = this.loadWithStatus(category);
147
+ return result.data;
148
+ }
149
+ /**
150
+ * Load settings with detailed status information
151
+ * Use this when you need to distinguish between "not found" vs "corrupted" vs "decryption failed"
152
+ */
153
+ loadWithStatus(category) {
154
+ const row = this.findByCategory(category);
155
+ if (!row) {
156
+ return { status: 'not_found' };
157
+ }
158
+ try {
159
+ const decrypted = this.decrypt(row.encrypted_data);
160
+ // Verify checksum to detect tampering
161
+ const checksum = this.computeChecksum(decrypted);
162
+ if (checksum !== row.checksum) {
163
+ console.error(`[SecureSettingsRepository] Checksum mismatch for category: ${category}. Data may be corrupted.`);
164
+ return {
165
+ status: 'checksum_mismatch',
166
+ error: 'Data integrity check failed. Settings may be corrupted.',
167
+ };
168
+ }
169
+ return {
170
+ status: 'success',
171
+ data: JSON.parse(decrypted),
172
+ };
173
+ }
174
+ catch (error) {
175
+ const errorMessage = error instanceof Error ? error.message : String(error);
176
+ console.error(`[SecureSettingsRepository] Failed to decrypt settings for category: ${category}`, error);
177
+ // Detect specific failure modes
178
+ if (errorMessage.includes('OS encryption was used but is no longer available')) {
179
+ return {
180
+ status: 'os_encryption_unavailable',
181
+ error: 'Settings were encrypted with OS keychain which is no longer accessible. You may need to re-enter your credentials.',
182
+ };
183
+ }
184
+ return {
185
+ status: 'decryption_failed',
186
+ error: errorMessage,
187
+ };
188
+ }
189
+ }
190
+ /**
191
+ * Check if settings can be decrypted (health check)
192
+ * Returns the status without exposing the actual data
193
+ */
194
+ checkHealth(category) {
195
+ return this.loadWithStatus(category).status;
196
+ }
197
+ /**
198
+ * Delete settings for a category
199
+ */
200
+ delete(category) {
201
+ const stmt = this.db.prepare('DELETE FROM secure_settings WHERE category = ?');
202
+ const result = stmt.run(category);
203
+ return result.changes > 0;
204
+ }
205
+ /**
206
+ * Check if settings exist for a category
207
+ */
208
+ exists(category) {
209
+ const stmt = this.db.prepare('SELECT 1 FROM secure_settings WHERE category = ? LIMIT 1');
210
+ const row = stmt.get(category);
211
+ return row !== undefined;
212
+ }
213
+ /**
214
+ * Get all categories that have settings stored
215
+ */
216
+ listCategories() {
217
+ const stmt = this.db.prepare('SELECT category FROM secure_settings ORDER BY category');
218
+ const rows = stmt.all();
219
+ return rows.map((r) => r.category);
220
+ }
221
+ /**
222
+ * Get metadata about stored settings (without decrypting)
223
+ */
224
+ getMetadata(category) {
225
+ const stmt = this.db.prepare('SELECT created_at, updated_at FROM secure_settings WHERE category = ?');
226
+ const row = stmt.get(category);
227
+ return row ? { createdAt: row.created_at, updatedAt: row.updated_at } : undefined;
228
+ }
229
+ // ============ Backup & Recovery ============
230
+ /**
231
+ * Create an encrypted backup of all settings to a file
232
+ * The backup is encrypted with OS keychain when available
233
+ */
234
+ createBackup(backupPath) {
235
+ try {
236
+ const categories = this.listCategories();
237
+ const backupData = {};
238
+ for (const category of categories) {
239
+ const result = this.loadWithStatus(category);
240
+ if (result.status === 'success' && result.data) {
241
+ backupData[category] = result.data;
242
+ }
243
+ }
244
+ const jsonData = JSON.stringify({
245
+ version: 1,
246
+ timestamp: Date.now(),
247
+ categories: backupData,
248
+ });
249
+ // Encrypt the backup
250
+ const encryptedBackup = this.encrypt(jsonData);
251
+ fs.writeFileSync(backupPath, encryptedBackup, { mode: 0o600 });
252
+ console.log(`[SecureSettingsRepository] Created backup with ${categories.length} categories`);
253
+ return { success: true, categoriesBackedUp: categories };
254
+ }
255
+ catch (error) {
256
+ const errorMessage = error instanceof Error ? error.message : String(error);
257
+ console.error('[SecureSettingsRepository] Backup failed:', error);
258
+ return { success: false, categoriesBackedUp: [], error: errorMessage };
259
+ }
260
+ }
261
+ /**
262
+ * Restore settings from an encrypted backup file
263
+ * @param backupPath Path to the backup file
264
+ * @param overwrite Whether to overwrite existing settings (default: false)
265
+ */
266
+ restoreBackup(backupPath, overwrite = false) {
267
+ try {
268
+ if (!fs.existsSync(backupPath)) {
269
+ return { success: false, categoriesRestored: [], error: 'Backup file not found' };
270
+ }
271
+ const encryptedBackup = fs.readFileSync(backupPath, 'utf-8');
272
+ const jsonData = this.decrypt(encryptedBackup);
273
+ const backup = JSON.parse(jsonData);
274
+ if (!backup.version || !backup.categories) {
275
+ return { success: false, categoriesRestored: [], error: 'Invalid backup format' };
276
+ }
277
+ const categoriesRestored = [];
278
+ for (const [category, data] of Object.entries(backup.categories)) {
279
+ const existingStatus = this.checkHealth(category);
280
+ // Skip if exists and not overwriting
281
+ if (existingStatus === 'success' && !overwrite) {
282
+ console.log(`[SecureSettingsRepository] Skipping ${category} (exists, overwrite=false)`);
283
+ continue;
284
+ }
285
+ this.save(category, data);
286
+ categoriesRestored.push(category);
287
+ }
288
+ console.log(`[SecureSettingsRepository] Restored ${categoriesRestored.length} categories from backup`);
289
+ return { success: true, categoriesRestored };
290
+ }
291
+ catch (error) {
292
+ const errorMessage = error instanceof Error ? error.message : String(error);
293
+ console.error('[SecureSettingsRepository] Restore failed:', error);
294
+ return { success: false, categoriesRestored: [], error: errorMessage };
295
+ }
296
+ }
297
+ /**
298
+ * Delete corrupted settings for a category
299
+ * Use this when checkHealth returns 'checksum_mismatch' or 'decryption_failed'
300
+ * to allow the user to start fresh
301
+ */
302
+ deleteCorrupted(category) {
303
+ const status = this.checkHealth(category);
304
+ if (status === 'success' || status === 'not_found') {
305
+ console.warn(`[SecureSettingsRepository] Category ${category} is not corrupted, not deleting`);
306
+ return false;
307
+ }
308
+ console.log(`[SecureSettingsRepository] Deleting corrupted settings for ${category} (status: ${status})`);
309
+ return this.delete(category);
310
+ }
311
+ /**
312
+ * Re-encrypt all settings with current encryption method
313
+ * Useful after OS keychain becomes available or for migration
314
+ */
315
+ reEncryptAll() {
316
+ const categories = this.listCategories();
317
+ const processed = [];
318
+ const errors = [];
319
+ for (const category of categories) {
320
+ try {
321
+ const result = this.loadWithStatus(category);
322
+ if (result.status === 'success' && result.data) {
323
+ // Re-save with current encryption method
324
+ this.save(category, result.data);
325
+ processed.push(category);
326
+ }
327
+ else {
328
+ errors.push(`${category}: ${result.error || result.status}`);
329
+ }
330
+ }
331
+ catch (error) {
332
+ errors.push(`${category}: ${error instanceof Error ? error.message : String(error)}`);
333
+ }
334
+ }
335
+ console.log(`[SecureSettingsRepository] Re-encrypted ${processed.length}/${categories.length} categories`);
336
+ return { success: errors.length === 0, categoriesProcessed: processed, errors };
337
+ }
338
+ // ============ Private Methods ============
339
+ findByCategory(category) {
340
+ const stmt = this.db.prepare('SELECT * FROM secure_settings WHERE category = ?');
341
+ return stmt.get(category);
342
+ }
343
+ /**
344
+ * Encrypt data using OS keychain (safeStorage) when available,
345
+ * otherwise use app-level encryption with a derived key
346
+ */
347
+ encrypt(data) {
348
+ if (this.encryptionAvailable) {
349
+ // Use OS keychain encryption
350
+ const encryptedBuffer = electron_1.safeStorage.encryptString(data);
351
+ return 'os:' + encryptedBuffer.toString('base64');
352
+ }
353
+ else {
354
+ // Fallback: Use app-level AES encryption
355
+ // The key is derived from a combination of app identity and machine-specific data
356
+ const key = this.deriveAppKey();
357
+ const iv = crypto.randomBytes(16);
358
+ const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
359
+ let encrypted = cipher.update(data, 'utf8', 'base64');
360
+ encrypted += cipher.final('base64');
361
+ const authTag = cipher.getAuthTag();
362
+ // Format: app:<iv>:<authTag>:<encrypted>
363
+ return `app:${iv.toString('base64')}:${authTag.toString('base64')}:${encrypted}`;
364
+ }
365
+ }
366
+ /**
367
+ * Decrypt data using the appropriate method based on prefix
368
+ */
369
+ decrypt(encryptedData) {
370
+ if (encryptedData.startsWith('os:')) {
371
+ // OS keychain decryption
372
+ if (!this.encryptionAvailable) {
373
+ throw new Error('OS encryption was used but is no longer available');
374
+ }
375
+ const base64Data = encryptedData.slice(3);
376
+ const encryptedBuffer = Buffer.from(base64Data, 'base64');
377
+ return electron_1.safeStorage.decryptString(encryptedBuffer);
378
+ }
379
+ else if (encryptedData.startsWith('app:')) {
380
+ // App-level AES decryption
381
+ const parts = encryptedData.slice(4).split(':');
382
+ if (parts.length !== 3) {
383
+ throw new Error('Invalid encrypted data format');
384
+ }
385
+ const [ivBase64, authTagBase64, encrypted] = parts;
386
+ const key = this.deriveAppKey();
387
+ const iv = Buffer.from(ivBase64, 'base64');
388
+ const authTag = Buffer.from(authTagBase64, 'base64');
389
+ const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
390
+ decipher.setAuthTag(authTag);
391
+ let decrypted = decipher.update(encrypted, 'base64', 'utf8');
392
+ decrypted += decipher.final('utf8');
393
+ return decrypted;
394
+ }
395
+ else {
396
+ // Legacy unencrypted data (shouldn't happen, but handle gracefully)
397
+ console.warn('[SecureSettingsRepository] Found unencrypted data, returning as-is');
398
+ return encryptedData;
399
+ }
400
+ }
401
+ /**
402
+ * Derive an app-specific encryption key
403
+ * This key is deterministic per machine but not stored anywhere
404
+ */
405
+ deriveAppKey() {
406
+ // Use a combination of:
407
+ // 1. App identifier (hardcoded, same for all installations)
408
+ // 2. Process info (changes per machine but is consistent)
409
+ const appSalt = 'cowork-os-secure-settings-v1';
410
+ const machineId = this.getMachineIdentifier();
411
+ // Derive a 256-bit key using PBKDF2
412
+ return crypto.pbkdf2Sync(appSalt, machineId, 100000, 32, 'sha512');
413
+ }
414
+ /**
415
+ * Get a machine-specific identifier for key derivation
416
+ * Uses a stable persistent ID to survive hostname changes, user renames, etc.
417
+ */
418
+ getMachineIdentifier() {
419
+ // Use stable machine ID if available (generated at first launch)
420
+ if (this.machineId) {
421
+ return this.machineId;
422
+ }
423
+ // Fallback: Combine system properties (less stable, for backwards compatibility)
424
+ // This path is only taken if machine ID file operations failed
425
+ const os = require('os');
426
+ const factors = [
427
+ os.hostname(),
428
+ os.platform(),
429
+ os.arch(),
430
+ os.homedir(),
431
+ process.env.USER || process.env.USERNAME || 'default-user',
432
+ ];
433
+ console.warn('[SecureSettingsRepository] Using volatile machine identifier as fallback');
434
+ return factors.join(':');
435
+ }
436
+ /**
437
+ * Compute a SHA-256 checksum for integrity verification
438
+ */
439
+ computeChecksum(data) {
440
+ return crypto.createHash('sha256').update(data).digest('hex');
441
+ }
442
+ }
443
+ exports.SecureSettingsRepository = SecureSettingsRepository;
444
+ SecureSettingsRepository.instance = null;
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TaskLabelRepository = void 0;
4
+ const uuid_1 = require("uuid");
5
+ const DEFAULT_LABEL_COLOR = '#6366f1';
6
+ /**
7
+ * Repository for managing task labels in the database
8
+ */
9
+ class TaskLabelRepository {
10
+ constructor(db) {
11
+ this.db = db;
12
+ }
13
+ /**
14
+ * Create a new task label
15
+ */
16
+ create(request) {
17
+ const now = Date.now();
18
+ const label = {
19
+ id: (0, uuid_1.v4)(),
20
+ workspaceId: request.workspaceId,
21
+ name: request.name,
22
+ color: request.color || DEFAULT_LABEL_COLOR,
23
+ createdAt: now,
24
+ };
25
+ const stmt = this.db.prepare(`
26
+ INSERT INTO task_labels (id, workspace_id, name, color, created_at)
27
+ VALUES (?, ?, ?, ?, ?)
28
+ `);
29
+ stmt.run(label.id, label.workspaceId, label.name, label.color, label.createdAt);
30
+ return label;
31
+ }
32
+ /**
33
+ * Find a task label by ID
34
+ */
35
+ findById(id) {
36
+ const stmt = this.db.prepare('SELECT * FROM task_labels WHERE id = ?');
37
+ const row = stmt.get(id);
38
+ return row ? this.mapRowToLabel(row) : undefined;
39
+ }
40
+ /**
41
+ * Find a task label by name within a workspace
42
+ */
43
+ findByName(workspaceId, name) {
44
+ const stmt = this.db.prepare('SELECT * FROM task_labels WHERE workspace_id = ? AND name = ?');
45
+ const row = stmt.get(workspaceId, name);
46
+ return row ? this.mapRowToLabel(row) : undefined;
47
+ }
48
+ /**
49
+ * List all labels for a workspace
50
+ */
51
+ list(query) {
52
+ const stmt = this.db.prepare('SELECT * FROM task_labels WHERE workspace_id = ? ORDER BY name ASC');
53
+ const rows = stmt.all(query.workspaceId);
54
+ return rows.map((row) => this.mapRowToLabel(row));
55
+ }
56
+ /**
57
+ * Update a task label
58
+ */
59
+ update(id, request) {
60
+ const existing = this.findById(id);
61
+ if (!existing)
62
+ return undefined;
63
+ const updates = [];
64
+ const params = [];
65
+ if (request.name !== undefined) {
66
+ updates.push('name = ?');
67
+ params.push(request.name);
68
+ }
69
+ if (request.color !== undefined) {
70
+ updates.push('color = ?');
71
+ params.push(request.color);
72
+ }
73
+ if (updates.length === 0)
74
+ return existing;
75
+ params.push(id);
76
+ const stmt = this.db.prepare(`UPDATE task_labels SET ${updates.join(', ')} WHERE id = ?`);
77
+ stmt.run(...params);
78
+ return this.findById(id);
79
+ }
80
+ /**
81
+ * Delete a task label
82
+ */
83
+ delete(id) {
84
+ const stmt = this.db.prepare('DELETE FROM task_labels WHERE id = ?');
85
+ const result = stmt.run(id);
86
+ return result.changes > 0;
87
+ }
88
+ /**
89
+ * Delete all labels for a workspace
90
+ */
91
+ deleteByWorkspace(workspaceId) {
92
+ const stmt = this.db.prepare('DELETE FROM task_labels WHERE workspace_id = ?');
93
+ const result = stmt.run(workspaceId);
94
+ return result.changes;
95
+ }
96
+ /**
97
+ * Get multiple labels by IDs
98
+ */
99
+ getByIds(ids) {
100
+ if (ids.length === 0)
101
+ return [];
102
+ const placeholders = ids.map(() => '?').join(', ');
103
+ const stmt = this.db.prepare(`SELECT * FROM task_labels WHERE id IN (${placeholders})`);
104
+ const rows = stmt.all(...ids);
105
+ return rows.map((row) => this.mapRowToLabel(row));
106
+ }
107
+ /**
108
+ * Map database row to TaskLabel object
109
+ */
110
+ mapRowToLabel(row) {
111
+ return {
112
+ id: row.id,
113
+ workspaceId: row.workspace_id,
114
+ name: row.name,
115
+ color: row.color,
116
+ createdAt: row.created_at,
117
+ };
118
+ }
119
+ }
120
+ exports.TaskLabelRepository = TaskLabelRepository;