cowork-os 0.3.21 → 0.3.23
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 +293 -6
- 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/daemon.js +25 -0
- package/dist/electron/electron/agent/executor.js +181 -26
- package/dist/electron/electron/agent/llm/anthropic-compatible-provider.js +177 -0
- 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 +11 -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 +318 -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/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/google-drive-tools.js +227 -0
- 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 +541 -0
- 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/gateway/index.js +1 -0
- package/dist/electron/electron/gateway/router.js +123 -143
- package/dist/electron/electron/ipc/canvas-handlers.js +5 -0
- package/dist/electron/electron/ipc/handlers.js +627 -158
- 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 +1 -1
- package/dist/electron/electron/preload.js +74 -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 +82 -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 +88 -1
- package/package.json +12 -2
- package/src/electron/agent/executor.ts +205 -28
- package/src/electron/agent/llm/anthropic-compatible-provider.ts +214 -0
- 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 +5 -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 +414 -6
- package/src/electron/agent/llm/types.ts +90 -1
- package/src/electron/agent/llm/xai-provider.ts +39 -0
- package/src/electron/agent/tools/box-tools.ts +239 -0
- package/src/electron/agent/tools/builtin-settings.ts +34 -0
- package/src/electron/agent/tools/dropbox-tools.ts +237 -0
- package/src/electron/agent/tools/google-drive-tools.ts +228 -0
- 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 +565 -0
- 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/database/SecureSettingsRepository.ts +7 -1
- package/src/electron/gateway/index.ts +1 -0
- package/src/electron/gateway/router.ts +134 -149
- package/src/electron/ipc/canvas-handlers.ts +10 -0
- package/src/electron/ipc/handlers.ts +673 -153
- 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 +5 -1
- package/src/electron/preload.ts +167 -4
- package/src/electron/settings/box-manager.ts +58 -0
- package/src/electron/settings/dropbox-manager.ts +58 -0
- package/src/electron/settings/google-drive-manager.ts +58 -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/google-drive-api.ts +183 -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 +102 -1
- package/src/electron/utils/x-cli.ts +1 -1
- package/src/renderer/App.tsx +20 -2
- 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/DropboxSettings.tsx +202 -0
- package/src/renderer/components/GoogleDriveSettings.tsx +201 -0
- package/src/renderer/components/MCPSettings.tsx +56 -0
- package/src/renderer/components/MainContent.tsx +270 -34
- 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/Settings.tsx +611 -8
- package/src/renderer/components/SharePointSettings.tsx +224 -0
- package/src/renderer/components/Sidebar.tsx +25 -9
- package/src/renderer/hooks/useOnboardingFlow.ts +21 -0
- package/src/renderer/styles/index.css +438 -25
- package/src/shared/channelMessages.ts +367 -4
- package/src/shared/llm-provider-catalog.ts +217 -0
- package/src/shared/types.ts +226 -1
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OneDrive API helpers (Microsoft Graph)
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { OneDriveConnectionTestResult, OneDriveSettingsData } from '../../shared/types';
|
|
6
|
+
|
|
7
|
+
export const ONEDRIVE_API_BASE = 'https://graph.microsoft.com/v1.0';
|
|
8
|
+
const DEFAULT_TIMEOUT_MS = 20000;
|
|
9
|
+
|
|
10
|
+
function parseJsonSafe(text: string): any | undefined {
|
|
11
|
+
const trimmed = text.trim();
|
|
12
|
+
if (!trimmed) return undefined;
|
|
13
|
+
try {
|
|
14
|
+
return JSON.parse(trimmed);
|
|
15
|
+
} catch {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function formatGraphError(status: number, data: any, fallback?: string): string {
|
|
21
|
+
const message =
|
|
22
|
+
data?.error?.message ||
|
|
23
|
+
data?.message ||
|
|
24
|
+
fallback ||
|
|
25
|
+
'Microsoft Graph error';
|
|
26
|
+
return `Microsoft Graph error ${status}: ${message}`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface OneDriveRequestOptions {
|
|
30
|
+
method: 'GET' | 'POST' | 'PATCH' | 'DELETE' | 'PUT';
|
|
31
|
+
path: string;
|
|
32
|
+
query?: Record<string, string | number | boolean | undefined>;
|
|
33
|
+
body?: any;
|
|
34
|
+
headers?: Record<string, string>;
|
|
35
|
+
timeoutMs?: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface OneDriveRequestResult {
|
|
39
|
+
status: number;
|
|
40
|
+
data?: any;
|
|
41
|
+
raw?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export async function onedriveRequest(
|
|
45
|
+
settings: OneDriveSettingsData,
|
|
46
|
+
options: OneDriveRequestOptions
|
|
47
|
+
): Promise<OneDriveRequestResult> {
|
|
48
|
+
if (!settings.accessToken) {
|
|
49
|
+
throw new Error('OneDrive access token not configured. Add it in Settings > Integrations > OneDrive.');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const params = new URLSearchParams();
|
|
53
|
+
if (options.query) {
|
|
54
|
+
for (const [key, value] of Object.entries(options.query)) {
|
|
55
|
+
if (value === undefined || value === null) continue;
|
|
56
|
+
params.set(key, String(value));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const queryString = params.toString();
|
|
60
|
+
const url = `${ONEDRIVE_API_BASE}${options.path}${queryString ? `?${queryString}` : ''}`;
|
|
61
|
+
|
|
62
|
+
const headers: Record<string, string> = {
|
|
63
|
+
Authorization: `Bearer ${settings.accessToken}`,
|
|
64
|
+
...(options.headers || {}),
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const isBinaryBody = options.body instanceof Uint8Array || options.body instanceof ArrayBuffer || Buffer.isBuffer(options.body);
|
|
68
|
+
if (options.body && !isBinaryBody && options.method !== 'GET' && options.method !== 'DELETE') {
|
|
69
|
+
headers['Content-Type'] = headers['Content-Type'] || 'application/json';
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const timeoutMs = options.timeoutMs ?? settings.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
73
|
+
const controller = new AbortController();
|
|
74
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
const response = await fetch(url, {
|
|
78
|
+
method: options.method,
|
|
79
|
+
headers,
|
|
80
|
+
body: options.body
|
|
81
|
+
? isBinaryBody
|
|
82
|
+
? options.body
|
|
83
|
+
: JSON.stringify(options.body)
|
|
84
|
+
: undefined,
|
|
85
|
+
signal: controller.signal,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const rawText = typeof response.text === 'function' ? await response.text() : '';
|
|
89
|
+
const data = rawText ? parseJsonSafe(rawText) : undefined;
|
|
90
|
+
|
|
91
|
+
if (!response.ok) {
|
|
92
|
+
throw new Error(formatGraphError(response.status, data, response.statusText));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
status: response.status,
|
|
97
|
+
data: data ?? undefined,
|
|
98
|
+
raw: rawText || undefined,
|
|
99
|
+
};
|
|
100
|
+
} catch (error: any) {
|
|
101
|
+
if (error?.name === 'AbortError') {
|
|
102
|
+
throw new Error('OneDrive API request timed out');
|
|
103
|
+
}
|
|
104
|
+
throw error;
|
|
105
|
+
} finally {
|
|
106
|
+
clearTimeout(timeout);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function extractDriveOwner(data: any): { name?: string; userId?: string; driveId?: string } {
|
|
111
|
+
if (!data || typeof data !== 'object') return {};
|
|
112
|
+
const name =
|
|
113
|
+
data?.owner?.user?.displayName ||
|
|
114
|
+
data?.owner?.user?.id ||
|
|
115
|
+
undefined;
|
|
116
|
+
const userId = data?.owner?.user?.id || undefined;
|
|
117
|
+
const driveId = data?.id || undefined;
|
|
118
|
+
return { name, userId, driveId };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export async function testOneDriveConnection(settings: OneDriveSettingsData): Promise<OneDriveConnectionTestResult> {
|
|
122
|
+
try {
|
|
123
|
+
const result = await onedriveRequest(settings, { method: 'GET', path: '/me/drive' });
|
|
124
|
+
const extracted = extractDriveOwner(result.data);
|
|
125
|
+
return {
|
|
126
|
+
success: true,
|
|
127
|
+
name: extracted.name,
|
|
128
|
+
userId: extracted.userId,
|
|
129
|
+
driveId: extracted.driveId,
|
|
130
|
+
};
|
|
131
|
+
} catch (error: any) {
|
|
132
|
+
return {
|
|
133
|
+
success: false,
|
|
134
|
+
error: error?.message || 'Failed to connect to OneDrive',
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SharePoint API helpers (Microsoft Graph)
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { SharePointConnectionTestResult, SharePointSettingsData } from '../../shared/types';
|
|
6
|
+
|
|
7
|
+
export const SHAREPOINT_API_BASE = 'https://graph.microsoft.com/v1.0';
|
|
8
|
+
const DEFAULT_TIMEOUT_MS = 20000;
|
|
9
|
+
|
|
10
|
+
function parseJsonSafe(text: string): any | undefined {
|
|
11
|
+
const trimmed = text.trim();
|
|
12
|
+
if (!trimmed) return undefined;
|
|
13
|
+
try {
|
|
14
|
+
return JSON.parse(trimmed);
|
|
15
|
+
} catch {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function formatGraphError(status: number, data: any, fallback?: string): string {
|
|
21
|
+
const message =
|
|
22
|
+
data?.error?.message ||
|
|
23
|
+
data?.message ||
|
|
24
|
+
fallback ||
|
|
25
|
+
'Microsoft Graph error';
|
|
26
|
+
return `Microsoft Graph error ${status}: ${message}`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface SharePointRequestOptions {
|
|
30
|
+
method: 'GET' | 'POST' | 'PATCH' | 'DELETE' | 'PUT';
|
|
31
|
+
path: string;
|
|
32
|
+
query?: Record<string, string | number | boolean | undefined>;
|
|
33
|
+
body?: any;
|
|
34
|
+
headers?: Record<string, string>;
|
|
35
|
+
timeoutMs?: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface SharePointRequestResult {
|
|
39
|
+
status: number;
|
|
40
|
+
data?: any;
|
|
41
|
+
raw?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export async function sharepointRequest(
|
|
45
|
+
settings: SharePointSettingsData,
|
|
46
|
+
options: SharePointRequestOptions
|
|
47
|
+
): Promise<SharePointRequestResult> {
|
|
48
|
+
if (!settings.accessToken) {
|
|
49
|
+
throw new Error('SharePoint access token not configured. Add it in Settings > Integrations > SharePoint.');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const params = new URLSearchParams();
|
|
53
|
+
if (options.query) {
|
|
54
|
+
for (const [key, value] of Object.entries(options.query)) {
|
|
55
|
+
if (value === undefined || value === null) continue;
|
|
56
|
+
params.set(key, String(value));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const queryString = params.toString();
|
|
60
|
+
const url = `${SHAREPOINT_API_BASE}${options.path}${queryString ? `?${queryString}` : ''}`;
|
|
61
|
+
|
|
62
|
+
const headers: Record<string, string> = {
|
|
63
|
+
Authorization: `Bearer ${settings.accessToken}`,
|
|
64
|
+
...(options.headers || {}),
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const isBinaryBody = options.body instanceof Uint8Array || options.body instanceof ArrayBuffer || Buffer.isBuffer(options.body);
|
|
68
|
+
if (options.body && !isBinaryBody && options.method !== 'GET' && options.method !== 'DELETE') {
|
|
69
|
+
headers['Content-Type'] = headers['Content-Type'] || 'application/json';
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const timeoutMs = options.timeoutMs ?? settings.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
73
|
+
const controller = new AbortController();
|
|
74
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
const response = await fetch(url, {
|
|
78
|
+
method: options.method,
|
|
79
|
+
headers,
|
|
80
|
+
body: options.body
|
|
81
|
+
? isBinaryBody
|
|
82
|
+
? options.body
|
|
83
|
+
: JSON.stringify(options.body)
|
|
84
|
+
: undefined,
|
|
85
|
+
signal: controller.signal,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const rawText = typeof response.text === 'function' ? await response.text() : '';
|
|
89
|
+
const data = rawText ? parseJsonSafe(rawText) : undefined;
|
|
90
|
+
|
|
91
|
+
if (!response.ok) {
|
|
92
|
+
throw new Error(formatGraphError(response.status, data, response.statusText));
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
status: response.status,
|
|
97
|
+
data: data ?? undefined,
|
|
98
|
+
raw: rawText || undefined,
|
|
99
|
+
};
|
|
100
|
+
} catch (error: any) {
|
|
101
|
+
if (error?.name === 'AbortError') {
|
|
102
|
+
throw new Error('SharePoint API request timed out');
|
|
103
|
+
}
|
|
104
|
+
throw error;
|
|
105
|
+
} finally {
|
|
106
|
+
clearTimeout(timeout);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function extractUserInfo(data: any): { name?: string; userId?: string } {
|
|
111
|
+
if (!data || typeof data !== 'object') return {};
|
|
112
|
+
const name = data.displayName || data.name || undefined;
|
|
113
|
+
const userId = data.id || undefined;
|
|
114
|
+
return { name, userId };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export async function testSharePointConnection(settings: SharePointSettingsData): Promise<SharePointConnectionTestResult> {
|
|
118
|
+
try {
|
|
119
|
+
const result = await sharepointRequest(settings, { method: 'GET', path: '/me' });
|
|
120
|
+
const extracted = extractUserInfo(result.data);
|
|
121
|
+
return {
|
|
122
|
+
success: true,
|
|
123
|
+
name: extracted.name,
|
|
124
|
+
userId: extracted.userId,
|
|
125
|
+
};
|
|
126
|
+
} catch (error: any) {
|
|
127
|
+
return {
|
|
128
|
+
success: false,
|
|
129
|
+
error: error?.message || 'Failed to connect to SharePoint',
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { z } from 'zod';
|
|
7
|
+
import { LLM_PROVIDER_TYPES } from '../../shared/types';
|
|
7
8
|
|
|
8
9
|
// Common validation patterns
|
|
9
10
|
const MAX_STRING_LENGTH = 10000;
|
|
@@ -63,6 +64,14 @@ export const TaskMessageSchema = z.object({
|
|
|
63
64
|
message: z.string().min(1).max(MAX_PROMPT_LENGTH),
|
|
64
65
|
});
|
|
65
66
|
|
|
67
|
+
export const FileImportSchema = z.object({
|
|
68
|
+
workspaceId: z.string().refine(
|
|
69
|
+
(val) => val === TEMP_WORKSPACE_ID || z.string().uuid().safeParse(val).success,
|
|
70
|
+
{ message: 'Must be a valid UUID or temp workspace ID' }
|
|
71
|
+
),
|
|
72
|
+
files: z.array(z.string().min(1).max(MAX_PATH_LENGTH)).min(1).max(20),
|
|
73
|
+
});
|
|
74
|
+
|
|
66
75
|
// ============ Approval Schemas ============
|
|
67
76
|
|
|
68
77
|
export const ApprovalResponseSchema = z.object({
|
|
@@ -72,7 +81,7 @@ export const ApprovalResponseSchema = z.object({
|
|
|
72
81
|
|
|
73
82
|
// ============ LLM Settings Schemas ============
|
|
74
83
|
|
|
75
|
-
export const LLMProviderTypeSchema = z.enum(
|
|
84
|
+
export const LLMProviderTypeSchema = z.enum(LLM_PROVIDER_TYPES);
|
|
76
85
|
|
|
77
86
|
export const AnthropicSettingsSchema = z.object({
|
|
78
87
|
apiKey: z.string().max(500).optional(),
|
|
@@ -102,6 +111,7 @@ export const GeminiSettingsSchema = z.object({
|
|
|
102
111
|
export const OpenRouterSettingsSchema = z.object({
|
|
103
112
|
apiKey: z.string().max(500).optional(),
|
|
104
113
|
model: z.string().max(200).optional(),
|
|
114
|
+
baseUrl: z.string().max(500).optional(),
|
|
105
115
|
}).optional();
|
|
106
116
|
|
|
107
117
|
export const OpenAISettingsSchema = z.object({
|
|
@@ -114,6 +124,32 @@ export const OpenAISettingsSchema = z.object({
|
|
|
114
124
|
authMethod: z.enum(['api_key', 'oauth']).optional(),
|
|
115
125
|
}).optional();
|
|
116
126
|
|
|
127
|
+
export const GroqSettingsSchema = z.object({
|
|
128
|
+
apiKey: z.string().max(500).optional(),
|
|
129
|
+
model: z.string().max(200).optional(),
|
|
130
|
+
baseUrl: z.string().max(500).optional(),
|
|
131
|
+
}).optional();
|
|
132
|
+
|
|
133
|
+
export const XAISettingsSchema = z.object({
|
|
134
|
+
apiKey: z.string().max(500).optional(),
|
|
135
|
+
model: z.string().max(200).optional(),
|
|
136
|
+
baseUrl: z.string().max(500).optional(),
|
|
137
|
+
}).optional();
|
|
138
|
+
|
|
139
|
+
export const KimiSettingsSchema = z.object({
|
|
140
|
+
apiKey: z.string().max(500).optional(),
|
|
141
|
+
model: z.string().max(200).optional(),
|
|
142
|
+
baseUrl: z.string().max(500).optional(),
|
|
143
|
+
}).optional();
|
|
144
|
+
|
|
145
|
+
export const CustomProviderConfigSchema = z.object({
|
|
146
|
+
apiKey: z.string().max(500).optional(),
|
|
147
|
+
model: z.string().max(200).optional(),
|
|
148
|
+
baseUrl: z.string().max(500).optional(),
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
export const CustomProvidersSchema = z.record(z.string(), CustomProviderConfigSchema).optional();
|
|
152
|
+
|
|
117
153
|
export const LLMSettingsSchema = z.object({
|
|
118
154
|
providerType: LLMProviderTypeSchema,
|
|
119
155
|
modelKey: z.string().max(200),
|
|
@@ -123,6 +159,10 @@ export const LLMSettingsSchema = z.object({
|
|
|
123
159
|
gemini: GeminiSettingsSchema,
|
|
124
160
|
openrouter: OpenRouterSettingsSchema,
|
|
125
161
|
openai: OpenAISettingsSchema,
|
|
162
|
+
groq: GroqSettingsSchema,
|
|
163
|
+
xai: XAISettingsSchema,
|
|
164
|
+
kimi: KimiSettingsSchema,
|
|
165
|
+
customProviders: CustomProvidersSchema,
|
|
126
166
|
});
|
|
127
167
|
|
|
128
168
|
// ============ Search Settings Schemas ============
|
|
@@ -163,6 +203,58 @@ export const XSettingsSchema = z.object({
|
|
|
163
203
|
quoteDepth: z.number().int().min(0).max(5).optional(),
|
|
164
204
|
});
|
|
165
205
|
|
|
206
|
+
// ============ Notion Settings Schema ============
|
|
207
|
+
|
|
208
|
+
export const NotionSettingsSchema = z.object({
|
|
209
|
+
enabled: z.boolean().default(false),
|
|
210
|
+
apiKey: z.string().max(2000).optional(),
|
|
211
|
+
notionVersion: z.string().max(50).optional(),
|
|
212
|
+
timeoutMs: z.number().int().min(1000).max(120000).optional(),
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
// ============ Box Settings Schema ============
|
|
216
|
+
|
|
217
|
+
export const BoxSettingsSchema = z.object({
|
|
218
|
+
enabled: z.boolean().default(false),
|
|
219
|
+
accessToken: z.string().max(4000).optional(),
|
|
220
|
+
timeoutMs: z.number().int().min(1000).max(120000).optional(),
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// ============ OneDrive Settings Schema ============
|
|
224
|
+
|
|
225
|
+
export const OneDriveSettingsSchema = z.object({
|
|
226
|
+
enabled: z.boolean().default(false),
|
|
227
|
+
accessToken: z.string().max(4000).optional(),
|
|
228
|
+
driveId: z.string().max(200).optional(),
|
|
229
|
+
timeoutMs: z.number().int().min(1000).max(120000).optional(),
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
// ============ Google Drive Settings Schema ============
|
|
233
|
+
|
|
234
|
+
export const GoogleDriveSettingsSchema = z.object({
|
|
235
|
+
enabled: z.boolean().default(false),
|
|
236
|
+
accessToken: z.string().max(4000).optional(),
|
|
237
|
+
timeoutMs: z.number().int().min(1000).max(120000).optional(),
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// ============ Dropbox Settings Schema ============
|
|
241
|
+
|
|
242
|
+
export const DropboxSettingsSchema = z.object({
|
|
243
|
+
enabled: z.boolean().default(false),
|
|
244
|
+
accessToken: z.string().max(4000).optional(),
|
|
245
|
+
timeoutMs: z.number().int().min(1000).max(120000).optional(),
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
// ============ SharePoint Settings Schema ============
|
|
249
|
+
|
|
250
|
+
export const SharePointSettingsSchema = z.object({
|
|
251
|
+
enabled: z.boolean().default(false),
|
|
252
|
+
accessToken: z.string().max(4000).optional(),
|
|
253
|
+
siteId: z.string().max(500).optional(),
|
|
254
|
+
driveId: z.string().max(500).optional(),
|
|
255
|
+
timeoutMs: z.number().int().min(1000).max(120000).optional(),
|
|
256
|
+
});
|
|
257
|
+
|
|
166
258
|
// ============ Guardrail Settings Schema ============
|
|
167
259
|
|
|
168
260
|
export const GuardrailSettingsSchema = z.object({
|
|
@@ -451,6 +543,15 @@ export const MCPRegistrySearchSchema = z.object({
|
|
|
451
543
|
offset: z.number().int().min(0).default(0),
|
|
452
544
|
});
|
|
453
545
|
|
|
546
|
+
export const MCPConnectorOAuthSchema = z.object({
|
|
547
|
+
provider: z.enum(['salesforce', 'jira', 'hubspot', 'zendesk']),
|
|
548
|
+
clientId: z.string().min(1).max(500),
|
|
549
|
+
clientSecret: z.string().max(500).optional(),
|
|
550
|
+
scopes: z.array(z.string().max(200)).max(50).optional(),
|
|
551
|
+
loginUrl: z.string().url().max(500).optional(),
|
|
552
|
+
subdomain: z.string().max(200).optional(),
|
|
553
|
+
});
|
|
554
|
+
|
|
454
555
|
// ============ Hooks (Webhooks) Schemas ============
|
|
455
556
|
|
|
456
557
|
export const HookMappingChannelSchema = z.enum(['telegram', 'discord', 'slack', 'whatsapp', 'imessage', 'signal', 'mattermost', 'matrix', 'twitch', 'line', 'bluebubbles', 'email', 'last']);
|
|
@@ -46,7 +46,7 @@ function buildGlobalArgs(settings: XSettingsData, json: boolean): string[] {
|
|
|
46
46
|
|
|
47
47
|
if (settings.authMethod === 'manual') {
|
|
48
48
|
if (!settings.authToken || !settings.ct0) {
|
|
49
|
-
throw new Error('Missing auth_token or ct0. Add them in Settings >
|
|
49
|
+
throw new Error('Missing auth_token or ct0. Add them in Settings > X (Twitter).');
|
|
50
50
|
}
|
|
51
51
|
args.push('--auth-token', settings.authToken, '--ct0', settings.ct0);
|
|
52
52
|
} else {
|
package/src/renderer/App.tsx
CHANGED
|
@@ -5,6 +5,7 @@ import { RightPanel } from './components/RightPanel';
|
|
|
5
5
|
import { Settings } from './components/Settings';
|
|
6
6
|
import { DisclaimerModal } from './components/DisclaimerModal';
|
|
7
7
|
import { Onboarding } from './components/Onboarding';
|
|
8
|
+
import { BrowserView } from './components/BrowserView';
|
|
8
9
|
// TaskQueuePanel moved to RightPanel
|
|
9
10
|
import { ToastContainer } from './components/Toast';
|
|
10
11
|
import { QuickTaskFAB } from './components/QuickTaskFAB';
|
|
@@ -20,14 +21,15 @@ function getEffectiveTheme(themeMode: ThemeMode): 'light' | 'dark' {
|
|
|
20
21
|
return themeMode;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
type AppView = 'main' | 'settings';
|
|
24
|
+
type AppView = 'main' | 'settings' | 'browser';
|
|
24
25
|
|
|
25
26
|
export function App() {
|
|
26
27
|
const [currentWorkspace, setCurrentWorkspace] = useState<Workspace | null>(null);
|
|
27
28
|
const [tasks, setTasks] = useState<Task[]>([]);
|
|
28
29
|
const [selectedTaskId, setSelectedTaskId] = useState<string | null>(null);
|
|
29
30
|
const [currentView, setCurrentView] = useState<AppView>('main');
|
|
30
|
-
const [
|
|
31
|
+
const [browserUrl, setBrowserUrl] = useState<string>('');
|
|
32
|
+
const [settingsTab, setSettingsTab] = useState<'appearance' | 'llm' | 'search' | 'telegram' | 'slack' | 'whatsapp' | 'teams' | 'x' | 'morechannels' | 'integrations' | 'updates' | 'guardrails' | 'queue' | 'skills' | 'scheduled' | 'voice' | 'missioncontrol'>('appearance');
|
|
31
33
|
const [events, setEvents] = useState<TaskEvent[]>([]);
|
|
32
34
|
|
|
33
35
|
// Model selection state
|
|
@@ -82,6 +84,11 @@ export function App() {
|
|
|
82
84
|
loadLLMConfig();
|
|
83
85
|
};
|
|
84
86
|
|
|
87
|
+
const handleOpenBrowserView = (url?: string) => {
|
|
88
|
+
setBrowserUrl(url || '');
|
|
89
|
+
setCurrentView('browser');
|
|
90
|
+
};
|
|
91
|
+
|
|
85
92
|
const handleShowOnboarding = () => {
|
|
86
93
|
// Reset onboarding state to show the wizard again
|
|
87
94
|
setOnboardingCompleted(false);
|
|
@@ -710,6 +717,10 @@ export function App() {
|
|
|
710
717
|
selectedTaskId={selectedTaskId}
|
|
711
718
|
onSelectTask={setSelectedTaskId}
|
|
712
719
|
onOpenSettings={() => setCurrentView('settings')}
|
|
720
|
+
onOpenMissionControl={() => {
|
|
721
|
+
setSettingsTab('missioncontrol');
|
|
722
|
+
setCurrentView('settings');
|
|
723
|
+
}}
|
|
713
724
|
onTasksChanged={loadTasks}
|
|
714
725
|
/>
|
|
715
726
|
)}
|
|
@@ -727,6 +738,7 @@ export function App() {
|
|
|
727
738
|
setCurrentView('settings');
|
|
728
739
|
}}
|
|
729
740
|
onStopTask={handleCancelTask}
|
|
741
|
+
onOpenBrowserView={handleOpenBrowserView}
|
|
730
742
|
selectedModel={selectedModel}
|
|
731
743
|
availableModels={availableModels}
|
|
732
744
|
onModelChange={handleModelChange}
|
|
@@ -770,6 +782,12 @@ export function App() {
|
|
|
770
782
|
onboardingCompletedAt={onboardingCompletedAt}
|
|
771
783
|
/>
|
|
772
784
|
)}
|
|
785
|
+
{currentView === 'browser' && (
|
|
786
|
+
<BrowserView
|
|
787
|
+
initialUrl={browserUrl}
|
|
788
|
+
onBack={() => setCurrentView('main')}
|
|
789
|
+
/>
|
|
790
|
+
)}
|
|
773
791
|
</div>
|
|
774
792
|
);
|
|
775
793
|
}
|