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,800 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Personality Settings Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages agent personality preferences including:
|
|
5
|
+
* - Base personality (professional, friendly, etc.)
|
|
6
|
+
* - Famous assistant personas (Jarvis, Friday, etc.)
|
|
7
|
+
* - Response style preferences (emoji, length, etc.)
|
|
8
|
+
* - Personality quirks (catchphrases, sign-offs)
|
|
9
|
+
* - Relationship data (user name, milestones)
|
|
10
|
+
*
|
|
11
|
+
* Settings are stored encrypted in the database using SecureSettingsRepository.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { app } from 'electron';
|
|
15
|
+
import * as fs from 'fs';
|
|
16
|
+
import * as path from 'path';
|
|
17
|
+
import { EventEmitter } from 'events';
|
|
18
|
+
import {
|
|
19
|
+
PersonalitySettings,
|
|
20
|
+
PersonalityId,
|
|
21
|
+
PersonaId,
|
|
22
|
+
PersonalityDefinition,
|
|
23
|
+
PersonaDefinition,
|
|
24
|
+
ResponseStylePreferences,
|
|
25
|
+
PersonalityQuirks,
|
|
26
|
+
RelationshipData,
|
|
27
|
+
PERSONALITY_DEFINITIONS,
|
|
28
|
+
PERSONA_DEFINITIONS,
|
|
29
|
+
ANALOGY_DOMAINS,
|
|
30
|
+
DEFAULT_RESPONSE_STYLE,
|
|
31
|
+
DEFAULT_QUIRKS,
|
|
32
|
+
DEFAULT_RELATIONSHIP,
|
|
33
|
+
getPersonalityById,
|
|
34
|
+
getPersonaById,
|
|
35
|
+
} from '../../shared/types';
|
|
36
|
+
import { SecureSettingsRepository } from '../database/SecureSettingsRepository';
|
|
37
|
+
|
|
38
|
+
const LEGACY_SETTINGS_FILE = 'personality-settings.json';
|
|
39
|
+
|
|
40
|
+
const DEFAULT_AGENT_NAME = 'CoWork';
|
|
41
|
+
|
|
42
|
+
const DEFAULT_SETTINGS: PersonalitySettings = {
|
|
43
|
+
activePersonality: 'professional',
|
|
44
|
+
customPrompt: '',
|
|
45
|
+
customName: 'Custom Assistant',
|
|
46
|
+
agentName: DEFAULT_AGENT_NAME,
|
|
47
|
+
activePersona: 'companion',
|
|
48
|
+
responseStyle: DEFAULT_RESPONSE_STYLE,
|
|
49
|
+
quirks: DEFAULT_QUIRKS,
|
|
50
|
+
relationship: DEFAULT_RELATIONSHIP,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// Milestone thresholds for celebrations
|
|
54
|
+
const MILESTONES = [1, 10, 25, 50, 100, 250, 500, 1000];
|
|
55
|
+
|
|
56
|
+
// Event emitter for personality settings changes
|
|
57
|
+
const personalityEvents = new EventEmitter();
|
|
58
|
+
|
|
59
|
+
export class PersonalityManager {
|
|
60
|
+
private static legacySettingsPath: string;
|
|
61
|
+
private static cachedSettings: PersonalitySettings | null = null;
|
|
62
|
+
private static initialized = false;
|
|
63
|
+
private static migrationCompleted = false;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Subscribe to settings changed events.
|
|
67
|
+
* The callback receives the updated settings.
|
|
68
|
+
*/
|
|
69
|
+
static onSettingsChanged(callback: (settings: PersonalitySettings) => void): () => void {
|
|
70
|
+
personalityEvents.on('settingsChanged', callback);
|
|
71
|
+
return () => personalityEvents.off('settingsChanged', callback);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Remove all event listeners (useful for testing)
|
|
76
|
+
*/
|
|
77
|
+
static removeAllListeners(): void {
|
|
78
|
+
personalityEvents.removeAllListeners();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Emit a settings changed event
|
|
83
|
+
*/
|
|
84
|
+
private static emitSettingsChanged(): void {
|
|
85
|
+
if (this.cachedSettings) {
|
|
86
|
+
personalityEvents.emit('settingsChanged', this.cachedSettings);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Initialize the PersonalityManager
|
|
92
|
+
*/
|
|
93
|
+
static initialize(): void {
|
|
94
|
+
if (this.initialized) {
|
|
95
|
+
return; // Already initialized
|
|
96
|
+
}
|
|
97
|
+
const userDataPath = app.getPath('userData');
|
|
98
|
+
this.legacySettingsPath = path.join(userDataPath, LEGACY_SETTINGS_FILE);
|
|
99
|
+
this.initialized = true;
|
|
100
|
+
console.log('[PersonalityManager] Initialized');
|
|
101
|
+
|
|
102
|
+
// Migrate from legacy JSON file to encrypted database
|
|
103
|
+
this.migrateFromLegacyFile();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Migrate settings from legacy JSON file to encrypted database
|
|
108
|
+
*/
|
|
109
|
+
private static migrateFromLegacyFile(): void {
|
|
110
|
+
if (this.migrationCompleted) return;
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
// Check if SecureSettingsRepository is initialized
|
|
114
|
+
if (!SecureSettingsRepository.isInitialized()) {
|
|
115
|
+
console.log('[PersonalityManager] SecureSettingsRepository not yet initialized, skipping migration');
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const repository = SecureSettingsRepository.getInstance();
|
|
120
|
+
|
|
121
|
+
// Check if already migrated to database
|
|
122
|
+
if (repository.exists('personality')) {
|
|
123
|
+
this.migrationCompleted = true;
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Check if legacy file exists
|
|
128
|
+
if (!fs.existsSync(this.legacySettingsPath)) {
|
|
129
|
+
console.log('[PersonalityManager] No legacy settings file found');
|
|
130
|
+
this.migrationCompleted = true;
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
console.log('[PersonalityManager] Migrating settings from legacy JSON file to encrypted database...');
|
|
135
|
+
|
|
136
|
+
// Create backup before migration
|
|
137
|
+
const backupPath = this.legacySettingsPath + '.migration-backup';
|
|
138
|
+
fs.copyFileSync(this.legacySettingsPath, backupPath);
|
|
139
|
+
|
|
140
|
+
try {
|
|
141
|
+
// Read legacy settings
|
|
142
|
+
const data = fs.readFileSync(this.legacySettingsPath, 'utf-8');
|
|
143
|
+
const parsed = JSON.parse(data);
|
|
144
|
+
const legacySettings = {
|
|
145
|
+
...DEFAULT_SETTINGS,
|
|
146
|
+
...parsed,
|
|
147
|
+
responseStyle: { ...DEFAULT_RESPONSE_STYLE, ...parsed.responseStyle },
|
|
148
|
+
quirks: { ...DEFAULT_QUIRKS, ...parsed.quirks },
|
|
149
|
+
relationship: { ...DEFAULT_RELATIONSHIP, ...parsed.relationship },
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
// Save to encrypted database
|
|
153
|
+
repository.save('personality', legacySettings);
|
|
154
|
+
console.log('[PersonalityManager] Settings migrated to encrypted database');
|
|
155
|
+
|
|
156
|
+
// Migration successful - delete backup and original
|
|
157
|
+
fs.unlinkSync(backupPath);
|
|
158
|
+
fs.unlinkSync(this.legacySettingsPath);
|
|
159
|
+
console.log('[PersonalityManager] Migration complete, cleaned up legacy files');
|
|
160
|
+
|
|
161
|
+
this.migrationCompleted = true;
|
|
162
|
+
} catch (migrationError) {
|
|
163
|
+
console.error('[PersonalityManager] Migration failed, backup preserved at:', backupPath);
|
|
164
|
+
throw migrationError;
|
|
165
|
+
}
|
|
166
|
+
} catch (error) {
|
|
167
|
+
console.error('[PersonalityManager] Migration failed:', error);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Ensure the manager is initialized before use
|
|
173
|
+
*/
|
|
174
|
+
private static ensureInitialized(): void {
|
|
175
|
+
if (!this.initialized) {
|
|
176
|
+
throw new Error('[PersonalityManager] Not initialized. Call PersonalityManager.initialize() first.');
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Load settings from encrypted database (with caching)
|
|
182
|
+
*/
|
|
183
|
+
static loadSettings(): PersonalitySettings {
|
|
184
|
+
this.ensureInitialized();
|
|
185
|
+
|
|
186
|
+
if (this.cachedSettings) {
|
|
187
|
+
return this.cachedSettings;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Deep copy DEFAULT_SETTINGS to avoid mutating the original constants
|
|
191
|
+
let settings: PersonalitySettings = {
|
|
192
|
+
...DEFAULT_SETTINGS,
|
|
193
|
+
responseStyle: { ...DEFAULT_RESPONSE_STYLE },
|
|
194
|
+
quirks: { ...DEFAULT_QUIRKS },
|
|
195
|
+
relationship: { ...DEFAULT_RELATIONSHIP },
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
try {
|
|
199
|
+
// Try to load from encrypted database
|
|
200
|
+
if (SecureSettingsRepository.isInitialized()) {
|
|
201
|
+
const repository = SecureSettingsRepository.getInstance();
|
|
202
|
+
const stored = repository.load<PersonalitySettings>('personality');
|
|
203
|
+
if (stored) {
|
|
204
|
+
settings = {
|
|
205
|
+
...DEFAULT_SETTINGS,
|
|
206
|
+
...stored,
|
|
207
|
+
responseStyle: { ...DEFAULT_RESPONSE_STYLE, ...stored.responseStyle },
|
|
208
|
+
quirks: { ...DEFAULT_QUIRKS, ...stored.quirks },
|
|
209
|
+
relationship: { ...DEFAULT_RELATIONSHIP, ...stored.relationship },
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Validate values
|
|
215
|
+
if (!isValidPersonalityId(settings.activePersonality)) {
|
|
216
|
+
settings.activePersonality = DEFAULT_SETTINGS.activePersonality;
|
|
217
|
+
}
|
|
218
|
+
if (!isValidPersonaId(settings.activePersona)) {
|
|
219
|
+
settings.activePersona = DEFAULT_SETTINGS.activePersona;
|
|
220
|
+
}
|
|
221
|
+
} catch (error) {
|
|
222
|
+
console.error('[PersonalityManager] Failed to load settings:', error);
|
|
223
|
+
// Deep copy DEFAULT_SETTINGS to avoid mutating the original constants
|
|
224
|
+
settings = {
|
|
225
|
+
...DEFAULT_SETTINGS,
|
|
226
|
+
responseStyle: { ...DEFAULT_RESPONSE_STYLE },
|
|
227
|
+
quirks: { ...DEFAULT_QUIRKS },
|
|
228
|
+
relationship: { ...DEFAULT_RELATIONSHIP },
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
this.cachedSettings = settings;
|
|
233
|
+
return settings;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Save settings to encrypted database
|
|
238
|
+
*/
|
|
239
|
+
static saveSettings(settings: PersonalitySettings): void {
|
|
240
|
+
try {
|
|
241
|
+
if (!SecureSettingsRepository.isInitialized()) {
|
|
242
|
+
throw new Error('SecureSettingsRepository not initialized');
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Load existing settings to preserve fields not being updated
|
|
246
|
+
const existingSettings = this.loadSettings();
|
|
247
|
+
|
|
248
|
+
// Validate and merge with existing settings
|
|
249
|
+
const validatedSettings: PersonalitySettings = {
|
|
250
|
+
activePersonality: isValidPersonalityId(settings.activePersonality)
|
|
251
|
+
? settings.activePersonality
|
|
252
|
+
: existingSettings.activePersonality,
|
|
253
|
+
customPrompt: settings.customPrompt ?? existingSettings.customPrompt,
|
|
254
|
+
customName: settings.customName ?? existingSettings.customName,
|
|
255
|
+
agentName: settings.agentName ?? existingSettings.agentName,
|
|
256
|
+
activePersona: isValidPersonaId(settings.activePersona)
|
|
257
|
+
? settings.activePersona
|
|
258
|
+
: existingSettings.activePersona,
|
|
259
|
+
responseStyle: settings.responseStyle
|
|
260
|
+
? { ...existingSettings.responseStyle, ...settings.responseStyle }
|
|
261
|
+
: existingSettings.responseStyle,
|
|
262
|
+
quirks: settings.quirks
|
|
263
|
+
? { ...existingSettings.quirks, ...settings.quirks }
|
|
264
|
+
: existingSettings.quirks,
|
|
265
|
+
relationship: settings.relationship
|
|
266
|
+
? { ...existingSettings.relationship, ...settings.relationship }
|
|
267
|
+
: existingSettings.relationship,
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
const repository = SecureSettingsRepository.getInstance();
|
|
271
|
+
repository.save('personality', validatedSettings);
|
|
272
|
+
this.cachedSettings = validatedSettings;
|
|
273
|
+
console.log('[PersonalityManager] Settings saved to encrypted database');
|
|
274
|
+
this.emitSettingsChanged();
|
|
275
|
+
} catch (error) {
|
|
276
|
+
console.error('[PersonalityManager] Failed to save settings:', error);
|
|
277
|
+
throw error;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Set the active personality
|
|
283
|
+
*/
|
|
284
|
+
static setActivePersonality(personalityId: PersonalityId): void {
|
|
285
|
+
const settings = this.loadSettings();
|
|
286
|
+
settings.activePersonality = personalityId;
|
|
287
|
+
this.saveSettings(settings);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Set the active persona
|
|
292
|
+
*/
|
|
293
|
+
static setActivePersona(personaId: PersonaId): void {
|
|
294
|
+
const settings = this.loadSettings();
|
|
295
|
+
settings.activePersona = personaId;
|
|
296
|
+
|
|
297
|
+
// Optionally apply persona's suggested name and quirks
|
|
298
|
+
const persona = getPersonaById(personaId);
|
|
299
|
+
if (persona && personaId !== 'none') {
|
|
300
|
+
if (persona.suggestedName && !settings.agentName) {
|
|
301
|
+
settings.agentName = persona.suggestedName;
|
|
302
|
+
}
|
|
303
|
+
if (persona.sampleCatchphrase && !settings.quirks?.catchphrase) {
|
|
304
|
+
settings.quirks = {
|
|
305
|
+
...settings.quirks,
|
|
306
|
+
catchphrase: persona.sampleCatchphrase,
|
|
307
|
+
} as PersonalityQuirks;
|
|
308
|
+
}
|
|
309
|
+
if (persona.sampleSignOff && !settings.quirks?.signOff) {
|
|
310
|
+
settings.quirks = {
|
|
311
|
+
...settings.quirks,
|
|
312
|
+
signOff: persona.sampleSignOff,
|
|
313
|
+
} as PersonalityQuirks;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
this.saveSettings(settings);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Get the currently active personality definition
|
|
322
|
+
*/
|
|
323
|
+
static getActivePersonality(): PersonalityDefinition | undefined {
|
|
324
|
+
const settings = this.loadSettings();
|
|
325
|
+
return getPersonalityById(settings.activePersonality);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Get the currently active persona definition
|
|
330
|
+
*/
|
|
331
|
+
static getActivePersona(): PersonaDefinition | undefined {
|
|
332
|
+
const settings = this.loadSettings();
|
|
333
|
+
return getPersonaById(settings.activePersona || 'none');
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Get the personality prompt for a specific personality ID.
|
|
338
|
+
* Used by sub-agents to get their configured personality prompt.
|
|
339
|
+
*/
|
|
340
|
+
static getPersonalityPromptById(personalityId: string): string {
|
|
341
|
+
// Validate and get the personality definition
|
|
342
|
+
if (!isValidPersonalityId(personalityId)) {
|
|
343
|
+
console.warn(`[PersonalityManager] Invalid personality ID: ${personalityId}, using default`);
|
|
344
|
+
return this.getPersonalityPrompt();
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
const personality = getPersonalityById(personalityId as PersonalityId);
|
|
348
|
+
if (!personality?.promptTemplate) {
|
|
349
|
+
return this.getPersonalityPrompt();
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Return just the base personality prompt for sub-agents
|
|
353
|
+
// (no persona overlay, no quirks - keep it focused)
|
|
354
|
+
return personality.promptTemplate;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Get the full personality prompt combining all elements
|
|
359
|
+
*/
|
|
360
|
+
static getPersonalityPrompt(): string {
|
|
361
|
+
const settings = this.loadSettings();
|
|
362
|
+
const parts: string[] = [];
|
|
363
|
+
|
|
364
|
+
// 1. Base personality prompt
|
|
365
|
+
if (settings.activePersonality === 'custom') {
|
|
366
|
+
if (settings.customPrompt) {
|
|
367
|
+
parts.push(settings.customPrompt);
|
|
368
|
+
}
|
|
369
|
+
} else {
|
|
370
|
+
const personality = getPersonalityById(settings.activePersonality);
|
|
371
|
+
if (personality?.promptTemplate) {
|
|
372
|
+
parts.push(personality.promptTemplate);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// 2. Persona overlay (if not 'none')
|
|
377
|
+
if (settings.activePersona && settings.activePersona !== 'none') {
|
|
378
|
+
const persona = getPersonaById(settings.activePersona);
|
|
379
|
+
if (persona?.promptTemplate) {
|
|
380
|
+
parts.push(persona.promptTemplate);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// 3. Response style preferences
|
|
385
|
+
const stylePrompt = this.getResponseStylePrompt(settings.responseStyle);
|
|
386
|
+
if (stylePrompt) {
|
|
387
|
+
parts.push(stylePrompt);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// 4. Quirks
|
|
391
|
+
const quirksPrompt = this.getQuirksPrompt(settings.quirks);
|
|
392
|
+
if (quirksPrompt) {
|
|
393
|
+
parts.push(quirksPrompt);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return parts.join('\n\n');
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Generate prompt section for response style preferences
|
|
401
|
+
*/
|
|
402
|
+
private static getResponseStylePrompt(style?: ResponseStylePreferences): string {
|
|
403
|
+
if (!style) return '';
|
|
404
|
+
|
|
405
|
+
const lines: string[] = ['RESPONSE STYLE PREFERENCES:'];
|
|
406
|
+
|
|
407
|
+
// Emoji usage
|
|
408
|
+
switch (style.emojiUsage) {
|
|
409
|
+
case 'none':
|
|
410
|
+
lines.push('- Do NOT use emojis in responses');
|
|
411
|
+
break;
|
|
412
|
+
case 'minimal':
|
|
413
|
+
lines.push('- Use emojis sparingly, only when they add clear value');
|
|
414
|
+
break;
|
|
415
|
+
case 'moderate':
|
|
416
|
+
lines.push('- Feel free to use emojis to enhance communication');
|
|
417
|
+
break;
|
|
418
|
+
case 'expressive':
|
|
419
|
+
lines.push('- Use emojis liberally to make responses engaging and expressive');
|
|
420
|
+
break;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Response length
|
|
424
|
+
switch (style.responseLength) {
|
|
425
|
+
case 'terse':
|
|
426
|
+
lines.push('- Keep responses very brief and to the point');
|
|
427
|
+
lines.push('- Omit explanations unless explicitly requested');
|
|
428
|
+
break;
|
|
429
|
+
case 'balanced':
|
|
430
|
+
lines.push('- Provide balanced responses with appropriate detail');
|
|
431
|
+
break;
|
|
432
|
+
case 'detailed':
|
|
433
|
+
lines.push('- Provide comprehensive, detailed responses');
|
|
434
|
+
lines.push('- Include context, explanations, and related information');
|
|
435
|
+
break;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// Code comment style
|
|
439
|
+
switch (style.codeCommentStyle) {
|
|
440
|
+
case 'minimal':
|
|
441
|
+
lines.push('- When writing code, use minimal comments (only for complex logic)');
|
|
442
|
+
break;
|
|
443
|
+
case 'moderate':
|
|
444
|
+
lines.push('- When writing code, include helpful comments for key sections');
|
|
445
|
+
break;
|
|
446
|
+
case 'verbose':
|
|
447
|
+
lines.push('- When writing code, include detailed comments explaining the approach');
|
|
448
|
+
break;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// Explanation depth
|
|
452
|
+
switch (style.explanationDepth) {
|
|
453
|
+
case 'expert':
|
|
454
|
+
lines.push('- Assume the user is an expert - skip basic explanations');
|
|
455
|
+
lines.push('- Focus on advanced considerations and edge cases');
|
|
456
|
+
break;
|
|
457
|
+
case 'balanced':
|
|
458
|
+
lines.push('- Balance explanations for a competent but curious user');
|
|
459
|
+
break;
|
|
460
|
+
case 'teaching':
|
|
461
|
+
lines.push('- Explain concepts thoroughly as you would to a student');
|
|
462
|
+
lines.push('- Include "why" explanations and learning opportunities');
|
|
463
|
+
break;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
return lines.length > 1 ? lines.join('\n') : '';
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Generate prompt section for personality quirks
|
|
471
|
+
*/
|
|
472
|
+
private static getQuirksPrompt(quirks?: PersonalityQuirks): string {
|
|
473
|
+
if (!quirks) return '';
|
|
474
|
+
|
|
475
|
+
const lines: string[] = [];
|
|
476
|
+
|
|
477
|
+
if (quirks.catchphrase) {
|
|
478
|
+
lines.push(`- Occasionally use your catchphrase: "${quirks.catchphrase}"`);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
if (quirks.signOff) {
|
|
482
|
+
lines.push(`- End longer responses with your signature sign-off: "${quirks.signOff}"`);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
if (quirks.analogyDomain && quirks.analogyDomain !== 'none') {
|
|
486
|
+
const domain = ANALOGY_DOMAINS[quirks.analogyDomain];
|
|
487
|
+
lines.push(`- When using analogies, prefer ${domain.name.toLowerCase()}-themed examples`);
|
|
488
|
+
if (domain.examples) {
|
|
489
|
+
lines.push(` Example: ${domain.examples}`);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
return lines.length > 0 ? 'PERSONALITY QUIRKS:\n' + lines.join('\n') : '';
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Get the identity prompt that tells the agent who it is
|
|
498
|
+
*/
|
|
499
|
+
static getIdentityPrompt(): string {
|
|
500
|
+
const settings = this.loadSettings();
|
|
501
|
+
const agentName = settings.agentName || DEFAULT_AGENT_NAME;
|
|
502
|
+
const relationship = settings.relationship;
|
|
503
|
+
const userName = relationship?.userName;
|
|
504
|
+
const tasksCompleted = relationship?.tasksCompleted || 0;
|
|
505
|
+
const projectsWorkedOn = relationship?.projectsWorkedOn || [];
|
|
506
|
+
|
|
507
|
+
let prompt = `YOUR IDENTITY:
|
|
508
|
+
You are ${agentName}, an AI assistant built into CoWork OS.
|
|
509
|
+
- When asked about your name or identity, say you are "${agentName}"
|
|
510
|
+
- Do NOT claim to be Claude, ChatGPT, or any other AI assistant
|
|
511
|
+
- You are a customizable assistant that users can personalize`;
|
|
512
|
+
|
|
513
|
+
// Add user relationship context
|
|
514
|
+
if (userName) {
|
|
515
|
+
prompt += `\n\nUSER CONTEXT:
|
|
516
|
+
- The user's name is "${userName}"
|
|
517
|
+
- You have completed ${tasksCompleted} tasks together`;
|
|
518
|
+
if (projectsWorkedOn.length > 0) {
|
|
519
|
+
prompt += `\n- Projects worked on: ${projectsWorkedOn.slice(-5).join(', ')}`;
|
|
520
|
+
}
|
|
521
|
+
prompt += `\n\nWhen asked "who am I?" or similar identity questions, respond with the USER's information (their name, your shared history) - NOT system info.`;
|
|
522
|
+
} else {
|
|
523
|
+
prompt += `\n\nUSER CONTEXT:
|
|
524
|
+
- You don't know the user's name yet
|
|
525
|
+
- When asked "who am I?", acknowledge you don't know their name and invite them to introduce themselves
|
|
526
|
+
- IMPORTANT: When the user introduces themselves (e.g., "I'm Alice", "My name is Bob", "Call me Charlie"),
|
|
527
|
+
use the set_user_name tool IMMEDIATELY to store their name so you can remember it for future conversations`;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
return prompt;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Get a personalized greeting based on relationship data
|
|
535
|
+
*/
|
|
536
|
+
static getGreeting(): string {
|
|
537
|
+
const settings = this.loadSettings();
|
|
538
|
+
const agentName = settings.agentName || DEFAULT_AGENT_NAME;
|
|
539
|
+
const userName = settings.relationship?.userName;
|
|
540
|
+
const tasksCompleted = settings.relationship?.tasksCompleted || 0;
|
|
541
|
+
|
|
542
|
+
// Check for milestone
|
|
543
|
+
const milestone = this.checkMilestone(tasksCompleted);
|
|
544
|
+
if (milestone) {
|
|
545
|
+
const congratsMessages = [
|
|
546
|
+
`We've completed ${milestone} tasks together!`,
|
|
547
|
+
`${milestone} tasks and counting! Great working with you${userName ? `, ${userName}` : ''}!`,
|
|
548
|
+
`Milestone achieved: ${milestone} tasks completed together!`,
|
|
549
|
+
];
|
|
550
|
+
return congratsMessages[Math.floor(Math.random() * congratsMessages.length)];
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// Regular greeting
|
|
554
|
+
if (userName) {
|
|
555
|
+
const greetings = [
|
|
556
|
+
`Welcome back, ${userName}!`,
|
|
557
|
+
`Good to see you, ${userName}!`,
|
|
558
|
+
`Hey ${userName}, ready to work?`,
|
|
559
|
+
`${userName}! Let's get things done.`,
|
|
560
|
+
];
|
|
561
|
+
return greetings[Math.floor(Math.random() * greetings.length)];
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
return '';
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Check if a milestone was reached
|
|
569
|
+
*/
|
|
570
|
+
private static checkMilestone(tasksCompleted: number): number | null {
|
|
571
|
+
const settings = this.loadSettings();
|
|
572
|
+
const lastCelebrated = settings.relationship?.lastMilestoneCelebrated || 0;
|
|
573
|
+
|
|
574
|
+
for (const milestone of MILESTONES) {
|
|
575
|
+
if (tasksCompleted >= milestone && milestone > lastCelebrated) {
|
|
576
|
+
return milestone;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
return null;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* Record a completed task and update relationship data
|
|
584
|
+
*/
|
|
585
|
+
static recordTaskCompleted(workspaceName?: string): void {
|
|
586
|
+
const settings = this.loadSettings();
|
|
587
|
+
const relationship = settings.relationship || { ...DEFAULT_RELATIONSHIP };
|
|
588
|
+
|
|
589
|
+
relationship.tasksCompleted = (relationship.tasksCompleted || 0) + 1;
|
|
590
|
+
|
|
591
|
+
if (!relationship.firstInteraction) {
|
|
592
|
+
relationship.firstInteraction = Date.now();
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
if (workspaceName && !relationship.projectsWorkedOn.includes(workspaceName)) {
|
|
596
|
+
relationship.projectsWorkedOn = [...relationship.projectsWorkedOn, workspaceName];
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
// Update milestone if reached
|
|
600
|
+
const milestone = this.checkMilestone(relationship.tasksCompleted);
|
|
601
|
+
if (milestone) {
|
|
602
|
+
relationship.lastMilestoneCelebrated = milestone;
|
|
603
|
+
console.log(`[PersonalityManager] Milestone reached: ${milestone} tasks completed!`);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
settings.relationship = relationship;
|
|
607
|
+
this.saveSettings(settings);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* Set the user's name
|
|
612
|
+
*/
|
|
613
|
+
static setUserName(name: string): void {
|
|
614
|
+
const settings = this.loadSettings();
|
|
615
|
+
settings.relationship = {
|
|
616
|
+
...settings.relationship,
|
|
617
|
+
userName: name.trim() || undefined,
|
|
618
|
+
} as RelationshipData;
|
|
619
|
+
this.saveSettings(settings);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
/**
|
|
623
|
+
* Get the user's name
|
|
624
|
+
*/
|
|
625
|
+
static getUserName(): string | undefined {
|
|
626
|
+
return this.loadSettings().relationship?.userName;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
/**
|
|
630
|
+
* Get all available personality definitions
|
|
631
|
+
*/
|
|
632
|
+
static getDefinitions(): PersonalityDefinition[] {
|
|
633
|
+
return PERSONALITY_DEFINITIONS;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* Get all available persona definitions
|
|
638
|
+
*/
|
|
639
|
+
static getPersonaDefinitions(): PersonaDefinition[] {
|
|
640
|
+
return PERSONA_DEFINITIONS;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Get the agent's name
|
|
645
|
+
*/
|
|
646
|
+
static getAgentName(): string {
|
|
647
|
+
const settings = this.loadSettings();
|
|
648
|
+
return settings.agentName || DEFAULT_AGENT_NAME;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* Set the agent's name
|
|
653
|
+
*/
|
|
654
|
+
static setAgentName(name: string): void {
|
|
655
|
+
const settings = this.loadSettings();
|
|
656
|
+
settings.agentName = name.trim() || DEFAULT_AGENT_NAME;
|
|
657
|
+
this.saveSettings(settings);
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
/**
|
|
661
|
+
* Update response style preferences
|
|
662
|
+
*/
|
|
663
|
+
static setResponseStyle(style: Partial<ResponseStylePreferences>): void {
|
|
664
|
+
const settings = this.loadSettings();
|
|
665
|
+
settings.responseStyle = {
|
|
666
|
+
...DEFAULT_RESPONSE_STYLE,
|
|
667
|
+
...settings.responseStyle,
|
|
668
|
+
...style,
|
|
669
|
+
};
|
|
670
|
+
this.saveSettings(settings);
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* Update personality quirks
|
|
675
|
+
*/
|
|
676
|
+
static setQuirks(quirks: Partial<PersonalityQuirks>): void {
|
|
677
|
+
const settings = this.loadSettings();
|
|
678
|
+
settings.quirks = {
|
|
679
|
+
...DEFAULT_QUIRKS,
|
|
680
|
+
...settings.quirks,
|
|
681
|
+
...quirks,
|
|
682
|
+
};
|
|
683
|
+
this.saveSettings(settings);
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* Get relationship stats for display
|
|
688
|
+
*/
|
|
689
|
+
static getRelationshipStats(): {
|
|
690
|
+
tasksCompleted: number;
|
|
691
|
+
projectsCount: number;
|
|
692
|
+
daysTogether: number;
|
|
693
|
+
nextMilestone: number | null;
|
|
694
|
+
} {
|
|
695
|
+
const settings = this.loadSettings();
|
|
696
|
+
const relationship = settings.relationship || DEFAULT_RELATIONSHIP;
|
|
697
|
+
|
|
698
|
+
const tasksCompleted = relationship.tasksCompleted || 0;
|
|
699
|
+
const projectsCount = relationship.projectsWorkedOn?.length || 0;
|
|
700
|
+
const daysTogether = relationship.firstInteraction
|
|
701
|
+
? Math.floor((Date.now() - relationship.firstInteraction) / (1000 * 60 * 60 * 24))
|
|
702
|
+
: 0;
|
|
703
|
+
|
|
704
|
+
// Find next milestone
|
|
705
|
+
let nextMilestone: number | null = null;
|
|
706
|
+
for (const milestone of MILESTONES) {
|
|
707
|
+
if (milestone > tasksCompleted) {
|
|
708
|
+
nextMilestone = milestone;
|
|
709
|
+
break;
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
return { tasksCompleted, projectsCount, daysTogether, nextMilestone };
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
/**
|
|
717
|
+
* Clear the settings cache
|
|
718
|
+
*/
|
|
719
|
+
static clearCache(): void {
|
|
720
|
+
this.cachedSettings = null;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* Get default settings
|
|
725
|
+
*/
|
|
726
|
+
static getDefaults(): PersonalitySettings {
|
|
727
|
+
return { ...DEFAULT_SETTINGS };
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
/**
|
|
731
|
+
* Reset all settings to defaults
|
|
732
|
+
* This clears everything except relationship data (to preserve task history)
|
|
733
|
+
*/
|
|
734
|
+
static resetToDefaults(preserveRelationship = true): void {
|
|
735
|
+
this.ensureInitialized();
|
|
736
|
+
|
|
737
|
+
// Deep copy DEFAULT_SETTINGS to avoid mutating the original constants
|
|
738
|
+
let newSettings: PersonalitySettings = {
|
|
739
|
+
...DEFAULT_SETTINGS,
|
|
740
|
+
responseStyle: { ...DEFAULT_RESPONSE_STYLE },
|
|
741
|
+
quirks: { ...DEFAULT_QUIRKS },
|
|
742
|
+
relationship: { ...DEFAULT_RELATIONSHIP },
|
|
743
|
+
};
|
|
744
|
+
|
|
745
|
+
if (preserveRelationship) {
|
|
746
|
+
// Load current settings to get relationship data (even if cache is cleared)
|
|
747
|
+
const currentSettings = this.loadSettings();
|
|
748
|
+
if (currentSettings.relationship) {
|
|
749
|
+
// Preserve the relationship data (task count, user name, etc.)
|
|
750
|
+
newSettings.relationship = { ...currentSettings.relationship };
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
// Save to encrypted database
|
|
755
|
+
if (SecureSettingsRepository.isInitialized()) {
|
|
756
|
+
const repository = SecureSettingsRepository.getInstance();
|
|
757
|
+
repository.save('personality', newSettings);
|
|
758
|
+
}
|
|
759
|
+
this.cachedSettings = newSettings;
|
|
760
|
+
console.log('[PersonalityManager] Settings reset to defaults', preserveRelationship ? '(preserved relationship)' : '');
|
|
761
|
+
this.emitSettingsChanged();
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
/**
|
|
765
|
+
* Check if the manager has been initialized
|
|
766
|
+
*/
|
|
767
|
+
static isInitialized(): boolean {
|
|
768
|
+
return this.initialized;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
function isValidPersonalityId(value: unknown): value is PersonalityId {
|
|
773
|
+
const validIds: PersonalityId[] = [
|
|
774
|
+
'professional',
|
|
775
|
+
'friendly',
|
|
776
|
+
'concise',
|
|
777
|
+
'creative',
|
|
778
|
+
'technical',
|
|
779
|
+
'casual',
|
|
780
|
+
'custom',
|
|
781
|
+
];
|
|
782
|
+
return validIds.includes(value as PersonalityId);
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
function isValidPersonaId(value: unknown): value is PersonaId {
|
|
786
|
+
const validIds: PersonaId[] = [
|
|
787
|
+
'none',
|
|
788
|
+
'jarvis',
|
|
789
|
+
'friday',
|
|
790
|
+
'hal',
|
|
791
|
+
'computer',
|
|
792
|
+
'alfred',
|
|
793
|
+
'intern',
|
|
794
|
+
'sensei',
|
|
795
|
+
'pirate',
|
|
796
|
+
'noir',
|
|
797
|
+
'companion',
|
|
798
|
+
];
|
|
799
|
+
return validIds.includes(value as PersonaId);
|
|
800
|
+
}
|