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,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* X/Twitter Settings Manager
|
|
3
|
+
*
|
|
4
|
+
* Stores X integration settings in encrypted database.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { SecureSettingsRepository } from '../database/SecureSettingsRepository';
|
|
8
|
+
import { XSettingsData } from '../../shared/types';
|
|
9
|
+
|
|
10
|
+
const DEFAULT_SETTINGS: XSettingsData = {
|
|
11
|
+
enabled: false,
|
|
12
|
+
authMethod: 'browser',
|
|
13
|
+
cookieSource: ['chrome'],
|
|
14
|
+
timeoutMs: 20000,
|
|
15
|
+
cookieTimeoutMs: 20000,
|
|
16
|
+
quoteDepth: 1,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export class XSettingsManager {
|
|
20
|
+
private static cachedSettings: XSettingsData | null = null;
|
|
21
|
+
|
|
22
|
+
static loadSettings(): XSettingsData {
|
|
23
|
+
if (this.cachedSettings) {
|
|
24
|
+
return this.cachedSettings;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let settings: XSettingsData = { ...DEFAULT_SETTINGS };
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
if (SecureSettingsRepository.isInitialized()) {
|
|
31
|
+
const repository = SecureSettingsRepository.getInstance();
|
|
32
|
+
const stored = repository.load<XSettingsData>('x');
|
|
33
|
+
if (stored) {
|
|
34
|
+
settings = { ...DEFAULT_SETTINGS, ...stored };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.error('[XSettingsManager] Failed to load settings:', error);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
this.cachedSettings = settings;
|
|
42
|
+
return settings;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
static saveSettings(settings: XSettingsData): void {
|
|
46
|
+
try {
|
|
47
|
+
if (!SecureSettingsRepository.isInitialized()) {
|
|
48
|
+
throw new Error('SecureSettingsRepository not initialized');
|
|
49
|
+
}
|
|
50
|
+
const repository = SecureSettingsRepository.getInstance();
|
|
51
|
+
repository.save('x', settings);
|
|
52
|
+
this.cachedSettings = settings;
|
|
53
|
+
console.log('[XSettingsManager] Settings saved');
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.error('[XSettingsManager] Failed to save settings:', error);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static clearCache(): void {
|
|
60
|
+
this.cachedSettings = null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tailscale Exposure Manager
|
|
3
|
+
*
|
|
4
|
+
* High-level API for exposing local services via Tailscale Serve or Funnel.
|
|
5
|
+
* Handles lifecycle management, cleanup, and status tracking.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
isTailscaleInstalled,
|
|
10
|
+
getTailnetHostname,
|
|
11
|
+
enableTailscaleServe,
|
|
12
|
+
disableTailscaleServe,
|
|
13
|
+
enableTailscaleFunnel,
|
|
14
|
+
disableTailscaleFunnel,
|
|
15
|
+
checkTailscaleFunnelAvailable,
|
|
16
|
+
} from './tailscale';
|
|
17
|
+
import { TailscaleSettingsManager, type TailscaleMode } from './settings';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Configuration for starting Tailscale exposure
|
|
21
|
+
*/
|
|
22
|
+
export interface TailscaleExposureConfig {
|
|
23
|
+
/** Mode: 'serve' (Tailnet only) or 'funnel' (public internet) */
|
|
24
|
+
mode: TailscaleMode;
|
|
25
|
+
/** Local port to expose */
|
|
26
|
+
port: number;
|
|
27
|
+
/** URL path prefix (default: '/') */
|
|
28
|
+
pathPrefix?: string;
|
|
29
|
+
/** Reset Tailscale config on cleanup */
|
|
30
|
+
resetOnExit?: boolean;
|
|
31
|
+
/** Logger functions */
|
|
32
|
+
log?: (message: string) => void;
|
|
33
|
+
warn?: (message: string) => void;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Result from starting Tailscale exposure
|
|
38
|
+
*/
|
|
39
|
+
export interface TailscaleExposureResult {
|
|
40
|
+
/** Whether exposure was successfully enabled */
|
|
41
|
+
success: boolean;
|
|
42
|
+
/** The public/Tailnet hostname */
|
|
43
|
+
hostname?: string;
|
|
44
|
+
/** Full HTTPS URL to access the service */
|
|
45
|
+
httpsUrl?: string;
|
|
46
|
+
/** Full WebSocket URL */
|
|
47
|
+
wssUrl?: string;
|
|
48
|
+
/** Error message if failed */
|
|
49
|
+
error?: string;
|
|
50
|
+
/** Cleanup function to disable exposure */
|
|
51
|
+
cleanup?: () => Promise<void>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Active exposure state tracking
|
|
56
|
+
*/
|
|
57
|
+
interface ActiveExposure {
|
|
58
|
+
mode: TailscaleMode;
|
|
59
|
+
port: number;
|
|
60
|
+
hostname: string;
|
|
61
|
+
startedAt: number;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
let activeExposure: ActiveExposure | null = null;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get current exposure status
|
|
68
|
+
*/
|
|
69
|
+
export function getExposureStatus(): {
|
|
70
|
+
active: boolean;
|
|
71
|
+
mode?: TailscaleMode;
|
|
72
|
+
hostname?: string;
|
|
73
|
+
httpsUrl?: string;
|
|
74
|
+
wssUrl?: string;
|
|
75
|
+
startedAt?: number;
|
|
76
|
+
} {
|
|
77
|
+
if (!activeExposure) {
|
|
78
|
+
return { active: false };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
active: true,
|
|
83
|
+
mode: activeExposure.mode,
|
|
84
|
+
hostname: activeExposure.hostname,
|
|
85
|
+
httpsUrl: `https://${activeExposure.hostname}`,
|
|
86
|
+
wssUrl: `wss://${activeExposure.hostname}`,
|
|
87
|
+
startedAt: activeExposure.startedAt,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Start Tailscale exposure for a local service
|
|
93
|
+
*
|
|
94
|
+
* @param config - Exposure configuration
|
|
95
|
+
* @returns Result with URLs and cleanup function
|
|
96
|
+
*/
|
|
97
|
+
export async function startTailscaleExposure(
|
|
98
|
+
config: TailscaleExposureConfig
|
|
99
|
+
): Promise<TailscaleExposureResult> {
|
|
100
|
+
const log = config.log || console.log;
|
|
101
|
+
const warn = config.warn || console.warn;
|
|
102
|
+
|
|
103
|
+
// Return early if mode is 'off'
|
|
104
|
+
if (config.mode === 'off') {
|
|
105
|
+
return { success: true };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Check if Tailscale is installed
|
|
109
|
+
const installed = await isTailscaleInstalled();
|
|
110
|
+
if (!installed) {
|
|
111
|
+
const error = 'Tailscale is not installed. Please install Tailscale first.';
|
|
112
|
+
warn(`[Tailscale Exposure] ${error}`);
|
|
113
|
+
return { success: false, error };
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// If mode is funnel, check availability
|
|
117
|
+
if (config.mode === 'funnel') {
|
|
118
|
+
const funnelAvailable = await checkTailscaleFunnelAvailable();
|
|
119
|
+
if (!funnelAvailable) {
|
|
120
|
+
warn('[Tailscale Exposure] Funnel not available, falling back to Serve mode');
|
|
121
|
+
config.mode = 'serve';
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Enable the appropriate mode
|
|
126
|
+
let enabled = false;
|
|
127
|
+
try {
|
|
128
|
+
if (config.mode === 'funnel') {
|
|
129
|
+
enabled = await enableTailscaleFunnel(config.port, config.pathPrefix || '/');
|
|
130
|
+
} else if (config.mode === 'serve') {
|
|
131
|
+
enabled = await enableTailscaleServe(config.port, config.pathPrefix || '/');
|
|
132
|
+
}
|
|
133
|
+
} catch (error: any) {
|
|
134
|
+
const message = error.message || String(error);
|
|
135
|
+
warn(`[Tailscale Exposure] Failed to enable ${config.mode}: ${message}`);
|
|
136
|
+
return { success: false, error: message };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (!enabled) {
|
|
140
|
+
const error = `Failed to enable Tailscale ${config.mode}`;
|
|
141
|
+
return { success: false, error };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Get the hostname
|
|
145
|
+
const hostname = await getTailnetHostname();
|
|
146
|
+
if (!hostname) {
|
|
147
|
+
warn('[Tailscale Exposure] Could not determine Tailnet hostname');
|
|
148
|
+
// Try to clean up
|
|
149
|
+
if (config.mode === 'funnel') {
|
|
150
|
+
await disableTailscaleFunnel();
|
|
151
|
+
} else {
|
|
152
|
+
await disableTailscaleServe();
|
|
153
|
+
}
|
|
154
|
+
return { success: false, error: 'Could not determine Tailnet hostname' };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Build URLs
|
|
158
|
+
const pathPrefix = config.pathPrefix || '';
|
|
159
|
+
const httpsUrl = `https://${hostname}${pathPrefix}`;
|
|
160
|
+
const wssUrl = `wss://${hostname}${pathPrefix}`;
|
|
161
|
+
|
|
162
|
+
// Update settings
|
|
163
|
+
TailscaleSettingsManager.updateSettings({
|
|
164
|
+
mode: config.mode,
|
|
165
|
+
lastHostname: hostname,
|
|
166
|
+
lastStatusCheck: Date.now(),
|
|
167
|
+
resetOnExit: config.resetOnExit ?? true,
|
|
168
|
+
pathPrefix: config.pathPrefix,
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// Track active exposure
|
|
172
|
+
activeExposure = {
|
|
173
|
+
mode: config.mode,
|
|
174
|
+
port: config.port,
|
|
175
|
+
hostname,
|
|
176
|
+
startedAt: Date.now(),
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
log(`[Tailscale Exposure] ${config.mode === 'funnel' ? 'Funnel' : 'Serve'} enabled`);
|
|
180
|
+
log(`[Tailscale Exposure] HTTPS: ${httpsUrl}`);
|
|
181
|
+
log(`[Tailscale Exposure] WSS: ${wssUrl}`);
|
|
182
|
+
|
|
183
|
+
// Create cleanup function
|
|
184
|
+
const cleanup = async () => {
|
|
185
|
+
try {
|
|
186
|
+
if (config.resetOnExit !== false) {
|
|
187
|
+
if (config.mode === 'funnel') {
|
|
188
|
+
await disableTailscaleFunnel();
|
|
189
|
+
} else if (config.mode === 'serve') {
|
|
190
|
+
await disableTailscaleServe();
|
|
191
|
+
}
|
|
192
|
+
log(`[Tailscale Exposure] ${config.mode} disabled`);
|
|
193
|
+
}
|
|
194
|
+
} catch (error: any) {
|
|
195
|
+
warn(`[Tailscale Exposure] Cleanup error: ${error.message || error}`);
|
|
196
|
+
} finally {
|
|
197
|
+
activeExposure = null;
|
|
198
|
+
TailscaleSettingsManager.updateSettings({ mode: 'off' });
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
return {
|
|
203
|
+
success: true,
|
|
204
|
+
hostname,
|
|
205
|
+
httpsUrl,
|
|
206
|
+
wssUrl,
|
|
207
|
+
cleanup,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Stop any active Tailscale exposure
|
|
213
|
+
*/
|
|
214
|
+
export async function stopTailscaleExposure(): Promise<void> {
|
|
215
|
+
if (!activeExposure) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
try {
|
|
220
|
+
if (activeExposure.mode === 'funnel') {
|
|
221
|
+
await disableTailscaleFunnel();
|
|
222
|
+
} else if (activeExposure.mode === 'serve') {
|
|
223
|
+
await disableTailscaleServe();
|
|
224
|
+
}
|
|
225
|
+
console.log(`[Tailscale Exposure] ${activeExposure.mode} disabled`);
|
|
226
|
+
} catch (error: any) {
|
|
227
|
+
console.error('[Tailscale Exposure] Stop error:', error.message || error);
|
|
228
|
+
} finally {
|
|
229
|
+
activeExposure = null;
|
|
230
|
+
TailscaleSettingsManager.updateSettings({ mode: 'off' });
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Check Tailscale availability and status
|
|
236
|
+
*/
|
|
237
|
+
export async function checkTailscaleAvailability(): Promise<{
|
|
238
|
+
installed: boolean;
|
|
239
|
+
funnelAvailable: boolean;
|
|
240
|
+
hostname: string | null;
|
|
241
|
+
}> {
|
|
242
|
+
const installed = await isTailscaleInstalled();
|
|
243
|
+
|
|
244
|
+
if (!installed) {
|
|
245
|
+
return {
|
|
246
|
+
installed: false,
|
|
247
|
+
funnelAvailable: false,
|
|
248
|
+
hostname: null,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const [funnelAvailable, hostname] = await Promise.all([
|
|
253
|
+
checkTailscaleFunnelAvailable(),
|
|
254
|
+
getTailnetHostname(),
|
|
255
|
+
]);
|
|
256
|
+
|
|
257
|
+
return {
|
|
258
|
+
installed: true,
|
|
259
|
+
funnelAvailable,
|
|
260
|
+
hostname,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tailscale Integration Module
|
|
3
|
+
*
|
|
4
|
+
* Provides utilities for Tailscale Serve and Funnel functionality.
|
|
5
|
+
* - Serve: Share local services to your Tailnet (private network)
|
|
6
|
+
* - Funnel: Expose local services to the public internet via Tailscale
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export {
|
|
10
|
+
findTailscaleBinary,
|
|
11
|
+
getTailscaleBinary,
|
|
12
|
+
isTailscaleInstalled,
|
|
13
|
+
getTailscaleStatus,
|
|
14
|
+
getTailnetHostname,
|
|
15
|
+
enableTailscaleServe,
|
|
16
|
+
disableTailscaleServe,
|
|
17
|
+
enableTailscaleFunnel,
|
|
18
|
+
disableTailscaleFunnel,
|
|
19
|
+
checkTailscaleFunnelAvailable,
|
|
20
|
+
} from './tailscale';
|
|
21
|
+
|
|
22
|
+
export {
|
|
23
|
+
TailscaleSettingsManager,
|
|
24
|
+
type TailscaleSettings,
|
|
25
|
+
} from './settings';
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
startTailscaleExposure,
|
|
29
|
+
stopTailscaleExposure,
|
|
30
|
+
getExposureStatus,
|
|
31
|
+
checkTailscaleAvailability,
|
|
32
|
+
type TailscaleExposureConfig,
|
|
33
|
+
type TailscaleExposureResult,
|
|
34
|
+
} from './exposure';
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tailscale Settings Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages Tailscale configuration persistence.
|
|
5
|
+
* Settings are stored encrypted in the database using SecureSettingsRepository.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { app } from 'electron';
|
|
9
|
+
import * as fs from 'fs';
|
|
10
|
+
import * as path from 'path';
|
|
11
|
+
import { SecureSettingsRepository } from '../database/SecureSettingsRepository';
|
|
12
|
+
|
|
13
|
+
const LEGACY_SETTINGS_FILE = 'tailscale-settings.json';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Tailscale mode options
|
|
17
|
+
* - off: Tailscale integration disabled
|
|
18
|
+
* - serve: Expose to Tailnet (private network)
|
|
19
|
+
* - funnel: Expose to public internet
|
|
20
|
+
*/
|
|
21
|
+
export type TailscaleMode = 'off' | 'serve' | 'funnel';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Tailscale settings interface
|
|
25
|
+
*/
|
|
26
|
+
export interface TailscaleSettings {
|
|
27
|
+
/** Current mode */
|
|
28
|
+
mode: TailscaleMode;
|
|
29
|
+
/** Whether to reset Tailscale config on app exit */
|
|
30
|
+
resetOnExit: boolean;
|
|
31
|
+
/** Custom path prefix for the exposed endpoint */
|
|
32
|
+
pathPrefix?: string;
|
|
33
|
+
/** Last known hostname */
|
|
34
|
+
lastHostname?: string;
|
|
35
|
+
/** Timestamp of last status check */
|
|
36
|
+
lastStatusCheck?: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Default Tailscale settings
|
|
41
|
+
*/
|
|
42
|
+
export const DEFAULT_TAILSCALE_SETTINGS: TailscaleSettings = {
|
|
43
|
+
mode: 'off',
|
|
44
|
+
resetOnExit: true,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Tailscale Settings Manager
|
|
49
|
+
*/
|
|
50
|
+
export class TailscaleSettingsManager {
|
|
51
|
+
private static legacySettingsPath: string;
|
|
52
|
+
private static cachedSettings: TailscaleSettings | null = null;
|
|
53
|
+
private static initialized = false;
|
|
54
|
+
private static migrationCompleted = false;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Initialize the settings manager (must be called after app is ready)
|
|
58
|
+
*/
|
|
59
|
+
static initialize(): void {
|
|
60
|
+
if (this.initialized) return;
|
|
61
|
+
|
|
62
|
+
const userDataPath = app.getPath('userData');
|
|
63
|
+
this.legacySettingsPath = path.join(userDataPath, LEGACY_SETTINGS_FILE);
|
|
64
|
+
this.initialized = true;
|
|
65
|
+
|
|
66
|
+
console.log('[Tailscale Settings] Initialized');
|
|
67
|
+
|
|
68
|
+
// Migrate from legacy JSON file to encrypted database
|
|
69
|
+
this.migrateFromLegacyFile();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Migrate settings from legacy JSON file to encrypted database
|
|
74
|
+
*/
|
|
75
|
+
private static migrateFromLegacyFile(): void {
|
|
76
|
+
if (this.migrationCompleted) return;
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
if (!SecureSettingsRepository.isInitialized()) {
|
|
80
|
+
console.log('[Tailscale Settings] SecureSettingsRepository not yet initialized, skipping migration');
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const repository = SecureSettingsRepository.getInstance();
|
|
85
|
+
|
|
86
|
+
if (repository.exists('tailscale')) {
|
|
87
|
+
this.migrationCompleted = true;
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!fs.existsSync(this.legacySettingsPath)) {
|
|
92
|
+
console.log('[Tailscale Settings] No legacy settings file found');
|
|
93
|
+
this.migrationCompleted = true;
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
console.log('[Tailscale Settings] Migrating settings from legacy JSON file to encrypted database...');
|
|
98
|
+
|
|
99
|
+
// Create backup before migration
|
|
100
|
+
const backupPath = this.legacySettingsPath + '.migration-backup';
|
|
101
|
+
fs.copyFileSync(this.legacySettingsPath, backupPath);
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
const data = fs.readFileSync(this.legacySettingsPath, 'utf-8');
|
|
105
|
+
const legacySettings = { ...DEFAULT_TAILSCALE_SETTINGS, ...JSON.parse(data) };
|
|
106
|
+
|
|
107
|
+
repository.save('tailscale', legacySettings);
|
|
108
|
+
console.log('[Tailscale Settings] Settings migrated to encrypted database');
|
|
109
|
+
|
|
110
|
+
// Migration successful - delete backup and original
|
|
111
|
+
fs.unlinkSync(backupPath);
|
|
112
|
+
fs.unlinkSync(this.legacySettingsPath);
|
|
113
|
+
console.log('[Tailscale Settings] Migration complete, cleaned up legacy files');
|
|
114
|
+
|
|
115
|
+
this.migrationCompleted = true;
|
|
116
|
+
} catch (migrationError) {
|
|
117
|
+
console.error('[Tailscale Settings] Migration failed, backup preserved at:', backupPath);
|
|
118
|
+
throw migrationError;
|
|
119
|
+
}
|
|
120
|
+
} catch (error) {
|
|
121
|
+
console.error('[Tailscale Settings] Migration failed:', error);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Ensure the manager is initialized
|
|
127
|
+
*/
|
|
128
|
+
private static ensureInitialized(): void {
|
|
129
|
+
if (!this.initialized) {
|
|
130
|
+
this.initialize();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Load settings from encrypted database
|
|
136
|
+
*/
|
|
137
|
+
static loadSettings(): TailscaleSettings {
|
|
138
|
+
this.ensureInitialized();
|
|
139
|
+
|
|
140
|
+
if (this.cachedSettings) {
|
|
141
|
+
return this.cachedSettings;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
try {
|
|
145
|
+
if (SecureSettingsRepository.isInitialized()) {
|
|
146
|
+
const repository = SecureSettingsRepository.getInstance();
|
|
147
|
+
const stored = repository.load<TailscaleSettings>('tailscale');
|
|
148
|
+
if (stored) {
|
|
149
|
+
const merged: TailscaleSettings = {
|
|
150
|
+
...DEFAULT_TAILSCALE_SETTINGS,
|
|
151
|
+
...stored,
|
|
152
|
+
};
|
|
153
|
+
this.cachedSettings = merged;
|
|
154
|
+
console.log('[Tailscale Settings] Loaded settings from encrypted database');
|
|
155
|
+
return this.cachedSettings;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
} catch (error) {
|
|
159
|
+
console.error('[Tailscale Settings] Failed to load settings:', error);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
console.log('[Tailscale Settings] No settings found, using defaults');
|
|
163
|
+
this.cachedSettings = { ...DEFAULT_TAILSCALE_SETTINGS };
|
|
164
|
+
return this.cachedSettings;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Save settings to encrypted database
|
|
169
|
+
*/
|
|
170
|
+
static saveSettings(settings: TailscaleSettings): void {
|
|
171
|
+
this.ensureInitialized();
|
|
172
|
+
|
|
173
|
+
try {
|
|
174
|
+
if (!SecureSettingsRepository.isInitialized()) {
|
|
175
|
+
throw new Error('SecureSettingsRepository not initialized');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const repository = SecureSettingsRepository.getInstance();
|
|
179
|
+
repository.save('tailscale', settings);
|
|
180
|
+
this.cachedSettings = settings;
|
|
181
|
+
console.log('[Tailscale Settings] Saved settings to encrypted database');
|
|
182
|
+
} catch (error) {
|
|
183
|
+
console.error('[Tailscale Settings] Failed to save settings:', error);
|
|
184
|
+
throw error;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Update settings partially
|
|
190
|
+
*/
|
|
191
|
+
static updateSettings(updates: Partial<TailscaleSettings>): TailscaleSettings {
|
|
192
|
+
const settings = this.loadSettings();
|
|
193
|
+
const updated = { ...settings, ...updates };
|
|
194
|
+
this.saveSettings(updated);
|
|
195
|
+
return updated;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Set the Tailscale mode
|
|
200
|
+
*/
|
|
201
|
+
static setMode(mode: TailscaleMode): TailscaleSettings {
|
|
202
|
+
return this.updateSettings({ mode });
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Clear the settings cache
|
|
207
|
+
*/
|
|
208
|
+
static clearCache(): void {
|
|
209
|
+
this.cachedSettings = null;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Get default settings
|
|
214
|
+
*/
|
|
215
|
+
static getDefaults(): TailscaleSettings {
|
|
216
|
+
return { ...DEFAULT_TAILSCALE_SETTINGS };
|
|
217
|
+
}
|
|
218
|
+
}
|