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,435 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Security Policy Manager
|
|
4
|
+
*
|
|
5
|
+
* Implements monotonic policy precedence (deny-wins) for tool access control.
|
|
6
|
+
*
|
|
7
|
+
* Policy layers (evaluated in order):
|
|
8
|
+
* 1. Global Guardrails (blocked commands, patterns)
|
|
9
|
+
* 2. Workspace Permissions (read, write, delete, shell, network)
|
|
10
|
+
* 3. Context Restrictions (private/group/public channel context)
|
|
11
|
+
* 4. Tool-Specific Rules (per-tool overrides)
|
|
12
|
+
*
|
|
13
|
+
* Key invariant: Once a tool is denied by an earlier layer, later layers CANNOT re-enable it.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.SecurityPolicyManager = void 0;
|
|
17
|
+
exports.createPolicyManager = createPolicyManager;
|
|
18
|
+
exports.isToolAllowedQuick = isToolAllowedQuick;
|
|
19
|
+
const types_1 = require("../../shared/types");
|
|
20
|
+
/**
|
|
21
|
+
* Security Policy Manager implementing monotonic deny-wins precedence
|
|
22
|
+
*/
|
|
23
|
+
class SecurityPolicyManager {
|
|
24
|
+
constructor(context) {
|
|
25
|
+
this.context = context;
|
|
26
|
+
this.deniedTools = new Set();
|
|
27
|
+
this.approvalRequiredTools = new Set();
|
|
28
|
+
this.layerDecisions = new Map();
|
|
29
|
+
this.evaluateAllPolicies();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Check if a tool is allowed to execute
|
|
33
|
+
* Implements C2: Approval Gate Enforcement
|
|
34
|
+
*/
|
|
35
|
+
checkToolAccess(toolName, input) {
|
|
36
|
+
// Check if tool was denied by any layer
|
|
37
|
+
if (this.deniedTools.has(toolName)) {
|
|
38
|
+
const decisions = this.layerDecisions.get(toolName) || [];
|
|
39
|
+
const denyDecision = decisions.find(d => d.decision === 'deny');
|
|
40
|
+
return {
|
|
41
|
+
allowed: false,
|
|
42
|
+
reason: denyDecision?.reason || `Tool "${toolName}" is not permitted`,
|
|
43
|
+
deniedBy: denyDecision?.layer,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
// Check if tool requires approval
|
|
47
|
+
if (this.approvalRequiredTools.has(toolName)) {
|
|
48
|
+
const decisions = this.layerDecisions.get(toolName) || [];
|
|
49
|
+
const approvalDecision = decisions.find(d => d.decision === 'require_approval');
|
|
50
|
+
return {
|
|
51
|
+
allowed: true,
|
|
52
|
+
requiresApproval: true,
|
|
53
|
+
approvalReason: approvalDecision?.reason || `Tool "${toolName}" requires approval`,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
// Tool-specific input validation for shell commands
|
|
57
|
+
if (toolName === 'run_command' && input?.command) {
|
|
58
|
+
const commandCheck = this.checkCommandPolicy(input.command);
|
|
59
|
+
if (!commandCheck.allowed) {
|
|
60
|
+
return commandCheck;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return { allowed: true };
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Check if a command is allowed by guardrails
|
|
67
|
+
*/
|
|
68
|
+
checkCommandPolicy(command) {
|
|
69
|
+
const { guardrails } = this.context;
|
|
70
|
+
// Check blocked patterns (always denied, cannot be overridden)
|
|
71
|
+
if (guardrails.blockDangerousCommands) {
|
|
72
|
+
const allBlockedPatterns = [
|
|
73
|
+
...getDefaultBlockedPatterns(),
|
|
74
|
+
...guardrails.customBlockedPatterns,
|
|
75
|
+
];
|
|
76
|
+
for (const pattern of allBlockedPatterns) {
|
|
77
|
+
try {
|
|
78
|
+
const regex = new RegExp(pattern, 'i');
|
|
79
|
+
if (regex.test(command)) {
|
|
80
|
+
return {
|
|
81
|
+
allowed: false,
|
|
82
|
+
reason: `Command blocked by security policy: matches pattern "${pattern}"`,
|
|
83
|
+
deniedBy: 'global_guardrails',
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// Invalid regex pattern, skip
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Check trusted patterns (auto-approve)
|
|
93
|
+
// NOTE: Trusted patterns can NEVER override a deny - they only affect approval requirement
|
|
94
|
+
if (guardrails.autoApproveTrustedCommands) {
|
|
95
|
+
for (const pattern of guardrails.trustedCommandPatterns) {
|
|
96
|
+
if (matchGlobPattern(command, pattern)) {
|
|
97
|
+
return {
|
|
98
|
+
allowed: true,
|
|
99
|
+
requiresApproval: false,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Default: requires approval for shell commands
|
|
105
|
+
return {
|
|
106
|
+
allowed: true,
|
|
107
|
+
requiresApproval: true,
|
|
108
|
+
approvalReason: 'Shell commands require approval',
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Get all denied tools
|
|
113
|
+
*/
|
|
114
|
+
getDeniedTools() {
|
|
115
|
+
return Array.from(this.deniedTools);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Get all tools requiring approval
|
|
119
|
+
*/
|
|
120
|
+
getApprovalRequiredTools() {
|
|
121
|
+
return Array.from(this.approvalRequiredTools);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get policy decisions for a tool (for debugging/audit)
|
|
125
|
+
*/
|
|
126
|
+
getToolDecisions(toolName) {
|
|
127
|
+
return this.layerDecisions.get(toolName) || [];
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Expand a tool group to individual tools
|
|
131
|
+
* Implements C4: Tool Group Expansion Accuracy
|
|
132
|
+
*/
|
|
133
|
+
static expandToolGroup(groupName) {
|
|
134
|
+
return types_1.TOOL_GROUPS[groupName] || [];
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Check if a tool belongs to a group
|
|
138
|
+
*/
|
|
139
|
+
static isToolInGroup(toolName, groupName) {
|
|
140
|
+
const tools = types_1.TOOL_GROUPS[groupName];
|
|
141
|
+
return tools ? tools.includes(toolName) : false;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Get risk level for a tool
|
|
145
|
+
*/
|
|
146
|
+
static getToolRiskLevel(toolName) {
|
|
147
|
+
return types_1.TOOL_RISK_LEVELS[toolName];
|
|
148
|
+
}
|
|
149
|
+
// Private methods
|
|
150
|
+
/**
|
|
151
|
+
* Evaluate all policy layers and build the denied/approval-required sets
|
|
152
|
+
* Key invariant: Once denied, a tool stays denied (monotonic)
|
|
153
|
+
*/
|
|
154
|
+
evaluateAllPolicies() {
|
|
155
|
+
const allTools = this.getAllKnownTools();
|
|
156
|
+
for (const toolName of allTools) {
|
|
157
|
+
const decisions = [];
|
|
158
|
+
// Layer 1: Global Guardrails
|
|
159
|
+
const guardrailDecision = this.evaluateGuardrailLayer(toolName);
|
|
160
|
+
decisions.push(guardrailDecision);
|
|
161
|
+
if (guardrailDecision.decision === 'deny') {
|
|
162
|
+
this.deniedTools.add(toolName);
|
|
163
|
+
this.layerDecisions.set(toolName, decisions);
|
|
164
|
+
continue; // Monotonic: skip remaining layers
|
|
165
|
+
}
|
|
166
|
+
// Layer 2: Workspace Permissions
|
|
167
|
+
const workspaceDecision = this.evaluateWorkspaceLayer(toolName);
|
|
168
|
+
decisions.push(workspaceDecision);
|
|
169
|
+
if (workspaceDecision.decision === 'deny') {
|
|
170
|
+
this.deniedTools.add(toolName);
|
|
171
|
+
this.layerDecisions.set(toolName, decisions);
|
|
172
|
+
continue; // Monotonic: skip remaining layers
|
|
173
|
+
}
|
|
174
|
+
// Layer 3: Context Restrictions (if gateway context is set)
|
|
175
|
+
if (this.context.gatewayContext) {
|
|
176
|
+
const contextDecision = this.evaluateContextLayer(toolName);
|
|
177
|
+
decisions.push(contextDecision);
|
|
178
|
+
if (contextDecision.decision === 'deny') {
|
|
179
|
+
this.deniedTools.add(toolName);
|
|
180
|
+
this.layerDecisions.set(toolName, decisions);
|
|
181
|
+
continue; // Monotonic: skip remaining layers
|
|
182
|
+
}
|
|
183
|
+
if (contextDecision.decision === 'require_approval') {
|
|
184
|
+
this.approvalRequiredTools.add(toolName);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
// Layer 4: Tool-Specific Rules
|
|
188
|
+
const toolSpecificDecision = this.evaluateToolSpecificLayer(toolName);
|
|
189
|
+
decisions.push(toolSpecificDecision);
|
|
190
|
+
if (toolSpecificDecision.decision === 'deny') {
|
|
191
|
+
this.deniedTools.add(toolName);
|
|
192
|
+
}
|
|
193
|
+
else if (toolSpecificDecision.decision === 'require_approval') {
|
|
194
|
+
this.approvalRequiredTools.add(toolName);
|
|
195
|
+
}
|
|
196
|
+
this.layerDecisions.set(toolName, decisions);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Layer 1: Global Guardrails
|
|
201
|
+
*/
|
|
202
|
+
evaluateGuardrailLayer(toolName) {
|
|
203
|
+
const { guardrails } = this.context;
|
|
204
|
+
// Network tools require network to be allowed in guardrails
|
|
205
|
+
if (SecurityPolicyManager.isToolInGroup(toolName, 'group:network')) {
|
|
206
|
+
if (guardrails.enforceAllowedDomains && guardrails.allowedDomains.length === 0) {
|
|
207
|
+
return {
|
|
208
|
+
layer: 'global_guardrails',
|
|
209
|
+
decision: 'deny',
|
|
210
|
+
reason: 'Network tools blocked: no allowed domains configured',
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return { layer: 'global_guardrails', decision: 'pass' };
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Layer 2: Workspace Permissions
|
|
218
|
+
*/
|
|
219
|
+
evaluateWorkspaceLayer(toolName) {
|
|
220
|
+
const { workspace } = this.context;
|
|
221
|
+
const permissions = workspace.permissions;
|
|
222
|
+
// Check read permission
|
|
223
|
+
if (SecurityPolicyManager.isToolInGroup(toolName, 'group:read')) {
|
|
224
|
+
if (!permissions.read) {
|
|
225
|
+
return {
|
|
226
|
+
layer: 'workspace_permissions',
|
|
227
|
+
decision: 'deny',
|
|
228
|
+
reason: 'Workspace does not have read permission',
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// Check write permission
|
|
233
|
+
if (SecurityPolicyManager.isToolInGroup(toolName, 'group:write')) {
|
|
234
|
+
if (!permissions.write) {
|
|
235
|
+
return {
|
|
236
|
+
layer: 'workspace_permissions',
|
|
237
|
+
decision: 'deny',
|
|
238
|
+
reason: 'Workspace does not have write permission',
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// Check delete permission
|
|
243
|
+
if (toolName === 'delete_file') {
|
|
244
|
+
if (!permissions.delete) {
|
|
245
|
+
return {
|
|
246
|
+
layer: 'workspace_permissions',
|
|
247
|
+
decision: 'require_approval',
|
|
248
|
+
reason: 'File deletion requires approval (delete permission not granted)',
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
// Check shell permission
|
|
253
|
+
if (toolName === 'run_command') {
|
|
254
|
+
if (!permissions.shell) {
|
|
255
|
+
return {
|
|
256
|
+
layer: 'workspace_permissions',
|
|
257
|
+
decision: 'deny',
|
|
258
|
+
reason: 'Workspace does not have shell permission',
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
// Shell commands always require approval even with permission
|
|
262
|
+
return {
|
|
263
|
+
layer: 'workspace_permissions',
|
|
264
|
+
decision: 'require_approval',
|
|
265
|
+
reason: 'Shell commands require approval',
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
// Check network permission
|
|
269
|
+
if (SecurityPolicyManager.isToolInGroup(toolName, 'group:network')) {
|
|
270
|
+
if (!permissions.network) {
|
|
271
|
+
return {
|
|
272
|
+
layer: 'workspace_permissions',
|
|
273
|
+
decision: 'deny',
|
|
274
|
+
reason: 'Workspace does not have network permission',
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return { layer: 'workspace_permissions', decision: 'pass' };
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Layer 3: Context Restrictions (Gateway context)
|
|
282
|
+
* Implements C1: Memory Tool Isolation in Shared Contexts
|
|
283
|
+
*/
|
|
284
|
+
evaluateContextLayer(toolName) {
|
|
285
|
+
const contextType = this.context.gatewayContext;
|
|
286
|
+
if (!contextType) {
|
|
287
|
+
return { layer: 'context_restrictions', decision: 'pass' };
|
|
288
|
+
}
|
|
289
|
+
const restrictions = types_1.CONTEXT_TOOL_RESTRICTIONS[contextType];
|
|
290
|
+
// Check if tool is explicitly denied
|
|
291
|
+
if (restrictions.deniedTools.includes(toolName)) {
|
|
292
|
+
return {
|
|
293
|
+
layer: 'context_restrictions',
|
|
294
|
+
decision: 'deny',
|
|
295
|
+
reason: `Tool "${toolName}" is not allowed in ${contextType} context`,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
// Check if tool's group is denied
|
|
299
|
+
for (const groupName of restrictions.deniedGroups) {
|
|
300
|
+
if (SecurityPolicyManager.isToolInGroup(toolName, groupName)) {
|
|
301
|
+
return {
|
|
302
|
+
layer: 'context_restrictions',
|
|
303
|
+
decision: 'deny',
|
|
304
|
+
reason: `Tool group "${groupName}" is not allowed in ${contextType} context`,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
// Check if tool requires approval in this context
|
|
309
|
+
if (restrictions.requireApprovalFor.includes(toolName)) {
|
|
310
|
+
return {
|
|
311
|
+
layer: 'context_restrictions',
|
|
312
|
+
decision: 'require_approval',
|
|
313
|
+
reason: `Tool "${toolName}" requires approval in ${contextType} context`,
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
return { layer: 'context_restrictions', decision: 'pass' };
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Layer 4: Tool-Specific Rules
|
|
320
|
+
*/
|
|
321
|
+
evaluateToolSpecificLayer(toolName) {
|
|
322
|
+
// Destructive tools always require approval
|
|
323
|
+
const riskLevel = SecurityPolicyManager.getToolRiskLevel(toolName);
|
|
324
|
+
if (riskLevel === 'destructive') {
|
|
325
|
+
return {
|
|
326
|
+
layer: 'tool_specific',
|
|
327
|
+
decision: 'require_approval',
|
|
328
|
+
reason: `Destructive tool "${toolName}" requires approval`,
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
return { layer: 'tool_specific', decision: 'pass' };
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Get all known tool names
|
|
335
|
+
*/
|
|
336
|
+
getAllKnownTools() {
|
|
337
|
+
const tools = new Set();
|
|
338
|
+
// Add all tools from groups
|
|
339
|
+
for (const groupTools of Object.values(types_1.TOOL_GROUPS)) {
|
|
340
|
+
for (const tool of groupTools) {
|
|
341
|
+
tools.add(tool);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
// Add tools from TOOL_RISK_LEVELS
|
|
345
|
+
for (const tool of Object.keys(types_1.TOOL_RISK_LEVELS)) {
|
|
346
|
+
tools.add(tool);
|
|
347
|
+
}
|
|
348
|
+
return Array.from(tools);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
exports.SecurityPolicyManager = SecurityPolicyManager;
|
|
352
|
+
/**
|
|
353
|
+
* Default blocked command patterns (security-critical)
|
|
354
|
+
*/
|
|
355
|
+
function getDefaultBlockedPatterns() {
|
|
356
|
+
return [
|
|
357
|
+
'sudo',
|
|
358
|
+
'rm\\s+-rf\\s+/',
|
|
359
|
+
'rm\\s+-rf\\s+~',
|
|
360
|
+
'rm\\s+-rf\\s+/\\*',
|
|
361
|
+
'rm\\s+-rf\\s+\\*',
|
|
362
|
+
'mkfs',
|
|
363
|
+
'dd\\s+if=',
|
|
364
|
+
':\\(\\)\\{\\s*:\\|:\\&\\s*\\};:', // Fork bomb
|
|
365
|
+
'curl.*\\|.*bash',
|
|
366
|
+
'wget.*\\|.*bash',
|
|
367
|
+
'curl.*\\|.*sh',
|
|
368
|
+
'wget.*\\|.*sh',
|
|
369
|
+
'chmod\\s+777',
|
|
370
|
+
'>\\s*/dev/sd',
|
|
371
|
+
'mv\\s+/\\*',
|
|
372
|
+
'format\\s+c:',
|
|
373
|
+
'del\\s+/f\\s+/s\\s+/q',
|
|
374
|
+
];
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Match a command against a glob-like pattern
|
|
378
|
+
*/
|
|
379
|
+
function matchGlobPattern(command, pattern) {
|
|
380
|
+
// Convert glob pattern to regex
|
|
381
|
+
const regexPattern = pattern
|
|
382
|
+
.replace(/[.+^${}()|[\]\\]/g, '\\$&') // Escape special chars except * and ?
|
|
383
|
+
.replace(/\*/g, '.*')
|
|
384
|
+
.replace(/\?/g, '.');
|
|
385
|
+
try {
|
|
386
|
+
const regex = new RegExp(`^${regexPattern}$`, 'i');
|
|
387
|
+
return regex.test(command);
|
|
388
|
+
}
|
|
389
|
+
catch {
|
|
390
|
+
return false;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Create a policy manager for a workspace context
|
|
395
|
+
*/
|
|
396
|
+
function createPolicyManager(workspace, guardrails, gatewayContext) {
|
|
397
|
+
return new SecurityPolicyManager({
|
|
398
|
+
workspace,
|
|
399
|
+
guardrails,
|
|
400
|
+
gatewayContext,
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Quick check if a tool is allowed (without full policy evaluation)
|
|
405
|
+
* Use for filtering tool lists before presenting to LLM
|
|
406
|
+
*/
|
|
407
|
+
function isToolAllowedQuick(toolName, workspace, gatewayContext) {
|
|
408
|
+
const permissions = workspace.permissions;
|
|
409
|
+
// Check basic permissions
|
|
410
|
+
if (SecurityPolicyManager.isToolInGroup(toolName, 'group:read') && !permissions.read) {
|
|
411
|
+
return false;
|
|
412
|
+
}
|
|
413
|
+
if (SecurityPolicyManager.isToolInGroup(toolName, 'group:write') && !permissions.write) {
|
|
414
|
+
return false;
|
|
415
|
+
}
|
|
416
|
+
if (toolName === 'run_command' && !permissions.shell) {
|
|
417
|
+
return false;
|
|
418
|
+
}
|
|
419
|
+
if (SecurityPolicyManager.isToolInGroup(toolName, 'group:network') && !permissions.network) {
|
|
420
|
+
return false;
|
|
421
|
+
}
|
|
422
|
+
// Check context restrictions
|
|
423
|
+
if (gatewayContext) {
|
|
424
|
+
const restrictions = types_1.CONTEXT_TOOL_RESTRICTIONS[gatewayContext];
|
|
425
|
+
if (restrictions.deniedTools.includes(toolName)) {
|
|
426
|
+
return false;
|
|
427
|
+
}
|
|
428
|
+
for (const groupName of restrictions.deniedGroups) {
|
|
429
|
+
if (SecurityPolicyManager.isToolInGroup(toolName, groupName)) {
|
|
430
|
+
return false;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
return true;
|
|
435
|
+
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Appearance Settings Manager
|
|
4
|
+
*
|
|
5
|
+
* Manages user appearance preferences (theme and accent color).
|
|
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.AppearanceManager = void 0;
|
|
43
|
+
const electron_1 = require("electron");
|
|
44
|
+
const fs = __importStar(require("fs"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
const SecureSettingsRepository_1 = require("../database/SecureSettingsRepository");
|
|
47
|
+
const LEGACY_SETTINGS_FILE = 'appearance-settings.json';
|
|
48
|
+
const DEFAULT_SETTINGS = {
|
|
49
|
+
themeMode: 'dark',
|
|
50
|
+
accentColor: 'cyan',
|
|
51
|
+
disclaimerAccepted: false,
|
|
52
|
+
onboardingCompleted: false,
|
|
53
|
+
onboardingCompletedAt: undefined,
|
|
54
|
+
};
|
|
55
|
+
class AppearanceManager {
|
|
56
|
+
/**
|
|
57
|
+
* Initialize the AppearanceManager
|
|
58
|
+
*/
|
|
59
|
+
static initialize() {
|
|
60
|
+
const userDataPath = electron_1.app.getPath('userData');
|
|
61
|
+
this.legacySettingsPath = path.join(userDataPath, LEGACY_SETTINGS_FILE);
|
|
62
|
+
console.log('[AppearanceManager] Initialized');
|
|
63
|
+
// Migrate from legacy JSON file to encrypted database
|
|
64
|
+
this.migrateFromLegacyFile();
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Migrate settings from legacy JSON file to encrypted database
|
|
68
|
+
*/
|
|
69
|
+
static migrateFromLegacyFile() {
|
|
70
|
+
if (this.migrationCompleted)
|
|
71
|
+
return;
|
|
72
|
+
try {
|
|
73
|
+
// Check if SecureSettingsRepository is initialized
|
|
74
|
+
if (!SecureSettingsRepository_1.SecureSettingsRepository.isInitialized()) {
|
|
75
|
+
console.log('[AppearanceManager] SecureSettingsRepository not yet initialized, skipping migration');
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const repository = SecureSettingsRepository_1.SecureSettingsRepository.getInstance();
|
|
79
|
+
// Check if already migrated to database
|
|
80
|
+
if (repository.exists('appearance')) {
|
|
81
|
+
this.migrationCompleted = true;
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
// Check if legacy file exists
|
|
85
|
+
if (!fs.existsSync(this.legacySettingsPath)) {
|
|
86
|
+
console.log('[AppearanceManager] No legacy settings file found');
|
|
87
|
+
this.migrationCompleted = true;
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
console.log('[AppearanceManager] Migrating settings from legacy JSON file to encrypted database...');
|
|
91
|
+
// Create backup before migration
|
|
92
|
+
const backupPath = this.legacySettingsPath + '.migration-backup';
|
|
93
|
+
fs.copyFileSync(this.legacySettingsPath, backupPath);
|
|
94
|
+
try {
|
|
95
|
+
// Read legacy settings
|
|
96
|
+
const data = fs.readFileSync(this.legacySettingsPath, 'utf-8');
|
|
97
|
+
const parsed = JSON.parse(data);
|
|
98
|
+
const legacySettings = { ...DEFAULT_SETTINGS, ...parsed };
|
|
99
|
+
// Save to encrypted database
|
|
100
|
+
repository.save('appearance', legacySettings);
|
|
101
|
+
console.log('[AppearanceManager] Settings migrated to encrypted database');
|
|
102
|
+
// Migration successful - delete backup and original
|
|
103
|
+
fs.unlinkSync(backupPath);
|
|
104
|
+
fs.unlinkSync(this.legacySettingsPath);
|
|
105
|
+
console.log('[AppearanceManager] Migration complete, cleaned up legacy files');
|
|
106
|
+
this.migrationCompleted = true;
|
|
107
|
+
}
|
|
108
|
+
catch (migrationError) {
|
|
109
|
+
console.error('[AppearanceManager] Migration failed, backup preserved at:', backupPath);
|
|
110
|
+
throw migrationError;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
console.error('[AppearanceManager] Migration failed:', error);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Load settings from encrypted database (with caching)
|
|
119
|
+
*/
|
|
120
|
+
static loadSettings() {
|
|
121
|
+
if (this.cachedSettings) {
|
|
122
|
+
return this.cachedSettings;
|
|
123
|
+
}
|
|
124
|
+
let settings = { ...DEFAULT_SETTINGS };
|
|
125
|
+
try {
|
|
126
|
+
// Try to load from encrypted database
|
|
127
|
+
if (SecureSettingsRepository_1.SecureSettingsRepository.isInitialized()) {
|
|
128
|
+
const repository = SecureSettingsRepository_1.SecureSettingsRepository.getInstance();
|
|
129
|
+
const stored = repository.load('appearance');
|
|
130
|
+
if (stored) {
|
|
131
|
+
settings = { ...DEFAULT_SETTINGS, ...stored };
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Validate values
|
|
135
|
+
if (!isValidThemeMode(settings.themeMode)) {
|
|
136
|
+
settings.themeMode = DEFAULT_SETTINGS.themeMode;
|
|
137
|
+
}
|
|
138
|
+
if (!isValidAccentColor(settings.accentColor)) {
|
|
139
|
+
settings.accentColor = DEFAULT_SETTINGS.accentColor;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
console.error('[AppearanceManager] Failed to load settings:', error);
|
|
144
|
+
settings = { ...DEFAULT_SETTINGS };
|
|
145
|
+
}
|
|
146
|
+
this.cachedSettings = settings;
|
|
147
|
+
return settings;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Save settings to encrypted database
|
|
151
|
+
*/
|
|
152
|
+
static saveSettings(settings) {
|
|
153
|
+
try {
|
|
154
|
+
if (!SecureSettingsRepository_1.SecureSettingsRepository.isInitialized()) {
|
|
155
|
+
throw new Error('SecureSettingsRepository not initialized');
|
|
156
|
+
}
|
|
157
|
+
// Load existing settings to preserve fields not being updated
|
|
158
|
+
const existingSettings = this.loadSettings();
|
|
159
|
+
// Validate and merge with existing settings
|
|
160
|
+
const validatedSettings = {
|
|
161
|
+
themeMode: isValidThemeMode(settings.themeMode) ? settings.themeMode : existingSettings.themeMode,
|
|
162
|
+
accentColor: isValidAccentColor(settings.accentColor) ? settings.accentColor : existingSettings.accentColor,
|
|
163
|
+
disclaimerAccepted: settings.disclaimerAccepted ?? existingSettings.disclaimerAccepted,
|
|
164
|
+
onboardingCompleted: settings.onboardingCompleted ?? existingSettings.onboardingCompleted,
|
|
165
|
+
onboardingCompletedAt: settings.onboardingCompletedAt ?? existingSettings.onboardingCompletedAt,
|
|
166
|
+
};
|
|
167
|
+
const repository = SecureSettingsRepository_1.SecureSettingsRepository.getInstance();
|
|
168
|
+
repository.save('appearance', validatedSettings);
|
|
169
|
+
this.cachedSettings = validatedSettings;
|
|
170
|
+
console.log('[AppearanceManager] Settings saved to encrypted database');
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
console.error('[AppearanceManager] Failed to save settings:', error);
|
|
174
|
+
throw error;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Clear the settings cache
|
|
179
|
+
*/
|
|
180
|
+
static clearCache() {
|
|
181
|
+
this.cachedSettings = null;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
exports.AppearanceManager = AppearanceManager;
|
|
185
|
+
AppearanceManager.cachedSettings = null;
|
|
186
|
+
AppearanceManager.migrationCompleted = false;
|
|
187
|
+
function isValidThemeMode(value) {
|
|
188
|
+
return value === 'light' || value === 'dark' || value === 'system';
|
|
189
|
+
}
|
|
190
|
+
function isValidAccentColor(value) {
|
|
191
|
+
const validColors = ['cyan', 'blue', 'purple', 'pink', 'rose', 'orange', 'green', 'teal'];
|
|
192
|
+
return validColors.includes(value);
|
|
193
|
+
}
|