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,231 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.BoxTools = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const box_manager_1 = require("../../settings/box-manager");
|
|
40
|
+
const box_api_1 = require("../../utils/box-api");
|
|
41
|
+
const DEFAULT_FOLDER_ID = '0';
|
|
42
|
+
class BoxTools {
|
|
43
|
+
constructor(workspace, daemon, taskId) {
|
|
44
|
+
this.workspace = workspace;
|
|
45
|
+
this.daemon = daemon;
|
|
46
|
+
this.taskId = taskId;
|
|
47
|
+
}
|
|
48
|
+
setWorkspace(workspace) {
|
|
49
|
+
this.workspace = workspace;
|
|
50
|
+
}
|
|
51
|
+
static isEnabled() {
|
|
52
|
+
return box_manager_1.BoxSettingsManager.loadSettings().enabled;
|
|
53
|
+
}
|
|
54
|
+
async requireApproval(summary, details) {
|
|
55
|
+
const approved = await this.daemon.requestApproval(this.taskId, 'external_service', summary, details);
|
|
56
|
+
if (!approved) {
|
|
57
|
+
throw new Error('User denied Box action');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
resolveFilePath(inputPath) {
|
|
61
|
+
if (!this.workspace.permissions.read) {
|
|
62
|
+
throw new Error('Read permission not granted for uploads');
|
|
63
|
+
}
|
|
64
|
+
const workspaceRoot = path.resolve(this.workspace.path);
|
|
65
|
+
const allowedPaths = this.workspace.permissions.allowedPaths || [];
|
|
66
|
+
const canReadOutside = this.workspace.isTemp || this.workspace.permissions.unrestrictedFileAccess;
|
|
67
|
+
const isPathAllowed = (absolutePath) => {
|
|
68
|
+
if (allowedPaths.length === 0)
|
|
69
|
+
return false;
|
|
70
|
+
const normalizedPath = path.normalize(absolutePath);
|
|
71
|
+
return allowedPaths.some((allowed) => {
|
|
72
|
+
const normalizedAllowed = path.normalize(allowed);
|
|
73
|
+
return normalizedPath === normalizedAllowed || normalizedPath.startsWith(normalizedAllowed + path.sep);
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
const candidate = path.isAbsolute(inputPath)
|
|
77
|
+
? path.normalize(inputPath)
|
|
78
|
+
: path.resolve(workspaceRoot, inputPath);
|
|
79
|
+
const relative = path.relative(workspaceRoot, candidate);
|
|
80
|
+
const isInsideWorkspace = !(relative.startsWith('..') || path.isAbsolute(relative));
|
|
81
|
+
if (!isInsideWorkspace && !canReadOutside && !isPathAllowed(candidate)) {
|
|
82
|
+
throw new Error('File path must be inside the workspace or in Allowed Paths');
|
|
83
|
+
}
|
|
84
|
+
if (!fs.existsSync(candidate)) {
|
|
85
|
+
throw new Error(`File not found: ${inputPath}`);
|
|
86
|
+
}
|
|
87
|
+
const stats = fs.statSync(candidate);
|
|
88
|
+
if (!stats.isFile()) {
|
|
89
|
+
throw new Error(`Path is not a file: ${inputPath}`);
|
|
90
|
+
}
|
|
91
|
+
return candidate;
|
|
92
|
+
}
|
|
93
|
+
async executeAction(input) {
|
|
94
|
+
const settings = box_manager_1.BoxSettingsManager.loadSettings();
|
|
95
|
+
if (!settings.enabled) {
|
|
96
|
+
throw new Error('Box integration is disabled. Enable it in Settings > Integrations > Box.');
|
|
97
|
+
}
|
|
98
|
+
const action = input.action;
|
|
99
|
+
if (!action) {
|
|
100
|
+
throw new Error('Missing required "action" parameter');
|
|
101
|
+
}
|
|
102
|
+
let result;
|
|
103
|
+
switch (action) {
|
|
104
|
+
case 'get_current_user': {
|
|
105
|
+
result = await (0, box_api_1.boxRequest)(settings, { method: 'GET', path: '/users/me' });
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
case 'search': {
|
|
109
|
+
if (!input.query)
|
|
110
|
+
throw new Error('Missing query for search');
|
|
111
|
+
result = await (0, box_api_1.boxRequest)(settings, {
|
|
112
|
+
method: 'GET',
|
|
113
|
+
path: '/search',
|
|
114
|
+
query: {
|
|
115
|
+
query: input.query,
|
|
116
|
+
limit: input.limit,
|
|
117
|
+
offset: input.offset,
|
|
118
|
+
fields: input.fields,
|
|
119
|
+
type: input.type,
|
|
120
|
+
ancestor_folder_ids: input.ancestor_folder_ids,
|
|
121
|
+
file_extensions: input.file_extensions,
|
|
122
|
+
content_types: input.content_types,
|
|
123
|
+
scope: input.scope,
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
case 'get_file': {
|
|
129
|
+
if (!input.file_id)
|
|
130
|
+
throw new Error('Missing file_id for get_file');
|
|
131
|
+
result = await (0, box_api_1.boxRequest)(settings, {
|
|
132
|
+
method: 'GET',
|
|
133
|
+
path: `/files/${input.file_id}`,
|
|
134
|
+
query: input.fields ? { fields: input.fields } : undefined,
|
|
135
|
+
});
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
case 'get_folder': {
|
|
139
|
+
if (!input.folder_id)
|
|
140
|
+
throw new Error('Missing folder_id for get_folder');
|
|
141
|
+
result = await (0, box_api_1.boxRequest)(settings, {
|
|
142
|
+
method: 'GET',
|
|
143
|
+
path: `/folders/${input.folder_id}`,
|
|
144
|
+
query: input.fields ? { fields: input.fields } : undefined,
|
|
145
|
+
});
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
case 'list_folder_items': {
|
|
149
|
+
const folderId = input.folder_id || DEFAULT_FOLDER_ID;
|
|
150
|
+
result = await (0, box_api_1.boxRequest)(settings, {
|
|
151
|
+
method: 'GET',
|
|
152
|
+
path: `/folders/${folderId}/items`,
|
|
153
|
+
query: {
|
|
154
|
+
limit: input.limit,
|
|
155
|
+
offset: input.offset,
|
|
156
|
+
fields: input.fields,
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
case 'create_folder': {
|
|
162
|
+
if (!input.name)
|
|
163
|
+
throw new Error('Missing name for create_folder');
|
|
164
|
+
const parentId = input.parent_id || DEFAULT_FOLDER_ID;
|
|
165
|
+
await this.requireApproval('Create a Box folder', {
|
|
166
|
+
action: 'create_folder',
|
|
167
|
+
parent_id: parentId,
|
|
168
|
+
name: input.name,
|
|
169
|
+
});
|
|
170
|
+
result = await (0, box_api_1.boxRequest)(settings, {
|
|
171
|
+
method: 'POST',
|
|
172
|
+
path: '/folders',
|
|
173
|
+
body: {
|
|
174
|
+
name: input.name,
|
|
175
|
+
parent: { id: parentId },
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
case 'delete_file': {
|
|
181
|
+
if (!input.file_id)
|
|
182
|
+
throw new Error('Missing file_id for delete_file');
|
|
183
|
+
await this.requireApproval('Delete a Box file', { action: 'delete_file', file_id: input.file_id });
|
|
184
|
+
result = await (0, box_api_1.boxRequest)(settings, { method: 'DELETE', path: `/files/${input.file_id}` });
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
case 'delete_folder': {
|
|
188
|
+
if (!input.folder_id)
|
|
189
|
+
throw new Error('Missing folder_id for delete_folder');
|
|
190
|
+
await this.requireApproval('Delete a Box folder', { action: 'delete_folder', folder_id: input.folder_id });
|
|
191
|
+
result = await (0, box_api_1.boxRequest)(settings, { method: 'DELETE', path: `/folders/${input.folder_id}` });
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
case 'upload_file': {
|
|
195
|
+
if (!input.file_path)
|
|
196
|
+
throw new Error('Missing file_path for upload_file');
|
|
197
|
+
const parentId = input.parent_id || DEFAULT_FOLDER_ID;
|
|
198
|
+
const resolved = this.resolveFilePath(input.file_path);
|
|
199
|
+
const data = fs.readFileSync(resolved);
|
|
200
|
+
const fileName = input.name || path.basename(resolved);
|
|
201
|
+
await this.requireApproval(`Upload file to Box: ${fileName}`, {
|
|
202
|
+
action: 'upload_file',
|
|
203
|
+
parent_id: parentId,
|
|
204
|
+
file: fileName,
|
|
205
|
+
});
|
|
206
|
+
result = await (0, box_api_1.boxUploadFile)(settings, {
|
|
207
|
+
fileName,
|
|
208
|
+
parentId,
|
|
209
|
+
data,
|
|
210
|
+
});
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
default:
|
|
214
|
+
throw new Error(`Unsupported action: ${action}`);
|
|
215
|
+
}
|
|
216
|
+
this.daemon.logEvent(this.taskId, 'tool_result', {
|
|
217
|
+
tool: 'box_action',
|
|
218
|
+
action,
|
|
219
|
+
status: result?.status,
|
|
220
|
+
hasData: result?.data ? true : false,
|
|
221
|
+
});
|
|
222
|
+
return {
|
|
223
|
+
success: true,
|
|
224
|
+
action,
|
|
225
|
+
status: result?.status,
|
|
226
|
+
data: result?.data,
|
|
227
|
+
raw: result?.raw,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
exports.BoxTools = BoxTools;
|
|
@@ -95,6 +95,8 @@ const DEFAULT_SETTINGS = {
|
|
|
95
95
|
},
|
|
96
96
|
},
|
|
97
97
|
toolOverrides: {},
|
|
98
|
+
toolTimeouts: {},
|
|
99
|
+
toolAutoApprove: {},
|
|
98
100
|
version: '1.0.0',
|
|
99
101
|
};
|
|
100
102
|
/**
|
|
@@ -107,6 +109,12 @@ const TOOL_CATEGORIES = {
|
|
|
107
109
|
edit_file: 'code',
|
|
108
110
|
// Web fetch tools (high priority)
|
|
109
111
|
web_fetch: 'webfetch',
|
|
112
|
+
notion_action: 'webfetch',
|
|
113
|
+
box_action: 'webfetch',
|
|
114
|
+
onedrive_action: 'webfetch',
|
|
115
|
+
google_drive_action: 'webfetch',
|
|
116
|
+
dropbox_action: 'webfetch',
|
|
117
|
+
sharepoint_action: 'webfetch',
|
|
110
118
|
// Browser tools
|
|
111
119
|
browser_navigate: 'browser',
|
|
112
120
|
browser_screenshot: 'browser',
|
|
@@ -276,6 +284,8 @@ class BuiltinToolsSettingsManager {
|
|
|
276
284
|
...settings.categories,
|
|
277
285
|
},
|
|
278
286
|
toolOverrides: settings.toolOverrides || {},
|
|
287
|
+
toolTimeouts: settings.toolTimeouts || {},
|
|
288
|
+
toolAutoApprove: settings.toolAutoApprove || {},
|
|
279
289
|
version: settings.version || defaults.version,
|
|
280
290
|
};
|
|
281
291
|
}
|
|
@@ -318,6 +328,24 @@ class BuiltinToolsSettingsManager {
|
|
|
318
328
|
static getToolCategory(toolName) {
|
|
319
329
|
return TOOL_CATEGORIES[toolName] || null;
|
|
320
330
|
}
|
|
331
|
+
/**
|
|
332
|
+
* Get per-tool timeout override (ms), if configured
|
|
333
|
+
*/
|
|
334
|
+
static getToolTimeoutMs(toolName) {
|
|
335
|
+
const settings = this.loadSettings();
|
|
336
|
+
const timeout = settings.toolTimeouts?.[toolName];
|
|
337
|
+
if (typeof timeout !== 'number' || !Number.isFinite(timeout) || timeout <= 0) {
|
|
338
|
+
return null;
|
|
339
|
+
}
|
|
340
|
+
return Math.round(timeout);
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Check if a tool should be auto-approved
|
|
344
|
+
*/
|
|
345
|
+
static getToolAutoApprove(toolName) {
|
|
346
|
+
const settings = this.loadSettings();
|
|
347
|
+
return Boolean(settings.toolAutoApprove?.[toolName]);
|
|
348
|
+
}
|
|
321
349
|
/**
|
|
322
350
|
* Get all tool categories with their tools
|
|
323
351
|
*/
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.DropboxTools = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const dropbox_manager_1 = require("../../settings/dropbox-manager");
|
|
40
|
+
const dropbox_api_1 = require("../../utils/dropbox-api");
|
|
41
|
+
class DropboxTools {
|
|
42
|
+
constructor(workspace, daemon, taskId) {
|
|
43
|
+
this.workspace = workspace;
|
|
44
|
+
this.daemon = daemon;
|
|
45
|
+
this.taskId = taskId;
|
|
46
|
+
}
|
|
47
|
+
setWorkspace(workspace) {
|
|
48
|
+
this.workspace = workspace;
|
|
49
|
+
}
|
|
50
|
+
static isEnabled() {
|
|
51
|
+
return dropbox_manager_1.DropboxSettingsManager.loadSettings().enabled;
|
|
52
|
+
}
|
|
53
|
+
async requireApproval(summary, details) {
|
|
54
|
+
const approved = await this.daemon.requestApproval(this.taskId, 'external_service', summary, details);
|
|
55
|
+
if (!approved) {
|
|
56
|
+
throw new Error('User denied Dropbox action');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
resolveFilePath(inputPath) {
|
|
60
|
+
if (!this.workspace.permissions.read) {
|
|
61
|
+
throw new Error('Read permission not granted for uploads');
|
|
62
|
+
}
|
|
63
|
+
const workspaceRoot = path.resolve(this.workspace.path);
|
|
64
|
+
const allowedPaths = this.workspace.permissions.allowedPaths || [];
|
|
65
|
+
const canReadOutside = this.workspace.isTemp || this.workspace.permissions.unrestrictedFileAccess;
|
|
66
|
+
const isPathAllowed = (absolutePath) => {
|
|
67
|
+
if (allowedPaths.length === 0)
|
|
68
|
+
return false;
|
|
69
|
+
const normalizedPath = path.normalize(absolutePath);
|
|
70
|
+
return allowedPaths.some((allowed) => {
|
|
71
|
+
const normalizedAllowed = path.normalize(allowed);
|
|
72
|
+
return normalizedPath === normalizedAllowed || normalizedPath.startsWith(normalizedAllowed + path.sep);
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
const candidate = path.isAbsolute(inputPath)
|
|
76
|
+
? path.normalize(inputPath)
|
|
77
|
+
: path.resolve(workspaceRoot, inputPath);
|
|
78
|
+
const relative = path.relative(workspaceRoot, candidate);
|
|
79
|
+
const isInsideWorkspace = !(relative.startsWith('..') || path.isAbsolute(relative));
|
|
80
|
+
if (!isInsideWorkspace && !canReadOutside && !isPathAllowed(candidate)) {
|
|
81
|
+
throw new Error('File path must be inside the workspace or in Allowed Paths');
|
|
82
|
+
}
|
|
83
|
+
if (!fs.existsSync(candidate)) {
|
|
84
|
+
throw new Error(`File not found: ${inputPath}`);
|
|
85
|
+
}
|
|
86
|
+
const stats = fs.statSync(candidate);
|
|
87
|
+
if (!stats.isFile()) {
|
|
88
|
+
throw new Error(`Path is not a file: ${inputPath}`);
|
|
89
|
+
}
|
|
90
|
+
return candidate;
|
|
91
|
+
}
|
|
92
|
+
normalizeDropboxPath(pathValue) {
|
|
93
|
+
const trimmed = pathValue.trim();
|
|
94
|
+
if (!trimmed)
|
|
95
|
+
return '';
|
|
96
|
+
return trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
|
|
97
|
+
}
|
|
98
|
+
async executeAction(input) {
|
|
99
|
+
const settings = dropbox_manager_1.DropboxSettingsManager.loadSettings();
|
|
100
|
+
if (!settings.enabled) {
|
|
101
|
+
throw new Error('Dropbox integration is disabled. Enable it in Settings > Integrations > Dropbox.');
|
|
102
|
+
}
|
|
103
|
+
const action = input.action;
|
|
104
|
+
if (!action) {
|
|
105
|
+
throw new Error('Missing required "action" parameter');
|
|
106
|
+
}
|
|
107
|
+
let result;
|
|
108
|
+
switch (action) {
|
|
109
|
+
case 'get_current_user': {
|
|
110
|
+
result = await (0, dropbox_api_1.dropboxRequest)(settings, { method: 'POST', path: '/users/get_current_account' });
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
case 'list_folder': {
|
|
114
|
+
const pathValue = input.path ? this.normalizeDropboxPath(input.path) : '';
|
|
115
|
+
result = await (0, dropbox_api_1.dropboxRequest)(settings, {
|
|
116
|
+
method: 'POST',
|
|
117
|
+
path: '/files/list_folder',
|
|
118
|
+
body: {
|
|
119
|
+
path: pathValue,
|
|
120
|
+
recursive: false,
|
|
121
|
+
include_deleted: false,
|
|
122
|
+
include_has_explicit_shared_members: false,
|
|
123
|
+
include_mounted_folders: true,
|
|
124
|
+
limit: input.limit,
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
case 'list_folder_continue': {
|
|
130
|
+
if (!input.cursor)
|
|
131
|
+
throw new Error('Missing cursor for list_folder_continue');
|
|
132
|
+
result = await (0, dropbox_api_1.dropboxRequest)(settings, {
|
|
133
|
+
method: 'POST',
|
|
134
|
+
path: '/files/list_folder/continue',
|
|
135
|
+
body: { cursor: input.cursor },
|
|
136
|
+
});
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
case 'search': {
|
|
140
|
+
if (!input.query)
|
|
141
|
+
throw new Error('Missing query for search');
|
|
142
|
+
result = await (0, dropbox_api_1.dropboxRequest)(settings, {
|
|
143
|
+
method: 'POST',
|
|
144
|
+
path: '/files/search_v2',
|
|
145
|
+
body: {
|
|
146
|
+
query: input.query,
|
|
147
|
+
options: {
|
|
148
|
+
path: input.path ? this.normalizeDropboxPath(input.path) : undefined,
|
|
149
|
+
max_results: input.limit,
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
case 'get_metadata': {
|
|
156
|
+
if (!input.path)
|
|
157
|
+
throw new Error('Missing path for get_metadata');
|
|
158
|
+
result = await (0, dropbox_api_1.dropboxRequest)(settings, {
|
|
159
|
+
method: 'POST',
|
|
160
|
+
path: '/files/get_metadata',
|
|
161
|
+
body: {
|
|
162
|
+
path: this.normalizeDropboxPath(input.path),
|
|
163
|
+
include_media_info: false,
|
|
164
|
+
include_deleted: false,
|
|
165
|
+
include_has_explicit_shared_members: false,
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
case 'create_folder': {
|
|
171
|
+
if (!input.path)
|
|
172
|
+
throw new Error('Missing path for create_folder');
|
|
173
|
+
const folderPath = this.normalizeDropboxPath(input.path);
|
|
174
|
+
await this.requireApproval('Create a Dropbox folder', {
|
|
175
|
+
action: 'create_folder',
|
|
176
|
+
path: folderPath,
|
|
177
|
+
});
|
|
178
|
+
result = await (0, dropbox_api_1.dropboxRequest)(settings, {
|
|
179
|
+
method: 'POST',
|
|
180
|
+
path: '/files/create_folder_v2',
|
|
181
|
+
body: {
|
|
182
|
+
path: folderPath,
|
|
183
|
+
autorename: true,
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
case 'delete_item': {
|
|
189
|
+
if (!input.path)
|
|
190
|
+
throw new Error('Missing path for delete_item');
|
|
191
|
+
const deletePath = this.normalizeDropboxPath(input.path);
|
|
192
|
+
await this.requireApproval('Delete a Dropbox item', {
|
|
193
|
+
action: 'delete_item',
|
|
194
|
+
path: deletePath,
|
|
195
|
+
});
|
|
196
|
+
result = await (0, dropbox_api_1.dropboxRequest)(settings, {
|
|
197
|
+
method: 'POST',
|
|
198
|
+
path: '/files/delete_v2',
|
|
199
|
+
body: { path: deletePath },
|
|
200
|
+
});
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
case 'upload_file': {
|
|
204
|
+
if (!input.file_path)
|
|
205
|
+
throw new Error('Missing file_path for upload_file');
|
|
206
|
+
const resolved = this.resolveFilePath(input.file_path);
|
|
207
|
+
const data = fs.readFileSync(resolved);
|
|
208
|
+
const fileName = input.name || path.basename(resolved);
|
|
209
|
+
const targetPath = input.path
|
|
210
|
+
? this.normalizeDropboxPath(input.path)
|
|
211
|
+
: this.normalizeDropboxPath(`${input.parent_path || ''}/${fileName}`);
|
|
212
|
+
await this.requireApproval(`Upload file to Dropbox: ${fileName}`, {
|
|
213
|
+
action: 'upload_file',
|
|
214
|
+
path: targetPath,
|
|
215
|
+
});
|
|
216
|
+
result = await (0, dropbox_api_1.dropboxContentUpload)(settings, { path: targetPath, data });
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
default:
|
|
220
|
+
throw new Error(`Unsupported action: ${action}`);
|
|
221
|
+
}
|
|
222
|
+
this.daemon.logEvent(this.taskId, 'tool_result', {
|
|
223
|
+
tool: 'dropbox_action',
|
|
224
|
+
action,
|
|
225
|
+
status: result?.status,
|
|
226
|
+
hasData: result?.data ? true : false,
|
|
227
|
+
});
|
|
228
|
+
return {
|
|
229
|
+
success: true,
|
|
230
|
+
action,
|
|
231
|
+
status: result?.status,
|
|
232
|
+
data: result?.data,
|
|
233
|
+
raw: result?.raw,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
exports.DropboxTools = DropboxTools;
|