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,800 @@
1
+ /**
2
+ * Personality Settings Manager
3
+ *
4
+ * Manages agent personality preferences including:
5
+ * - Base personality (professional, friendly, etc.)
6
+ * - Famous assistant personas (Jarvis, Friday, etc.)
7
+ * - Response style preferences (emoji, length, etc.)
8
+ * - Personality quirks (catchphrases, sign-offs)
9
+ * - Relationship data (user name, milestones)
10
+ *
11
+ * Settings are stored encrypted in the database using SecureSettingsRepository.
12
+ */
13
+
14
+ import { app } from 'electron';
15
+ import * as fs from 'fs';
16
+ import * as path from 'path';
17
+ import { EventEmitter } from 'events';
18
+ import {
19
+ PersonalitySettings,
20
+ PersonalityId,
21
+ PersonaId,
22
+ PersonalityDefinition,
23
+ PersonaDefinition,
24
+ ResponseStylePreferences,
25
+ PersonalityQuirks,
26
+ RelationshipData,
27
+ PERSONALITY_DEFINITIONS,
28
+ PERSONA_DEFINITIONS,
29
+ ANALOGY_DOMAINS,
30
+ DEFAULT_RESPONSE_STYLE,
31
+ DEFAULT_QUIRKS,
32
+ DEFAULT_RELATIONSHIP,
33
+ getPersonalityById,
34
+ getPersonaById,
35
+ } from '../../shared/types';
36
+ import { SecureSettingsRepository } from '../database/SecureSettingsRepository';
37
+
38
+ const LEGACY_SETTINGS_FILE = 'personality-settings.json';
39
+
40
+ const DEFAULT_AGENT_NAME = 'CoWork';
41
+
42
+ const DEFAULT_SETTINGS: PersonalitySettings = {
43
+ activePersonality: 'professional',
44
+ customPrompt: '',
45
+ customName: 'Custom Assistant',
46
+ agentName: DEFAULT_AGENT_NAME,
47
+ activePersona: 'companion',
48
+ responseStyle: DEFAULT_RESPONSE_STYLE,
49
+ quirks: DEFAULT_QUIRKS,
50
+ relationship: DEFAULT_RELATIONSHIP,
51
+ };
52
+
53
+ // Milestone thresholds for celebrations
54
+ const MILESTONES = [1, 10, 25, 50, 100, 250, 500, 1000];
55
+
56
+ // Event emitter for personality settings changes
57
+ const personalityEvents = new EventEmitter();
58
+
59
+ export class PersonalityManager {
60
+ private static legacySettingsPath: string;
61
+ private static cachedSettings: PersonalitySettings | null = null;
62
+ private static initialized = false;
63
+ private static migrationCompleted = false;
64
+
65
+ /**
66
+ * Subscribe to settings changed events.
67
+ * The callback receives the updated settings.
68
+ */
69
+ static onSettingsChanged(callback: (settings: PersonalitySettings) => void): () => void {
70
+ personalityEvents.on('settingsChanged', callback);
71
+ return () => personalityEvents.off('settingsChanged', callback);
72
+ }
73
+
74
+ /**
75
+ * Remove all event listeners (useful for testing)
76
+ */
77
+ static removeAllListeners(): void {
78
+ personalityEvents.removeAllListeners();
79
+ }
80
+
81
+ /**
82
+ * Emit a settings changed event
83
+ */
84
+ private static emitSettingsChanged(): void {
85
+ if (this.cachedSettings) {
86
+ personalityEvents.emit('settingsChanged', this.cachedSettings);
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Initialize the PersonalityManager
92
+ */
93
+ static initialize(): void {
94
+ if (this.initialized) {
95
+ return; // Already initialized
96
+ }
97
+ const userDataPath = app.getPath('userData');
98
+ this.legacySettingsPath = path.join(userDataPath, LEGACY_SETTINGS_FILE);
99
+ this.initialized = true;
100
+ console.log('[PersonalityManager] Initialized');
101
+
102
+ // Migrate from legacy JSON file to encrypted database
103
+ this.migrateFromLegacyFile();
104
+ }
105
+
106
+ /**
107
+ * Migrate settings from legacy JSON file to encrypted database
108
+ */
109
+ private static migrateFromLegacyFile(): void {
110
+ if (this.migrationCompleted) return;
111
+
112
+ try {
113
+ // Check if SecureSettingsRepository is initialized
114
+ if (!SecureSettingsRepository.isInitialized()) {
115
+ console.log('[PersonalityManager] SecureSettingsRepository not yet initialized, skipping migration');
116
+ return;
117
+ }
118
+
119
+ const repository = SecureSettingsRepository.getInstance();
120
+
121
+ // Check if already migrated to database
122
+ if (repository.exists('personality')) {
123
+ this.migrationCompleted = true;
124
+ return;
125
+ }
126
+
127
+ // Check if legacy file exists
128
+ if (!fs.existsSync(this.legacySettingsPath)) {
129
+ console.log('[PersonalityManager] No legacy settings file found');
130
+ this.migrationCompleted = true;
131
+ return;
132
+ }
133
+
134
+ console.log('[PersonalityManager] Migrating settings from legacy JSON file to encrypted database...');
135
+
136
+ // Create backup before migration
137
+ const backupPath = this.legacySettingsPath + '.migration-backup';
138
+ fs.copyFileSync(this.legacySettingsPath, backupPath);
139
+
140
+ try {
141
+ // Read legacy settings
142
+ const data = fs.readFileSync(this.legacySettingsPath, 'utf-8');
143
+ const parsed = JSON.parse(data);
144
+ const legacySettings = {
145
+ ...DEFAULT_SETTINGS,
146
+ ...parsed,
147
+ responseStyle: { ...DEFAULT_RESPONSE_STYLE, ...parsed.responseStyle },
148
+ quirks: { ...DEFAULT_QUIRKS, ...parsed.quirks },
149
+ relationship: { ...DEFAULT_RELATIONSHIP, ...parsed.relationship },
150
+ };
151
+
152
+ // Save to encrypted database
153
+ repository.save('personality', legacySettings);
154
+ console.log('[PersonalityManager] Settings migrated to encrypted database');
155
+
156
+ // Migration successful - delete backup and original
157
+ fs.unlinkSync(backupPath);
158
+ fs.unlinkSync(this.legacySettingsPath);
159
+ console.log('[PersonalityManager] Migration complete, cleaned up legacy files');
160
+
161
+ this.migrationCompleted = true;
162
+ } catch (migrationError) {
163
+ console.error('[PersonalityManager] Migration failed, backup preserved at:', backupPath);
164
+ throw migrationError;
165
+ }
166
+ } catch (error) {
167
+ console.error('[PersonalityManager] Migration failed:', error);
168
+ }
169
+ }
170
+
171
+ /**
172
+ * Ensure the manager is initialized before use
173
+ */
174
+ private static ensureInitialized(): void {
175
+ if (!this.initialized) {
176
+ throw new Error('[PersonalityManager] Not initialized. Call PersonalityManager.initialize() first.');
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Load settings from encrypted database (with caching)
182
+ */
183
+ static loadSettings(): PersonalitySettings {
184
+ this.ensureInitialized();
185
+
186
+ if (this.cachedSettings) {
187
+ return this.cachedSettings;
188
+ }
189
+
190
+ // Deep copy DEFAULT_SETTINGS to avoid mutating the original constants
191
+ let settings: PersonalitySettings = {
192
+ ...DEFAULT_SETTINGS,
193
+ responseStyle: { ...DEFAULT_RESPONSE_STYLE },
194
+ quirks: { ...DEFAULT_QUIRKS },
195
+ relationship: { ...DEFAULT_RELATIONSHIP },
196
+ };
197
+
198
+ try {
199
+ // Try to load from encrypted database
200
+ if (SecureSettingsRepository.isInitialized()) {
201
+ const repository = SecureSettingsRepository.getInstance();
202
+ const stored = repository.load<PersonalitySettings>('personality');
203
+ if (stored) {
204
+ settings = {
205
+ ...DEFAULT_SETTINGS,
206
+ ...stored,
207
+ responseStyle: { ...DEFAULT_RESPONSE_STYLE, ...stored.responseStyle },
208
+ quirks: { ...DEFAULT_QUIRKS, ...stored.quirks },
209
+ relationship: { ...DEFAULT_RELATIONSHIP, ...stored.relationship },
210
+ };
211
+ }
212
+ }
213
+
214
+ // Validate values
215
+ if (!isValidPersonalityId(settings.activePersonality)) {
216
+ settings.activePersonality = DEFAULT_SETTINGS.activePersonality;
217
+ }
218
+ if (!isValidPersonaId(settings.activePersona)) {
219
+ settings.activePersona = DEFAULT_SETTINGS.activePersona;
220
+ }
221
+ } catch (error) {
222
+ console.error('[PersonalityManager] Failed to load settings:', error);
223
+ // Deep copy DEFAULT_SETTINGS to avoid mutating the original constants
224
+ settings = {
225
+ ...DEFAULT_SETTINGS,
226
+ responseStyle: { ...DEFAULT_RESPONSE_STYLE },
227
+ quirks: { ...DEFAULT_QUIRKS },
228
+ relationship: { ...DEFAULT_RELATIONSHIP },
229
+ };
230
+ }
231
+
232
+ this.cachedSettings = settings;
233
+ return settings;
234
+ }
235
+
236
+ /**
237
+ * Save settings to encrypted database
238
+ */
239
+ static saveSettings(settings: PersonalitySettings): void {
240
+ try {
241
+ if (!SecureSettingsRepository.isInitialized()) {
242
+ throw new Error('SecureSettingsRepository not initialized');
243
+ }
244
+
245
+ // Load existing settings to preserve fields not being updated
246
+ const existingSettings = this.loadSettings();
247
+
248
+ // Validate and merge with existing settings
249
+ const validatedSettings: PersonalitySettings = {
250
+ activePersonality: isValidPersonalityId(settings.activePersonality)
251
+ ? settings.activePersonality
252
+ : existingSettings.activePersonality,
253
+ customPrompt: settings.customPrompt ?? existingSettings.customPrompt,
254
+ customName: settings.customName ?? existingSettings.customName,
255
+ agentName: settings.agentName ?? existingSettings.agentName,
256
+ activePersona: isValidPersonaId(settings.activePersona)
257
+ ? settings.activePersona
258
+ : existingSettings.activePersona,
259
+ responseStyle: settings.responseStyle
260
+ ? { ...existingSettings.responseStyle, ...settings.responseStyle }
261
+ : existingSettings.responseStyle,
262
+ quirks: settings.quirks
263
+ ? { ...existingSettings.quirks, ...settings.quirks }
264
+ : existingSettings.quirks,
265
+ relationship: settings.relationship
266
+ ? { ...existingSettings.relationship, ...settings.relationship }
267
+ : existingSettings.relationship,
268
+ };
269
+
270
+ const repository = SecureSettingsRepository.getInstance();
271
+ repository.save('personality', validatedSettings);
272
+ this.cachedSettings = validatedSettings;
273
+ console.log('[PersonalityManager] Settings saved to encrypted database');
274
+ this.emitSettingsChanged();
275
+ } catch (error) {
276
+ console.error('[PersonalityManager] Failed to save settings:', error);
277
+ throw error;
278
+ }
279
+ }
280
+
281
+ /**
282
+ * Set the active personality
283
+ */
284
+ static setActivePersonality(personalityId: PersonalityId): void {
285
+ const settings = this.loadSettings();
286
+ settings.activePersonality = personalityId;
287
+ this.saveSettings(settings);
288
+ }
289
+
290
+ /**
291
+ * Set the active persona
292
+ */
293
+ static setActivePersona(personaId: PersonaId): void {
294
+ const settings = this.loadSettings();
295
+ settings.activePersona = personaId;
296
+
297
+ // Optionally apply persona's suggested name and quirks
298
+ const persona = getPersonaById(personaId);
299
+ if (persona && personaId !== 'none') {
300
+ if (persona.suggestedName && !settings.agentName) {
301
+ settings.agentName = persona.suggestedName;
302
+ }
303
+ if (persona.sampleCatchphrase && !settings.quirks?.catchphrase) {
304
+ settings.quirks = {
305
+ ...settings.quirks,
306
+ catchphrase: persona.sampleCatchphrase,
307
+ } as PersonalityQuirks;
308
+ }
309
+ if (persona.sampleSignOff && !settings.quirks?.signOff) {
310
+ settings.quirks = {
311
+ ...settings.quirks,
312
+ signOff: persona.sampleSignOff,
313
+ } as PersonalityQuirks;
314
+ }
315
+ }
316
+
317
+ this.saveSettings(settings);
318
+ }
319
+
320
+ /**
321
+ * Get the currently active personality definition
322
+ */
323
+ static getActivePersonality(): PersonalityDefinition | undefined {
324
+ const settings = this.loadSettings();
325
+ return getPersonalityById(settings.activePersonality);
326
+ }
327
+
328
+ /**
329
+ * Get the currently active persona definition
330
+ */
331
+ static getActivePersona(): PersonaDefinition | undefined {
332
+ const settings = this.loadSettings();
333
+ return getPersonaById(settings.activePersona || 'none');
334
+ }
335
+
336
+ /**
337
+ * Get the personality prompt for a specific personality ID.
338
+ * Used by sub-agents to get their configured personality prompt.
339
+ */
340
+ static getPersonalityPromptById(personalityId: string): string {
341
+ // Validate and get the personality definition
342
+ if (!isValidPersonalityId(personalityId)) {
343
+ console.warn(`[PersonalityManager] Invalid personality ID: ${personalityId}, using default`);
344
+ return this.getPersonalityPrompt();
345
+ }
346
+
347
+ const personality = getPersonalityById(personalityId as PersonalityId);
348
+ if (!personality?.promptTemplate) {
349
+ return this.getPersonalityPrompt();
350
+ }
351
+
352
+ // Return just the base personality prompt for sub-agents
353
+ // (no persona overlay, no quirks - keep it focused)
354
+ return personality.promptTemplate;
355
+ }
356
+
357
+ /**
358
+ * Get the full personality prompt combining all elements
359
+ */
360
+ static getPersonalityPrompt(): string {
361
+ const settings = this.loadSettings();
362
+ const parts: string[] = [];
363
+
364
+ // 1. Base personality prompt
365
+ if (settings.activePersonality === 'custom') {
366
+ if (settings.customPrompt) {
367
+ parts.push(settings.customPrompt);
368
+ }
369
+ } else {
370
+ const personality = getPersonalityById(settings.activePersonality);
371
+ if (personality?.promptTemplate) {
372
+ parts.push(personality.promptTemplate);
373
+ }
374
+ }
375
+
376
+ // 2. Persona overlay (if not 'none')
377
+ if (settings.activePersona && settings.activePersona !== 'none') {
378
+ const persona = getPersonaById(settings.activePersona);
379
+ if (persona?.promptTemplate) {
380
+ parts.push(persona.promptTemplate);
381
+ }
382
+ }
383
+
384
+ // 3. Response style preferences
385
+ const stylePrompt = this.getResponseStylePrompt(settings.responseStyle);
386
+ if (stylePrompt) {
387
+ parts.push(stylePrompt);
388
+ }
389
+
390
+ // 4. Quirks
391
+ const quirksPrompt = this.getQuirksPrompt(settings.quirks);
392
+ if (quirksPrompt) {
393
+ parts.push(quirksPrompt);
394
+ }
395
+
396
+ return parts.join('\n\n');
397
+ }
398
+
399
+ /**
400
+ * Generate prompt section for response style preferences
401
+ */
402
+ private static getResponseStylePrompt(style?: ResponseStylePreferences): string {
403
+ if (!style) return '';
404
+
405
+ const lines: string[] = ['RESPONSE STYLE PREFERENCES:'];
406
+
407
+ // Emoji usage
408
+ switch (style.emojiUsage) {
409
+ case 'none':
410
+ lines.push('- Do NOT use emojis in responses');
411
+ break;
412
+ case 'minimal':
413
+ lines.push('- Use emojis sparingly, only when they add clear value');
414
+ break;
415
+ case 'moderate':
416
+ lines.push('- Feel free to use emojis to enhance communication');
417
+ break;
418
+ case 'expressive':
419
+ lines.push('- Use emojis liberally to make responses engaging and expressive');
420
+ break;
421
+ }
422
+
423
+ // Response length
424
+ switch (style.responseLength) {
425
+ case 'terse':
426
+ lines.push('- Keep responses very brief and to the point');
427
+ lines.push('- Omit explanations unless explicitly requested');
428
+ break;
429
+ case 'balanced':
430
+ lines.push('- Provide balanced responses with appropriate detail');
431
+ break;
432
+ case 'detailed':
433
+ lines.push('- Provide comprehensive, detailed responses');
434
+ lines.push('- Include context, explanations, and related information');
435
+ break;
436
+ }
437
+
438
+ // Code comment style
439
+ switch (style.codeCommentStyle) {
440
+ case 'minimal':
441
+ lines.push('- When writing code, use minimal comments (only for complex logic)');
442
+ break;
443
+ case 'moderate':
444
+ lines.push('- When writing code, include helpful comments for key sections');
445
+ break;
446
+ case 'verbose':
447
+ lines.push('- When writing code, include detailed comments explaining the approach');
448
+ break;
449
+ }
450
+
451
+ // Explanation depth
452
+ switch (style.explanationDepth) {
453
+ case 'expert':
454
+ lines.push('- Assume the user is an expert - skip basic explanations');
455
+ lines.push('- Focus on advanced considerations and edge cases');
456
+ break;
457
+ case 'balanced':
458
+ lines.push('- Balance explanations for a competent but curious user');
459
+ break;
460
+ case 'teaching':
461
+ lines.push('- Explain concepts thoroughly as you would to a student');
462
+ lines.push('- Include "why" explanations and learning opportunities');
463
+ break;
464
+ }
465
+
466
+ return lines.length > 1 ? lines.join('\n') : '';
467
+ }
468
+
469
+ /**
470
+ * Generate prompt section for personality quirks
471
+ */
472
+ private static getQuirksPrompt(quirks?: PersonalityQuirks): string {
473
+ if (!quirks) return '';
474
+
475
+ const lines: string[] = [];
476
+
477
+ if (quirks.catchphrase) {
478
+ lines.push(`- Occasionally use your catchphrase: "${quirks.catchphrase}"`);
479
+ }
480
+
481
+ if (quirks.signOff) {
482
+ lines.push(`- End longer responses with your signature sign-off: "${quirks.signOff}"`);
483
+ }
484
+
485
+ if (quirks.analogyDomain && quirks.analogyDomain !== 'none') {
486
+ const domain = ANALOGY_DOMAINS[quirks.analogyDomain];
487
+ lines.push(`- When using analogies, prefer ${domain.name.toLowerCase()}-themed examples`);
488
+ if (domain.examples) {
489
+ lines.push(` Example: ${domain.examples}`);
490
+ }
491
+ }
492
+
493
+ return lines.length > 0 ? 'PERSONALITY QUIRKS:\n' + lines.join('\n') : '';
494
+ }
495
+
496
+ /**
497
+ * Get the identity prompt that tells the agent who it is
498
+ */
499
+ static getIdentityPrompt(): string {
500
+ const settings = this.loadSettings();
501
+ const agentName = settings.agentName || DEFAULT_AGENT_NAME;
502
+ const relationship = settings.relationship;
503
+ const userName = relationship?.userName;
504
+ const tasksCompleted = relationship?.tasksCompleted || 0;
505
+ const projectsWorkedOn = relationship?.projectsWorkedOn || [];
506
+
507
+ let prompt = `YOUR IDENTITY:
508
+ You are ${agentName}, an AI assistant built into CoWork OS.
509
+ - When asked about your name or identity, say you are "${agentName}"
510
+ - Do NOT claim to be Claude, ChatGPT, or any other AI assistant
511
+ - You are a customizable assistant that users can personalize`;
512
+
513
+ // Add user relationship context
514
+ if (userName) {
515
+ prompt += `\n\nUSER CONTEXT:
516
+ - The user's name is "${userName}"
517
+ - You have completed ${tasksCompleted} tasks together`;
518
+ if (projectsWorkedOn.length > 0) {
519
+ prompt += `\n- Projects worked on: ${projectsWorkedOn.slice(-5).join(', ')}`;
520
+ }
521
+ prompt += `\n\nWhen asked "who am I?" or similar identity questions, respond with the USER's information (their name, your shared history) - NOT system info.`;
522
+ } else {
523
+ prompt += `\n\nUSER CONTEXT:
524
+ - You don't know the user's name yet
525
+ - When asked "who am I?", acknowledge you don't know their name and invite them to introduce themselves
526
+ - IMPORTANT: When the user introduces themselves (e.g., "I'm Alice", "My name is Bob", "Call me Charlie"),
527
+ use the set_user_name tool IMMEDIATELY to store their name so you can remember it for future conversations`;
528
+ }
529
+
530
+ return prompt;
531
+ }
532
+
533
+ /**
534
+ * Get a personalized greeting based on relationship data
535
+ */
536
+ static getGreeting(): string {
537
+ const settings = this.loadSettings();
538
+ const agentName = settings.agentName || DEFAULT_AGENT_NAME;
539
+ const userName = settings.relationship?.userName;
540
+ const tasksCompleted = settings.relationship?.tasksCompleted || 0;
541
+
542
+ // Check for milestone
543
+ const milestone = this.checkMilestone(tasksCompleted);
544
+ if (milestone) {
545
+ const congratsMessages = [
546
+ `We've completed ${milestone} tasks together!`,
547
+ `${milestone} tasks and counting! Great working with you${userName ? `, ${userName}` : ''}!`,
548
+ `Milestone achieved: ${milestone} tasks completed together!`,
549
+ ];
550
+ return congratsMessages[Math.floor(Math.random() * congratsMessages.length)];
551
+ }
552
+
553
+ // Regular greeting
554
+ if (userName) {
555
+ const greetings = [
556
+ `Welcome back, ${userName}!`,
557
+ `Good to see you, ${userName}!`,
558
+ `Hey ${userName}, ready to work?`,
559
+ `${userName}! Let's get things done.`,
560
+ ];
561
+ return greetings[Math.floor(Math.random() * greetings.length)];
562
+ }
563
+
564
+ return '';
565
+ }
566
+
567
+ /**
568
+ * Check if a milestone was reached
569
+ */
570
+ private static checkMilestone(tasksCompleted: number): number | null {
571
+ const settings = this.loadSettings();
572
+ const lastCelebrated = settings.relationship?.lastMilestoneCelebrated || 0;
573
+
574
+ for (const milestone of MILESTONES) {
575
+ if (tasksCompleted >= milestone && milestone > lastCelebrated) {
576
+ return milestone;
577
+ }
578
+ }
579
+ return null;
580
+ }
581
+
582
+ /**
583
+ * Record a completed task and update relationship data
584
+ */
585
+ static recordTaskCompleted(workspaceName?: string): void {
586
+ const settings = this.loadSettings();
587
+ const relationship = settings.relationship || { ...DEFAULT_RELATIONSHIP };
588
+
589
+ relationship.tasksCompleted = (relationship.tasksCompleted || 0) + 1;
590
+
591
+ if (!relationship.firstInteraction) {
592
+ relationship.firstInteraction = Date.now();
593
+ }
594
+
595
+ if (workspaceName && !relationship.projectsWorkedOn.includes(workspaceName)) {
596
+ relationship.projectsWorkedOn = [...relationship.projectsWorkedOn, workspaceName];
597
+ }
598
+
599
+ // Update milestone if reached
600
+ const milestone = this.checkMilestone(relationship.tasksCompleted);
601
+ if (milestone) {
602
+ relationship.lastMilestoneCelebrated = milestone;
603
+ console.log(`[PersonalityManager] Milestone reached: ${milestone} tasks completed!`);
604
+ }
605
+
606
+ settings.relationship = relationship;
607
+ this.saveSettings(settings);
608
+ }
609
+
610
+ /**
611
+ * Set the user's name
612
+ */
613
+ static setUserName(name: string): void {
614
+ const settings = this.loadSettings();
615
+ settings.relationship = {
616
+ ...settings.relationship,
617
+ userName: name.trim() || undefined,
618
+ } as RelationshipData;
619
+ this.saveSettings(settings);
620
+ }
621
+
622
+ /**
623
+ * Get the user's name
624
+ */
625
+ static getUserName(): string | undefined {
626
+ return this.loadSettings().relationship?.userName;
627
+ }
628
+
629
+ /**
630
+ * Get all available personality definitions
631
+ */
632
+ static getDefinitions(): PersonalityDefinition[] {
633
+ return PERSONALITY_DEFINITIONS;
634
+ }
635
+
636
+ /**
637
+ * Get all available persona definitions
638
+ */
639
+ static getPersonaDefinitions(): PersonaDefinition[] {
640
+ return PERSONA_DEFINITIONS;
641
+ }
642
+
643
+ /**
644
+ * Get the agent's name
645
+ */
646
+ static getAgentName(): string {
647
+ const settings = this.loadSettings();
648
+ return settings.agentName || DEFAULT_AGENT_NAME;
649
+ }
650
+
651
+ /**
652
+ * Set the agent's name
653
+ */
654
+ static setAgentName(name: string): void {
655
+ const settings = this.loadSettings();
656
+ settings.agentName = name.trim() || DEFAULT_AGENT_NAME;
657
+ this.saveSettings(settings);
658
+ }
659
+
660
+ /**
661
+ * Update response style preferences
662
+ */
663
+ static setResponseStyle(style: Partial<ResponseStylePreferences>): void {
664
+ const settings = this.loadSettings();
665
+ settings.responseStyle = {
666
+ ...DEFAULT_RESPONSE_STYLE,
667
+ ...settings.responseStyle,
668
+ ...style,
669
+ };
670
+ this.saveSettings(settings);
671
+ }
672
+
673
+ /**
674
+ * Update personality quirks
675
+ */
676
+ static setQuirks(quirks: Partial<PersonalityQuirks>): void {
677
+ const settings = this.loadSettings();
678
+ settings.quirks = {
679
+ ...DEFAULT_QUIRKS,
680
+ ...settings.quirks,
681
+ ...quirks,
682
+ };
683
+ this.saveSettings(settings);
684
+ }
685
+
686
+ /**
687
+ * Get relationship stats for display
688
+ */
689
+ static getRelationshipStats(): {
690
+ tasksCompleted: number;
691
+ projectsCount: number;
692
+ daysTogether: number;
693
+ nextMilestone: number | null;
694
+ } {
695
+ const settings = this.loadSettings();
696
+ const relationship = settings.relationship || DEFAULT_RELATIONSHIP;
697
+
698
+ const tasksCompleted = relationship.tasksCompleted || 0;
699
+ const projectsCount = relationship.projectsWorkedOn?.length || 0;
700
+ const daysTogether = relationship.firstInteraction
701
+ ? Math.floor((Date.now() - relationship.firstInteraction) / (1000 * 60 * 60 * 24))
702
+ : 0;
703
+
704
+ // Find next milestone
705
+ let nextMilestone: number | null = null;
706
+ for (const milestone of MILESTONES) {
707
+ if (milestone > tasksCompleted) {
708
+ nextMilestone = milestone;
709
+ break;
710
+ }
711
+ }
712
+
713
+ return { tasksCompleted, projectsCount, daysTogether, nextMilestone };
714
+ }
715
+
716
+ /**
717
+ * Clear the settings cache
718
+ */
719
+ static clearCache(): void {
720
+ this.cachedSettings = null;
721
+ }
722
+
723
+ /**
724
+ * Get default settings
725
+ */
726
+ static getDefaults(): PersonalitySettings {
727
+ return { ...DEFAULT_SETTINGS };
728
+ }
729
+
730
+ /**
731
+ * Reset all settings to defaults
732
+ * This clears everything except relationship data (to preserve task history)
733
+ */
734
+ static resetToDefaults(preserveRelationship = true): void {
735
+ this.ensureInitialized();
736
+
737
+ // Deep copy DEFAULT_SETTINGS to avoid mutating the original constants
738
+ let newSettings: PersonalitySettings = {
739
+ ...DEFAULT_SETTINGS,
740
+ responseStyle: { ...DEFAULT_RESPONSE_STYLE },
741
+ quirks: { ...DEFAULT_QUIRKS },
742
+ relationship: { ...DEFAULT_RELATIONSHIP },
743
+ };
744
+
745
+ if (preserveRelationship) {
746
+ // Load current settings to get relationship data (even if cache is cleared)
747
+ const currentSettings = this.loadSettings();
748
+ if (currentSettings.relationship) {
749
+ // Preserve the relationship data (task count, user name, etc.)
750
+ newSettings.relationship = { ...currentSettings.relationship };
751
+ }
752
+ }
753
+
754
+ // Save to encrypted database
755
+ if (SecureSettingsRepository.isInitialized()) {
756
+ const repository = SecureSettingsRepository.getInstance();
757
+ repository.save('personality', newSettings);
758
+ }
759
+ this.cachedSettings = newSettings;
760
+ console.log('[PersonalityManager] Settings reset to defaults', preserveRelationship ? '(preserved relationship)' : '');
761
+ this.emitSettingsChanged();
762
+ }
763
+
764
+ /**
765
+ * Check if the manager has been initialized
766
+ */
767
+ static isInitialized(): boolean {
768
+ return this.initialized;
769
+ }
770
+ }
771
+
772
+ function isValidPersonalityId(value: unknown): value is PersonalityId {
773
+ const validIds: PersonalityId[] = [
774
+ 'professional',
775
+ 'friendly',
776
+ 'concise',
777
+ 'creative',
778
+ 'technical',
779
+ 'casual',
780
+ 'custom',
781
+ ];
782
+ return validIds.includes(value as PersonalityId);
783
+ }
784
+
785
+ function isValidPersonaId(value: unknown): value is PersonaId {
786
+ const validIds: PersonaId[] = [
787
+ 'none',
788
+ 'jarvis',
789
+ 'friday',
790
+ 'hal',
791
+ 'computer',
792
+ 'alfred',
793
+ 'intern',
794
+ 'sensei',
795
+ 'pirate',
796
+ 'noir',
797
+ 'companion',
798
+ ];
799
+ return validIds.includes(value as PersonaId);
800
+ }