cowork-os 0.3.21 → 0.3.25
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/README.md +372 -10
- package/connectors/README.md +20 -0
- package/connectors/asana-mcp/README.md +24 -0
- package/connectors/asana-mcp/dist/index.js +427 -0
- package/connectors/asana-mcp/package.json +15 -0
- package/connectors/asana-mcp/src/index.ts +553 -0
- package/connectors/asana-mcp/tsconfig.json +13 -0
- package/connectors/hubspot-mcp/README.md +35 -0
- package/connectors/hubspot-mcp/dist/index.js +454 -0
- package/connectors/hubspot-mcp/package.json +15 -0
- package/connectors/hubspot-mcp/src/index.ts +562 -0
- package/connectors/hubspot-mcp/tsconfig.json +13 -0
- package/connectors/jira-mcp/README.md +49 -0
- package/connectors/jira-mcp/dist/index.js +588 -0
- package/connectors/jira-mcp/package.json +15 -0
- package/connectors/jira-mcp/src/index.ts +711 -0
- package/connectors/jira-mcp/tsconfig.json +13 -0
- package/connectors/linear-mcp/README.md +22 -0
- package/connectors/linear-mcp/dist/index.js +402 -0
- package/connectors/linear-mcp/package.json +15 -0
- package/connectors/linear-mcp/src/index.ts +522 -0
- package/connectors/linear-mcp/tsconfig.json +13 -0
- package/connectors/okta-mcp/README.md +24 -0
- package/connectors/okta-mcp/dist/index.js +411 -0
- package/connectors/okta-mcp/package.json +15 -0
- package/connectors/okta-mcp/src/index.ts +520 -0
- package/connectors/okta-mcp/tsconfig.json +13 -0
- package/connectors/salesforce-mcp/README.md +47 -0
- package/connectors/salesforce-mcp/dist/index.js +584 -0
- package/connectors/salesforce-mcp/package.json +15 -0
- package/connectors/salesforce-mcp/src/index.ts +722 -0
- package/connectors/salesforce-mcp/tsconfig.json +13 -0
- package/connectors/servicenow-mcp/README.md +26 -0
- package/connectors/servicenow-mcp/dist/index.js +400 -0
- package/connectors/servicenow-mcp/package.json +15 -0
- package/connectors/servicenow-mcp/src/index.ts +500 -0
- package/connectors/servicenow-mcp/tsconfig.json +13 -0
- package/connectors/templates/mcp-connector/README.md +31 -0
- package/connectors/templates/mcp-connector/package.json +15 -0
- package/connectors/templates/mcp-connector/src/index.ts +330 -0
- package/connectors/templates/mcp-connector/tsconfig.json +13 -0
- package/connectors/zendesk-mcp/README.md +40 -0
- package/connectors/zendesk-mcp/dist/index.js +431 -0
- package/connectors/zendesk-mcp/package.json +15 -0
- package/connectors/zendesk-mcp/src/index.ts +543 -0
- package/connectors/zendesk-mcp/tsconfig.json +13 -0
- package/dist/electron/electron/agent/custom-skill-loader.js +31 -1
- package/dist/electron/electron/agent/daemon.js +189 -13
- package/dist/electron/electron/agent/executor.js +895 -78
- package/dist/electron/electron/agent/llm/anthropic-compatible-provider.js +177 -0
- package/dist/electron/electron/agent/llm/azure-openai-provider.js +328 -0
- package/dist/electron/electron/agent/llm/bedrock-provider.js +49 -9
- package/dist/electron/electron/agent/llm/github-copilot-provider.js +97 -0
- package/dist/electron/electron/agent/llm/groq-provider.js +33 -0
- package/dist/electron/electron/agent/llm/index.js +13 -1
- package/dist/electron/electron/agent/llm/kimi-provider.js +33 -0
- package/dist/electron/electron/agent/llm/openai-compatible-provider.js +116 -0
- package/dist/electron/electron/agent/llm/openai-compatible.js +111 -0
- package/dist/electron/electron/agent/llm/openai-oauth.js +2 -1
- package/dist/electron/electron/agent/llm/openrouter-provider.js +1 -1
- package/dist/electron/electron/agent/llm/provider-factory.js +350 -4
- package/dist/electron/electron/agent/llm/types.js +66 -1
- package/dist/electron/electron/agent/llm/xai-provider.js +33 -0
- package/dist/electron/electron/agent/search/provider-factory.js +38 -2
- package/dist/electron/electron/agent/tools/box-tools.js +231 -0
- package/dist/electron/electron/agent/tools/builtin-settings.js +28 -0
- package/dist/electron/electron/agent/tools/dropbox-tools.js +237 -0
- package/dist/electron/electron/agent/tools/file-tools.js +66 -3
- package/dist/electron/electron/agent/tools/google-drive-tools.js +227 -0
- package/dist/electron/electron/agent/tools/grep-tools.js +90 -10
- package/dist/electron/electron/agent/tools/image-tools.js +11 -1
- package/dist/electron/electron/agent/tools/notion-tools.js +312 -0
- package/dist/electron/electron/agent/tools/onedrive-tools.js +217 -0
- package/dist/electron/electron/agent/tools/registry.js +548 -10
- package/dist/electron/electron/agent/tools/search-tools.js +28 -10
- package/dist/electron/electron/agent/tools/sharepoint-tools.js +243 -0
- package/dist/electron/electron/agent/tools/shell-tools.js +12 -3
- package/dist/electron/electron/agent/tools/x-tools.js +1 -1
- package/dist/electron/electron/agents/agent-dispatch.js +63 -0
- package/dist/electron/electron/database/repositories.js +19 -5
- package/dist/electron/electron/database/schema.js +8 -0
- package/dist/electron/electron/gateway/channels/whatsapp.js +55 -0
- package/dist/electron/electron/gateway/index.js +75 -1
- package/dist/electron/electron/gateway/router.js +209 -154
- package/dist/electron/electron/ipc/canvas-handlers.js +5 -0
- package/dist/electron/electron/ipc/handlers.js +763 -267
- package/dist/electron/electron/main.js +63 -0
- package/dist/electron/electron/mcp/oauth/connector-oauth.js +333 -0
- package/dist/electron/electron/mcp/registry/MCPRegistryManager.js +503 -154
- package/dist/electron/electron/memory/MemoryService.js +2 -1
- package/dist/electron/electron/preload.js +78 -1
- package/dist/electron/electron/settings/appearance-manager.js +18 -1
- package/dist/electron/electron/settings/box-manager.js +54 -0
- package/dist/electron/electron/settings/dropbox-manager.js +54 -0
- package/dist/electron/electron/settings/google-drive-manager.js +54 -0
- package/dist/electron/electron/settings/notion-manager.js +56 -0
- package/dist/electron/electron/settings/onedrive-manager.js +54 -0
- package/dist/electron/electron/settings/sharepoint-manager.js +54 -0
- package/dist/electron/electron/utils/box-api.js +153 -0
- package/dist/electron/electron/utils/dropbox-api.js +144 -0
- package/dist/electron/electron/utils/env-migration.js +19 -0
- package/dist/electron/electron/utils/google-drive-api.js +152 -0
- package/dist/electron/electron/utils/notion-api.js +103 -0
- package/dist/electron/electron/utils/onedrive-api.js +113 -0
- package/dist/electron/electron/utils/sharepoint-api.js +109 -0
- package/dist/electron/electron/utils/validation.js +98 -3
- package/dist/electron/electron/utils/x-cli.js +1 -1
- package/dist/electron/shared/channelMessages.js +284 -3
- package/dist/electron/shared/llm-provider-catalog.js +198 -0
- package/dist/electron/shared/types.js +90 -1
- package/package.json +14 -3
- package/resources/skills/nano-banana-pro.json +4 -4
- package/resources/skills/openai-image-gen.json +3 -3
- package/resources/skills/scripts/gen.py +163 -0
- package/resources/skills/scripts/generate_image.py +91 -0
- package/src/electron/agent/custom-skill-loader.ts +34 -1
- package/src/electron/agent/daemon.ts +210 -14
- package/src/electron/agent/executor.ts +1124 -85
- package/src/electron/agent/llm/anthropic-compatible-provider.ts +214 -0
- package/src/electron/agent/llm/azure-openai-provider.ts +388 -0
- package/src/electron/agent/llm/bedrock-provider.ts +62 -9
- package/src/electron/agent/llm/github-copilot-provider.ts +117 -0
- package/src/electron/agent/llm/groq-provider.ts +39 -0
- package/src/electron/agent/llm/index.ts +6 -0
- package/src/electron/agent/llm/kimi-provider.ts +39 -0
- package/src/electron/agent/llm/openai-compatible-provider.ts +153 -0
- package/src/electron/agent/llm/openai-compatible.ts +133 -0
- package/src/electron/agent/llm/openai-oauth.ts +2 -1
- package/src/electron/agent/llm/openrouter-provider.ts +2 -1
- package/src/electron/agent/llm/provider-factory.ts +459 -6
- package/src/electron/agent/llm/types.ts +95 -1
- package/src/electron/agent/llm/xai-provider.ts +39 -0
- package/src/electron/agent/search/provider-factory.ts +43 -2
- package/src/electron/agent/tools/box-tools.ts +239 -0
- package/src/electron/agent/tools/builtin-settings.ts +36 -0
- package/src/electron/agent/tools/dropbox-tools.ts +237 -0
- package/src/electron/agent/tools/file-tools.ts +66 -3
- package/src/electron/agent/tools/gmail-tools.ts +240 -0
- package/src/electron/agent/tools/google-calendar-tools.ts +258 -0
- package/src/electron/agent/tools/google-drive-tools.ts +228 -0
- package/src/electron/agent/tools/grep-tools.ts +97 -12
- package/src/electron/agent/tools/image-tools.ts +11 -1
- package/src/electron/agent/tools/notion-tools.ts +330 -0
- package/src/electron/agent/tools/onedrive-tools.ts +217 -0
- package/src/electron/agent/tools/registry.ts +794 -10
- package/src/electron/agent/tools/search-tools.ts +29 -11
- package/src/electron/agent/tools/sharepoint-tools.ts +247 -0
- package/src/electron/agent/tools/shell-tools.ts +11 -3
- package/src/electron/agent/tools/x-tools.ts +1 -1
- package/src/electron/agents/agent-dispatch.ts +79 -0
- package/src/electron/database/SecureSettingsRepository.ts +7 -1
- package/src/electron/database/repositories.ts +58 -6
- package/src/electron/database/schema.ts +8 -0
- package/src/electron/gateway/channels/discord.ts +4 -0
- package/src/electron/gateway/channels/google-chat.ts +3 -0
- package/src/electron/gateway/channels/line.ts +3 -0
- package/src/electron/gateway/channels/matrix-client.ts +15 -0
- package/src/electron/gateway/channels/matrix.ts +31 -0
- package/src/electron/gateway/channels/mattermost.ts +3 -0
- package/src/electron/gateway/channels/signal.ts +3 -0
- package/src/electron/gateway/channels/slack.ts +9 -4
- package/src/electron/gateway/channels/teams.ts +4 -0
- package/src/electron/gateway/channels/telegram.ts +2 -0
- package/src/electron/gateway/channels/twitch.ts +2 -0
- package/src/electron/gateway/channels/types.ts +8 -0
- package/src/electron/gateway/channels/whatsapp.ts +66 -0
- package/src/electron/gateway/index.ts +95 -2
- package/src/electron/gateway/router.ts +231 -161
- package/src/electron/gateway/security.ts +21 -9
- package/src/electron/ipc/canvas-handlers.ts +10 -0
- package/src/electron/ipc/handlers.ts +848 -292
- package/src/electron/main.ts +35 -0
- package/src/electron/mcp/oauth/connector-oauth.ts +448 -0
- package/src/electron/mcp/registry/MCPRegistryManager.ts +343 -12
- package/src/electron/memory/MemoryService.ts +7 -1
- package/src/electron/preload.ts +200 -5
- package/src/electron/settings/appearance-manager.ts +20 -2
- package/src/electron/settings/box-manager.ts +58 -0
- package/src/electron/settings/dropbox-manager.ts +58 -0
- package/src/electron/settings/google-workspace-manager.ts +59 -0
- package/src/electron/settings/notion-manager.ts +60 -0
- package/src/electron/settings/onedrive-manager.ts +58 -0
- package/src/electron/settings/sharepoint-manager.ts +58 -0
- package/src/electron/utils/box-api.ts +184 -0
- package/src/electron/utils/dropbox-api.ts +171 -0
- package/src/electron/utils/env-migration.ts +22 -0
- package/src/electron/utils/gmail-api.ts +121 -0
- package/src/electron/utils/google-calendar-api.ts +115 -0
- package/src/electron/utils/google-workspace-api.ts +228 -0
- package/src/electron/utils/google-workspace-auth.ts +109 -0
- package/src/electron/utils/google-workspace-oauth.ts +232 -0
- package/src/electron/utils/notion-api.ts +126 -0
- package/src/electron/utils/onedrive-api.ts +137 -0
- package/src/electron/utils/sharepoint-api.ts +132 -0
- package/src/electron/utils/validation.ts +128 -1
- package/src/electron/utils/x-cli.ts +1 -1
- package/src/renderer/App.tsx +119 -8
- package/src/renderer/components/ActivityFeedItem.tsx +34 -17
- package/src/renderer/components/AgentWorkingStatePanel.tsx +7 -5
- package/src/renderer/components/AppearanceSettings.tsx +37 -2
- package/src/renderer/components/BlueBubblesSettings.tsx +18 -7
- package/src/renderer/components/BoxSettings.tsx +203 -0
- package/src/renderer/components/BrowserView.tsx +101 -0
- package/src/renderer/components/BuiltinToolsSettings.tsx +105 -0
- package/src/renderer/components/CanvasPreview.tsx +68 -1
- package/src/renderer/components/ConnectorEnvModal.tsx +116 -0
- package/src/renderer/components/ConnectorSetupModal.tsx +566 -0
- package/src/renderer/components/ConnectorsSettings.tsx +397 -0
- package/src/renderer/components/ControlPlaneSettings.tsx +2 -0
- package/src/renderer/components/DiscordSettings.tsx +18 -7
- package/src/renderer/components/DropboxSettings.tsx +202 -0
- package/src/renderer/components/EmailSettings.tsx +18 -7
- package/src/renderer/components/FileViewer.tsx +21 -13
- package/src/renderer/components/GoogleChatSettings.tsx +17 -7
- package/src/renderer/components/GoogleWorkspaceSettings.tsx +332 -0
- package/src/renderer/components/ImessageSettings.tsx +22 -11
- package/src/renderer/components/LineIcons.tsx +376 -0
- package/src/renderer/components/LineSettings.tsx +18 -7
- package/src/renderer/components/MCPSettings.tsx +56 -0
- package/src/renderer/components/MainContent.tsx +740 -76
- package/src/renderer/components/MatrixSettings.tsx +18 -7
- package/src/renderer/components/MattermostSettings.tsx +18 -7
- package/src/renderer/components/NodesSettings.tsx +58 -99
- package/src/renderer/components/NotificationPanel.tsx +25 -11
- package/src/renderer/components/NotionSettings.tsx +231 -0
- package/src/renderer/components/Onboarding/Onboarding.tsx +13 -1
- package/src/renderer/components/OnboardingModal.tsx +70 -1
- package/src/renderer/components/OneDriveSettings.tsx +212 -0
- package/src/renderer/components/RightPanel.tsx +141 -28
- package/src/renderer/components/ScheduledTasksSettings.tsx +10 -62
- package/src/renderer/components/SearchSettings.tsx +118 -114
- package/src/renderer/components/Settings.tsx +1425 -651
- package/src/renderer/components/SharePointSettings.tsx +224 -0
- package/src/renderer/components/Sidebar.tsx +94 -19
- package/src/renderer/components/SignalSettings.tsx +18 -7
- package/src/renderer/components/SkillHubBrowser.tsx +144 -185
- package/src/renderer/components/SlackSettings.tsx +18 -7
- package/src/renderer/components/TaskQuickActions.tsx +11 -6
- package/src/renderer/components/TaskTimeline.tsx +58 -26
- package/src/renderer/components/TeamsSettings.tsx +18 -7
- package/src/renderer/components/TelegramSettings.tsx +18 -7
- package/src/renderer/components/ThemeIcon.tsx +16 -0
- package/src/renderer/components/TwitchSettings.tsx +18 -7
- package/src/renderer/components/VoiceSettings.tsx +30 -74
- package/src/renderer/components/WhatsAppSettings.tsx +48 -37
- package/src/renderer/components/WorkingStateHistory.tsx +7 -5
- package/src/renderer/components/WorkspaceSelector.tsx +42 -13
- package/src/renderer/hooks/useOnboardingFlow.ts +21 -0
- package/src/renderer/styles/index.css +2333 -209
- package/src/shared/channelMessages.ts +367 -4
- package/src/shared/llm-provider-catalog.ts +217 -0
- package/src/shared/types.ts +251 -2
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SharePoint API helpers (Microsoft Graph)
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SHAREPOINT_API_BASE = void 0;
|
|
7
|
+
exports.sharepointRequest = sharepointRequest;
|
|
8
|
+
exports.testSharePointConnection = testSharePointConnection;
|
|
9
|
+
exports.SHAREPOINT_API_BASE = 'https://graph.microsoft.com/v1.0';
|
|
10
|
+
const DEFAULT_TIMEOUT_MS = 20000;
|
|
11
|
+
function parseJsonSafe(text) {
|
|
12
|
+
const trimmed = text.trim();
|
|
13
|
+
if (!trimmed)
|
|
14
|
+
return undefined;
|
|
15
|
+
try {
|
|
16
|
+
return JSON.parse(trimmed);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function formatGraphError(status, data, fallback) {
|
|
23
|
+
const message = data?.error?.message ||
|
|
24
|
+
data?.message ||
|
|
25
|
+
fallback ||
|
|
26
|
+
'Microsoft Graph error';
|
|
27
|
+
return `Microsoft Graph error ${status}: ${message}`;
|
|
28
|
+
}
|
|
29
|
+
async function sharepointRequest(settings, options) {
|
|
30
|
+
if (!settings.accessToken) {
|
|
31
|
+
throw new Error('SharePoint access token not configured. Add it in Settings > Integrations > SharePoint.');
|
|
32
|
+
}
|
|
33
|
+
const params = new URLSearchParams();
|
|
34
|
+
if (options.query) {
|
|
35
|
+
for (const [key, value] of Object.entries(options.query)) {
|
|
36
|
+
if (value === undefined || value === null)
|
|
37
|
+
continue;
|
|
38
|
+
params.set(key, String(value));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const queryString = params.toString();
|
|
42
|
+
const url = `${exports.SHAREPOINT_API_BASE}${options.path}${queryString ? `?${queryString}` : ''}`;
|
|
43
|
+
const headers = {
|
|
44
|
+
Authorization: `Bearer ${settings.accessToken}`,
|
|
45
|
+
...(options.headers || {}),
|
|
46
|
+
};
|
|
47
|
+
const isBinaryBody = options.body instanceof Uint8Array || options.body instanceof ArrayBuffer || Buffer.isBuffer(options.body);
|
|
48
|
+
if (options.body && !isBinaryBody && options.method !== 'GET' && options.method !== 'DELETE') {
|
|
49
|
+
headers['Content-Type'] = headers['Content-Type'] || 'application/json';
|
|
50
|
+
}
|
|
51
|
+
const timeoutMs = options.timeoutMs ?? settings.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
52
|
+
const controller = new AbortController();
|
|
53
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
54
|
+
try {
|
|
55
|
+
const response = await fetch(url, {
|
|
56
|
+
method: options.method,
|
|
57
|
+
headers,
|
|
58
|
+
body: options.body
|
|
59
|
+
? isBinaryBody
|
|
60
|
+
? options.body
|
|
61
|
+
: JSON.stringify(options.body)
|
|
62
|
+
: undefined,
|
|
63
|
+
signal: controller.signal,
|
|
64
|
+
});
|
|
65
|
+
const rawText = typeof response.text === 'function' ? await response.text() : '';
|
|
66
|
+
const data = rawText ? parseJsonSafe(rawText) : undefined;
|
|
67
|
+
if (!response.ok) {
|
|
68
|
+
throw new Error(formatGraphError(response.status, data, response.statusText));
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
status: response.status,
|
|
72
|
+
data: data ?? undefined,
|
|
73
|
+
raw: rawText || undefined,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
if (error?.name === 'AbortError') {
|
|
78
|
+
throw new Error('SharePoint API request timed out');
|
|
79
|
+
}
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
finally {
|
|
83
|
+
clearTimeout(timeout);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function extractUserInfo(data) {
|
|
87
|
+
if (!data || typeof data !== 'object')
|
|
88
|
+
return {};
|
|
89
|
+
const name = data.displayName || data.name || undefined;
|
|
90
|
+
const userId = data.id || undefined;
|
|
91
|
+
return { name, userId };
|
|
92
|
+
}
|
|
93
|
+
async function testSharePointConnection(settings) {
|
|
94
|
+
try {
|
|
95
|
+
const result = await sharepointRequest(settings, { method: 'GET', path: '/me' });
|
|
96
|
+
const extracted = extractUserInfo(result.data);
|
|
97
|
+
return {
|
|
98
|
+
success: true,
|
|
99
|
+
name: extracted.name,
|
|
100
|
+
userId: extracted.userId,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
return {
|
|
105
|
+
success: false,
|
|
106
|
+
error: error?.message || 'Failed to connect to SharePoint',
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
* Provides type-safe validation to prevent malformed input attacks
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.
|
|
8
|
-
exports.HookMappingSchema = exports.HookMappingChannelSchema = void 0;
|
|
7
|
+
exports.AddChannelSchema = exports.AddEmailChannelSchema = exports.AddBlueBubblesChannelSchema = exports.AddLineChannelSchema = exports.AddTwitchChannelSchema = exports.AddMatrixChannelSchema = exports.AddMattermostChannelSchema = exports.AddSignalChannelSchema = exports.AddImessageChannelSchema = exports.SignalTrustModeSchema = exports.SignalModeSchema = exports.GroupPolicySchema = exports.DmPolicySchema = exports.AddWhatsAppChannelSchema = exports.AddSlackChannelSchema = exports.AddDiscordChannelSchema = exports.AddTelegramChannelSchema = exports.SecurityModeSchema = exports.GuardrailSettingsSchema = exports.SharePointSettingsSchema = exports.DropboxSettingsSchema = exports.GoogleDriveSettingsSchema = exports.OneDriveSettingsSchema = exports.BoxSettingsSchema = exports.NotionSettingsSchema = exports.XSettingsSchema = exports.SearchSettingsSchema = exports.SearchProviderTypeSchema = exports.LLMSettingsSchema = exports.CustomProvidersSchema = exports.CustomProviderConfigSchema = exports.KimiSettingsSchema = exports.XAISettingsSchema = exports.GroqSettingsSchema = exports.AzureSettingsSchema = exports.OpenAISettingsSchema = exports.OpenRouterSettingsSchema = exports.GeminiSettingsSchema = exports.OllamaSettingsSchema = exports.BedrockSettingsSchema = exports.AnthropicSettingsSchema = exports.LLMProviderTypeSchema = exports.ApprovalResponseSchema = exports.FileImportDataSchema = exports.FileImportSchema = exports.TaskMessageSchema = exports.TaskRenameSchema = exports.TaskCreateSchema = exports.SuccessCriteriaSchema = exports.WorkspaceCreateSchema = void 0;
|
|
8
|
+
exports.HookMappingSchema = exports.HookMappingChannelSchema = exports.MCPConnectorOAuthSchema = exports.MCPRegistrySearchSchema = exports.MCPSettingsSchema = exports.MCPServerUpdateSchema = exports.MCPServerConfigSchema = exports.MCPAuthConfigSchema = exports.MCPTransportTypeSchema = exports.StringIdSchema = exports.UUIDSchema = exports.FilePathSchema = exports.GeneratePairingSchema = exports.RevokeAccessSchema = exports.GrantAccessSchema = exports.UpdateChannelSchema = exports.ChannelConfigSchema = void 0;
|
|
9
9
|
exports.validateInput = validateInput;
|
|
10
10
|
const zod_1 = require("zod");
|
|
11
|
+
const types_1 = require("../../shared/types");
|
|
11
12
|
// Common validation patterns
|
|
12
13
|
const MAX_STRING_LENGTH = 10000;
|
|
13
14
|
const MAX_PATH_LENGTH = 4096;
|
|
@@ -54,13 +55,25 @@ exports.TaskMessageSchema = zod_1.z.object({
|
|
|
54
55
|
taskId: zod_1.z.string().uuid(),
|
|
55
56
|
message: zod_1.z.string().min(1).max(MAX_PROMPT_LENGTH),
|
|
56
57
|
});
|
|
58
|
+
exports.FileImportSchema = zod_1.z.object({
|
|
59
|
+
workspaceId: zod_1.z.string().refine((val) => val === TEMP_WORKSPACE_ID || zod_1.z.string().uuid().safeParse(val).success, { message: 'Must be a valid UUID or temp workspace ID' }),
|
|
60
|
+
files: zod_1.z.array(zod_1.z.string().min(1).max(MAX_PATH_LENGTH)).min(1).max(20),
|
|
61
|
+
});
|
|
62
|
+
exports.FileImportDataSchema = zod_1.z.object({
|
|
63
|
+
workspaceId: zod_1.z.string().refine((val) => val === TEMP_WORKSPACE_ID || zod_1.z.string().uuid().safeParse(val).success, { message: 'Must be a valid UUID or temp workspace ID' }),
|
|
64
|
+
files: zod_1.z.array(zod_1.z.object({
|
|
65
|
+
name: zod_1.z.string().min(1).max(MAX_PATH_LENGTH),
|
|
66
|
+
data: zod_1.z.string().min(1),
|
|
67
|
+
mimeType: zod_1.z.string().max(200).optional(),
|
|
68
|
+
})).min(1).max(20),
|
|
69
|
+
});
|
|
57
70
|
// ============ Approval Schemas ============
|
|
58
71
|
exports.ApprovalResponseSchema = zod_1.z.object({
|
|
59
72
|
approvalId: zod_1.z.string().uuid(),
|
|
60
73
|
approved: zod_1.z.boolean(),
|
|
61
74
|
});
|
|
62
75
|
// ============ LLM Settings Schemas ============
|
|
63
|
-
exports.LLMProviderTypeSchema = zod_1.z.enum(
|
|
76
|
+
exports.LLMProviderTypeSchema = zod_1.z.enum(types_1.LLM_PROVIDER_TYPES);
|
|
64
77
|
exports.AnthropicSettingsSchema = zod_1.z.object({
|
|
65
78
|
apiKey: zod_1.z.string().max(500).optional(),
|
|
66
79
|
}).optional();
|
|
@@ -85,6 +98,7 @@ exports.GeminiSettingsSchema = zod_1.z.object({
|
|
|
85
98
|
exports.OpenRouterSettingsSchema = zod_1.z.object({
|
|
86
99
|
apiKey: zod_1.z.string().max(500).optional(),
|
|
87
100
|
model: zod_1.z.string().max(200).optional(),
|
|
101
|
+
baseUrl: zod_1.z.string().max(500).optional(),
|
|
88
102
|
}).optional();
|
|
89
103
|
exports.OpenAISettingsSchema = zod_1.z.object({
|
|
90
104
|
apiKey: zod_1.z.string().max(500).optional(),
|
|
@@ -95,6 +109,34 @@ exports.OpenAISettingsSchema = zod_1.z.object({
|
|
|
95
109
|
tokenExpiresAt: zod_1.z.number().optional(),
|
|
96
110
|
authMethod: zod_1.z.enum(['api_key', 'oauth']).optional(),
|
|
97
111
|
}).optional();
|
|
112
|
+
exports.AzureSettingsSchema = zod_1.z.object({
|
|
113
|
+
apiKey: zod_1.z.string().max(500).optional(),
|
|
114
|
+
endpoint: zod_1.z.string().max(500).optional(),
|
|
115
|
+
deployment: zod_1.z.string().max(200).optional(),
|
|
116
|
+
deployments: zod_1.z.array(zod_1.z.string().max(200)).max(50).optional(),
|
|
117
|
+
apiVersion: zod_1.z.string().max(200).optional(),
|
|
118
|
+
}).optional();
|
|
119
|
+
exports.GroqSettingsSchema = zod_1.z.object({
|
|
120
|
+
apiKey: zod_1.z.string().max(500).optional(),
|
|
121
|
+
model: zod_1.z.string().max(200).optional(),
|
|
122
|
+
baseUrl: zod_1.z.string().max(500).optional(),
|
|
123
|
+
}).optional();
|
|
124
|
+
exports.XAISettingsSchema = zod_1.z.object({
|
|
125
|
+
apiKey: zod_1.z.string().max(500).optional(),
|
|
126
|
+
model: zod_1.z.string().max(200).optional(),
|
|
127
|
+
baseUrl: zod_1.z.string().max(500).optional(),
|
|
128
|
+
}).optional();
|
|
129
|
+
exports.KimiSettingsSchema = zod_1.z.object({
|
|
130
|
+
apiKey: zod_1.z.string().max(500).optional(),
|
|
131
|
+
model: zod_1.z.string().max(200).optional(),
|
|
132
|
+
baseUrl: zod_1.z.string().max(500).optional(),
|
|
133
|
+
}).optional();
|
|
134
|
+
exports.CustomProviderConfigSchema = zod_1.z.object({
|
|
135
|
+
apiKey: zod_1.z.string().max(500).optional(),
|
|
136
|
+
model: zod_1.z.string().max(200).optional(),
|
|
137
|
+
baseUrl: zod_1.z.string().max(500).optional(),
|
|
138
|
+
});
|
|
139
|
+
exports.CustomProvidersSchema = zod_1.z.record(zod_1.z.string(), exports.CustomProviderConfigSchema).optional();
|
|
98
140
|
exports.LLMSettingsSchema = zod_1.z.object({
|
|
99
141
|
providerType: exports.LLMProviderTypeSchema,
|
|
100
142
|
modelKey: zod_1.z.string().max(200),
|
|
@@ -104,6 +146,11 @@ exports.LLMSettingsSchema = zod_1.z.object({
|
|
|
104
146
|
gemini: exports.GeminiSettingsSchema,
|
|
105
147
|
openrouter: exports.OpenRouterSettingsSchema,
|
|
106
148
|
openai: exports.OpenAISettingsSchema,
|
|
149
|
+
azure: exports.AzureSettingsSchema,
|
|
150
|
+
groq: exports.GroqSettingsSchema,
|
|
151
|
+
xai: exports.XAISettingsSchema,
|
|
152
|
+
kimi: exports.KimiSettingsSchema,
|
|
153
|
+
customProviders: exports.CustomProvidersSchema,
|
|
107
154
|
});
|
|
108
155
|
// ============ Search Settings Schemas ============
|
|
109
156
|
exports.SearchProviderTypeSchema = zod_1.z.enum(['tavily', 'brave', 'serpapi', 'google']).nullable();
|
|
@@ -138,6 +185,46 @@ exports.XSettingsSchema = zod_1.z.object({
|
|
|
138
185
|
cookieTimeoutMs: zod_1.z.number().int().min(1000).max(120000).optional(),
|
|
139
186
|
quoteDepth: zod_1.z.number().int().min(0).max(5).optional(),
|
|
140
187
|
});
|
|
188
|
+
// ============ Notion Settings Schema ============
|
|
189
|
+
exports.NotionSettingsSchema = zod_1.z.object({
|
|
190
|
+
enabled: zod_1.z.boolean().default(false),
|
|
191
|
+
apiKey: zod_1.z.string().max(2000).optional(),
|
|
192
|
+
notionVersion: zod_1.z.string().max(50).optional(),
|
|
193
|
+
timeoutMs: zod_1.z.number().int().min(1000).max(120000).optional(),
|
|
194
|
+
});
|
|
195
|
+
// ============ Box Settings Schema ============
|
|
196
|
+
exports.BoxSettingsSchema = zod_1.z.object({
|
|
197
|
+
enabled: zod_1.z.boolean().default(false),
|
|
198
|
+
accessToken: zod_1.z.string().max(4000).optional(),
|
|
199
|
+
timeoutMs: zod_1.z.number().int().min(1000).max(120000).optional(),
|
|
200
|
+
});
|
|
201
|
+
// ============ OneDrive Settings Schema ============
|
|
202
|
+
exports.OneDriveSettingsSchema = zod_1.z.object({
|
|
203
|
+
enabled: zod_1.z.boolean().default(false),
|
|
204
|
+
accessToken: zod_1.z.string().max(4000).optional(),
|
|
205
|
+
driveId: zod_1.z.string().max(200).optional(),
|
|
206
|
+
timeoutMs: zod_1.z.number().int().min(1000).max(120000).optional(),
|
|
207
|
+
});
|
|
208
|
+
// ============ Google Drive Settings Schema ============
|
|
209
|
+
exports.GoogleDriveSettingsSchema = zod_1.z.object({
|
|
210
|
+
enabled: zod_1.z.boolean().default(false),
|
|
211
|
+
accessToken: zod_1.z.string().max(4000).optional(),
|
|
212
|
+
timeoutMs: zod_1.z.number().int().min(1000).max(120000).optional(),
|
|
213
|
+
});
|
|
214
|
+
// ============ Dropbox Settings Schema ============
|
|
215
|
+
exports.DropboxSettingsSchema = zod_1.z.object({
|
|
216
|
+
enabled: zod_1.z.boolean().default(false),
|
|
217
|
+
accessToken: zod_1.z.string().max(4000).optional(),
|
|
218
|
+
timeoutMs: zod_1.z.number().int().min(1000).max(120000).optional(),
|
|
219
|
+
});
|
|
220
|
+
// ============ SharePoint Settings Schema ============
|
|
221
|
+
exports.SharePointSettingsSchema = zod_1.z.object({
|
|
222
|
+
enabled: zod_1.z.boolean().default(false),
|
|
223
|
+
accessToken: zod_1.z.string().max(4000).optional(),
|
|
224
|
+
siteId: zod_1.z.string().max(500).optional(),
|
|
225
|
+
driveId: zod_1.z.string().max(500).optional(),
|
|
226
|
+
timeoutMs: zod_1.z.number().int().min(1000).max(120000).optional(),
|
|
227
|
+
});
|
|
141
228
|
// ============ Guardrail Settings Schema ============
|
|
142
229
|
exports.GuardrailSettingsSchema = zod_1.z.object({
|
|
143
230
|
// Token budget
|
|
@@ -381,6 +468,14 @@ exports.MCPRegistrySearchSchema = zod_1.z.object({
|
|
|
381
468
|
limit: zod_1.z.number().int().min(1).max(100).default(50),
|
|
382
469
|
offset: zod_1.z.number().int().min(0).default(0),
|
|
383
470
|
});
|
|
471
|
+
exports.MCPConnectorOAuthSchema = zod_1.z.object({
|
|
472
|
+
provider: zod_1.z.enum(['salesforce', 'jira', 'hubspot', 'zendesk']),
|
|
473
|
+
clientId: zod_1.z.string().min(1).max(500),
|
|
474
|
+
clientSecret: zod_1.z.string().max(500).optional(),
|
|
475
|
+
scopes: zod_1.z.array(zod_1.z.string().max(200)).max(50).optional(),
|
|
476
|
+
loginUrl: zod_1.z.string().url().max(500).optional(),
|
|
477
|
+
subdomain: zod_1.z.string().max(200).optional(),
|
|
478
|
+
});
|
|
384
479
|
// ============ Hooks (Webhooks) Schemas ============
|
|
385
480
|
exports.HookMappingChannelSchema = zod_1.z.enum(['telegram', 'discord', 'slack', 'whatsapp', 'imessage', 'signal', 'mattermost', 'matrix', 'twitch', 'line', 'bluebubbles', 'email', 'last']);
|
|
386
481
|
exports.HookMappingSchema = zod_1.z.object({
|
|
@@ -47,7 +47,7 @@ function buildGlobalArgs(settings, json) {
|
|
|
47
47
|
const args = [];
|
|
48
48
|
if (settings.authMethod === 'manual') {
|
|
49
49
|
if (!settings.authToken || !settings.ct0) {
|
|
50
|
-
throw new Error('Missing auth_token or ct0. Add them in Settings >
|
|
50
|
+
throw new Error('Missing auth_token or ct0. Add them in Settings > X (Twitter).');
|
|
51
51
|
}
|
|
52
52
|
args.push('--auth-token', settings.authToken, '--ct0', settings.ct0);
|
|
53
53
|
}
|
|
@@ -10,7 +10,256 @@
|
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
11
|
exports.DEFAULT_CHANNEL_CONTEXT = void 0;
|
|
12
12
|
exports.getChannelMessage = getChannelMessage;
|
|
13
|
+
exports.getChannelUiCopy = getChannelUiCopy;
|
|
13
14
|
exports.getCompletionMessage = getCompletionMessage;
|
|
15
|
+
const CHANNEL_UI_COPY = {
|
|
16
|
+
welcomeStandard: '👋 Welcome to CoWork! Send me a task whenever you are ready.',
|
|
17
|
+
welcomeBack: '👋 Welcome back!\n\nWorkspace: *{workspaceName}*\n\nSend me what you want to do.\n\nType /help for commands.',
|
|
18
|
+
welcomeNoWorkspace: '👋 Welcome to CoWork!\n\nFirst, add a workspace:\n`/addworkspace /path/to/project`\n\nOr add one from the desktop app.',
|
|
19
|
+
welcomeSingleWorkspace: '👋 Welcome to CoWork!\n\n✅ Workspace: *{workspaceName}*\n\nTell me what you want to do.\n\nExamples:\n• "Add dark mode support"\n• "Fix the login bug"\n• "Create a new API endpoint"',
|
|
20
|
+
welcomeSelectWorkspace: '👋 Welcome to CoWork!\n\nSelect a workspace to start:\n\n{workspaceList}\nReply with a number (e.g., `1`)',
|
|
21
|
+
workspaceSelected: '✅ *{workspaceName}* selected!',
|
|
22
|
+
workspaceSelectedExample: 'You can now send tasks.\n\nExample: "Create a new React component called Button"',
|
|
23
|
+
unauthorized: '⚠️ You are not authorized to use this bot. Please contact the administrator.',
|
|
24
|
+
pairingRequired: '🔐 Please enter your pairing code to get started.',
|
|
25
|
+
pairingPrompt: '🔐 Please provide a pairing code.\n\nUsage: `/pair <code>`',
|
|
26
|
+
pairingSuccess: '✅ Pairing successful! You can now use the bot.',
|
|
27
|
+
pairingFailed: '❌ {error}',
|
|
28
|
+
unknownCommand: 'Unknown command: {command}\n\nUse /help to see available commands.',
|
|
29
|
+
statusHeader: 'Online and ready.',
|
|
30
|
+
statusNoWorkspace: '⚠️ No workspace selected. Use /workspaces to see available workspaces.',
|
|
31
|
+
statusActiveTask: '🔄 Active task: {taskTitle} ({status})',
|
|
32
|
+
workspacesNone: '📁 No workspaces configured yet.\n\nAdd a workspace in the CoWork desktop app first, or use:\n`/addworkspace /path/to/your/project`',
|
|
33
|
+
workspacesHeader: '📁 *Available Workspaces*',
|
|
34
|
+
workspacesFooter: 'Reply with the number or name to select.\nExample: `1` or `myproject`',
|
|
35
|
+
workspacesSelectPrompt: 'Tap a workspace to select it:',
|
|
36
|
+
workspaceCurrent: '📁 Current workspace: *{workspaceName}*\n`{workspacePath}`\n\nUse `/workspaces` to see available workspaces.',
|
|
37
|
+
workspaceNoneSelected: 'No workspace selected. Use `/workspaces` to see available workspaces.',
|
|
38
|
+
workspaceNotFound: '❌ Workspace not found: "{selector}"\n\nUse /workspaces to see available workspaces.',
|
|
39
|
+
workspaceNotFoundShort: '❌ Workspace not found.',
|
|
40
|
+
workspaceSet: '✅ Workspace set to: *{workspaceName}*\n`{workspacePath}`\n\nYou can now send messages to create tasks in this workspace.',
|
|
41
|
+
workspaceAddUsage: '📁 *Add Workspace*\n\nUsage: `/addworkspace <path>`\n\nExample:\n`/addworkspace /Users/john/projects/myapp`\n`/addworkspace ~/Documents`',
|
|
42
|
+
workspacePathNotDir: '❌ Path is not a directory: `{workspacePath}`',
|
|
43
|
+
workspacePathNotFound: '❌ Directory not found: `{workspacePath}`',
|
|
44
|
+
workspaceAlreadyExists: '📁 Workspace already exists!\n\n✅ Selected: *{workspaceName}*\n`{workspacePath}`',
|
|
45
|
+
workspaceAdded: '✅ Workspace added and selected!\n\n📁 *{workspaceName}*\n`{workspacePath}`\n\nYou can now send messages to create tasks in this workspace.',
|
|
46
|
+
workspaceRemoveUsage: '❌ Please specify a workspace name to remove.\n\nUsage: `/removeworkspace <name>`',
|
|
47
|
+
workspaceRemoved: '✅ Workspace "{workspaceName}" removed successfully.',
|
|
48
|
+
taskStartAck: '🚀 Task started: "{taskTitle}"\n\nI\'ll update you when it\'s ready or if I need your input.',
|
|
49
|
+
taskStartAckSimple: 'I\'m on it — I\'ll check back soon.',
|
|
50
|
+
taskStartFailed: '❌ Failed to start task: {error}',
|
|
51
|
+
taskContinueFailed: '❌ Failed to send message. Use /newtask to start a new task.',
|
|
52
|
+
agentUnavailable: '❌ Agent not available. Please try again later.',
|
|
53
|
+
workspaceMissingForTask: '❌ Workspace not found. Please select a workspace with /workspace.',
|
|
54
|
+
approvalNone: '❌ No pending approval request.',
|
|
55
|
+
approvalApproved: '✅ Approved. Working on it.',
|
|
56
|
+
approvalDenied: '🛑 Denied. Action cancelled.',
|
|
57
|
+
approvalFailed: '❌ Failed to process approval.',
|
|
58
|
+
approvalButtonApprove: '✅ Approve',
|
|
59
|
+
approvalButtonDeny: '❌ Deny',
|
|
60
|
+
approvalRequiredTitle: 'Approval Required',
|
|
61
|
+
queueCleared: '✅ Queue cleared.\n\n• Running tasks cancelled: {running}\n• Queued tasks removed: {queued}\n\nBrowser sessions and other resources have been cleaned up.',
|
|
62
|
+
queueStatus: '{statusText}',
|
|
63
|
+
cancelled: '🛑 Task cancelled.',
|
|
64
|
+
cancelNoActive: 'No active task to cancel.',
|
|
65
|
+
newTaskReady: '🆕 Ready for a new task.\n\nSend me a message describing what you want to do.',
|
|
66
|
+
retryNone: '❌ No failed task found to retry.\n\nStart a new task by sending a message.',
|
|
67
|
+
retrying: '🔄 Retrying task...\n\nOriginal prompt: "{taskTitle}"',
|
|
68
|
+
historyNone: '📋 No task history found.\n\nStart a new task by sending a message.',
|
|
69
|
+
historyHeader: '📋 *Recent Tasks*\n\n{history}',
|
|
70
|
+
skillsNone: '📚 No skills available.\n\nSkills are stored in:\n`~/Library/Application Support/cowork-os/skills/`',
|
|
71
|
+
skillsLoadFailed: '❌ Failed to load skills.',
|
|
72
|
+
skillSpecify: '❌ Please specify a skill ID.\n\nUsage: `/skill <id>`\n\nUse /skills to see available skills.',
|
|
73
|
+
skillNotFound: '❌ Skill "{skillId}" not found.\n\nUse /skills to see available skills.',
|
|
74
|
+
skillToggle: '{emoji} *{skillName}* is now {statusText}',
|
|
75
|
+
debugStatus: '🐛 Debug mode is now {statusText}',
|
|
76
|
+
shellInvalidOption: '❌ Invalid option. Use `/shell on` or `/shell off`',
|
|
77
|
+
workspaceNotFoundForShell: '❌ Workspace not found.',
|
|
78
|
+
responseFailed: '❌ Failed to process response.',
|
|
79
|
+
helpCompact: `📚 *Commands*
|
|
80
|
+
|
|
81
|
+
*Basics*
|
|
82
|
+
/workspaces - Select workspace
|
|
83
|
+
/status - Current status
|
|
84
|
+
/newtask - Fresh start
|
|
85
|
+
|
|
86
|
+
*Tasks*
|
|
87
|
+
/cancel - Stop task
|
|
88
|
+
/approve or /yes - Approve action
|
|
89
|
+
/deny or /no - Reject action
|
|
90
|
+
|
|
91
|
+
*Settings*
|
|
92
|
+
/shell on|off - Shell access
|
|
93
|
+
/models - Change AI model
|
|
94
|
+
|
|
95
|
+
━━━━━━━━━━━━━━━
|
|
96
|
+
💡 Just send your task directly!
|
|
97
|
+
Example: "Add a login form"`,
|
|
98
|
+
helpFull: `📚 *Available Commands*
|
|
99
|
+
|
|
100
|
+
*Core*
|
|
101
|
+
/start - Start the bot
|
|
102
|
+
/help - Show this help message
|
|
103
|
+
/status - Check bot status and workspace
|
|
104
|
+
/version - Show version information
|
|
105
|
+
|
|
106
|
+
*Workspaces*
|
|
107
|
+
/workspaces - List available workspaces
|
|
108
|
+
/workspace <name> - Select a workspace
|
|
109
|
+
/addworkspace <path> - Add a new workspace
|
|
110
|
+
/removeworkspace <name> - Remove a workspace
|
|
111
|
+
|
|
112
|
+
*Tasks*
|
|
113
|
+
/newtask - Start a fresh task/conversation
|
|
114
|
+
/cancel - Cancel current task
|
|
115
|
+
/retry - Retry the last failed task
|
|
116
|
+
/history - Show recent task history
|
|
117
|
+
/approve - Approve pending action (or /yes, /y)
|
|
118
|
+
/deny - Reject pending action (or /no, /n)
|
|
119
|
+
/queue - View/clear task queue
|
|
120
|
+
|
|
121
|
+
*Models*
|
|
122
|
+
/providers - List available AI providers
|
|
123
|
+
/provider <name> - Show or change provider
|
|
124
|
+
/models - List available AI models
|
|
125
|
+
/model <name> - Show or change model
|
|
126
|
+
|
|
127
|
+
*Skills*
|
|
128
|
+
/skills - List available skills
|
|
129
|
+
/skill <name> - Toggle a skill on/off
|
|
130
|
+
|
|
131
|
+
*Settings*
|
|
132
|
+
/settings - View current settings
|
|
133
|
+
/shell - Enable/disable shell commands
|
|
134
|
+
/debug - Toggle debug mode
|
|
135
|
+
|
|
136
|
+
💬 *Quick Start*
|
|
137
|
+
1. \`/workspaces\` → \`/workspace <name>\`
|
|
138
|
+
2. \`/shell on\` (if needed)
|
|
139
|
+
3. Send your task message
|
|
140
|
+
4. \`/newtask\` to start fresh`,
|
|
141
|
+
};
|
|
142
|
+
const PERSONA_CHANNEL_UI_OVERRIDES = {
|
|
143
|
+
companion: {
|
|
144
|
+
welcomeStandard: '👋 I\'m here. Send me a task whenever you\'re ready.',
|
|
145
|
+
welcomeBack: '👋 Welcome back.\n\nWorkspace: *{workspaceName}*\n\nTell me what you want to do.\n\nType /help for commands.',
|
|
146
|
+
welcomeNoWorkspace: '👋 I\'m here.\n\nAdd a workspace to begin:\n`/addworkspace /path/to/project`\n\nOr add one from the desktop app.',
|
|
147
|
+
welcomeSingleWorkspace: '👋 We\'re set.\n\n✅ Workspace: *{workspaceName}*\n\nTell me what you want to do.\n\nExamples:\n• "Add dark mode support"\n• "Fix the login bug"\n• "Create a new API endpoint"',
|
|
148
|
+
welcomeSelectWorkspace: '👋 Let\'s pick a workspace:\n\n{workspaceList}\nReply with a number (e.g., `1`)',
|
|
149
|
+
workspaceSelected: '✅ *{workspaceName}* selected.',
|
|
150
|
+
workspaceSelectedExample: 'You can send tasks now.\n\nExample: "Create a new React component called Button"',
|
|
151
|
+
pairingPrompt: '🔐 Share your pairing code so I can connect.\n\nUsage: `/pair <code>`',
|
|
152
|
+
pairingSuccess: '✅ Paired. I\'m ready.',
|
|
153
|
+
pairingFailed: '❌ {error}',
|
|
154
|
+
unknownCommand: 'I didn\'t recognize that command: {command}\n\nUse /help to see options.',
|
|
155
|
+
statusHeader: 'Here and ready.',
|
|
156
|
+
statusNoWorkspace: '⚠️ No workspace selected. Use /workspaces to choose one.',
|
|
157
|
+
workspacesNone: '📁 No workspaces yet.\n\nAdd one in the desktop app, or use:\n`/addworkspace /path/to/your/project`',
|
|
158
|
+
workspacesHeader: '📁 *Workspaces*',
|
|
159
|
+
workspacesFooter: 'Reply with a number or name.\nExample: `1` or `myproject`',
|
|
160
|
+
workspaceCurrent: '📁 Current workspace: *{workspaceName}*\n`{workspacePath}`\n\nUse `/workspaces` to switch.',
|
|
161
|
+
workspaceNoneSelected: 'No workspace selected yet. Use `/workspaces` to pick one.',
|
|
162
|
+
workspaceNotFound: '❌ I couldn\'t find "{selector}".\n\nUse /workspaces to see available workspaces.',
|
|
163
|
+
workspaceNotFoundShort: 'I couldn\'t find that workspace.',
|
|
164
|
+
workspaceSet: '✅ Workspace set: *{workspaceName}*\n`{workspacePath}`\n\nSend a message to start a task.',
|
|
165
|
+
workspaceAddUsage: '📁 *Add Workspace*\n\nUsage: `/addworkspace <path>`\n\nExample:\n`/addworkspace /Users/john/projects/myapp`\n`/addworkspace ~/Documents`',
|
|
166
|
+
workspaceAlreadyExists: '📁 Workspace already exists.\n\n✅ Selected: *{workspaceName}*\n`{workspacePath}`',
|
|
167
|
+
workspaceAdded: '✅ Workspace added and selected.\n\n📁 *{workspaceName}*\n`{workspacePath}`\n\nSend a message to start a task.',
|
|
168
|
+
workspaceRemoveUsage: 'Please specify a workspace name to remove.\n\nUsage: `/removeworkspace <name>`',
|
|
169
|
+
workspaceRemoved: 'Workspace "{workspaceName}" removed.',
|
|
170
|
+
taskStartAck: 'I\'m on it — "{taskTitle}".\n\nI\'ll check back soon or ask if I need input.',
|
|
171
|
+
taskStartAckSimple: 'I\'m on it. I\'ll check back soon.',
|
|
172
|
+
taskContinueFailed: 'I couldn\'t send that. Use /newtask to start fresh.',
|
|
173
|
+
agentUnavailable: 'I\'m not available right now. Try again in a moment.',
|
|
174
|
+
workspaceMissingForTask: 'I can\'t find a workspace. Use /workspace to select one.',
|
|
175
|
+
approvalNone: 'No pending approval right now.',
|
|
176
|
+
approvalApproved: 'Approved. I\'m working on it.',
|
|
177
|
+
approvalDenied: 'Okay. I cancelled that.',
|
|
178
|
+
approvalFailed: 'I couldn\'t process that approval.',
|
|
179
|
+
approvalButtonApprove: 'Approve',
|
|
180
|
+
approvalButtonDeny: 'Deny',
|
|
181
|
+
approvalRequiredTitle: 'Approval required',
|
|
182
|
+
queueCleared: 'Queue cleared.\n\n• Running tasks cancelled: {running}\n• Queued tasks removed: {queued}\n\nYou can start new tasks now.',
|
|
183
|
+
cancelled: 'Task cancelled.',
|
|
184
|
+
cancelNoActive: 'No active task to cancel.',
|
|
185
|
+
newTaskReady: 'Ready for a fresh task.\n\nSend me what you want to do.',
|
|
186
|
+
retryNone: 'No failed task to retry.\n\nSend a new task when you\'re ready.',
|
|
187
|
+
retrying: 'Retrying...\n\nOriginal prompt: "{taskTitle}"',
|
|
188
|
+
historyNone: 'No recent task history yet.',
|
|
189
|
+
historyHeader: 'Recent tasks:\n\n{history}',
|
|
190
|
+
skillsNone: 'No skills available yet.',
|
|
191
|
+
skillsLoadFailed: 'Couldn\'t load skills.',
|
|
192
|
+
skillSpecify: 'Please specify a skill ID.\n\nUsage: `/skill <id>`\n\nUse /skills to see available skills.',
|
|
193
|
+
skillNotFound: 'Skill "{skillId}" not found.\n\nUse /skills to see available skills.',
|
|
194
|
+
skillToggle: '{emoji} *{skillName}* is now {statusText}',
|
|
195
|
+
debugStatus: 'Debug mode is now {statusText}',
|
|
196
|
+
shellInvalidOption: 'Invalid option. Use `/shell on` or `/shell off`',
|
|
197
|
+
workspaceNotFoundForShell: 'I couldn\'t find that workspace.',
|
|
198
|
+
responseFailed: 'I couldn\'t process that response.',
|
|
199
|
+
helpCompact: `📚 *Commands*
|
|
200
|
+
|
|
201
|
+
*Basics*
|
|
202
|
+
/workspaces - Select workspace
|
|
203
|
+
/status - Current status
|
|
204
|
+
/newtask - Fresh start
|
|
205
|
+
|
|
206
|
+
*Tasks*
|
|
207
|
+
/cancel - Stop task
|
|
208
|
+
/approve or /yes - Approve action
|
|
209
|
+
/deny or /no - Reject action
|
|
210
|
+
|
|
211
|
+
*Settings*
|
|
212
|
+
/shell on|off - Shell access
|
|
213
|
+
/models - Change AI model
|
|
214
|
+
|
|
215
|
+
━━━━━━━━━━━━━━━
|
|
216
|
+
💡 Just send your task directly.
|
|
217
|
+
Example: "Add a login form"`,
|
|
218
|
+
helpFull: `📚 *Commands*
|
|
219
|
+
|
|
220
|
+
*Core*
|
|
221
|
+
/start - Start
|
|
222
|
+
/help - Help
|
|
223
|
+
/status - Status
|
|
224
|
+
/version - Version
|
|
225
|
+
|
|
226
|
+
*Workspaces*
|
|
227
|
+
/workspaces - List workspaces
|
|
228
|
+
/workspace <name> - Select workspace
|
|
229
|
+
/addworkspace <path> - Add workspace
|
|
230
|
+
/removeworkspace <name> - Remove workspace
|
|
231
|
+
|
|
232
|
+
*Tasks*
|
|
233
|
+
/newtask - New task
|
|
234
|
+
/cancel - Cancel current task
|
|
235
|
+
/retry - Retry last failed task
|
|
236
|
+
/history - Recent tasks
|
|
237
|
+
/approve - Approve (or /yes, /y)
|
|
238
|
+
/deny - Deny (or /no, /n)
|
|
239
|
+
/queue - View/clear queue
|
|
240
|
+
|
|
241
|
+
*Models*
|
|
242
|
+
/providers - List providers
|
|
243
|
+
/provider <name> - Change provider
|
|
244
|
+
/models - List models
|
|
245
|
+
/model <name> - Change model
|
|
246
|
+
|
|
247
|
+
*Skills*
|
|
248
|
+
/skills - List skills
|
|
249
|
+
/skill <name> - Toggle skill
|
|
250
|
+
|
|
251
|
+
*Settings*
|
|
252
|
+
/settings - Current settings
|
|
253
|
+
/shell - Toggle shell access
|
|
254
|
+
/debug - Toggle debug mode
|
|
255
|
+
|
|
256
|
+
💬 *Quick Start*
|
|
257
|
+
1. \`/workspaces\` → \`/workspace <name>\`
|
|
258
|
+
2. \`/shell on\` if needed
|
|
259
|
+
3. Send your task
|
|
260
|
+
4. \`/newtask\` to reset`,
|
|
261
|
+
},
|
|
262
|
+
};
|
|
14
263
|
/**
|
|
15
264
|
* Message templates organized by personality type
|
|
16
265
|
*/
|
|
@@ -79,6 +328,17 @@ const CHANNEL_MESSAGES = {
|
|
|
79
328
|
approvalNeeded: 'Approval needed.',
|
|
80
329
|
},
|
|
81
330
|
};
|
|
331
|
+
const PERSONA_CHANNEL_MESSAGE_OVERRIDES = {
|
|
332
|
+
companion: {
|
|
333
|
+
taskComplete: 'All set.',
|
|
334
|
+
taskCompleteWithResult: 'All set.\n\n{result}',
|
|
335
|
+
taskFailed: 'I hit a snag: {error}',
|
|
336
|
+
toolError: 'I ran into an issue with {tool}: {error}',
|
|
337
|
+
followUpProcessed: 'Got it. I\'m on it.',
|
|
338
|
+
followUpFailed: 'I couldn\'t complete that: {error}',
|
|
339
|
+
approvalNeeded: 'I need your OK on this.',
|
|
340
|
+
},
|
|
341
|
+
};
|
|
82
342
|
/**
|
|
83
343
|
* Emoji mappings for message types
|
|
84
344
|
*/
|
|
@@ -110,10 +370,13 @@ function addEmoji(message, key, emojiUsage) {
|
|
|
110
370
|
* Get a personalized channel message
|
|
111
371
|
*/
|
|
112
372
|
function getChannelMessage(key, ctx, replacements) {
|
|
113
|
-
const { personality, emojiUsage, quirks } = ctx;
|
|
373
|
+
const { personality, emojiUsage, quirks, persona } = ctx;
|
|
114
374
|
// Get base message for personality
|
|
115
375
|
const messages = CHANNEL_MESSAGES[personality] || CHANNEL_MESSAGES.professional;
|
|
116
|
-
|
|
376
|
+
const personaOverride = persona
|
|
377
|
+
? PERSONA_CHANNEL_MESSAGE_OVERRIDES[persona]?.[key]
|
|
378
|
+
: undefined;
|
|
379
|
+
let message = personaOverride || messages[key] || CHANNEL_MESSAGES.professional[key] || key;
|
|
117
380
|
// Replace placeholders
|
|
118
381
|
if (replacements) {
|
|
119
382
|
for (const [placeholder, value] of Object.entries(replacements)) {
|
|
@@ -128,6 +391,22 @@ function getChannelMessage(key, ctx, replacements) {
|
|
|
128
391
|
}
|
|
129
392
|
return message;
|
|
130
393
|
}
|
|
394
|
+
/**
|
|
395
|
+
* Get channel UI copy with optional persona overrides
|
|
396
|
+
*/
|
|
397
|
+
function getChannelUiCopy(key, ctx, replacements) {
|
|
398
|
+
const base = CHANNEL_UI_COPY[key] || key;
|
|
399
|
+
const override = ctx.persona
|
|
400
|
+
? PERSONA_CHANNEL_UI_OVERRIDES[ctx.persona]?.[key]
|
|
401
|
+
: undefined;
|
|
402
|
+
let message = override || base;
|
|
403
|
+
if (replacements) {
|
|
404
|
+
for (const [placeholder, value] of Object.entries(replacements)) {
|
|
405
|
+
message = message.replace(new RegExp(`\\{${placeholder}\\}`, 'g'), String(value));
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return message;
|
|
409
|
+
}
|
|
131
410
|
/**
|
|
132
411
|
* Get completion message with optional result and follow-up hint
|
|
133
412
|
* This is specific to channel messages which may include additional hints
|
|
@@ -137,6 +416,7 @@ function getCompletionMessage(ctx, result, includeFollowUpHint = true) {
|
|
|
137
416
|
let message = getChannelMessage(key, ctx, result ? { result } : undefined);
|
|
138
417
|
// Add follow-up hint for channels that support it
|
|
139
418
|
if (includeFollowUpHint && ctx.personality !== 'concise') {
|
|
419
|
+
const companionHint = 'Send another message to continue, or use /newtask for a clean start.';
|
|
140
420
|
const hints = {
|
|
141
421
|
professional: 'Send a follow-up message to continue, or use /newtask to start fresh.',
|
|
142
422
|
friendly: 'Got more to do? Just send another message!',
|
|
@@ -146,7 +426,7 @@ function getCompletionMessage(ctx, result, includeFollowUpHint = true) {
|
|
|
146
426
|
casual: 'What\'s next? Just hit me up.',
|
|
147
427
|
custom: 'Send a follow-up message to continue.',
|
|
148
428
|
};
|
|
149
|
-
const hint = hints[ctx.personality];
|
|
429
|
+
const hint = ctx.persona === 'companion' ? companionHint : hints[ctx.personality];
|
|
150
430
|
if (hint) {
|
|
151
431
|
message = `${message}\n\n${hint}`;
|
|
152
432
|
}
|
|
@@ -160,6 +440,7 @@ exports.DEFAULT_CHANNEL_CONTEXT = {
|
|
|
160
440
|
agentName: 'CoWork',
|
|
161
441
|
userName: undefined,
|
|
162
442
|
personality: 'professional',
|
|
443
|
+
persona: undefined,
|
|
163
444
|
emojiUsage: 'minimal',
|
|
164
445
|
quirks: {
|
|
165
446
|
catchphrase: undefined,
|