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,258 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Security Utilities for Sandbox Operations
|
|
4
|
+
*
|
|
5
|
+
* Provides secure implementations for common operations:
|
|
6
|
+
* - Secure temp file creation (TOCTOU-safe)
|
|
7
|
+
* - Path validation with symlink resolution
|
|
8
|
+
* - String escaping for sandbox profiles
|
|
9
|
+
*/
|
|
10
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
13
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
14
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
15
|
+
}
|
|
16
|
+
Object.defineProperty(o, k2, desc);
|
|
17
|
+
}) : (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
o[k2] = m[k];
|
|
20
|
+
}));
|
|
21
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
22
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
23
|
+
}) : function(o, v) {
|
|
24
|
+
o["default"] = v;
|
|
25
|
+
});
|
|
26
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
27
|
+
var ownKeys = function(o) {
|
|
28
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
29
|
+
var ar = [];
|
|
30
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
31
|
+
return ar;
|
|
32
|
+
};
|
|
33
|
+
return ownKeys(o);
|
|
34
|
+
};
|
|
35
|
+
return function (mod) {
|
|
36
|
+
if (mod && mod.__esModule) return mod;
|
|
37
|
+
var result = {};
|
|
38
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
39
|
+
__setModuleDefault(result, mod);
|
|
40
|
+
return result;
|
|
41
|
+
};
|
|
42
|
+
})();
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.createSecureTempFile = createSecureTempFile;
|
|
45
|
+
exports.validateAndResolvePath = validateAndResolvePath;
|
|
46
|
+
exports.escapeSandboxProfileString = escapeSandboxProfileString;
|
|
47
|
+
exports.validatePathForSandboxProfile = validatePathForSandboxProfile;
|
|
48
|
+
exports.escapeDockerEnvValue = escapeDockerEnvValue;
|
|
49
|
+
exports.validateEnvVarName = validateEnvVarName;
|
|
50
|
+
exports.buildSafeEnvironment = buildSafeEnvironment;
|
|
51
|
+
const fs = __importStar(require("fs"));
|
|
52
|
+
const path = __importStar(require("path"));
|
|
53
|
+
const os = __importStar(require("os"));
|
|
54
|
+
const crypto = __importStar(require("crypto"));
|
|
55
|
+
/**
|
|
56
|
+
* Create a secure temporary file with random name
|
|
57
|
+
* Uses crypto.randomBytes to prevent predictable filenames (TOCTOU mitigation)
|
|
58
|
+
*
|
|
59
|
+
* @param extension - File extension (e.g., '.py', '.js')
|
|
60
|
+
* @param content - Content to write to the file
|
|
61
|
+
* @returns Object with file path and cleanup function
|
|
62
|
+
*/
|
|
63
|
+
function createSecureTempFile(extension, content) {
|
|
64
|
+
// Generate cryptographically random filename
|
|
65
|
+
const randomBytes = crypto.randomBytes(16).toString('hex');
|
|
66
|
+
const filename = `cowork_${randomBytes}${extension}`;
|
|
67
|
+
const tempDir = os.tmpdir();
|
|
68
|
+
// Validate temp directory exists and is writable
|
|
69
|
+
if (!fs.existsSync(tempDir)) {
|
|
70
|
+
throw new Error(`Temp directory does not exist: ${tempDir}`);
|
|
71
|
+
}
|
|
72
|
+
const filePath = path.join(tempDir, filename);
|
|
73
|
+
// Use O_CREAT | O_EXCL to atomically create file (fails if exists)
|
|
74
|
+
// This prevents TOCTOU race conditions
|
|
75
|
+
const fd = fs.openSync(filePath, fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_WRONLY, 0o600);
|
|
76
|
+
try {
|
|
77
|
+
fs.writeSync(fd, content, 0, 'utf8');
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
fs.closeSync(fd);
|
|
81
|
+
}
|
|
82
|
+
const cleanup = () => {
|
|
83
|
+
try {
|
|
84
|
+
if (fs.existsSync(filePath)) {
|
|
85
|
+
fs.unlinkSync(filePath);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// Ignore cleanup errors
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
return { filePath, cleanup };
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Validate and resolve a path, following symlinks
|
|
96
|
+
* Returns null if path is outside allowed boundaries
|
|
97
|
+
*
|
|
98
|
+
* @param targetPath - Path to validate
|
|
99
|
+
* @param allowedBasePaths - List of allowed base paths
|
|
100
|
+
* @returns Resolved real path or null if invalid/outside boundaries
|
|
101
|
+
*/
|
|
102
|
+
function validateAndResolvePath(targetPath, allowedBasePaths) {
|
|
103
|
+
// Reject paths with null bytes (path traversal attack vector)
|
|
104
|
+
if (targetPath.includes('\0')) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
// Normalize the path first
|
|
108
|
+
const normalizedTarget = path.normalize(targetPath);
|
|
109
|
+
// Check if path exists before attempting to resolve symlinks
|
|
110
|
+
if (!fs.existsSync(normalizedTarget)) {
|
|
111
|
+
// For non-existent paths, just validate against normalized path
|
|
112
|
+
for (const basePath of allowedBasePaths) {
|
|
113
|
+
const normalizedBase = path.resolve(basePath);
|
|
114
|
+
if (path.resolve(normalizedTarget).startsWith(normalizedBase + path.sep) ||
|
|
115
|
+
path.resolve(normalizedTarget) === normalizedBase) {
|
|
116
|
+
return path.resolve(normalizedTarget);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
// Resolve symlinks to get real path
|
|
123
|
+
const realPath = fs.realpathSync(normalizedTarget);
|
|
124
|
+
// Check if real path is within allowed boundaries
|
|
125
|
+
for (const basePath of allowedBasePaths) {
|
|
126
|
+
const realBasePath = fs.existsSync(basePath)
|
|
127
|
+
? fs.realpathSync(basePath)
|
|
128
|
+
: path.resolve(basePath);
|
|
129
|
+
if (realPath.startsWith(realBasePath + path.sep) || realPath === realBasePath) {
|
|
130
|
+
return realPath;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
// If we can't resolve the path, it's not valid
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Escape a string for use in macOS sandbox-exec profile
|
|
142
|
+
* Prevents sandbox profile injection attacks
|
|
143
|
+
*
|
|
144
|
+
* @param input - String to escape
|
|
145
|
+
* @returns Escaped string safe for sandbox profile
|
|
146
|
+
*/
|
|
147
|
+
function escapeSandboxProfileString(input) {
|
|
148
|
+
// Validate input doesn't contain null bytes
|
|
149
|
+
if (input.includes('\0')) {
|
|
150
|
+
throw new Error('Path contains null byte, which is not allowed');
|
|
151
|
+
}
|
|
152
|
+
// Escape characters that have special meaning in sandbox profiles:
|
|
153
|
+
// - Backslash: escape character
|
|
154
|
+
// - Double quote: string delimiter
|
|
155
|
+
// - Parentheses: LISP-like syntax
|
|
156
|
+
// - Semicolon: comment start
|
|
157
|
+
return input
|
|
158
|
+
.replace(/\\/g, '\\\\') // Escape backslashes first
|
|
159
|
+
.replace(/"/g, '\\"') // Escape double quotes
|
|
160
|
+
.replace(/\(/g, '\\(') // Escape open paren
|
|
161
|
+
.replace(/\)/g, '\\)') // Escape close paren
|
|
162
|
+
.replace(/;/g, '\\;'); // Escape semicolons
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Validate a path is safe for sandbox profile inclusion
|
|
166
|
+
* Rejects paths with dangerous characters that could break profile syntax
|
|
167
|
+
*
|
|
168
|
+
* @param pathToValidate - Path to validate
|
|
169
|
+
* @returns true if safe, throws error if not
|
|
170
|
+
*/
|
|
171
|
+
function validatePathForSandboxProfile(pathToValidate) {
|
|
172
|
+
// Check for null bytes
|
|
173
|
+
if (pathToValidate.includes('\0')) {
|
|
174
|
+
throw new Error('Path contains null byte');
|
|
175
|
+
}
|
|
176
|
+
// Check for newlines (could inject new profile lines)
|
|
177
|
+
if (pathToValidate.includes('\n') || pathToValidate.includes('\r')) {
|
|
178
|
+
throw new Error('Path contains newline characters');
|
|
179
|
+
}
|
|
180
|
+
// Validate path is absolute and normalized
|
|
181
|
+
if (!path.isAbsolute(pathToValidate)) {
|
|
182
|
+
throw new Error('Path must be absolute');
|
|
183
|
+
}
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Escape a value for Docker environment variable
|
|
188
|
+
* Prevents command injection through environment variables
|
|
189
|
+
*
|
|
190
|
+
* @param value - Environment variable value to escape
|
|
191
|
+
* @returns Escaped value safe for Docker -e flag
|
|
192
|
+
*/
|
|
193
|
+
function escapeDockerEnvValue(value) {
|
|
194
|
+
// Reject values with null bytes
|
|
195
|
+
if (value.includes('\0')) {
|
|
196
|
+
throw new Error('Environment value contains null byte');
|
|
197
|
+
}
|
|
198
|
+
// For Docker, we need to handle shell metacharacters
|
|
199
|
+
// The safest approach is to reject problematic characters
|
|
200
|
+
// or use Docker's --env-file feature for complex values
|
|
201
|
+
// Check for newlines which could inject additional arguments
|
|
202
|
+
if (value.includes('\n') || value.includes('\r')) {
|
|
203
|
+
throw new Error('Environment value contains newline characters');
|
|
204
|
+
}
|
|
205
|
+
return value;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Validate an environment variable name is safe
|
|
209
|
+
*
|
|
210
|
+
* @param name - Environment variable name
|
|
211
|
+
* @returns true if valid, throws if not
|
|
212
|
+
*/
|
|
213
|
+
function validateEnvVarName(name) {
|
|
214
|
+
// Standard env var naming: alphanumeric and underscore, starting with letter or underscore
|
|
215
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
|
|
216
|
+
throw new Error(`Invalid environment variable name: ${name}`);
|
|
217
|
+
}
|
|
218
|
+
// Blacklist dangerous environment variables that could affect sandboxed processes
|
|
219
|
+
const dangerousVars = [
|
|
220
|
+
'LD_PRELOAD',
|
|
221
|
+
'LD_LIBRARY_PATH',
|
|
222
|
+
'DYLD_INSERT_LIBRARIES',
|
|
223
|
+
'DYLD_LIBRARY_PATH',
|
|
224
|
+
'PYTHONPATH',
|
|
225
|
+
'NODE_OPTIONS',
|
|
226
|
+
'NODE_PATH',
|
|
227
|
+
'PERL5OPT',
|
|
228
|
+
'RUBYOPT',
|
|
229
|
+
];
|
|
230
|
+
if (dangerousVars.includes(name.toUpperCase())) {
|
|
231
|
+
throw new Error(`Dangerous environment variable not allowed: ${name}`);
|
|
232
|
+
}
|
|
233
|
+
return true;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Safe environment passthrough that validates and filters variables
|
|
237
|
+
*
|
|
238
|
+
* @param requestedVars - List of environment variable names to pass through
|
|
239
|
+
* @returns Record of safe environment variables
|
|
240
|
+
*/
|
|
241
|
+
function buildSafeEnvironment(requestedVars) {
|
|
242
|
+
const safeEnv = {};
|
|
243
|
+
for (const name of requestedVars) {
|
|
244
|
+
try {
|
|
245
|
+
validateEnvVarName(name);
|
|
246
|
+
const value = process.env[name];
|
|
247
|
+
if (value !== undefined) {
|
|
248
|
+
escapeDockerEnvValue(value); // Validates value is safe
|
|
249
|
+
safeEnv[name] = value;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
// Skip invalid or dangerous variables silently
|
|
254
|
+
console.warn(`[SecurityUtils] Skipping unsafe environment variable: ${name}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return safeEnv;
|
|
258
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BraveProvider = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Brave Search API provider
|
|
6
|
+
* https://brave.com/search/api/
|
|
7
|
+
*/
|
|
8
|
+
class BraveProvider {
|
|
9
|
+
constructor(config) {
|
|
10
|
+
this.type = 'brave';
|
|
11
|
+
this.supportedSearchTypes = ['web', 'news', 'images'];
|
|
12
|
+
this.baseUrl = 'https://api.search.brave.com/res/v1';
|
|
13
|
+
const apiKey = config.braveApiKey;
|
|
14
|
+
if (!apiKey) {
|
|
15
|
+
throw new Error('Brave API key is required. Configure it in Settings or get one from https://brave.com/search/api/');
|
|
16
|
+
}
|
|
17
|
+
this.apiKey = apiKey;
|
|
18
|
+
}
|
|
19
|
+
async search(query) {
|
|
20
|
+
const searchType = query.searchType || 'web';
|
|
21
|
+
if (!this.supportedSearchTypes.includes(searchType)) {
|
|
22
|
+
throw new Error(`Brave does not support ${searchType} search`);
|
|
23
|
+
}
|
|
24
|
+
const endpoint = this.getEndpoint(searchType);
|
|
25
|
+
const params = new URLSearchParams({
|
|
26
|
+
q: query.query,
|
|
27
|
+
count: String(query.maxResults || 10),
|
|
28
|
+
...(query.region && { country: query.region }),
|
|
29
|
+
...(query.language && { search_lang: query.language }),
|
|
30
|
+
...(query.safeSearch !== undefined && {
|
|
31
|
+
safesearch: query.safeSearch ? 'strict' : 'off',
|
|
32
|
+
}),
|
|
33
|
+
...(query.dateRange && { freshness: this.mapDateRange(query.dateRange) }),
|
|
34
|
+
});
|
|
35
|
+
const response = await fetch(`${this.baseUrl}/${endpoint}?${params}`, {
|
|
36
|
+
headers: {
|
|
37
|
+
Accept: 'application/json',
|
|
38
|
+
'X-Subscription-Token': this.apiKey,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
const error = await response.text();
|
|
43
|
+
throw new Error(`Brave API error: ${response.status} - ${error}`);
|
|
44
|
+
}
|
|
45
|
+
const data = await response.json();
|
|
46
|
+
return {
|
|
47
|
+
results: this.mapResults(data, searchType),
|
|
48
|
+
query: query.query,
|
|
49
|
+
searchType,
|
|
50
|
+
provider: 'brave',
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
async testConnection() {
|
|
54
|
+
try {
|
|
55
|
+
await this.search({ query: 'test', maxResults: 1 });
|
|
56
|
+
return { success: true };
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
return {
|
|
60
|
+
success: false,
|
|
61
|
+
error: error.message || 'Failed to connect to Brave Search API',
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
getEndpoint(searchType) {
|
|
66
|
+
switch (searchType) {
|
|
67
|
+
case 'news':
|
|
68
|
+
return 'news/search';
|
|
69
|
+
case 'images':
|
|
70
|
+
return 'images/search';
|
|
71
|
+
default:
|
|
72
|
+
return 'web/search';
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
mapDateRange(range) {
|
|
76
|
+
switch (range) {
|
|
77
|
+
case 'day':
|
|
78
|
+
return 'pd'; // past day
|
|
79
|
+
case 'week':
|
|
80
|
+
return 'pw'; // past week
|
|
81
|
+
case 'month':
|
|
82
|
+
return 'pm'; // past month
|
|
83
|
+
case 'year':
|
|
84
|
+
return 'py'; // past year
|
|
85
|
+
default:
|
|
86
|
+
return 'pw';
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
mapResults(data, searchType) {
|
|
90
|
+
if (searchType === 'images') {
|
|
91
|
+
return (data.results || []).map((r) => ({
|
|
92
|
+
title: r.title || '',
|
|
93
|
+
url: r.url || r.page_url || '',
|
|
94
|
+
snippet: r.description || '',
|
|
95
|
+
thumbnailUrl: r.thumbnail?.src,
|
|
96
|
+
imageUrl: r.properties?.url || r.url,
|
|
97
|
+
width: r.properties?.width,
|
|
98
|
+
height: r.properties?.height,
|
|
99
|
+
}));
|
|
100
|
+
}
|
|
101
|
+
if (searchType === 'news') {
|
|
102
|
+
return (data.results || []).map((r) => ({
|
|
103
|
+
title: r.title || '',
|
|
104
|
+
url: r.url || '',
|
|
105
|
+
snippet: r.description || '',
|
|
106
|
+
publishedDate: r.age,
|
|
107
|
+
source: r.meta_url?.hostname,
|
|
108
|
+
}));
|
|
109
|
+
}
|
|
110
|
+
// Web results
|
|
111
|
+
return (data.web?.results || []).map((r) => ({
|
|
112
|
+
title: r.title || '',
|
|
113
|
+
url: r.url || '',
|
|
114
|
+
snippet: r.description || '',
|
|
115
|
+
source: r.meta_url?.hostname,
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.BraveProvider = BraveProvider;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GoogleProvider = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Google Custom Search API provider
|
|
6
|
+
* https://developers.google.com/custom-search/v1/introduction
|
|
7
|
+
*/
|
|
8
|
+
class GoogleProvider {
|
|
9
|
+
constructor(config) {
|
|
10
|
+
this.type = 'google';
|
|
11
|
+
this.supportedSearchTypes = ['web', 'images'];
|
|
12
|
+
this.baseUrl = 'https://www.googleapis.com/customsearch/v1';
|
|
13
|
+
const apiKey = config.googleApiKey;
|
|
14
|
+
const searchEngineId = config.googleSearchEngineId;
|
|
15
|
+
if (!apiKey) {
|
|
16
|
+
throw new Error('Google API key is required. Configure it in Settings or get one from https://console.cloud.google.com/');
|
|
17
|
+
}
|
|
18
|
+
if (!searchEngineId) {
|
|
19
|
+
throw new Error('Google Search Engine ID is required. Configure it in Settings or create one at https://programmablesearchengine.google.com/');
|
|
20
|
+
}
|
|
21
|
+
this.apiKey = apiKey;
|
|
22
|
+
this.searchEngineId = searchEngineId;
|
|
23
|
+
}
|
|
24
|
+
async search(query) {
|
|
25
|
+
const searchType = query.searchType || 'web';
|
|
26
|
+
if (!this.supportedSearchTypes.includes(searchType)) {
|
|
27
|
+
throw new Error(`Google Custom Search does not support ${searchType} search. Use 'web' or 'images'.`);
|
|
28
|
+
}
|
|
29
|
+
const params = new URLSearchParams({
|
|
30
|
+
key: this.apiKey,
|
|
31
|
+
cx: this.searchEngineId,
|
|
32
|
+
q: query.query,
|
|
33
|
+
num: String(Math.min(query.maxResults || 10, 10)), // Google CSE max is 10
|
|
34
|
+
...(query.region && { gl: query.region }),
|
|
35
|
+
...(query.language && { lr: `lang_${query.language}` }),
|
|
36
|
+
...(query.safeSearch !== undefined && {
|
|
37
|
+
safe: query.safeSearch ? 'active' : 'off',
|
|
38
|
+
}),
|
|
39
|
+
...(searchType === 'images' && { searchType: 'image' }),
|
|
40
|
+
...(query.dateRange && { dateRestrict: this.mapDateRange(query.dateRange) }),
|
|
41
|
+
});
|
|
42
|
+
const response = await fetch(`${this.baseUrl}?${params}`);
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
const error = await response.json();
|
|
45
|
+
throw new Error(`Google CSE error: ${response.status} - ${error.error?.message || 'Unknown error'}`);
|
|
46
|
+
}
|
|
47
|
+
const data = await response.json();
|
|
48
|
+
return {
|
|
49
|
+
results: this.mapResults(data.items || [], searchType),
|
|
50
|
+
query: query.query,
|
|
51
|
+
searchType,
|
|
52
|
+
totalResults: data.searchInformation?.totalResults
|
|
53
|
+
? parseInt(data.searchInformation.totalResults)
|
|
54
|
+
: undefined,
|
|
55
|
+
provider: 'google',
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
async testConnection() {
|
|
59
|
+
try {
|
|
60
|
+
await this.search({ query: 'test', maxResults: 1 });
|
|
61
|
+
return { success: true };
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
return {
|
|
65
|
+
success: false,
|
|
66
|
+
error: error.message || 'Failed to connect to Google Custom Search',
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
mapDateRange(range) {
|
|
71
|
+
switch (range) {
|
|
72
|
+
case 'day':
|
|
73
|
+
return 'd1';
|
|
74
|
+
case 'week':
|
|
75
|
+
return 'w1';
|
|
76
|
+
case 'month':
|
|
77
|
+
return 'm1';
|
|
78
|
+
case 'year':
|
|
79
|
+
return 'y1';
|
|
80
|
+
default:
|
|
81
|
+
return 'w1';
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
mapResults(items, searchType) {
|
|
85
|
+
return items.map((item) => ({
|
|
86
|
+
title: item.title || '',
|
|
87
|
+
url: item.link || '',
|
|
88
|
+
snippet: item.snippet || '',
|
|
89
|
+
// Image-specific fields
|
|
90
|
+
...(searchType === 'images' && {
|
|
91
|
+
thumbnailUrl: item.image?.thumbnailLink,
|
|
92
|
+
imageUrl: item.link,
|
|
93
|
+
width: item.image?.width,
|
|
94
|
+
height: item.image?.height,
|
|
95
|
+
}),
|
|
96
|
+
source: item.displayLink,
|
|
97
|
+
}));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.GoogleProvider = GoogleProvider;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.SearchProviderFactory = exports.GoogleProvider = exports.SerpApiProvider = exports.BraveProvider = exports.TavilyProvider = void 0;
|
|
18
|
+
__exportStar(require("./types"), exports);
|
|
19
|
+
var tavily_provider_1 = require("./tavily-provider");
|
|
20
|
+
Object.defineProperty(exports, "TavilyProvider", { enumerable: true, get: function () { return tavily_provider_1.TavilyProvider; } });
|
|
21
|
+
var brave_provider_1 = require("./brave-provider");
|
|
22
|
+
Object.defineProperty(exports, "BraveProvider", { enumerable: true, get: function () { return brave_provider_1.BraveProvider; } });
|
|
23
|
+
var serpapi_provider_1 = require("./serpapi-provider");
|
|
24
|
+
Object.defineProperty(exports, "SerpApiProvider", { enumerable: true, get: function () { return serpapi_provider_1.SerpApiProvider; } });
|
|
25
|
+
var google_provider_1 = require("./google-provider");
|
|
26
|
+
Object.defineProperty(exports, "GoogleProvider", { enumerable: true, get: function () { return google_provider_1.GoogleProvider; } });
|
|
27
|
+
var provider_factory_1 = require("./provider-factory");
|
|
28
|
+
Object.defineProperty(exports, "SearchProviderFactory", { enumerable: true, get: function () { return provider_factory_1.SearchProviderFactory; } });
|