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.
- package/LICENSE +21 -0
- package/README.md +1638 -0
- package/bin/cowork.js +42 -0
- package/build/entitlements.mac.plist +16 -0
- package/build/icon.icns +0 -0
- package/build/icon.png +0 -0
- package/dist/electron/electron/activity/ActivityRepository.js +190 -0
- package/dist/electron/electron/agent/browser/browser-service.js +639 -0
- package/dist/electron/electron/agent/context-manager.js +225 -0
- package/dist/electron/electron/agent/custom-skill-loader.js +566 -0
- package/dist/electron/electron/agent/daemon.js +975 -0
- package/dist/electron/electron/agent/executor.js +3561 -0
- package/dist/electron/electron/agent/llm/anthropic-provider.js +155 -0
- package/dist/electron/electron/agent/llm/bedrock-provider.js +202 -0
- package/dist/electron/electron/agent/llm/gemini-provider.js +375 -0
- package/dist/electron/electron/agent/llm/index.js +34 -0
- package/dist/electron/electron/agent/llm/ollama-provider.js +263 -0
- package/dist/electron/electron/agent/llm/openai-oauth.js +101 -0
- package/dist/electron/electron/agent/llm/openai-provider.js +657 -0
- package/dist/electron/electron/agent/llm/openrouter-provider.js +232 -0
- package/dist/electron/electron/agent/llm/pricing.js +160 -0
- package/dist/electron/electron/agent/llm/provider-factory.js +880 -0
- package/dist/electron/electron/agent/llm/types.js +178 -0
- package/dist/electron/electron/agent/queue-manager.js +378 -0
- package/dist/electron/electron/agent/sandbox/docker-sandbox.js +402 -0
- package/dist/electron/electron/agent/sandbox/macos-sandbox.js +407 -0
- package/dist/electron/electron/agent/sandbox/runner.js +410 -0
- package/dist/electron/electron/agent/sandbox/sandbox-factory.js +228 -0
- package/dist/electron/electron/agent/sandbox/security-utils.js +258 -0
- package/dist/electron/electron/agent/search/brave-provider.js +119 -0
- package/dist/electron/electron/agent/search/google-provider.js +100 -0
- package/dist/electron/electron/agent/search/index.js +28 -0
- package/dist/electron/electron/agent/search/provider-factory.js +395 -0
- package/dist/electron/electron/agent/search/serpapi-provider.js +112 -0
- package/dist/electron/electron/agent/search/tavily-provider.js +90 -0
- package/dist/electron/electron/agent/search/types.js +40 -0
- package/dist/electron/electron/agent/security/index.js +12 -0
- package/dist/electron/electron/agent/security/input-sanitizer.js +303 -0
- package/dist/electron/electron/agent/security/output-filter.js +217 -0
- package/dist/electron/electron/agent/skill-eligibility.js +281 -0
- package/dist/electron/electron/agent/skill-registry.js +396 -0
- package/dist/electron/electron/agent/skills/document.js +878 -0
- package/dist/electron/electron/agent/skills/image-generator.js +225 -0
- package/dist/electron/electron/agent/skills/organizer.js +141 -0
- package/dist/electron/electron/agent/skills/presentation.js +367 -0
- package/dist/electron/electron/agent/skills/spreadsheet.js +165 -0
- package/dist/electron/electron/agent/tools/browser-tools.js +523 -0
- package/dist/electron/electron/agent/tools/builtin-settings.js +384 -0
- package/dist/electron/electron/agent/tools/canvas-tools.js +530 -0
- package/dist/electron/electron/agent/tools/cron-tools.js +577 -0
- package/dist/electron/electron/agent/tools/edit-tools.js +194 -0
- package/dist/electron/electron/agent/tools/file-tools.js +719 -0
- package/dist/electron/electron/agent/tools/glob-tools.js +283 -0
- package/dist/electron/electron/agent/tools/grep-tools.js +387 -0
- package/dist/electron/electron/agent/tools/image-tools.js +111 -0
- package/dist/electron/electron/agent/tools/mention-tools.js +282 -0
- package/dist/electron/electron/agent/tools/node-tools.js +476 -0
- package/dist/electron/electron/agent/tools/registry.js +2719 -0
- package/dist/electron/electron/agent/tools/search-tools.js +91 -0
- package/dist/electron/electron/agent/tools/shell-tools.js +574 -0
- package/dist/electron/electron/agent/tools/skill-tools.js +274 -0
- package/dist/electron/electron/agent/tools/system-tools.js +578 -0
- package/dist/electron/electron/agent/tools/web-fetch-tools.js +444 -0
- package/dist/electron/electron/agent/tools/x-tools.js +264 -0
- package/dist/electron/electron/agents/AgentRoleRepository.js +420 -0
- package/dist/electron/electron/agents/HeartbeatService.js +356 -0
- package/dist/electron/electron/agents/MentionRepository.js +197 -0
- package/dist/electron/electron/agents/TaskSubscriptionRepository.js +168 -0
- package/dist/electron/electron/agents/WorkingStateRepository.js +229 -0
- package/dist/electron/electron/canvas/canvas-manager.js +714 -0
- package/dist/electron/electron/canvas/canvas-preload.js +53 -0
- package/dist/electron/electron/canvas/canvas-protocol.js +195 -0
- package/dist/electron/electron/canvas/canvas-store.js +174 -0
- package/dist/electron/electron/canvas/index.js +13 -0
- package/dist/electron/electron/control-plane/client.js +364 -0
- package/dist/electron/electron/control-plane/handlers.js +572 -0
- package/dist/electron/electron/control-plane/index.js +41 -0
- package/dist/electron/electron/control-plane/node-manager.js +264 -0
- package/dist/electron/electron/control-plane/protocol.js +194 -0
- package/dist/electron/electron/control-plane/remote-client.js +437 -0
- package/dist/electron/electron/control-plane/server.js +640 -0
- package/dist/electron/electron/control-plane/settings.js +369 -0
- package/dist/electron/electron/control-plane/ssh-tunnel.js +549 -0
- package/dist/electron/electron/cron/index.js +30 -0
- package/dist/electron/electron/cron/schedule.js +190 -0
- package/dist/electron/electron/cron/service.js +614 -0
- package/dist/electron/electron/cron/store.js +155 -0
- package/dist/electron/electron/cron/types.js +82 -0
- package/dist/electron/electron/cron/webhook.js +258 -0
- package/dist/electron/electron/database/SecureSettingsRepository.js +444 -0
- package/dist/electron/electron/database/TaskLabelRepository.js +120 -0
- package/dist/electron/electron/database/repositories.js +1781 -0
- package/dist/electron/electron/database/schema.js +978 -0
- package/dist/electron/electron/extensions/index.js +33 -0
- package/dist/electron/electron/extensions/loader.js +313 -0
- package/dist/electron/electron/extensions/registry.js +485 -0
- package/dist/electron/electron/extensions/types.js +11 -0
- package/dist/electron/electron/gateway/channel-registry.js +1102 -0
- package/dist/electron/electron/gateway/channels/bluebubbles-client.js +479 -0
- package/dist/electron/electron/gateway/channels/bluebubbles.js +432 -0
- package/dist/electron/electron/gateway/channels/discord.js +975 -0
- package/dist/electron/electron/gateway/channels/email-client.js +593 -0
- package/dist/electron/electron/gateway/channels/email.js +443 -0
- package/dist/electron/electron/gateway/channels/google-chat.js +631 -0
- package/dist/electron/electron/gateway/channels/imessage-client.js +363 -0
- package/dist/electron/electron/gateway/channels/imessage.js +465 -0
- package/dist/electron/electron/gateway/channels/index.js +36 -0
- package/dist/electron/electron/gateway/channels/line-client.js +470 -0
- package/dist/electron/electron/gateway/channels/line.js +479 -0
- package/dist/electron/electron/gateway/channels/matrix-client.js +432 -0
- package/dist/electron/electron/gateway/channels/matrix.js +592 -0
- package/dist/electron/electron/gateway/channels/mattermost-client.js +394 -0
- package/dist/electron/electron/gateway/channels/mattermost.js +496 -0
- package/dist/electron/electron/gateway/channels/signal-client.js +500 -0
- package/dist/electron/electron/gateway/channels/signal.js +582 -0
- package/dist/electron/electron/gateway/channels/slack.js +415 -0
- package/dist/electron/electron/gateway/channels/teams.js +596 -0
- package/dist/electron/electron/gateway/channels/telegram.js +1390 -0
- package/dist/electron/electron/gateway/channels/twitch-client.js +502 -0
- package/dist/electron/electron/gateway/channels/twitch.js +396 -0
- package/dist/electron/electron/gateway/channels/types.js +8 -0
- package/dist/electron/electron/gateway/channels/whatsapp.js +953 -0
- package/dist/electron/electron/gateway/context-policy.js +268 -0
- package/dist/electron/electron/gateway/index.js +1063 -0
- package/dist/electron/electron/gateway/infrastructure.js +496 -0
- package/dist/electron/electron/gateway/router.js +2700 -0
- package/dist/electron/electron/gateway/security.js +375 -0
- package/dist/electron/electron/gateway/session.js +115 -0
- package/dist/electron/electron/gateway/tunnel.js +503 -0
- package/dist/electron/electron/guardrails/guardrail-manager.js +348 -0
- package/dist/electron/electron/hooks/gmail-watcher.js +300 -0
- package/dist/electron/electron/hooks/index.js +46 -0
- package/dist/electron/electron/hooks/mappings.js +381 -0
- package/dist/electron/electron/hooks/server.js +480 -0
- package/dist/electron/electron/hooks/settings.js +447 -0
- package/dist/electron/electron/hooks/types.js +41 -0
- package/dist/electron/electron/ipc/canvas-handlers.js +158 -0
- package/dist/electron/electron/ipc/handlers.js +3138 -0
- package/dist/electron/electron/ipc/mission-control-handlers.js +141 -0
- package/dist/electron/electron/main.js +448 -0
- package/dist/electron/electron/mcp/client/MCPClientManager.js +330 -0
- package/dist/electron/electron/mcp/client/MCPServerConnection.js +437 -0
- package/dist/electron/electron/mcp/client/transports/SSETransport.js +304 -0
- package/dist/electron/electron/mcp/client/transports/StdioTransport.js +307 -0
- package/dist/electron/electron/mcp/client/transports/WebSocketTransport.js +329 -0
- package/dist/electron/electron/mcp/host/MCPHostServer.js +354 -0
- package/dist/electron/electron/mcp/host/ToolAdapter.js +100 -0
- package/dist/electron/electron/mcp/registry/MCPRegistryManager.js +497 -0
- package/dist/electron/electron/mcp/settings.js +446 -0
- package/dist/electron/electron/mcp/types.js +59 -0
- package/dist/electron/electron/memory/MemoryService.js +435 -0
- package/dist/electron/electron/notifications/index.js +17 -0
- package/dist/electron/electron/notifications/service.js +118 -0
- package/dist/electron/electron/notifications/store.js +144 -0
- package/dist/electron/electron/preload.js +842 -0
- package/dist/electron/electron/reports/StandupReportService.js +272 -0
- package/dist/electron/electron/security/concurrency.js +293 -0
- package/dist/electron/electron/security/index.js +15 -0
- package/dist/electron/electron/security/policy-manager.js +435 -0
- package/dist/electron/electron/settings/appearance-manager.js +193 -0
- package/dist/electron/electron/settings/personality-manager.js +724 -0
- package/dist/electron/electron/settings/x-manager.js +58 -0
- package/dist/electron/electron/tailscale/exposure.js +188 -0
- package/dist/electron/electron/tailscale/index.js +28 -0
- package/dist/electron/electron/tailscale/settings.js +205 -0
- package/dist/electron/electron/tailscale/tailscale.js +355 -0
- package/dist/electron/electron/tray/QuickInputWindow.js +568 -0
- package/dist/electron/electron/tray/TrayManager.js +895 -0
- package/dist/electron/electron/tray/index.js +9 -0
- package/dist/electron/electron/updater/index.js +6 -0
- package/dist/electron/electron/updater/update-manager.js +418 -0
- package/dist/electron/electron/utils/env-migration.js +209 -0
- package/dist/electron/electron/utils/process.js +102 -0
- package/dist/electron/electron/utils/rate-limiter.js +104 -0
- package/dist/electron/electron/utils/validation.js +419 -0
- package/dist/electron/electron/utils/x-cli.js +177 -0
- package/dist/electron/electron/voice/VoiceService.js +507 -0
- package/dist/electron/electron/voice/index.js +14 -0
- package/dist/electron/electron/voice/voice-settings-manager.js +359 -0
- package/dist/electron/shared/channelMessages.js +170 -0
- package/dist/electron/shared/types.js +1185 -0
- package/package.json +159 -0
- package/resources/skills/1password.json +10 -0
- package/resources/skills/add-documentation.json +31 -0
- package/resources/skills/analyze-csv.json +17 -0
- package/resources/skills/apple-notes.json +10 -0
- package/resources/skills/apple-reminders.json +10 -0
- package/resources/skills/auto-commenter.json +10 -0
- package/resources/skills/bear-notes.json +10 -0
- package/resources/skills/bird.json +35 -0
- package/resources/skills/blogwatcher.json +10 -0
- package/resources/skills/blucli.json +10 -0
- package/resources/skills/bluebubbles.json +10 -0
- package/resources/skills/camsnap.json +10 -0
- package/resources/skills/clean-imports.json +18 -0
- package/resources/skills/code-review.json +18 -0
- package/resources/skills/coding-agent.json +10 -0
- package/resources/skills/compare-files.json +23 -0
- package/resources/skills/convert-code.json +34 -0
- package/resources/skills/create-changelog.json +24 -0
- package/resources/skills/debug-error.json +17 -0
- package/resources/skills/dependency-check.json +10 -0
- package/resources/skills/discord.json +10 -0
- package/resources/skills/eightctl.json +10 -0
- package/resources/skills/explain-code.json +29 -0
- package/resources/skills/extract-todos.json +18 -0
- package/resources/skills/food-order.json +10 -0
- package/resources/skills/gemini.json +10 -0
- package/resources/skills/generate-readme.json +10 -0
- package/resources/skills/gifgrep.json +10 -0
- package/resources/skills/git-commit.json +10 -0
- package/resources/skills/github.json +10 -0
- package/resources/skills/gog.json +10 -0
- package/resources/skills/goplaces.json +10 -0
- package/resources/skills/himalaya.json +10 -0
- package/resources/skills/imsg.json +10 -0
- package/resources/skills/karpathy-guidelines.json +12 -0
- package/resources/skills/last30days.json +26 -0
- package/resources/skills/local-places.json +10 -0
- package/resources/skills/mcporter.json +10 -0
- package/resources/skills/model-usage.json +10 -0
- package/resources/skills/nano-banana-pro.json +10 -0
- package/resources/skills/nano-pdf.json +10 -0
- package/resources/skills/notion.json +10 -0
- package/resources/skills/obsidian.json +10 -0
- package/resources/skills/openai-image-gen.json +10 -0
- package/resources/skills/openai-whisper-api.json +10 -0
- package/resources/skills/openai-whisper.json +10 -0
- package/resources/skills/openhue.json +10 -0
- package/resources/skills/oracle.json +10 -0
- package/resources/skills/ordercli.json +10 -0
- package/resources/skills/peekaboo.json +10 -0
- package/resources/skills/project-structure.json +10 -0
- package/resources/skills/proofread.json +17 -0
- package/resources/skills/refactor-code.json +31 -0
- package/resources/skills/rename-symbol.json +23 -0
- package/resources/skills/sag.json +10 -0
- package/resources/skills/security-audit.json +18 -0
- package/resources/skills/session-logs.json +10 -0
- package/resources/skills/sherpa-onnx-tts.json +10 -0
- package/resources/skills/skill-creator.json +15 -0
- package/resources/skills/skill-hub.json +29 -0
- package/resources/skills/slack.json +10 -0
- package/resources/skills/songsee.json +10 -0
- package/resources/skills/sonoscli.json +10 -0
- package/resources/skills/spotify-player.json +10 -0
- package/resources/skills/startup-cfo.json +55 -0
- package/resources/skills/summarize-folder.json +18 -0
- package/resources/skills/summarize.json +10 -0
- package/resources/skills/things-mac.json +10 -0
- package/resources/skills/tmux.json +10 -0
- package/resources/skills/translate.json +36 -0
- package/resources/skills/trello.json +10 -0
- package/resources/skills/video-frames.json +10 -0
- package/resources/skills/voice-call.json +10 -0
- package/resources/skills/wacli.json +10 -0
- package/resources/skills/weather.json +10 -0
- package/resources/skills/write-tests.json +31 -0
- package/src/electron/activity/ActivityRepository.ts +238 -0
- package/src/electron/agent/browser/browser-service.ts +721 -0
- package/src/electron/agent/context-manager.ts +257 -0
- package/src/electron/agent/custom-skill-loader.ts +634 -0
- package/src/electron/agent/daemon.ts +1097 -0
- package/src/electron/agent/executor.ts +4017 -0
- package/src/electron/agent/llm/anthropic-provider.ts +175 -0
- package/src/electron/agent/llm/bedrock-provider.ts +236 -0
- package/src/electron/agent/llm/gemini-provider.ts +422 -0
- package/src/electron/agent/llm/index.ts +9 -0
- package/src/electron/agent/llm/ollama-provider.ts +347 -0
- package/src/electron/agent/llm/openai-oauth.ts +127 -0
- package/src/electron/agent/llm/openai-provider.ts +686 -0
- package/src/electron/agent/llm/openrouter-provider.ts +273 -0
- package/src/electron/agent/llm/pricing.ts +180 -0
- package/src/electron/agent/llm/provider-factory.ts +971 -0
- package/src/electron/agent/llm/types.ts +291 -0
- package/src/electron/agent/queue-manager.ts +408 -0
- package/src/electron/agent/sandbox/docker-sandbox.ts +453 -0
- package/src/electron/agent/sandbox/macos-sandbox.ts +426 -0
- package/src/electron/agent/sandbox/runner.ts +453 -0
- package/src/electron/agent/sandbox/sandbox-factory.ts +337 -0
- package/src/electron/agent/sandbox/security-utils.ts +251 -0
- package/src/electron/agent/search/brave-provider.ts +141 -0
- package/src/electron/agent/search/google-provider.ts +131 -0
- package/src/electron/agent/search/index.ts +6 -0
- package/src/electron/agent/search/provider-factory.ts +450 -0
- package/src/electron/agent/search/serpapi-provider.ts +138 -0
- package/src/electron/agent/search/tavily-provider.ts +108 -0
- package/src/electron/agent/search/types.ts +118 -0
- package/src/electron/agent/security/index.ts +20 -0
- package/src/electron/agent/security/input-sanitizer.ts +380 -0
- package/src/electron/agent/security/output-filter.ts +259 -0
- package/src/electron/agent/skill-eligibility.ts +334 -0
- package/src/electron/agent/skill-registry.ts +457 -0
- package/src/electron/agent/skills/document.ts +1070 -0
- package/src/electron/agent/skills/image-generator.ts +272 -0
- package/src/electron/agent/skills/organizer.ts +131 -0
- package/src/electron/agent/skills/presentation.ts +418 -0
- package/src/electron/agent/skills/spreadsheet.ts +166 -0
- package/src/electron/agent/tools/browser-tools.ts +546 -0
- package/src/electron/agent/tools/builtin-settings.ts +422 -0
- package/src/electron/agent/tools/canvas-tools.ts +572 -0
- package/src/electron/agent/tools/cron-tools.ts +723 -0
- package/src/electron/agent/tools/edit-tools.ts +196 -0
- package/src/electron/agent/tools/file-tools.ts +811 -0
- package/src/electron/agent/tools/glob-tools.ts +303 -0
- package/src/electron/agent/tools/grep-tools.ts +432 -0
- package/src/electron/agent/tools/image-tools.ts +126 -0
- package/src/electron/agent/tools/mention-tools.ts +371 -0
- package/src/electron/agent/tools/node-tools.ts +550 -0
- package/src/electron/agent/tools/registry.ts +3052 -0
- package/src/electron/agent/tools/search-tools.ts +111 -0
- package/src/electron/agent/tools/shell-tools.ts +651 -0
- package/src/electron/agent/tools/skill-tools.ts +340 -0
- package/src/electron/agent/tools/system-tools.ts +665 -0
- package/src/electron/agent/tools/web-fetch-tools.ts +528 -0
- package/src/electron/agent/tools/x-tools.ts +267 -0
- package/src/electron/agents/AgentRoleRepository.ts +557 -0
- package/src/electron/agents/HeartbeatService.ts +469 -0
- package/src/electron/agents/MentionRepository.ts +242 -0
- package/src/electron/agents/TaskSubscriptionRepository.ts +231 -0
- package/src/electron/agents/WorkingStateRepository.ts +278 -0
- package/src/electron/canvas/canvas-manager.ts +818 -0
- package/src/electron/canvas/canvas-preload.ts +102 -0
- package/src/electron/canvas/canvas-protocol.ts +174 -0
- package/src/electron/canvas/canvas-store.ts +200 -0
- package/src/electron/canvas/index.ts +8 -0
- package/src/electron/control-plane/client.ts +527 -0
- package/src/electron/control-plane/handlers.ts +723 -0
- package/src/electron/control-plane/index.ts +51 -0
- package/src/electron/control-plane/node-manager.ts +322 -0
- package/src/electron/control-plane/protocol.ts +269 -0
- package/src/electron/control-plane/remote-client.ts +517 -0
- package/src/electron/control-plane/server.ts +853 -0
- package/src/electron/control-plane/settings.ts +401 -0
- package/src/electron/control-plane/ssh-tunnel.ts +624 -0
- package/src/electron/cron/index.ts +9 -0
- package/src/electron/cron/schedule.ts +217 -0
- package/src/electron/cron/service.ts +743 -0
- package/src/electron/cron/store.ts +165 -0
- package/src/electron/cron/types.ts +291 -0
- package/src/electron/cron/webhook.ts +303 -0
- package/src/electron/database/SecureSettingsRepository.ts +514 -0
- package/src/electron/database/TaskLabelRepository.ts +148 -0
- package/src/electron/database/repositories.ts +2397 -0
- package/src/electron/database/schema.ts +1017 -0
- package/src/electron/extensions/index.ts +18 -0
- package/src/electron/extensions/loader.ts +336 -0
- package/src/electron/extensions/registry.ts +546 -0
- package/src/electron/extensions/types.ts +372 -0
- package/src/electron/gateway/channel-registry.ts +1267 -0
- package/src/electron/gateway/channels/bluebubbles-client.ts +641 -0
- package/src/electron/gateway/channels/bluebubbles.ts +509 -0
- package/src/electron/gateway/channels/discord.ts +1150 -0
- package/src/electron/gateway/channels/email-client.ts +708 -0
- package/src/electron/gateway/channels/email.ts +516 -0
- package/src/electron/gateway/channels/google-chat.ts +760 -0
- package/src/electron/gateway/channels/imessage-client.ts +473 -0
- package/src/electron/gateway/channels/imessage.ts +520 -0
- package/src/electron/gateway/channels/index.ts +21 -0
- package/src/electron/gateway/channels/line-client.ts +598 -0
- package/src/electron/gateway/channels/line.ts +559 -0
- package/src/electron/gateway/channels/matrix-client.ts +632 -0
- package/src/electron/gateway/channels/matrix.ts +655 -0
- package/src/electron/gateway/channels/mattermost-client.ts +526 -0
- package/src/electron/gateway/channels/mattermost.ts +550 -0
- package/src/electron/gateway/channels/signal-client.ts +722 -0
- package/src/electron/gateway/channels/signal.ts +666 -0
- package/src/electron/gateway/channels/slack.ts +458 -0
- package/src/electron/gateway/channels/teams.ts +681 -0
- package/src/electron/gateway/channels/telegram.ts +1727 -0
- package/src/electron/gateway/channels/twitch-client.ts +665 -0
- package/src/electron/gateway/channels/twitch.ts +468 -0
- package/src/electron/gateway/channels/types.ts +1002 -0
- package/src/electron/gateway/channels/whatsapp.ts +1101 -0
- package/src/electron/gateway/context-policy.ts +382 -0
- package/src/electron/gateway/index.ts +1274 -0
- package/src/electron/gateway/infrastructure.ts +645 -0
- package/src/electron/gateway/router.ts +3206 -0
- package/src/electron/gateway/security.ts +422 -0
- package/src/electron/gateway/session.ts +144 -0
- package/src/electron/gateway/tunnel.ts +626 -0
- package/src/electron/guardrails/guardrail-manager.ts +380 -0
- package/src/electron/hooks/gmail-watcher.ts +355 -0
- package/src/electron/hooks/index.ts +30 -0
- package/src/electron/hooks/mappings.ts +404 -0
- package/src/electron/hooks/server.ts +574 -0
- package/src/electron/hooks/settings.ts +466 -0
- package/src/electron/hooks/types.ts +245 -0
- package/src/electron/ipc/canvas-handlers.ts +223 -0
- package/src/electron/ipc/handlers.ts +3661 -0
- package/src/electron/ipc/mission-control-handlers.ts +182 -0
- package/src/electron/main.ts +496 -0
- package/src/electron/mcp/client/MCPClientManager.ts +406 -0
- package/src/electron/mcp/client/MCPServerConnection.ts +514 -0
- package/src/electron/mcp/client/transports/SSETransport.ts +360 -0
- package/src/electron/mcp/client/transports/StdioTransport.ts +355 -0
- package/src/electron/mcp/client/transports/WebSocketTransport.ts +384 -0
- package/src/electron/mcp/host/MCPHostServer.ts +388 -0
- package/src/electron/mcp/host/ToolAdapter.ts +140 -0
- package/src/electron/mcp/registry/MCPRegistryManager.ts +565 -0
- package/src/electron/mcp/settings.ts +468 -0
- package/src/electron/mcp/types.ts +371 -0
- package/src/electron/memory/MemoryService.ts +523 -0
- package/src/electron/notifications/index.ts +16 -0
- package/src/electron/notifications/service.ts +161 -0
- package/src/electron/notifications/store.ts +163 -0
- package/src/electron/preload.ts +2845 -0
- package/src/electron/reports/StandupReportService.ts +356 -0
- package/src/electron/security/concurrency.ts +333 -0
- package/src/electron/security/index.ts +17 -0
- package/src/electron/security/policy-manager.ts +539 -0
- package/src/electron/settings/appearance-manager.ts +182 -0
- package/src/electron/settings/personality-manager.ts +800 -0
- package/src/electron/settings/x-manager.ts +62 -0
- package/src/electron/tailscale/exposure.ts +262 -0
- package/src/electron/tailscale/index.ts +34 -0
- package/src/electron/tailscale/settings.ts +218 -0
- package/src/electron/tailscale/tailscale.ts +379 -0
- package/src/electron/tray/QuickInputWindow.ts +609 -0
- package/src/electron/tray/TrayManager.ts +1005 -0
- package/src/electron/tray/index.ts +6 -0
- package/src/electron/updater/index.ts +1 -0
- package/src/electron/updater/update-manager.ts +447 -0
- package/src/electron/utils/env-migration.ts +203 -0
- package/src/electron/utils/process.ts +124 -0
- package/src/electron/utils/rate-limiter.ts +130 -0
- package/src/electron/utils/validation.ts +493 -0
- package/src/electron/utils/x-cli.ts +198 -0
- package/src/electron/voice/VoiceService.ts +583 -0
- package/src/electron/voice/index.ts +9 -0
- package/src/electron/voice/voice-settings-manager.ts +403 -0
- package/src/renderer/App.tsx +775 -0
- package/src/renderer/components/ActivityFeed.tsx +407 -0
- package/src/renderer/components/ActivityFeedItem.tsx +285 -0
- package/src/renderer/components/AgentRoleCard.tsx +343 -0
- package/src/renderer/components/AgentRoleEditor.tsx +805 -0
- package/src/renderer/components/AgentSquadSettings.tsx +295 -0
- package/src/renderer/components/AgentWorkingStatePanel.tsx +411 -0
- package/src/renderer/components/AppearanceSettings.tsx +122 -0
- package/src/renderer/components/ApprovalDialog.tsx +100 -0
- package/src/renderer/components/BlueBubblesSettings.tsx +505 -0
- package/src/renderer/components/BuiltinToolsSettings.tsx +307 -0
- package/src/renderer/components/CanvasPreview.tsx +1189 -0
- package/src/renderer/components/CommandOutput.tsx +202 -0
- package/src/renderer/components/ContextPolicySettings.tsx +523 -0
- package/src/renderer/components/ControlPlaneSettings.tsx +1134 -0
- package/src/renderer/components/DisclaimerModal.tsx +124 -0
- package/src/renderer/components/DiscordSettings.tsx +436 -0
- package/src/renderer/components/EmailSettings.tsx +606 -0
- package/src/renderer/components/ExtensionsSettings.tsx +542 -0
- package/src/renderer/components/FileViewer.tsx +224 -0
- package/src/renderer/components/GoogleChatSettings.tsx +535 -0
- package/src/renderer/components/GuardrailSettings.tsx +487 -0
- package/src/renderer/components/HooksSettings.tsx +581 -0
- package/src/renderer/components/ImessageSettings.tsx +484 -0
- package/src/renderer/components/LineSettings.tsx +483 -0
- package/src/renderer/components/MCPRegistryBrowser.tsx +386 -0
- package/src/renderer/components/MCPSettings.tsx +943 -0
- package/src/renderer/components/MainContent.tsx +2433 -0
- package/src/renderer/components/MatrixSettings.tsx +510 -0
- package/src/renderer/components/MattermostSettings.tsx +473 -0
- package/src/renderer/components/MemorySettings.tsx +247 -0
- package/src/renderer/components/MentionBadge.tsx +87 -0
- package/src/renderer/components/MentionInput.tsx +409 -0
- package/src/renderer/components/MentionList.tsx +476 -0
- package/src/renderer/components/MissionControlPanel.tsx +1995 -0
- package/src/renderer/components/NodesSettings.tsx +316 -0
- package/src/renderer/components/NotificationPanel.tsx +481 -0
- package/src/renderer/components/Onboarding/AwakeningOrb.tsx +44 -0
- package/src/renderer/components/Onboarding/Onboarding.tsx +443 -0
- package/src/renderer/components/Onboarding/TypewriterText.tsx +102 -0
- package/src/renderer/components/Onboarding/index.ts +3 -0
- package/src/renderer/components/OnboardingModal.tsx +698 -0
- package/src/renderer/components/PairingCodeDisplay.tsx +324 -0
- package/src/renderer/components/PersonalitySettings.tsx +597 -0
- package/src/renderer/components/QueueSettings.tsx +119 -0
- package/src/renderer/components/QuickTaskFAB.tsx +71 -0
- package/src/renderer/components/RightPanel.tsx +413 -0
- package/src/renderer/components/ScheduledTasksSettings.tsx +1328 -0
- package/src/renderer/components/SearchSettings.tsx +328 -0
- package/src/renderer/components/Settings.tsx +1504 -0
- package/src/renderer/components/Sidebar.tsx +344 -0
- package/src/renderer/components/SignalSettings.tsx +673 -0
- package/src/renderer/components/SkillHubBrowser.tsx +458 -0
- package/src/renderer/components/SkillParameterModal.tsx +185 -0
- package/src/renderer/components/SkillsSettings.tsx +451 -0
- package/src/renderer/components/SlackSettings.tsx +442 -0
- package/src/renderer/components/StandupReportViewer.tsx +614 -0
- package/src/renderer/components/TaskBoard.tsx +498 -0
- package/src/renderer/components/TaskBoardCard.tsx +357 -0
- package/src/renderer/components/TaskBoardColumn.tsx +211 -0
- package/src/renderer/components/TaskLabelManager.tsx +472 -0
- package/src/renderer/components/TaskQueuePanel.tsx +144 -0
- package/src/renderer/components/TaskQuickActions.tsx +492 -0
- package/src/renderer/components/TaskTimeline.tsx +216 -0
- package/src/renderer/components/TaskView.tsx +162 -0
- package/src/renderer/components/TeamsSettings.tsx +518 -0
- package/src/renderer/components/TelegramSettings.tsx +421 -0
- package/src/renderer/components/Toast.tsx +76 -0
- package/src/renderer/components/TraySettings.tsx +189 -0
- package/src/renderer/components/TwitchSettings.tsx +511 -0
- package/src/renderer/components/UpdateSettings.tsx +295 -0
- package/src/renderer/components/VoiceIndicator.tsx +270 -0
- package/src/renderer/components/VoiceSettings.tsx +867 -0
- package/src/renderer/components/WhatsAppSettings.tsx +721 -0
- package/src/renderer/components/WorkingStateEditor.tsx +309 -0
- package/src/renderer/components/WorkingStateHistory.tsx +481 -0
- package/src/renderer/components/WorkspaceSelector.tsx +150 -0
- package/src/renderer/components/XSettings.tsx +311 -0
- package/src/renderer/global.d.ts +9 -0
- package/src/renderer/hooks/useAgentContext.ts +153 -0
- package/src/renderer/hooks/useOnboardingFlow.ts +548 -0
- package/src/renderer/hooks/useVoiceInput.ts +268 -0
- package/src/renderer/index.html +12 -0
- package/src/renderer/main.tsx +10 -0
- package/src/renderer/public/cowork-os-logo.png +0 -0
- package/src/renderer/quick-input.html +164 -0
- package/src/renderer/styles/index.css +14504 -0
- package/src/renderer/utils/agentMessages.ts +749 -0
- package/src/renderer/utils/voice-directives.ts +169 -0
- package/src/shared/channelMessages.ts +213 -0
- package/src/shared/types.ts +3608 -0
- package/tsconfig.electron.json +26 -0
- package/tsconfig.json +26 -0
- package/tsconfig.node.json +10 -0
- package/vite.config.ts +23 -0
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setupMissionControlHandlers = setupMissionControlHandlers;
|
|
4
|
+
const electron_1 = require("electron");
|
|
5
|
+
const types_1 = require("../../shared/types");
|
|
6
|
+
const rate_limiter_1 = require("../utils/rate-limiter");
|
|
7
|
+
const validation_1 = require("../utils/validation");
|
|
8
|
+
// Get main window for event broadcasting
|
|
9
|
+
let mainWindowGetter = null;
|
|
10
|
+
function getMainWindow() {
|
|
11
|
+
return mainWindowGetter?.() ?? null;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Rate limit check helper
|
|
15
|
+
*/
|
|
16
|
+
function checkRateLimit(channel) {
|
|
17
|
+
if (!rate_limiter_1.rateLimiter.check(channel)) {
|
|
18
|
+
throw new Error(`Rate limit exceeded for ${channel}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Set up Mission Control IPC handlers
|
|
23
|
+
*/
|
|
24
|
+
function setupMissionControlHandlers(deps) {
|
|
25
|
+
mainWindowGetter = deps.getMainWindow;
|
|
26
|
+
const { agentRoleRepo, taskSubscriptionRepo, standupService, heartbeatService, } = deps;
|
|
27
|
+
// ============ Heartbeat Handlers ============
|
|
28
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.HEARTBEAT_GET_CONFIG, async (_, agentRoleId) => {
|
|
29
|
+
const validated = (0, validation_1.validateInput)(validation_1.UUIDSchema, agentRoleId, 'agent role ID');
|
|
30
|
+
const role = agentRoleRepo.findById(validated);
|
|
31
|
+
if (!role) {
|
|
32
|
+
throw new Error('Agent role not found');
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
heartbeatEnabled: role.heartbeatEnabled,
|
|
36
|
+
heartbeatIntervalMinutes: role.heartbeatIntervalMinutes,
|
|
37
|
+
heartbeatStaggerOffset: role.heartbeatStaggerOffset,
|
|
38
|
+
lastHeartbeatAt: role.lastHeartbeatAt,
|
|
39
|
+
heartbeatStatus: role.heartbeatStatus,
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.HEARTBEAT_UPDATE_CONFIG, async (_, agentRoleId, config) => {
|
|
43
|
+
checkRateLimit(types_1.IPC_CHANNELS.HEARTBEAT_UPDATE_CONFIG);
|
|
44
|
+
const validated = (0, validation_1.validateInput)(validation_1.UUIDSchema, agentRoleId, 'agent role ID');
|
|
45
|
+
const result = agentRoleRepo.updateHeartbeatConfig(validated, config);
|
|
46
|
+
if (result) {
|
|
47
|
+
heartbeatService.updateAgentConfig(validated, config);
|
|
48
|
+
getMainWindow()?.webContents.send(types_1.IPC_CHANNELS.HEARTBEAT_EVENT, {
|
|
49
|
+
type: 'config_updated',
|
|
50
|
+
agentRoleId: validated,
|
|
51
|
+
config,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
});
|
|
56
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.HEARTBEAT_TRIGGER, async (_, agentRoleId) => {
|
|
57
|
+
checkRateLimit(types_1.IPC_CHANNELS.HEARTBEAT_TRIGGER);
|
|
58
|
+
const validated = (0, validation_1.validateInput)(validation_1.UUIDSchema, agentRoleId, 'agent role ID');
|
|
59
|
+
const result = await heartbeatService.triggerHeartbeat(validated);
|
|
60
|
+
getMainWindow()?.webContents.send(types_1.IPC_CHANNELS.HEARTBEAT_EVENT, {
|
|
61
|
+
type: 'triggered',
|
|
62
|
+
agentRoleId: validated,
|
|
63
|
+
result,
|
|
64
|
+
});
|
|
65
|
+
return result;
|
|
66
|
+
});
|
|
67
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.HEARTBEAT_GET_STATUS, async (_, agentRoleId) => {
|
|
68
|
+
const validated = (0, validation_1.validateInput)(validation_1.UUIDSchema, agentRoleId, 'agent role ID');
|
|
69
|
+
return heartbeatService.getStatus(validated);
|
|
70
|
+
});
|
|
71
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.HEARTBEAT_GET_ALL_STATUS, async () => {
|
|
72
|
+
return heartbeatService.getAllStatus();
|
|
73
|
+
});
|
|
74
|
+
// Forward heartbeat events to renderer
|
|
75
|
+
heartbeatService.on('heartbeat', (event) => {
|
|
76
|
+
getMainWindow()?.webContents.send(types_1.IPC_CHANNELS.HEARTBEAT_EVENT, event);
|
|
77
|
+
});
|
|
78
|
+
// ============ Task Subscription Handlers ============
|
|
79
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.SUBSCRIPTION_LIST, async (_, taskId) => {
|
|
80
|
+
const validated = (0, validation_1.validateInput)(validation_1.UUIDSchema, taskId, 'task ID');
|
|
81
|
+
return taskSubscriptionRepo.getSubscribers(validated);
|
|
82
|
+
});
|
|
83
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.SUBSCRIPTION_ADD, async (_, taskId, agentRoleId, reason) => {
|
|
84
|
+
checkRateLimit(types_1.IPC_CHANNELS.SUBSCRIPTION_ADD);
|
|
85
|
+
const validatedTaskId = (0, validation_1.validateInput)(validation_1.UUIDSchema, taskId, 'task ID');
|
|
86
|
+
const validatedAgentRoleId = (0, validation_1.validateInput)(validation_1.UUIDSchema, agentRoleId, 'agent role ID');
|
|
87
|
+
const subscription = taskSubscriptionRepo.subscribe(validatedTaskId, validatedAgentRoleId, reason);
|
|
88
|
+
getMainWindow()?.webContents.send(types_1.IPC_CHANNELS.SUBSCRIPTION_EVENT, {
|
|
89
|
+
type: 'added',
|
|
90
|
+
subscription,
|
|
91
|
+
});
|
|
92
|
+
return subscription;
|
|
93
|
+
});
|
|
94
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.SUBSCRIPTION_REMOVE, async (_, taskId, agentRoleId) => {
|
|
95
|
+
checkRateLimit(types_1.IPC_CHANNELS.SUBSCRIPTION_REMOVE);
|
|
96
|
+
const validatedTaskId = (0, validation_1.validateInput)(validation_1.UUIDSchema, taskId, 'task ID');
|
|
97
|
+
const validatedAgentRoleId = (0, validation_1.validateInput)(validation_1.UUIDSchema, agentRoleId, 'agent role ID');
|
|
98
|
+
const success = taskSubscriptionRepo.unsubscribe(validatedTaskId, validatedAgentRoleId);
|
|
99
|
+
if (success) {
|
|
100
|
+
getMainWindow()?.webContents.send(types_1.IPC_CHANNELS.SUBSCRIPTION_EVENT, {
|
|
101
|
+
type: 'removed',
|
|
102
|
+
taskId: validatedTaskId,
|
|
103
|
+
agentRoleId: validatedAgentRoleId,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
return { success };
|
|
107
|
+
});
|
|
108
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.SUBSCRIPTION_GET_SUBSCRIBERS, async (_, taskId) => {
|
|
109
|
+
const validated = (0, validation_1.validateInput)(validation_1.UUIDSchema, taskId, 'task ID');
|
|
110
|
+
return taskSubscriptionRepo.getSubscribers(validated);
|
|
111
|
+
});
|
|
112
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.SUBSCRIPTION_GET_FOR_AGENT, async (_, agentRoleId) => {
|
|
113
|
+
const validated = (0, validation_1.validateInput)(validation_1.UUIDSchema, agentRoleId, 'agent role ID');
|
|
114
|
+
return taskSubscriptionRepo.getSubscriptionsForAgent(validated);
|
|
115
|
+
});
|
|
116
|
+
// ============ Standup Report Handlers ============
|
|
117
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.STANDUP_GENERATE, async (_, workspaceId) => {
|
|
118
|
+
checkRateLimit(types_1.IPC_CHANNELS.STANDUP_GENERATE);
|
|
119
|
+
const validated = (0, validation_1.validateInput)(validation_1.UUIDSchema, workspaceId, 'workspace ID');
|
|
120
|
+
return standupService.generateReport(validated);
|
|
121
|
+
});
|
|
122
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.STANDUP_GET_LATEST, async (_, workspaceId) => {
|
|
123
|
+
const validated = (0, validation_1.validateInput)(validation_1.UUIDSchema, workspaceId, 'workspace ID');
|
|
124
|
+
return standupService.getLatest(validated);
|
|
125
|
+
});
|
|
126
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.STANDUP_LIST, async (_, workspaceId, limit) => {
|
|
127
|
+
const validated = (0, validation_1.validateInput)(validation_1.UUIDSchema, workspaceId, 'workspace ID');
|
|
128
|
+
return standupService.list({ workspaceId: validated, limit });
|
|
129
|
+
});
|
|
130
|
+
electron_1.ipcMain.handle(types_1.IPC_CHANNELS.STANDUP_DELIVER, async (_, reportId, channelType, channelId) => {
|
|
131
|
+
checkRateLimit(types_1.IPC_CHANNELS.STANDUP_DELIVER);
|
|
132
|
+
const validatedReportId = (0, validation_1.validateInput)(validation_1.UUIDSchema, reportId, 'report ID');
|
|
133
|
+
const report = standupService.findById(validatedReportId);
|
|
134
|
+
if (!report) {
|
|
135
|
+
throw new Error('Standup report not found');
|
|
136
|
+
}
|
|
137
|
+
await standupService.deliverReport(report, { channelType, channelId });
|
|
138
|
+
return { success: true };
|
|
139
|
+
});
|
|
140
|
+
console.log('[MissionControl] Handlers initialized');
|
|
141
|
+
}
|
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const path_1 = __importDefault(require("path"));
|
|
7
|
+
const url_1 = require("url");
|
|
8
|
+
const electron_1 = require("electron");
|
|
9
|
+
const schema_1 = require("./database/schema");
|
|
10
|
+
const SecureSettingsRepository_1 = require("./database/SecureSettingsRepository");
|
|
11
|
+
const handlers_1 = require("./ipc/handlers");
|
|
12
|
+
const mission_control_handlers_1 = require("./ipc/mission-control-handlers");
|
|
13
|
+
const TaskSubscriptionRepository_1 = require("./agents/TaskSubscriptionRepository");
|
|
14
|
+
const StandupReportService_1 = require("./reports/StandupReportService");
|
|
15
|
+
const HeartbeatService_1 = require("./agents/HeartbeatService");
|
|
16
|
+
const AgentRoleRepository_1 = require("./agents/AgentRoleRepository");
|
|
17
|
+
const MentionRepository_1 = require("./agents/MentionRepository");
|
|
18
|
+
const ActivityRepository_1 = require("./activity/ActivityRepository");
|
|
19
|
+
const WorkingStateRepository_1 = require("./agents/WorkingStateRepository");
|
|
20
|
+
const daemon_1 = require("./agent/daemon");
|
|
21
|
+
const repositories_1 = require("./database/repositories");
|
|
22
|
+
const llm_1 = require("./agent/llm");
|
|
23
|
+
const search_1 = require("./agent/search");
|
|
24
|
+
const gateway_1 = require("./gateway");
|
|
25
|
+
const updater_1 = require("./updater");
|
|
26
|
+
const env_migration_1 = require("./utils/env-migration");
|
|
27
|
+
const guardrail_manager_1 = require("./guardrails/guardrail-manager");
|
|
28
|
+
const appearance_manager_1 = require("./settings/appearance-manager");
|
|
29
|
+
const personality_manager_1 = require("./settings/personality-manager");
|
|
30
|
+
const MCPClientManager_1 = require("./mcp/client/MCPClientManager");
|
|
31
|
+
const tray_1 = require("./tray");
|
|
32
|
+
const cron_1 = require("./cron");
|
|
33
|
+
const MemoryService_1 = require("./memory/MemoryService");
|
|
34
|
+
const control_plane_1 = require("./control-plane");
|
|
35
|
+
// Live Canvas feature
|
|
36
|
+
const canvas_1 = require("./canvas");
|
|
37
|
+
const canvas_handlers_1 = require("./ipc/canvas-handlers");
|
|
38
|
+
let mainWindow = null;
|
|
39
|
+
let dbManager;
|
|
40
|
+
let agentDaemon;
|
|
41
|
+
let channelGateway;
|
|
42
|
+
let cronService = null;
|
|
43
|
+
// Suppress GPU-related Chromium errors that occur with transparent windows and vibrancy
|
|
44
|
+
// These are cosmetic errors that don't affect functionality
|
|
45
|
+
electron_1.app.commandLine.appendSwitch('disable-gpu-driver-bug-workarounds');
|
|
46
|
+
electron_1.app.commandLine.appendSwitch('enable-gpu-rasterization');
|
|
47
|
+
electron_1.app.commandLine.appendSwitch('ignore-gpu-blocklist');
|
|
48
|
+
// Register canvas:// protocol scheme (must be called before app.ready)
|
|
49
|
+
(0, canvas_1.registerCanvasScheme)();
|
|
50
|
+
function createWindow() {
|
|
51
|
+
mainWindow = new electron_1.BrowserWindow({
|
|
52
|
+
width: 1600,
|
|
53
|
+
height: 1000,
|
|
54
|
+
minWidth: 1200,
|
|
55
|
+
minHeight: 800,
|
|
56
|
+
center: true,
|
|
57
|
+
titleBarStyle: 'hiddenInset',
|
|
58
|
+
vibrancy: 'under-window',
|
|
59
|
+
visualEffectState: 'active',
|
|
60
|
+
transparent: true,
|
|
61
|
+
backgroundColor: '#00000000',
|
|
62
|
+
webPreferences: {
|
|
63
|
+
nodeIntegration: false,
|
|
64
|
+
contextIsolation: true,
|
|
65
|
+
webviewTag: true, // Enable webview for canvas interactive mode
|
|
66
|
+
preload: path_1.default.join(__dirname, 'preload.js'),
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
// Load the app
|
|
70
|
+
if (process.env.NODE_ENV === 'development') {
|
|
71
|
+
mainWindow.loadURL('http://localhost:5173');
|
|
72
|
+
mainWindow.webContents.openDevTools();
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
mainWindow.loadFile(path_1.default.join(__dirname, '../../renderer/index.html'));
|
|
76
|
+
}
|
|
77
|
+
mainWindow.on('closed', () => {
|
|
78
|
+
mainWindow = null;
|
|
79
|
+
});
|
|
80
|
+
// Open external links in the system browser instead of inside the app
|
|
81
|
+
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
|
|
82
|
+
// Open all new window requests in external browser
|
|
83
|
+
electron_1.shell.openExternal(url);
|
|
84
|
+
return { action: 'deny' };
|
|
85
|
+
});
|
|
86
|
+
mainWindow.webContents.on('will-navigate', (event, url) => {
|
|
87
|
+
// Allow navigation to the app itself (dev server or file://), block external URLs
|
|
88
|
+
const appUrl = process.env.NODE_ENV === 'development'
|
|
89
|
+
? 'http://localhost:5173'
|
|
90
|
+
: `file://${path_1.default.join(__dirname, '../../renderer')}`;
|
|
91
|
+
if (!url.startsWith(appUrl)) {
|
|
92
|
+
event.preventDefault();
|
|
93
|
+
electron_1.shell.openExternal(url);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
electron_1.app.whenReady().then(async () => {
|
|
98
|
+
// Set up Content Security Policy for production builds
|
|
99
|
+
if (process.env.NODE_ENV !== 'development') {
|
|
100
|
+
const appRoot = (0, url_1.pathToFileURL)(path_1.default.join(__dirname, '../../renderer')).toString();
|
|
101
|
+
electron_1.session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
|
|
102
|
+
if (!details.url.startsWith(appRoot)) {
|
|
103
|
+
callback({ responseHeaders: details.responseHeaders });
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
callback({
|
|
107
|
+
responseHeaders: {
|
|
108
|
+
...details.responseHeaders,
|
|
109
|
+
'Content-Security-Policy': [
|
|
110
|
+
"default-src 'self'; " +
|
|
111
|
+
"script-src 'self'; " +
|
|
112
|
+
"style-src 'self' 'unsafe-inline'; " + // Allow inline styles for React
|
|
113
|
+
"img-src 'self' data: https:; " + // Allow images from self, data URIs, and HTTPS
|
|
114
|
+
"font-src 'self' data:; " + // Allow fonts from self and data URIs
|
|
115
|
+
"connect-src 'self' https:; " + // Allow API calls to HTTPS endpoints
|
|
116
|
+
"frame-ancestors 'none'; " + // Prevent embedding in iframes
|
|
117
|
+
"form-action 'self';" // Restrict form submissions
|
|
118
|
+
],
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
// Initialize database first - required for SecureSettingsRepository
|
|
124
|
+
dbManager = new schema_1.DatabaseManager();
|
|
125
|
+
// Initialize secure settings repository for encrypted settings storage
|
|
126
|
+
// This MUST be done before provider factories so they can migrate legacy settings
|
|
127
|
+
new SecureSettingsRepository_1.SecureSettingsRepository(dbManager.getDatabase());
|
|
128
|
+
console.log('[Main] SecureSettingsRepository initialized');
|
|
129
|
+
// Initialize provider factories (loads settings from disk, migrates legacy files)
|
|
130
|
+
llm_1.LLMProviderFactory.initialize();
|
|
131
|
+
search_1.SearchProviderFactory.initialize();
|
|
132
|
+
guardrail_manager_1.GuardrailManager.initialize();
|
|
133
|
+
appearance_manager_1.AppearanceManager.initialize();
|
|
134
|
+
personality_manager_1.PersonalityManager.initialize();
|
|
135
|
+
// Migrate .env configuration to Settings (one-time upgrade path)
|
|
136
|
+
const migrationResult = await (0, env_migration_1.migrateEnvToSettings)();
|
|
137
|
+
// Initialize agent daemon
|
|
138
|
+
agentDaemon = new daemon_1.AgentDaemon(dbManager);
|
|
139
|
+
await agentDaemon.initialize();
|
|
140
|
+
// Initialize Memory Service for cross-session context
|
|
141
|
+
try {
|
|
142
|
+
MemoryService_1.MemoryService.initialize(dbManager);
|
|
143
|
+
console.log('[Main] Memory Service initialized');
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
console.error('[Main] Failed to initialize Memory Service:', error);
|
|
147
|
+
// Don't fail app startup if memory init fails
|
|
148
|
+
}
|
|
149
|
+
// Initialize MCP Client Manager - auto-connects enabled servers on startup
|
|
150
|
+
try {
|
|
151
|
+
const mcpClientManager = MCPClientManager_1.MCPClientManager.getInstance();
|
|
152
|
+
await mcpClientManager.initialize();
|
|
153
|
+
console.log('[Main] MCP Client Manager initialized');
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
console.error('[Main] Failed to initialize MCP Client Manager:', error);
|
|
157
|
+
// Don't fail app startup if MCP init fails
|
|
158
|
+
}
|
|
159
|
+
// Initialize Cron Service for scheduled task execution
|
|
160
|
+
try {
|
|
161
|
+
cronService = new cron_1.CronService({
|
|
162
|
+
cronEnabled: true,
|
|
163
|
+
storePath: (0, cron_1.getCronStorePath)(),
|
|
164
|
+
maxConcurrentRuns: 3, // Allow up to 3 concurrent jobs
|
|
165
|
+
// Webhook configuration (disabled by default, can be enabled in settings)
|
|
166
|
+
webhook: {
|
|
167
|
+
enabled: false, // Set to true to enable webhook triggers
|
|
168
|
+
port: 9876,
|
|
169
|
+
host: '127.0.0.1',
|
|
170
|
+
// secret: 'your-secret-here', // Uncomment and set for secure webhooks
|
|
171
|
+
},
|
|
172
|
+
createTask: async (params) => {
|
|
173
|
+
const task = await agentDaemon.createTask({
|
|
174
|
+
title: params.title,
|
|
175
|
+
prompt: params.prompt,
|
|
176
|
+
workspaceId: params.workspaceId,
|
|
177
|
+
});
|
|
178
|
+
return { id: task.id };
|
|
179
|
+
},
|
|
180
|
+
// Channel delivery handler - sends job results to messaging platforms
|
|
181
|
+
deliverToChannel: async (params) => {
|
|
182
|
+
if (!channelGateway) {
|
|
183
|
+
console.warn('[Cron] Cannot deliver to channel - gateway not initialized');
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
// Build the message
|
|
187
|
+
const statusEmoji = params.status === 'ok' ? '✅' : params.status === 'error' ? '❌' : '⏱️';
|
|
188
|
+
let message = `${statusEmoji} **Scheduled Task: ${params.jobName}**\n\n`;
|
|
189
|
+
if (params.status === 'ok') {
|
|
190
|
+
message += `Task completed successfully.\n`;
|
|
191
|
+
}
|
|
192
|
+
else if (params.status === 'error') {
|
|
193
|
+
message += `Task failed.\n`;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
message += `Task timed out.\n`;
|
|
197
|
+
}
|
|
198
|
+
if (params.error) {
|
|
199
|
+
message += `\n**Error:** ${params.error}\n`;
|
|
200
|
+
}
|
|
201
|
+
if (params.taskId && !params.summaryOnly) {
|
|
202
|
+
message += `\n_Task ID: ${params.taskId}_`;
|
|
203
|
+
}
|
|
204
|
+
// Find the channel to verify it exists
|
|
205
|
+
const channels = channelGateway.getChannels();
|
|
206
|
+
const channel = channels.find((ch) => ch.type === params.channelType && ch.id === params.channelId);
|
|
207
|
+
if (!channel) {
|
|
208
|
+
console.warn(`[Cron] Channel not found: ${params.channelType}:${params.channelId}`);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
// Send the message via the gateway
|
|
213
|
+
await channelGateway.sendMessage(params.channelType, params.channelId, message, { parseMode: 'markdown' });
|
|
214
|
+
console.log(`[Cron] Delivered to ${params.channelType}:${params.channelId}`);
|
|
215
|
+
}
|
|
216
|
+
catch (err) {
|
|
217
|
+
console.error(`[Cron] Failed to deliver to ${params.channelType}:${params.channelId}:`, err);
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
onEvent: async (evt) => {
|
|
221
|
+
// Forward cron events to renderer
|
|
222
|
+
if (mainWindow?.webContents) {
|
|
223
|
+
mainWindow.webContents.send('cron:event', evt);
|
|
224
|
+
}
|
|
225
|
+
console.log('[Cron] Event:', evt.action, evt.jobId);
|
|
226
|
+
// Show desktop notification when scheduled task finishes
|
|
227
|
+
if (evt.action === 'finished') {
|
|
228
|
+
const statusEmoji = evt.status === 'ok' ? '✅' : evt.status === 'error' ? '❌' : '⏱️';
|
|
229
|
+
const statusText = evt.status === 'ok' ? 'completed' : evt.status === 'error' ? 'failed' : 'timed out';
|
|
230
|
+
// Add in-app notification
|
|
231
|
+
const notificationService = (0, handlers_1.getNotificationService)();
|
|
232
|
+
if (notificationService) {
|
|
233
|
+
try {
|
|
234
|
+
// Get job name for the notification
|
|
235
|
+
const job = cronService ? await cronService.get(evt.jobId) : null;
|
|
236
|
+
const jobName = job?.name || 'Scheduled Task';
|
|
237
|
+
await notificationService.add({
|
|
238
|
+
type: evt.status === 'ok' ? 'task_completed' : 'task_failed',
|
|
239
|
+
title: `${statusEmoji} ${jobName} ${statusText}`,
|
|
240
|
+
message: evt.error || (evt.status === 'ok' ? 'Task completed successfully.' : 'Task did not complete.'),
|
|
241
|
+
taskId: evt.taskId,
|
|
242
|
+
cronJobId: evt.jobId,
|
|
243
|
+
workspaceId: job?.workspaceId,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
catch (err) {
|
|
247
|
+
console.error('[Cron] Failed to add in-app notification:', err);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
// Show macOS notification
|
|
251
|
+
if (electron_1.Notification.isSupported()) {
|
|
252
|
+
const notification = new electron_1.Notification({
|
|
253
|
+
title: `${statusEmoji} Scheduled Task ${statusText}`,
|
|
254
|
+
body: evt.error ? `Error: ${evt.error}` : 'Click to view results in the app.',
|
|
255
|
+
silent: false,
|
|
256
|
+
});
|
|
257
|
+
notification.on('click', () => {
|
|
258
|
+
// Bring the main window to focus
|
|
259
|
+
if (mainWindow) {
|
|
260
|
+
if (mainWindow.isMinimized())
|
|
261
|
+
mainWindow.restore();
|
|
262
|
+
mainWindow.focus();
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
notification.show();
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
log: {
|
|
270
|
+
debug: (msg, data) => console.log(`[Cron] ${msg}`, data ?? ''),
|
|
271
|
+
info: (msg, data) => console.log(`[Cron] ${msg}`, data ?? ''),
|
|
272
|
+
warn: (msg, data) => console.warn(`[Cron] ${msg}`, data ?? ''),
|
|
273
|
+
error: (msg, data) => console.error(`[Cron] ${msg}`, data ?? ''),
|
|
274
|
+
},
|
|
275
|
+
});
|
|
276
|
+
(0, cron_1.setCronService)(cronService);
|
|
277
|
+
await cronService.start();
|
|
278
|
+
console.log('[Main] Cron Service initialized');
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
console.error('[Main] Failed to initialize Cron Service:', error);
|
|
282
|
+
// Don't fail app startup if cron init fails
|
|
283
|
+
}
|
|
284
|
+
// Initialize channel gateway with agent daemon for task processing
|
|
285
|
+
channelGateway = new gateway_1.ChannelGateway(dbManager.getDatabase(), {
|
|
286
|
+
autoConnect: true, // Auto-connect enabled channels on startup
|
|
287
|
+
agentDaemon,
|
|
288
|
+
});
|
|
289
|
+
// Setup IPC handlers
|
|
290
|
+
await (0, handlers_1.setupIpcHandlers)(dbManager, agentDaemon, channelGateway);
|
|
291
|
+
// Initialize Mission Control services
|
|
292
|
+
try {
|
|
293
|
+
const db = dbManager.getDatabase();
|
|
294
|
+
const agentRoleRepo = new AgentRoleRepository_1.AgentRoleRepository(db);
|
|
295
|
+
// Sync any new default agents to existing workspaces
|
|
296
|
+
const addedAgents = agentRoleRepo.syncNewDefaults();
|
|
297
|
+
if (addedAgents.length > 0) {
|
|
298
|
+
console.log(`[Main] Added ${addedAgents.length} new default agent(s)`);
|
|
299
|
+
}
|
|
300
|
+
const mentionRepo = new MentionRepository_1.MentionRepository(db);
|
|
301
|
+
const activityRepo = new ActivityRepository_1.ActivityRepository(db);
|
|
302
|
+
const workingStateRepo = new WorkingStateRepository_1.WorkingStateRepository(db);
|
|
303
|
+
const taskSubscriptionRepo = new TaskSubscriptionRepository_1.TaskSubscriptionRepository(db);
|
|
304
|
+
const standupService = new StandupReportService_1.StandupReportService(db);
|
|
305
|
+
// Create repositories for heartbeat service
|
|
306
|
+
const taskRepo = new repositories_1.TaskRepository(db);
|
|
307
|
+
const workspaceRepo = new repositories_1.WorkspaceRepository(db);
|
|
308
|
+
// Initialize HeartbeatService with dependencies
|
|
309
|
+
const heartbeatDeps = {
|
|
310
|
+
agentRoleRepo,
|
|
311
|
+
mentionRepo,
|
|
312
|
+
activityRepo,
|
|
313
|
+
workingStateRepo,
|
|
314
|
+
createTask: async (workspaceId, prompt, title, _agentRoleId) => {
|
|
315
|
+
// Create task via agentDaemon (doesn't support assignedAgentRoleId directly)
|
|
316
|
+
const task = await agentDaemon.createTask({
|
|
317
|
+
title,
|
|
318
|
+
prompt,
|
|
319
|
+
workspaceId,
|
|
320
|
+
});
|
|
321
|
+
// Note: Task assignment would need to be done separately if needed
|
|
322
|
+
return task;
|
|
323
|
+
},
|
|
324
|
+
getTasksForAgent: (agentRoleId, workspaceId) => {
|
|
325
|
+
// Get assigned tasks for the agent using the task repository
|
|
326
|
+
const tasks = workspaceId
|
|
327
|
+
? taskRepo.findByWorkspace(workspaceId)
|
|
328
|
+
: taskRepo.findByStatus(['pending', 'running']);
|
|
329
|
+
return tasks.filter((t) => t.assignedAgentRoleId === agentRoleId);
|
|
330
|
+
},
|
|
331
|
+
getDefaultWorkspaceId: () => {
|
|
332
|
+
// Get the first workspace as default
|
|
333
|
+
const workspaces = workspaceRepo.findAll();
|
|
334
|
+
return workspaces[0]?.id;
|
|
335
|
+
},
|
|
336
|
+
};
|
|
337
|
+
const heartbeatService = new HeartbeatService_1.HeartbeatService(heartbeatDeps);
|
|
338
|
+
await heartbeatService.start();
|
|
339
|
+
// Setup Mission Control IPC handlers
|
|
340
|
+
(0, mission_control_handlers_1.setupMissionControlHandlers)({
|
|
341
|
+
agentRoleRepo,
|
|
342
|
+
taskSubscriptionRepo,
|
|
343
|
+
standupService,
|
|
344
|
+
heartbeatService,
|
|
345
|
+
getMainWindow: () => mainWindow,
|
|
346
|
+
});
|
|
347
|
+
console.log('[Main] Mission Control services initialized');
|
|
348
|
+
}
|
|
349
|
+
catch (error) {
|
|
350
|
+
console.error('[Main] Failed to initialize Mission Control:', error);
|
|
351
|
+
// Don't fail app startup if Mission Control init fails
|
|
352
|
+
}
|
|
353
|
+
// Register canvas:// protocol handler (must be after app.ready)
|
|
354
|
+
(0, canvas_1.registerCanvasProtocol)();
|
|
355
|
+
// Create window
|
|
356
|
+
createWindow();
|
|
357
|
+
// Initialize gateway with main window reference
|
|
358
|
+
if (mainWindow) {
|
|
359
|
+
await channelGateway.initialize(mainWindow);
|
|
360
|
+
// Initialize update manager with main window reference
|
|
361
|
+
updater_1.updateManager.setMainWindow(mainWindow);
|
|
362
|
+
// Initialize Live Canvas handlers and set main window reference
|
|
363
|
+
(0, canvas_handlers_1.setupCanvasHandlers)(mainWindow, agentDaemon);
|
|
364
|
+
canvas_1.CanvasManager.getInstance().setMainWindow(mainWindow);
|
|
365
|
+
// Restore persisted canvas sessions from disk
|
|
366
|
+
await canvas_1.CanvasManager.getInstance().restoreSessions();
|
|
367
|
+
// Initialize control plane (WebSocket gateway)
|
|
368
|
+
(0, control_plane_1.setupControlPlaneHandlers)(mainWindow);
|
|
369
|
+
// Initialize menu bar tray (macOS native companion)
|
|
370
|
+
if (process.platform === 'darwin') {
|
|
371
|
+
await tray_1.trayManager.initialize(mainWindow, channelGateway, dbManager, agentDaemon);
|
|
372
|
+
}
|
|
373
|
+
// Show migration notification after window is ready
|
|
374
|
+
if (migrationResult.migrated && migrationResult.migratedKeys.length > 0) {
|
|
375
|
+
mainWindow.webContents.once('did-finish-load', () => {
|
|
376
|
+
electron_1.dialog.showMessageBox(mainWindow, {
|
|
377
|
+
type: 'info',
|
|
378
|
+
title: 'Configuration Migrated',
|
|
379
|
+
message: 'Your API credentials have been migrated',
|
|
380
|
+
detail: `The following credentials were migrated from your .env file to secure Settings storage:\n\n` +
|
|
381
|
+
`${migrationResult.migratedKeys.map(k => `• ${k}`).join('\n')}\n\n` +
|
|
382
|
+
`Your .env file has been renamed to .env.migrated. ` +
|
|
383
|
+
`You can safely delete it after verifying your settings work correctly.\n\n` +
|
|
384
|
+
`Open Settings (gear icon) to review your configuration.`,
|
|
385
|
+
buttons: ['OK'],
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
electron_1.app.on('activate', () => {
|
|
391
|
+
if (electron_1.BrowserWindow.getAllWindows().length === 0) {
|
|
392
|
+
createWindow();
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
});
|
|
396
|
+
electron_1.app.on('window-all-closed', () => {
|
|
397
|
+
if (process.platform !== 'darwin') {
|
|
398
|
+
electron_1.app.quit();
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
electron_1.app.on('before-quit', async () => {
|
|
402
|
+
// Destroy tray
|
|
403
|
+
tray_1.trayManager.destroy();
|
|
404
|
+
// Stop cron service (async to properly shutdown webhook server)
|
|
405
|
+
if (cronService) {
|
|
406
|
+
await cronService.stop();
|
|
407
|
+
(0, cron_1.setCronService)(null);
|
|
408
|
+
}
|
|
409
|
+
// Cleanup canvas manager (close all windows and watchers)
|
|
410
|
+
await (0, canvas_handlers_1.cleanupCanvasHandlers)();
|
|
411
|
+
// Shutdown control plane (WebSocket gateway and Tailscale)
|
|
412
|
+
await (0, control_plane_1.shutdownControlPlane)();
|
|
413
|
+
if (channelGateway) {
|
|
414
|
+
await channelGateway.shutdown();
|
|
415
|
+
}
|
|
416
|
+
// Disconnect all MCP servers
|
|
417
|
+
try {
|
|
418
|
+
const mcpClientManager = MCPClientManager_1.MCPClientManager.getInstance();
|
|
419
|
+
await mcpClientManager.shutdown();
|
|
420
|
+
}
|
|
421
|
+
catch (error) {
|
|
422
|
+
console.error('[Main] Failed to shutdown MCP servers:', error);
|
|
423
|
+
}
|
|
424
|
+
// Shutdown Memory Service
|
|
425
|
+
try {
|
|
426
|
+
MemoryService_1.MemoryService.shutdown();
|
|
427
|
+
}
|
|
428
|
+
catch (error) {
|
|
429
|
+
console.error('[Main] Failed to shutdown Memory Service:', error);
|
|
430
|
+
}
|
|
431
|
+
if (dbManager) {
|
|
432
|
+
dbManager.close();
|
|
433
|
+
}
|
|
434
|
+
if (agentDaemon) {
|
|
435
|
+
agentDaemon.shutdown();
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
// Handle folder selection
|
|
439
|
+
electron_1.ipcMain.handle('dialog:selectFolder', async () => {
|
|
440
|
+
const result = await electron_1.dialog.showOpenDialog({
|
|
441
|
+
properties: ['openDirectory'],
|
|
442
|
+
title: 'Select Workspace Folder',
|
|
443
|
+
});
|
|
444
|
+
if (!result.canceled && result.filePaths.length > 0) {
|
|
445
|
+
return result.filePaths[0];
|
|
446
|
+
}
|
|
447
|
+
return null;
|
|
448
|
+
});
|