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,348 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Guardrail Manager
|
|
4
|
+
*
|
|
5
|
+
* Manages user-configurable safety guardrails for the agent.
|
|
6
|
+
* Settings are stored encrypted in the database using SecureSettingsRepository.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.GuardrailManager = void 0;
|
|
43
|
+
const electron_1 = require("electron");
|
|
44
|
+
const fs = __importStar(require("fs"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
const types_1 = require("../../shared/types");
|
|
47
|
+
const SecureSettingsRepository_1 = require("../database/SecureSettingsRepository");
|
|
48
|
+
const LEGACY_SETTINGS_FILE = 'guardrail-settings.json';
|
|
49
|
+
const DEFAULT_SETTINGS = {
|
|
50
|
+
// Token Budget
|
|
51
|
+
maxTokensPerTask: 100000,
|
|
52
|
+
tokenBudgetEnabled: true,
|
|
53
|
+
// Cost Budget
|
|
54
|
+
maxCostPerTask: 1.00,
|
|
55
|
+
costBudgetEnabled: false,
|
|
56
|
+
// Dangerous Commands
|
|
57
|
+
blockDangerousCommands: true,
|
|
58
|
+
customBlockedPatterns: [],
|
|
59
|
+
// Auto-Approve Trusted Commands
|
|
60
|
+
autoApproveTrustedCommands: true, // Enabled by default for common safe commands
|
|
61
|
+
trustedCommandPatterns: [],
|
|
62
|
+
// File Size
|
|
63
|
+
maxFileSizeMB: 50,
|
|
64
|
+
fileSizeLimitEnabled: true,
|
|
65
|
+
// Network Domains
|
|
66
|
+
enforceAllowedDomains: false,
|
|
67
|
+
allowedDomains: [],
|
|
68
|
+
// Iterations
|
|
69
|
+
maxIterationsPerTask: 50,
|
|
70
|
+
iterationLimitEnabled: true,
|
|
71
|
+
};
|
|
72
|
+
class GuardrailManager {
|
|
73
|
+
/**
|
|
74
|
+
* Initialize the GuardrailManager
|
|
75
|
+
*/
|
|
76
|
+
static initialize() {
|
|
77
|
+
const userDataPath = electron_1.app.getPath('userData');
|
|
78
|
+
this.legacySettingsPath = path.join(userDataPath, LEGACY_SETTINGS_FILE);
|
|
79
|
+
// Migrate from legacy JSON file to encrypted database
|
|
80
|
+
this.migrateFromLegacyFile();
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Migrate settings from legacy JSON file to encrypted database
|
|
84
|
+
*/
|
|
85
|
+
static migrateFromLegacyFile() {
|
|
86
|
+
if (this.migrationCompleted)
|
|
87
|
+
return;
|
|
88
|
+
try {
|
|
89
|
+
if (!SecureSettingsRepository_1.SecureSettingsRepository.isInitialized()) {
|
|
90
|
+
console.log('[GuardrailManager] SecureSettingsRepository not yet initialized, skipping migration');
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const repository = SecureSettingsRepository_1.SecureSettingsRepository.getInstance();
|
|
94
|
+
if (repository.exists('guardrails')) {
|
|
95
|
+
this.migrationCompleted = true;
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (!fs.existsSync(this.legacySettingsPath)) {
|
|
99
|
+
console.log('[GuardrailManager] No legacy settings file found');
|
|
100
|
+
this.migrationCompleted = true;
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
console.log('[GuardrailManager] Migrating settings from legacy JSON file to encrypted database...');
|
|
104
|
+
// Create backup before migration
|
|
105
|
+
const backupPath = this.legacySettingsPath + '.migration-backup';
|
|
106
|
+
fs.copyFileSync(this.legacySettingsPath, backupPath);
|
|
107
|
+
try {
|
|
108
|
+
const data = fs.readFileSync(this.legacySettingsPath, 'utf-8');
|
|
109
|
+
const legacySettings = { ...DEFAULT_SETTINGS, ...JSON.parse(data) };
|
|
110
|
+
repository.save('guardrails', legacySettings);
|
|
111
|
+
console.log('[GuardrailManager] Settings migrated to encrypted database');
|
|
112
|
+
// Migration successful - delete backup and original
|
|
113
|
+
fs.unlinkSync(backupPath);
|
|
114
|
+
fs.unlinkSync(this.legacySettingsPath);
|
|
115
|
+
console.log('[GuardrailManager] Migration complete, cleaned up legacy files');
|
|
116
|
+
this.migrationCompleted = true;
|
|
117
|
+
}
|
|
118
|
+
catch (migrationError) {
|
|
119
|
+
console.error('[GuardrailManager] Migration failed, backup preserved at:', backupPath);
|
|
120
|
+
throw migrationError;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
console.error('[GuardrailManager] Migration failed:', error);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Load settings from encrypted database (with caching)
|
|
129
|
+
*/
|
|
130
|
+
static loadSettings() {
|
|
131
|
+
if (this.cachedSettings) {
|
|
132
|
+
return this.cachedSettings;
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
if (SecureSettingsRepository_1.SecureSettingsRepository.isInitialized()) {
|
|
136
|
+
const repository = SecureSettingsRepository_1.SecureSettingsRepository.getInstance();
|
|
137
|
+
const stored = repository.load('guardrails');
|
|
138
|
+
if (stored) {
|
|
139
|
+
this.cachedSettings = { ...DEFAULT_SETTINGS, ...stored };
|
|
140
|
+
return this.cachedSettings;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
console.error('[GuardrailManager] Failed to load settings:', error);
|
|
146
|
+
}
|
|
147
|
+
this.cachedSettings = { ...DEFAULT_SETTINGS };
|
|
148
|
+
return this.cachedSettings;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Save settings to encrypted database
|
|
152
|
+
*/
|
|
153
|
+
static saveSettings(settings) {
|
|
154
|
+
try {
|
|
155
|
+
if (!SecureSettingsRepository_1.SecureSettingsRepository.isInitialized()) {
|
|
156
|
+
throw new Error('SecureSettingsRepository not initialized');
|
|
157
|
+
}
|
|
158
|
+
const repository = SecureSettingsRepository_1.SecureSettingsRepository.getInstance();
|
|
159
|
+
repository.save('guardrails', settings);
|
|
160
|
+
this.cachedSettings = settings;
|
|
161
|
+
console.log('[GuardrailManager] Settings saved to encrypted database');
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
console.error('[GuardrailManager] Failed to save settings:', error);
|
|
165
|
+
throw error;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Clear the settings cache (call after external changes)
|
|
170
|
+
*/
|
|
171
|
+
static clearCache() {
|
|
172
|
+
this.cachedSettings = null;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Get default settings (for reference)
|
|
176
|
+
*/
|
|
177
|
+
static getDefaults() {
|
|
178
|
+
return { ...DEFAULT_SETTINGS };
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Check if a command matches any blocked pattern
|
|
182
|
+
* @returns Object with blocked status and matched pattern if blocked
|
|
183
|
+
*/
|
|
184
|
+
static isCommandBlocked(command) {
|
|
185
|
+
const settings = this.loadSettings();
|
|
186
|
+
if (!settings.blockDangerousCommands) {
|
|
187
|
+
return { blocked: false };
|
|
188
|
+
}
|
|
189
|
+
// Combine default patterns with custom patterns
|
|
190
|
+
const allPatterns = [
|
|
191
|
+
...types_1.DEFAULT_BLOCKED_COMMAND_PATTERNS,
|
|
192
|
+
...settings.customBlockedPatterns,
|
|
193
|
+
];
|
|
194
|
+
for (const pattern of allPatterns) {
|
|
195
|
+
try {
|
|
196
|
+
// Try to compile as regex
|
|
197
|
+
const regex = new RegExp(pattern, 'i');
|
|
198
|
+
if (regex.test(command)) {
|
|
199
|
+
return { blocked: true, pattern };
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
// If invalid regex, try simple case-insensitive substring match
|
|
204
|
+
if (command.toLowerCase().includes(pattern.toLowerCase())) {
|
|
205
|
+
return { blocked: true, pattern };
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return { blocked: false };
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Convert a glob-like pattern to regex
|
|
213
|
+
* Supports * as wildcard for any characters
|
|
214
|
+
*/
|
|
215
|
+
static globToRegex(pattern) {
|
|
216
|
+
// Escape special regex characters except *
|
|
217
|
+
const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, '\\$&');
|
|
218
|
+
// Convert * to regex wildcard (.*)
|
|
219
|
+
const regexStr = '^' + escaped.replace(/\*/g, '.*') + '$';
|
|
220
|
+
return new RegExp(regexStr, 'i');
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Check if a command matches any trusted pattern (auto-approve without user confirmation)
|
|
224
|
+
* @returns Object with trusted status and matched pattern if trusted
|
|
225
|
+
*/
|
|
226
|
+
static isCommandTrusted(command) {
|
|
227
|
+
const settings = this.loadSettings();
|
|
228
|
+
if (!settings.autoApproveTrustedCommands) {
|
|
229
|
+
return { trusted: false };
|
|
230
|
+
}
|
|
231
|
+
// Combine default patterns with custom patterns
|
|
232
|
+
const allPatterns = [
|
|
233
|
+
...types_1.DEFAULT_TRUSTED_COMMAND_PATTERNS,
|
|
234
|
+
...settings.trustedCommandPatterns,
|
|
235
|
+
];
|
|
236
|
+
for (const pattern of allPatterns) {
|
|
237
|
+
try {
|
|
238
|
+
const regex = this.globToRegex(pattern);
|
|
239
|
+
if (regex.test(command)) {
|
|
240
|
+
return { trusted: true, pattern };
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
// If conversion fails, try simple prefix match
|
|
245
|
+
const prefix = pattern.replace(/\*/g, '');
|
|
246
|
+
if (command.toLowerCase().startsWith(prefix.toLowerCase())) {
|
|
247
|
+
return { trusted: true, pattern };
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return { trusted: false };
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Check if a URL's domain is allowed for network access
|
|
255
|
+
* @returns true if allowed, false if blocked
|
|
256
|
+
*/
|
|
257
|
+
static isDomainAllowed(url) {
|
|
258
|
+
const settings = this.loadSettings();
|
|
259
|
+
// If domain enforcement is disabled, allow everything
|
|
260
|
+
if (!settings.enforceAllowedDomains) {
|
|
261
|
+
return true;
|
|
262
|
+
}
|
|
263
|
+
// If no domains configured, block everything (safety)
|
|
264
|
+
if (settings.allowedDomains.length === 0) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
try {
|
|
268
|
+
const parsedUrl = new URL(url);
|
|
269
|
+
const hostname = parsedUrl.hostname.toLowerCase();
|
|
270
|
+
return settings.allowedDomains.some(pattern => {
|
|
271
|
+
const normalizedPattern = pattern.toLowerCase().trim();
|
|
272
|
+
if (normalizedPattern.startsWith('*.')) {
|
|
273
|
+
// Wildcard match (e.g., *.google.com matches maps.google.com)
|
|
274
|
+
const suffix = normalizedPattern.slice(2);
|
|
275
|
+
return hostname === suffix || hostname.endsWith('.' + suffix);
|
|
276
|
+
}
|
|
277
|
+
// Exact match
|
|
278
|
+
return hostname === normalizedPattern;
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
catch {
|
|
282
|
+
// Invalid URL - block it
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Check if file size exceeds the limit
|
|
288
|
+
* @param sizeInBytes Size of the content in bytes
|
|
289
|
+
* @returns Object with exceeded status and limit info
|
|
290
|
+
*/
|
|
291
|
+
static isFileSizeExceeded(sizeInBytes) {
|
|
292
|
+
const settings = this.loadSettings();
|
|
293
|
+
const sizeMB = sizeInBytes / (1024 * 1024);
|
|
294
|
+
if (!settings.fileSizeLimitEnabled) {
|
|
295
|
+
return { exceeded: false, sizeMB, limitMB: settings.maxFileSizeMB };
|
|
296
|
+
}
|
|
297
|
+
return {
|
|
298
|
+
exceeded: sizeMB > settings.maxFileSizeMB,
|
|
299
|
+
sizeMB,
|
|
300
|
+
limitMB: settings.maxFileSizeMB,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Check if token budget is exceeded
|
|
305
|
+
*/
|
|
306
|
+
static isTokenBudgetExceeded(tokensUsed) {
|
|
307
|
+
const settings = this.loadSettings();
|
|
308
|
+
if (!settings.tokenBudgetEnabled) {
|
|
309
|
+
return { exceeded: false, used: tokensUsed, limit: settings.maxTokensPerTask };
|
|
310
|
+
}
|
|
311
|
+
return {
|
|
312
|
+
exceeded: tokensUsed >= settings.maxTokensPerTask,
|
|
313
|
+
used: tokensUsed,
|
|
314
|
+
limit: settings.maxTokensPerTask,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Check if cost budget is exceeded
|
|
319
|
+
*/
|
|
320
|
+
static isCostBudgetExceeded(costIncurred) {
|
|
321
|
+
const settings = this.loadSettings();
|
|
322
|
+
if (!settings.costBudgetEnabled) {
|
|
323
|
+
return { exceeded: false, cost: costIncurred, limit: settings.maxCostPerTask };
|
|
324
|
+
}
|
|
325
|
+
return {
|
|
326
|
+
exceeded: costIncurred >= settings.maxCostPerTask,
|
|
327
|
+
cost: costIncurred,
|
|
328
|
+
limit: settings.maxCostPerTask,
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Check if iteration limit is exceeded
|
|
333
|
+
*/
|
|
334
|
+
static isIterationLimitExceeded(iterations) {
|
|
335
|
+
const settings = this.loadSettings();
|
|
336
|
+
if (!settings.iterationLimitEnabled) {
|
|
337
|
+
return { exceeded: false, iterations, limit: settings.maxIterationsPerTask };
|
|
338
|
+
}
|
|
339
|
+
return {
|
|
340
|
+
exceeded: iterations >= settings.maxIterationsPerTask,
|
|
341
|
+
iterations,
|
|
342
|
+
limit: settings.maxIterationsPerTask,
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
exports.GuardrailManager = GuardrailManager;
|
|
347
|
+
GuardrailManager.cachedSettings = null;
|
|
348
|
+
GuardrailManager.migrationCompleted = false;
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Gmail Watcher Service
|
|
4
|
+
*
|
|
5
|
+
* Automatically starts Gmail watch when the app starts,
|
|
6
|
+
* if hooks.gmail is configured with an account.
|
|
7
|
+
*
|
|
8
|
+
* This requires 'gog' (gogcli) to be installed and configured.
|
|
9
|
+
* See: https://gogcli.sh/
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.isGogAvailable = isGogAvailable;
|
|
13
|
+
exports.resolveGmailRuntimeConfig = resolveGmailRuntimeConfig;
|
|
14
|
+
exports.startGmailWatcher = startGmailWatcher;
|
|
15
|
+
exports.stopGmailWatcher = stopGmailWatcher;
|
|
16
|
+
exports.isGmailWatcherRunning = isGmailWatcherRunning;
|
|
17
|
+
exports.getGmailRuntimeConfig = getGmailRuntimeConfig;
|
|
18
|
+
const child_process_1 = require("child_process");
|
|
19
|
+
const process_1 = require("../utils/process");
|
|
20
|
+
const ADDRESS_IN_USE_RE = /address already in use|EADDRINUSE/i;
|
|
21
|
+
let watcherProcess = null;
|
|
22
|
+
let renewInterval = null;
|
|
23
|
+
let shuttingDown = false;
|
|
24
|
+
let currentConfig = null;
|
|
25
|
+
/**
|
|
26
|
+
* Check if gog binary is available
|
|
27
|
+
*/
|
|
28
|
+
async function isGogAvailable() {
|
|
29
|
+
return (0, process_1.checkBinaryExists)('gog');
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Resolve Gmail runtime configuration from hooks config
|
|
33
|
+
*/
|
|
34
|
+
function resolveGmailRuntimeConfig(config) {
|
|
35
|
+
const hooks = config;
|
|
36
|
+
const gmail = hooks.gmail;
|
|
37
|
+
const hookToken = hooks.token?.trim();
|
|
38
|
+
if (!hookToken) {
|
|
39
|
+
return { ok: false, error: 'hooks.token missing (needed for gmail hook)' };
|
|
40
|
+
}
|
|
41
|
+
const account = gmail?.account?.trim();
|
|
42
|
+
if (!account) {
|
|
43
|
+
return { ok: false, error: 'gmail account required' };
|
|
44
|
+
}
|
|
45
|
+
const topic = gmail?.topic?.trim();
|
|
46
|
+
if (!topic) {
|
|
47
|
+
return { ok: false, error: 'gmail topic required' };
|
|
48
|
+
}
|
|
49
|
+
const pushToken = gmail?.pushToken?.trim();
|
|
50
|
+
if (!pushToken) {
|
|
51
|
+
return { ok: false, error: 'gmail push token required' };
|
|
52
|
+
}
|
|
53
|
+
const subscription = gmail?.subscription || 'cowork-gmail-watch-push';
|
|
54
|
+
const label = gmail?.label || 'INBOX';
|
|
55
|
+
const hookUrl = gmail?.hookUrl || 'http://127.0.0.1:9877/hooks/gmail';
|
|
56
|
+
const includeBody = gmail?.includeBody ?? true;
|
|
57
|
+
const maxBytes = gmail?.maxBytes || 20000;
|
|
58
|
+
const renewEveryMinutes = gmail?.renewEveryMinutes || 12 * 60;
|
|
59
|
+
const serveBind = gmail?.serve?.bind || '127.0.0.1';
|
|
60
|
+
const servePort = gmail?.serve?.port || 8788;
|
|
61
|
+
const servePath = gmail?.serve?.path || '/gmail-pubsub';
|
|
62
|
+
const tailscaleMode = gmail?.tailscale?.mode || 'off';
|
|
63
|
+
const tailscalePath = gmail?.tailscale?.path || servePath;
|
|
64
|
+
const tailscaleTarget = gmail?.tailscale?.target;
|
|
65
|
+
return {
|
|
66
|
+
ok: true,
|
|
67
|
+
value: {
|
|
68
|
+
account,
|
|
69
|
+
label,
|
|
70
|
+
topic,
|
|
71
|
+
subscription,
|
|
72
|
+
pushToken,
|
|
73
|
+
hookToken,
|
|
74
|
+
hookUrl,
|
|
75
|
+
includeBody,
|
|
76
|
+
maxBytes,
|
|
77
|
+
renewEveryMinutes,
|
|
78
|
+
serve: {
|
|
79
|
+
bind: serveBind,
|
|
80
|
+
port: servePort,
|
|
81
|
+
path: servePath,
|
|
82
|
+
},
|
|
83
|
+
tailscale: {
|
|
84
|
+
mode: tailscaleMode,
|
|
85
|
+
path: tailscalePath,
|
|
86
|
+
target: tailscaleTarget,
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Build gog watch start arguments
|
|
93
|
+
*/
|
|
94
|
+
function buildWatchStartArgs(cfg) {
|
|
95
|
+
return [
|
|
96
|
+
'gmail',
|
|
97
|
+
'watch',
|
|
98
|
+
'start',
|
|
99
|
+
'--account',
|
|
100
|
+
cfg.account,
|
|
101
|
+
'--label',
|
|
102
|
+
cfg.label,
|
|
103
|
+
'--topic',
|
|
104
|
+
cfg.topic,
|
|
105
|
+
];
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Build gog watch serve arguments
|
|
109
|
+
*/
|
|
110
|
+
function buildWatchServeArgs(cfg) {
|
|
111
|
+
const args = [
|
|
112
|
+
'gmail',
|
|
113
|
+
'watch',
|
|
114
|
+
'serve',
|
|
115
|
+
'--account',
|
|
116
|
+
cfg.account,
|
|
117
|
+
'--bind',
|
|
118
|
+
cfg.serve.bind,
|
|
119
|
+
'--port',
|
|
120
|
+
String(cfg.serve.port),
|
|
121
|
+
'--path',
|
|
122
|
+
cfg.serve.path,
|
|
123
|
+
'--token',
|
|
124
|
+
cfg.pushToken,
|
|
125
|
+
'--hook-url',
|
|
126
|
+
cfg.hookUrl,
|
|
127
|
+
'--hook-token',
|
|
128
|
+
cfg.hookToken,
|
|
129
|
+
];
|
|
130
|
+
if (cfg.includeBody) {
|
|
131
|
+
args.push('--include-body');
|
|
132
|
+
}
|
|
133
|
+
if (cfg.maxBytes > 0) {
|
|
134
|
+
args.push('--max-bytes', String(cfg.maxBytes));
|
|
135
|
+
}
|
|
136
|
+
return args;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Start the Gmail watch (registers with Gmail API)
|
|
140
|
+
*/
|
|
141
|
+
async function startGmailWatch(cfg) {
|
|
142
|
+
const args = buildWatchStartArgs(cfg);
|
|
143
|
+
console.log(`[GmailWatcher] Starting watch: gog ${args.join(' ')}`);
|
|
144
|
+
try {
|
|
145
|
+
const result = await (0, process_1.runCommand)('gog', args, { timeoutMs: 120000 });
|
|
146
|
+
if (result.code !== 0) {
|
|
147
|
+
const message = result.stderr || result.stdout || 'gog watch start failed';
|
|
148
|
+
console.error(`[GmailWatcher] Watch start failed: ${message}`);
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
console.log(`[GmailWatcher] Watch started for ${cfg.account}`);
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
console.error(`[GmailWatcher] Watch start error: ${String(err)}`);
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Spawn the gog gmail watch serve process
|
|
161
|
+
*/
|
|
162
|
+
function spawnGogServe(cfg) {
|
|
163
|
+
const args = buildWatchServeArgs(cfg);
|
|
164
|
+
console.log(`[GmailWatcher] Starting serve: gog ${args.join(' ')}`);
|
|
165
|
+
let addressInUse = false;
|
|
166
|
+
const child = (0, child_process_1.spawn)('gog', args, {
|
|
167
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
168
|
+
detached: false,
|
|
169
|
+
});
|
|
170
|
+
child.stdout?.on('data', (data) => {
|
|
171
|
+
const line = data.toString().trim();
|
|
172
|
+
if (line)
|
|
173
|
+
console.log(`[GmailWatcher] [gog] ${line}`);
|
|
174
|
+
});
|
|
175
|
+
child.stderr?.on('data', (data) => {
|
|
176
|
+
const line = data.toString().trim();
|
|
177
|
+
if (!line)
|
|
178
|
+
return;
|
|
179
|
+
if (ADDRESS_IN_USE_RE.test(line)) {
|
|
180
|
+
addressInUse = true;
|
|
181
|
+
}
|
|
182
|
+
console.warn(`[GmailWatcher] [gog] ${line}`);
|
|
183
|
+
});
|
|
184
|
+
child.on('error', (err) => {
|
|
185
|
+
console.error(`[GmailWatcher] gog process error: ${String(err)}`);
|
|
186
|
+
});
|
|
187
|
+
child.on('exit', (code, signal) => {
|
|
188
|
+
if (shuttingDown)
|
|
189
|
+
return;
|
|
190
|
+
if (addressInUse) {
|
|
191
|
+
console.warn('[GmailWatcher] gog serve failed to bind (address already in use); stopping restarts. ' +
|
|
192
|
+
'Another watcher is likely running.');
|
|
193
|
+
watcherProcess = null;
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
console.warn(`[GmailWatcher] gog exited (code=${code}, signal=${signal}); restarting in 5s`);
|
|
197
|
+
watcherProcess = null;
|
|
198
|
+
setTimeout(() => {
|
|
199
|
+
if (shuttingDown || !currentConfig)
|
|
200
|
+
return;
|
|
201
|
+
watcherProcess = spawnGogServe(currentConfig);
|
|
202
|
+
}, 5000);
|
|
203
|
+
});
|
|
204
|
+
return child;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Start the Gmail watcher service.
|
|
208
|
+
* Called automatically by the app if hooks.gmail is configured.
|
|
209
|
+
*/
|
|
210
|
+
async function startGmailWatcher(config) {
|
|
211
|
+
// Check if gmail hooks are configured
|
|
212
|
+
if (!config.enabled) {
|
|
213
|
+
return { started: false, reason: 'hooks not enabled' };
|
|
214
|
+
}
|
|
215
|
+
if (!config.gmail?.account) {
|
|
216
|
+
return { started: false, reason: 'no gmail account configured' };
|
|
217
|
+
}
|
|
218
|
+
// Check if gog is available
|
|
219
|
+
const gogAvailable = await isGogAvailable();
|
|
220
|
+
if (!gogAvailable) {
|
|
221
|
+
return { started: false, reason: 'gog binary not found (install from gogcli.sh)' };
|
|
222
|
+
}
|
|
223
|
+
// Resolve the full runtime config
|
|
224
|
+
const resolved = resolveGmailRuntimeConfig(config);
|
|
225
|
+
if (!resolved.ok) {
|
|
226
|
+
return { started: false, reason: resolved.error };
|
|
227
|
+
}
|
|
228
|
+
const runtimeConfig = resolved.value;
|
|
229
|
+
// Check if watcher is already running
|
|
230
|
+
if (watcherProcess && currentConfig) {
|
|
231
|
+
// If same account, already running
|
|
232
|
+
if (currentConfig.account === runtimeConfig.account) {
|
|
233
|
+
console.log(`[GmailWatcher] Already running for ${runtimeConfig.account}`);
|
|
234
|
+
return { started: true };
|
|
235
|
+
}
|
|
236
|
+
// Different account - stop the old watcher first
|
|
237
|
+
console.log(`[GmailWatcher] Switching from ${currentConfig.account} to ${runtimeConfig.account}`);
|
|
238
|
+
await stopGmailWatcher();
|
|
239
|
+
}
|
|
240
|
+
currentConfig = runtimeConfig;
|
|
241
|
+
// Start the Gmail watch (register with Gmail API)
|
|
242
|
+
const watchStarted = await startGmailWatch(runtimeConfig);
|
|
243
|
+
if (!watchStarted) {
|
|
244
|
+
console.warn('[GmailWatcher] Gmail watch start failed, but continuing with serve');
|
|
245
|
+
}
|
|
246
|
+
// Spawn the gog serve process
|
|
247
|
+
shuttingDown = false;
|
|
248
|
+
watcherProcess = spawnGogServe(runtimeConfig);
|
|
249
|
+
// Set up renewal interval
|
|
250
|
+
const renewMs = runtimeConfig.renewEveryMinutes * 60000;
|
|
251
|
+
renewInterval = setInterval(() => {
|
|
252
|
+
if (shuttingDown)
|
|
253
|
+
return;
|
|
254
|
+
void startGmailWatch(runtimeConfig);
|
|
255
|
+
}, renewMs);
|
|
256
|
+
console.log(`[GmailWatcher] Gmail watcher started for ${runtimeConfig.account} (renew every ${runtimeConfig.renewEveryMinutes}m)`);
|
|
257
|
+
return { started: true };
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Stop the Gmail watcher service.
|
|
261
|
+
*/
|
|
262
|
+
async function stopGmailWatcher() {
|
|
263
|
+
shuttingDown = true;
|
|
264
|
+
if (renewInterval) {
|
|
265
|
+
clearInterval(renewInterval);
|
|
266
|
+
renewInterval = null;
|
|
267
|
+
}
|
|
268
|
+
if (watcherProcess) {
|
|
269
|
+
console.log('[GmailWatcher] Stopping Gmail watcher');
|
|
270
|
+
watcherProcess.kill('SIGTERM');
|
|
271
|
+
// Wait a bit for graceful shutdown
|
|
272
|
+
await new Promise((resolve) => {
|
|
273
|
+
const timeout = setTimeout(() => {
|
|
274
|
+
if (watcherProcess) {
|
|
275
|
+
watcherProcess.kill('SIGKILL');
|
|
276
|
+
}
|
|
277
|
+
resolve();
|
|
278
|
+
}, 3000);
|
|
279
|
+
watcherProcess?.on('exit', () => {
|
|
280
|
+
clearTimeout(timeout);
|
|
281
|
+
resolve();
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
watcherProcess = null;
|
|
285
|
+
}
|
|
286
|
+
currentConfig = null;
|
|
287
|
+
console.log('[GmailWatcher] Gmail watcher stopped');
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Check if the Gmail watcher is running.
|
|
291
|
+
*/
|
|
292
|
+
function isGmailWatcherRunning() {
|
|
293
|
+
return watcherProcess !== null && !shuttingDown;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Get the current Gmail runtime config (if running)
|
|
297
|
+
*/
|
|
298
|
+
function getGmailRuntimeConfig() {
|
|
299
|
+
return currentConfig;
|
|
300
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Hooks Module
|
|
4
|
+
*
|
|
5
|
+
* Webhook ingress for wake and isolated agent runs.
|
|
6
|
+
* Includes Gmail Pub/Sub integration.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
20
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.getGmailRuntimeConfig = exports.resolveGmailRuntimeConfig = exports.isGogAvailable = exports.isGmailWatcherRunning = exports.stopGmailWatcher = exports.startGmailWatcher = exports.resolveHooksConfig = exports.HooksServer = exports.normalizeHooksPath = exports.applyHookMappings = exports.resolveHookMappings = exports.generateHookToken = exports.HooksSettingsManager = void 0;
|
|
24
|
+
// Types
|
|
25
|
+
__exportStar(require("./types"), exports);
|
|
26
|
+
// Settings Manager
|
|
27
|
+
var settings_1 = require("./settings");
|
|
28
|
+
Object.defineProperty(exports, "HooksSettingsManager", { enumerable: true, get: function () { return settings_1.HooksSettingsManager; } });
|
|
29
|
+
Object.defineProperty(exports, "generateHookToken", { enumerable: true, get: function () { return settings_1.generateHookToken; } });
|
|
30
|
+
// Hook Mappings
|
|
31
|
+
var mappings_1 = require("./mappings");
|
|
32
|
+
Object.defineProperty(exports, "resolveHookMappings", { enumerable: true, get: function () { return mappings_1.resolveHookMappings; } });
|
|
33
|
+
Object.defineProperty(exports, "applyHookMappings", { enumerable: true, get: function () { return mappings_1.applyHookMappings; } });
|
|
34
|
+
Object.defineProperty(exports, "normalizeHooksPath", { enumerable: true, get: function () { return mappings_1.normalizeHooksPath; } });
|
|
35
|
+
// Webhook Server
|
|
36
|
+
var server_1 = require("./server");
|
|
37
|
+
Object.defineProperty(exports, "HooksServer", { enumerable: true, get: function () { return server_1.HooksServer; } });
|
|
38
|
+
Object.defineProperty(exports, "resolveHooksConfig", { enumerable: true, get: function () { return server_1.resolveHooksConfig; } });
|
|
39
|
+
// Gmail Watcher
|
|
40
|
+
var gmail_watcher_1 = require("./gmail-watcher");
|
|
41
|
+
Object.defineProperty(exports, "startGmailWatcher", { enumerable: true, get: function () { return gmail_watcher_1.startGmailWatcher; } });
|
|
42
|
+
Object.defineProperty(exports, "stopGmailWatcher", { enumerable: true, get: function () { return gmail_watcher_1.stopGmailWatcher; } });
|
|
43
|
+
Object.defineProperty(exports, "isGmailWatcherRunning", { enumerable: true, get: function () { return gmail_watcher_1.isGmailWatcherRunning; } });
|
|
44
|
+
Object.defineProperty(exports, "isGogAvailable", { enumerable: true, get: function () { return gmail_watcher_1.isGogAvailable; } });
|
|
45
|
+
Object.defineProperty(exports, "resolveGmailRuntimeConfig", { enumerable: true, get: function () { return gmail_watcher_1.resolveGmailRuntimeConfig; } });
|
|
46
|
+
Object.defineProperty(exports, "getGmailRuntimeConfig", { enumerable: true, get: function () { return gmail_watcher_1.getGmailRuntimeConfig; } });
|