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,566 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Custom Skill Loader
|
|
4
|
+
*
|
|
5
|
+
* Loads skills from multiple sources with precedence:
|
|
6
|
+
* - Bundled skills (resources/skills/) - lowest precedence
|
|
7
|
+
* - Managed skills (~/Library/Application Support/cowork-os/skills/) - medium precedence
|
|
8
|
+
* - Workspace skills (workspace/skills/) - highest precedence
|
|
9
|
+
*
|
|
10
|
+
* Skills with the same ID from higher precedence sources override lower ones.
|
|
11
|
+
*/
|
|
12
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
15
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
16
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
17
|
+
}
|
|
18
|
+
Object.defineProperty(o, k2, desc);
|
|
19
|
+
}) : (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
o[k2] = m[k];
|
|
22
|
+
}));
|
|
23
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
24
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
25
|
+
}) : function(o, v) {
|
|
26
|
+
o["default"] = v;
|
|
27
|
+
});
|
|
28
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
29
|
+
var ownKeys = function(o) {
|
|
30
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
31
|
+
var ar = [];
|
|
32
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
33
|
+
return ar;
|
|
34
|
+
};
|
|
35
|
+
return ownKeys(o);
|
|
36
|
+
};
|
|
37
|
+
return function (mod) {
|
|
38
|
+
if (mod && mod.__esModule) return mod;
|
|
39
|
+
var result = {};
|
|
40
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
41
|
+
__setModuleDefault(result, mod);
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
})();
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.CustomSkillLoader = void 0;
|
|
47
|
+
exports.getCustomSkillLoader = getCustomSkillLoader;
|
|
48
|
+
exports.resetCustomSkillLoader = resetCustomSkillLoader;
|
|
49
|
+
const fs = __importStar(require("fs"));
|
|
50
|
+
const path = __importStar(require("path"));
|
|
51
|
+
const electron_1 = require("electron");
|
|
52
|
+
const skill_eligibility_1 = require("./skill-eligibility");
|
|
53
|
+
const security_1 = require("./security");
|
|
54
|
+
const SKILLS_FOLDER_NAME = 'skills';
|
|
55
|
+
const SKILL_FILE_EXTENSION = '.json';
|
|
56
|
+
const RELOAD_DEBOUNCE_MS = 100; // Debounce rapid reload calls
|
|
57
|
+
class CustomSkillLoader {
|
|
58
|
+
constructor(config) {
|
|
59
|
+
this.workspaceSkillsDir = null;
|
|
60
|
+
this.skills = new Map();
|
|
61
|
+
this.initialized = false;
|
|
62
|
+
// Debounce state for reloadSkills
|
|
63
|
+
this.reloadDebounceTimer = null;
|
|
64
|
+
this.reloadPromise = null;
|
|
65
|
+
this.isReloading = false;
|
|
66
|
+
// Bundled skills directory
|
|
67
|
+
const isDev = process.env.NODE_ENV === 'development';
|
|
68
|
+
if (config?.bundledSkillsDir) {
|
|
69
|
+
this.bundledSkillsDir = config.bundledSkillsDir;
|
|
70
|
+
}
|
|
71
|
+
else if (isDev) {
|
|
72
|
+
this.bundledSkillsDir = path.join(process.cwd(), 'resources', SKILLS_FOLDER_NAME);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
this.bundledSkillsDir = path.join(process.resourcesPath || '', SKILLS_FOLDER_NAME);
|
|
76
|
+
}
|
|
77
|
+
// Managed skills directory (from registry)
|
|
78
|
+
this.managedSkillsDir =
|
|
79
|
+
config?.managedSkillsDir ||
|
|
80
|
+
path.join(electron_1.app.getPath('userData'), SKILLS_FOLDER_NAME);
|
|
81
|
+
// Workspace skills directory (set later when workspace is loaded)
|
|
82
|
+
this.workspaceSkillsDir = config?.workspaceSkillsDir || null;
|
|
83
|
+
// Skills config
|
|
84
|
+
this.skillsConfig = config?.skillsConfig;
|
|
85
|
+
// Initialize eligibility checker
|
|
86
|
+
this.eligibilityChecker = (0, skill_eligibility_1.getSkillEligibilityChecker)(this.skillsConfig);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Initialize the skill loader - loads all skills from all sources
|
|
90
|
+
*/
|
|
91
|
+
async initialize() {
|
|
92
|
+
if (this.initialized)
|
|
93
|
+
return;
|
|
94
|
+
// Ensure managed skills directory exists
|
|
95
|
+
if (!fs.existsSync(this.managedSkillsDir)) {
|
|
96
|
+
fs.mkdirSync(this.managedSkillsDir, { recursive: true });
|
|
97
|
+
}
|
|
98
|
+
// Load all skills
|
|
99
|
+
await this.reloadSkills();
|
|
100
|
+
this.initialized = true;
|
|
101
|
+
console.log(`[CustomSkillLoader] Initialized with ${this.skills.size} skills`);
|
|
102
|
+
console.log(`[CustomSkillLoader] Bundled: ${this.bundledSkillsDir}`);
|
|
103
|
+
console.log(`[CustomSkillLoader] Managed: ${this.managedSkillsDir}`);
|
|
104
|
+
if (this.workspaceSkillsDir) {
|
|
105
|
+
console.log(`[CustomSkillLoader] Workspace: ${this.workspaceSkillsDir}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Set the workspace skills directory
|
|
110
|
+
*/
|
|
111
|
+
setWorkspaceSkillsDir(workspacePath) {
|
|
112
|
+
this.workspaceSkillsDir = path.join(workspacePath, SKILLS_FOLDER_NAME);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get directory paths
|
|
116
|
+
*/
|
|
117
|
+
getBundledSkillsDir() {
|
|
118
|
+
return this.bundledSkillsDir;
|
|
119
|
+
}
|
|
120
|
+
getManagedSkillsDir() {
|
|
121
|
+
return this.managedSkillsDir;
|
|
122
|
+
}
|
|
123
|
+
getWorkspaceSkillsDir() {
|
|
124
|
+
return this.workspaceSkillsDir;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Get the skills directory path (for backward compatibility)
|
|
128
|
+
*/
|
|
129
|
+
getSkillsDirectory() {
|
|
130
|
+
return this.bundledSkillsDir;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Load skills from a directory
|
|
134
|
+
*/
|
|
135
|
+
loadSkillsFromDir(dir, source) {
|
|
136
|
+
const skills = [];
|
|
137
|
+
if (!fs.existsSync(dir)) {
|
|
138
|
+
return skills;
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
const files = fs.readdirSync(dir);
|
|
142
|
+
const skillFiles = files.filter((f) => f.endsWith(SKILL_FILE_EXTENSION));
|
|
143
|
+
for (const file of skillFiles) {
|
|
144
|
+
try {
|
|
145
|
+
const filePath = path.join(dir, file);
|
|
146
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
147
|
+
const skill = JSON.parse(content);
|
|
148
|
+
// Add metadata
|
|
149
|
+
skill.filePath = filePath;
|
|
150
|
+
skill.source = source;
|
|
151
|
+
// Validate skill has required fields
|
|
152
|
+
if (this.validateSkill(skill)) {
|
|
153
|
+
skills.push(skill);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
console.warn(`[CustomSkillLoader] Invalid skill file: ${file}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
console.error(`[CustomSkillLoader] Failed to load skill file ${file}:`, error);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
console.error(`[CustomSkillLoader] Failed to read directory ${dir}:`, error);
|
|
166
|
+
}
|
|
167
|
+
return skills;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Reload all skills from all sources
|
|
171
|
+
* Precedence: workspace > managed > bundled
|
|
172
|
+
* Uses debouncing to prevent rapid consecutive calls
|
|
173
|
+
*/
|
|
174
|
+
async reloadSkills() {
|
|
175
|
+
// If already reloading, return the existing promise
|
|
176
|
+
if (this.isReloading && this.reloadPromise) {
|
|
177
|
+
return this.reloadPromise;
|
|
178
|
+
}
|
|
179
|
+
// Clear any pending debounce timer
|
|
180
|
+
if (this.reloadDebounceTimer) {
|
|
181
|
+
clearTimeout(this.reloadDebounceTimer);
|
|
182
|
+
this.reloadDebounceTimer = null;
|
|
183
|
+
}
|
|
184
|
+
// Create a debounced reload promise
|
|
185
|
+
this.reloadPromise = new Promise((resolve) => {
|
|
186
|
+
this.reloadDebounceTimer = setTimeout(async () => {
|
|
187
|
+
this.isReloading = true;
|
|
188
|
+
try {
|
|
189
|
+
const result = await this.doReloadSkills();
|
|
190
|
+
resolve(result);
|
|
191
|
+
}
|
|
192
|
+
finally {
|
|
193
|
+
this.isReloading = false;
|
|
194
|
+
this.reloadPromise = null;
|
|
195
|
+
this.reloadDebounceTimer = null;
|
|
196
|
+
}
|
|
197
|
+
}, RELOAD_DEBOUNCE_MS);
|
|
198
|
+
});
|
|
199
|
+
return this.reloadPromise;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Internal method to actually reload skills
|
|
203
|
+
*/
|
|
204
|
+
async doReloadSkills() {
|
|
205
|
+
this.skills.clear();
|
|
206
|
+
// Load from all sources
|
|
207
|
+
const bundledSkills = this.loadSkillsFromDir(this.bundledSkillsDir, 'bundled');
|
|
208
|
+
const managedSkills = this.loadSkillsFromDir(this.managedSkillsDir, 'managed');
|
|
209
|
+
const workspaceSkills = this.workspaceSkillsDir
|
|
210
|
+
? this.loadSkillsFromDir(this.workspaceSkillsDir, 'workspace')
|
|
211
|
+
: [];
|
|
212
|
+
// Merge with precedence: bundled < managed < workspace
|
|
213
|
+
for (const skill of bundledSkills) {
|
|
214
|
+
this.skills.set(skill.id, skill);
|
|
215
|
+
}
|
|
216
|
+
for (const skill of managedSkills) {
|
|
217
|
+
this.skills.set(skill.id, skill);
|
|
218
|
+
}
|
|
219
|
+
for (const skill of workspaceSkills) {
|
|
220
|
+
this.skills.set(skill.id, skill);
|
|
221
|
+
}
|
|
222
|
+
const counts = {
|
|
223
|
+
bundled: bundledSkills.length,
|
|
224
|
+
managed: managedSkills.length,
|
|
225
|
+
workspace: workspaceSkills.length,
|
|
226
|
+
total: this.skills.size,
|
|
227
|
+
};
|
|
228
|
+
console.log(`[CustomSkillLoader] Loaded ${counts.total} skills ` +
|
|
229
|
+
`(bundled: ${counts.bundled}, managed: ${counts.managed}, workspace: ${counts.workspace})`);
|
|
230
|
+
return this.listSkills();
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Validate a skill has all required fields
|
|
234
|
+
*/
|
|
235
|
+
validateSkill(skill) {
|
|
236
|
+
return !!(skill.id &&
|
|
237
|
+
skill.name &&
|
|
238
|
+
skill.description &&
|
|
239
|
+
skill.prompt &&
|
|
240
|
+
typeof skill.id === 'string' &&
|
|
241
|
+
typeof skill.name === 'string' &&
|
|
242
|
+
typeof skill.description === 'string' &&
|
|
243
|
+
typeof skill.prompt === 'string');
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* List all loaded skills
|
|
247
|
+
*/
|
|
248
|
+
listSkills() {
|
|
249
|
+
return Array.from(this.skills.values()).sort((a, b) => {
|
|
250
|
+
// Sort by priority first (lower = higher priority, default 100)
|
|
251
|
+
const priorityA = a.priority ?? 100;
|
|
252
|
+
const priorityB = b.priority ?? 100;
|
|
253
|
+
if (priorityA !== priorityB) {
|
|
254
|
+
return priorityA - priorityB;
|
|
255
|
+
}
|
|
256
|
+
// Then by category
|
|
257
|
+
if (a.category && b.category && a.category !== b.category) {
|
|
258
|
+
return a.category.localeCompare(b.category);
|
|
259
|
+
}
|
|
260
|
+
// Finally by name
|
|
261
|
+
return a.name.localeCompare(b.name);
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* List skills by source
|
|
266
|
+
*/
|
|
267
|
+
listSkillsBySource(source) {
|
|
268
|
+
return this.listSkills().filter((skill) => skill.source === source);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* List only task skills (excludes guideline skills)
|
|
272
|
+
* Used for the skill dropdown in UI
|
|
273
|
+
*/
|
|
274
|
+
listTaskSkills() {
|
|
275
|
+
return this.listSkills().filter((skill) => skill.type !== 'guideline');
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* List only guideline skills
|
|
279
|
+
*/
|
|
280
|
+
listGuidelineSkills() {
|
|
281
|
+
return this.listSkills().filter((skill) => skill.type === 'guideline');
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Get enabled guideline skills for system prompt injection
|
|
285
|
+
* Returns the combined prompt content of all enabled guideline skills
|
|
286
|
+
* Guidelines are validated and sanitized to prevent injection attacks
|
|
287
|
+
*/
|
|
288
|
+
getEnabledGuidelinesPrompt() {
|
|
289
|
+
const enabledGuidelines = this.listGuidelineSkills().filter((skill) => skill.enabled !== false);
|
|
290
|
+
if (enabledGuidelines.length === 0) {
|
|
291
|
+
return '';
|
|
292
|
+
}
|
|
293
|
+
// Validate and sanitize each guideline before injection
|
|
294
|
+
return enabledGuidelines.map((skill) => {
|
|
295
|
+
const validation = security_1.InputSanitizer.validateSkillGuidelines(skill.prompt);
|
|
296
|
+
if (!validation.valid) {
|
|
297
|
+
console.warn(`[CustomSkillLoader] Security: Skill "${skill.id}" guidelines contain suspicious patterns:`, validation.issues);
|
|
298
|
+
return validation.sanitized;
|
|
299
|
+
}
|
|
300
|
+
return skill.prompt;
|
|
301
|
+
}).join('\n\n');
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* List skills that can be automatically invoked by the model
|
|
305
|
+
* Excludes guidelines and skills with disableModelInvocation set
|
|
306
|
+
*/
|
|
307
|
+
listModelInvocableSkills() {
|
|
308
|
+
return this.listSkills().filter((skill) => {
|
|
309
|
+
// Exclude guideline skills
|
|
310
|
+
if (skill.type === 'guideline')
|
|
311
|
+
return false;
|
|
312
|
+
// Exclude disabled skills
|
|
313
|
+
if (skill.enabled === false)
|
|
314
|
+
return false;
|
|
315
|
+
// Exclude skills that explicitly disable model invocation
|
|
316
|
+
if (skill.invocation?.disableModelInvocation === true)
|
|
317
|
+
return false;
|
|
318
|
+
return true;
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Get formatted skill descriptions for the model's system prompt
|
|
323
|
+
* Groups skills by category and includes parameter info
|
|
324
|
+
*/
|
|
325
|
+
getSkillDescriptionsForModel() {
|
|
326
|
+
const skills = this.listModelInvocableSkills();
|
|
327
|
+
if (skills.length === 0) {
|
|
328
|
+
return '';
|
|
329
|
+
}
|
|
330
|
+
// Group skills by category
|
|
331
|
+
const byCategory = {};
|
|
332
|
+
for (const skill of skills) {
|
|
333
|
+
const category = skill.category || 'General';
|
|
334
|
+
if (!byCategory[category]) {
|
|
335
|
+
byCategory[category] = [];
|
|
336
|
+
}
|
|
337
|
+
byCategory[category].push(skill);
|
|
338
|
+
}
|
|
339
|
+
// Format descriptions
|
|
340
|
+
const lines = [];
|
|
341
|
+
for (const [category, categorySkills] of Object.entries(byCategory).sort()) {
|
|
342
|
+
lines.push(`\n${category}:`);
|
|
343
|
+
for (const skill of categorySkills) {
|
|
344
|
+
const paramInfo = skill.parameters?.length
|
|
345
|
+
? ` (params: ${skill.parameters.map(p => p.name + (p.required ? '*' : '')).join(', ')})`
|
|
346
|
+
: '';
|
|
347
|
+
lines.push(`- ${skill.id}: ${skill.description}${paramInfo}`);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return lines.join('\n');
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Get a specific skill by ID
|
|
354
|
+
*/
|
|
355
|
+
getSkill(id) {
|
|
356
|
+
return this.skills.get(id);
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Expand a skill's prompt template with parameter values
|
|
360
|
+
*/
|
|
361
|
+
expandPrompt(skill, parameterValues) {
|
|
362
|
+
let prompt = skill.prompt;
|
|
363
|
+
// Replace {{param}} placeholders with values
|
|
364
|
+
if (skill.parameters) {
|
|
365
|
+
for (const param of skill.parameters) {
|
|
366
|
+
const value = parameterValues[param.name] ?? param.default ?? '';
|
|
367
|
+
const placeholder = new RegExp(`\\{\\{${param.name}\\}\\}`, 'g');
|
|
368
|
+
prompt = prompt.replace(placeholder, String(value));
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
// Remove any remaining unreplaced placeholders
|
|
372
|
+
prompt = prompt.replace(/\{\{[^}]+\}\}/g, '');
|
|
373
|
+
return prompt.trim();
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Get eligible skills (those that meet all requirements)
|
|
377
|
+
*/
|
|
378
|
+
async getEligibleSkills() {
|
|
379
|
+
const statusEntries = await this.getSkillStatus();
|
|
380
|
+
return statusEntries.skills
|
|
381
|
+
.filter((entry) => entry.eligible)
|
|
382
|
+
.map((entry) => this.getSkill(entry.id))
|
|
383
|
+
.filter(Boolean);
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Get skill status with eligibility information
|
|
387
|
+
*/
|
|
388
|
+
async getSkillStatus() {
|
|
389
|
+
const skills = this.listSkills();
|
|
390
|
+
const statusEntries = await this.eligibilityChecker.buildStatusEntries(skills);
|
|
391
|
+
const summary = {
|
|
392
|
+
total: statusEntries.length,
|
|
393
|
+
eligible: statusEntries.filter((s) => s.eligible).length,
|
|
394
|
+
disabled: statusEntries.filter((s) => s.disabled).length,
|
|
395
|
+
missingRequirements: statusEntries.filter((s) => !s.eligible && !s.disabled && !s.blockedByAllowlist).length,
|
|
396
|
+
};
|
|
397
|
+
return {
|
|
398
|
+
workspaceDir: this.workspaceSkillsDir || '',
|
|
399
|
+
managedSkillsDir: this.managedSkillsDir,
|
|
400
|
+
bundledSkillsDir: this.bundledSkillsDir,
|
|
401
|
+
skills: statusEntries,
|
|
402
|
+
summary,
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Get status for a single skill
|
|
407
|
+
*/
|
|
408
|
+
async getSkillStatusEntry(skillId) {
|
|
409
|
+
const skill = this.getSkill(skillId);
|
|
410
|
+
if (!skill)
|
|
411
|
+
return null;
|
|
412
|
+
return this.eligibilityChecker.buildStatusEntry(skill);
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Update skills config
|
|
416
|
+
*/
|
|
417
|
+
updateConfig(config) {
|
|
418
|
+
this.skillsConfig = config;
|
|
419
|
+
this.eligibilityChecker.updateConfig(config);
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Clear eligibility cache (useful after installing dependencies)
|
|
423
|
+
*/
|
|
424
|
+
clearEligibilityCache() {
|
|
425
|
+
this.eligibilityChecker.clearCache();
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Create a skill in the workspace directory
|
|
429
|
+
*/
|
|
430
|
+
async createWorkspaceSkill(skill) {
|
|
431
|
+
if (!this.workspaceSkillsDir) {
|
|
432
|
+
throw new Error('Workspace skills directory not set');
|
|
433
|
+
}
|
|
434
|
+
// Ensure workspace skills directory exists
|
|
435
|
+
if (!fs.existsSync(this.workspaceSkillsDir)) {
|
|
436
|
+
fs.mkdirSync(this.workspaceSkillsDir, { recursive: true });
|
|
437
|
+
}
|
|
438
|
+
const filePath = path.join(this.workspaceSkillsDir, `${skill.id}.json`);
|
|
439
|
+
const fullSkill = {
|
|
440
|
+
...skill,
|
|
441
|
+
source: 'workspace',
|
|
442
|
+
filePath,
|
|
443
|
+
};
|
|
444
|
+
fs.writeFileSync(filePath, JSON.stringify(fullSkill, null, 2), 'utf-8');
|
|
445
|
+
// Reload skills to pick up the new one
|
|
446
|
+
await this.reloadSkills();
|
|
447
|
+
return fullSkill;
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Update a skill
|
|
451
|
+
*/
|
|
452
|
+
async updateSkill(skillId, updates) {
|
|
453
|
+
const skill = this.getSkill(skillId);
|
|
454
|
+
if (!skill || !skill.filePath) {
|
|
455
|
+
return null;
|
|
456
|
+
}
|
|
457
|
+
// Only allow updating workspace and managed skills
|
|
458
|
+
if (skill.source === 'bundled') {
|
|
459
|
+
throw new Error('Cannot update bundled skills');
|
|
460
|
+
}
|
|
461
|
+
const updatedSkill = {
|
|
462
|
+
...skill,
|
|
463
|
+
...updates,
|
|
464
|
+
};
|
|
465
|
+
fs.writeFileSync(skill.filePath, JSON.stringify(updatedSkill, null, 2), 'utf-8');
|
|
466
|
+
// Reload skills to pick up the update
|
|
467
|
+
await this.reloadSkills();
|
|
468
|
+
return updatedSkill;
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Delete a workspace skill
|
|
472
|
+
*/
|
|
473
|
+
async deleteWorkspaceSkill(skillId) {
|
|
474
|
+
const skill = this.getSkill(skillId);
|
|
475
|
+
if (!skill || !skill.filePath || skill.source !== 'workspace') {
|
|
476
|
+
return false;
|
|
477
|
+
}
|
|
478
|
+
try {
|
|
479
|
+
fs.unlinkSync(skill.filePath);
|
|
480
|
+
await this.reloadSkills();
|
|
481
|
+
return true;
|
|
482
|
+
}
|
|
483
|
+
catch {
|
|
484
|
+
return false;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Delete a managed skill (from registry)
|
|
489
|
+
*/
|
|
490
|
+
async deleteManagedSkill(skillId) {
|
|
491
|
+
const skill = this.getSkill(skillId);
|
|
492
|
+
if (!skill || !skill.filePath || skill.source !== 'managed') {
|
|
493
|
+
return false;
|
|
494
|
+
}
|
|
495
|
+
try {
|
|
496
|
+
fs.unlinkSync(skill.filePath);
|
|
497
|
+
await this.reloadSkills();
|
|
498
|
+
return true;
|
|
499
|
+
}
|
|
500
|
+
catch {
|
|
501
|
+
return false;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Open the managed skills folder in the system file browser
|
|
506
|
+
*/
|
|
507
|
+
async openSkillsFolder() {
|
|
508
|
+
const { shell } = await Promise.resolve().then(() => __importStar(require('electron')));
|
|
509
|
+
// Ensure directory exists
|
|
510
|
+
if (!fs.existsSync(this.managedSkillsDir)) {
|
|
511
|
+
fs.mkdirSync(this.managedSkillsDir, { recursive: true });
|
|
512
|
+
}
|
|
513
|
+
await shell.openPath(this.managedSkillsDir);
|
|
514
|
+
}
|
|
515
|
+
// === Backward compatibility aliases ===
|
|
516
|
+
/**
|
|
517
|
+
* Create a skill (alias for createWorkspaceSkill)
|
|
518
|
+
* @deprecated Use createWorkspaceSkill instead
|
|
519
|
+
*/
|
|
520
|
+
async createSkill(skill) {
|
|
521
|
+
// For backward compatibility, if no workspace is set, create in managed dir
|
|
522
|
+
if (!this.workspaceSkillsDir) {
|
|
523
|
+
const filePath = path.join(this.managedSkillsDir, `${skill.id}.json`);
|
|
524
|
+
const fullSkill = {
|
|
525
|
+
...skill,
|
|
526
|
+
source: 'managed',
|
|
527
|
+
filePath,
|
|
528
|
+
};
|
|
529
|
+
fs.writeFileSync(filePath, JSON.stringify(fullSkill, null, 2), 'utf-8');
|
|
530
|
+
await this.reloadSkills();
|
|
531
|
+
return fullSkill;
|
|
532
|
+
}
|
|
533
|
+
return this.createWorkspaceSkill(skill);
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Delete a skill (checks both workspace and managed)
|
|
537
|
+
* @deprecated Use deleteWorkspaceSkill or deleteManagedSkill instead
|
|
538
|
+
*/
|
|
539
|
+
async deleteSkill(skillId) {
|
|
540
|
+
const skill = this.getSkill(skillId);
|
|
541
|
+
if (!skill)
|
|
542
|
+
return false;
|
|
543
|
+
if (skill.source === 'workspace') {
|
|
544
|
+
return this.deleteWorkspaceSkill(skillId);
|
|
545
|
+
}
|
|
546
|
+
if (skill.source === 'managed') {
|
|
547
|
+
return this.deleteManagedSkill(skillId);
|
|
548
|
+
}
|
|
549
|
+
return false;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
exports.CustomSkillLoader = CustomSkillLoader;
|
|
553
|
+
// Singleton instance
|
|
554
|
+
let instance = null;
|
|
555
|
+
function getCustomSkillLoader(config) {
|
|
556
|
+
if (!instance) {
|
|
557
|
+
instance = new CustomSkillLoader(config);
|
|
558
|
+
}
|
|
559
|
+
return instance;
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Reset the singleton instance (useful for testing)
|
|
563
|
+
*/
|
|
564
|
+
function resetCustomSkillLoader() {
|
|
565
|
+
instance = null;
|
|
566
|
+
}
|