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,227 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.GoogleDriveTools = void 0;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const mime_types_1 = __importDefault(require("mime-types"));
|
|
43
|
+
const google_drive_manager_1 = require("../../settings/google-drive-manager");
|
|
44
|
+
const google_drive_api_1 = require("../../utils/google-drive-api");
|
|
45
|
+
const DEFAULT_LIST_FIELDS = 'nextPageToken, files(id,name,mimeType,modifiedTime,parents,webViewLink,size)';
|
|
46
|
+
const DEFAULT_FILE_FIELDS = 'id,name,mimeType,modifiedTime,parents,webViewLink,size';
|
|
47
|
+
class GoogleDriveTools {
|
|
48
|
+
constructor(workspace, daemon, taskId) {
|
|
49
|
+
this.workspace = workspace;
|
|
50
|
+
this.daemon = daemon;
|
|
51
|
+
this.taskId = taskId;
|
|
52
|
+
}
|
|
53
|
+
setWorkspace(workspace) {
|
|
54
|
+
this.workspace = workspace;
|
|
55
|
+
}
|
|
56
|
+
static isEnabled() {
|
|
57
|
+
return google_drive_manager_1.GoogleDriveSettingsManager.loadSettings().enabled;
|
|
58
|
+
}
|
|
59
|
+
async requireApproval(summary, details) {
|
|
60
|
+
const approved = await this.daemon.requestApproval(this.taskId, 'external_service', summary, details);
|
|
61
|
+
if (!approved) {
|
|
62
|
+
throw new Error('User denied Google Drive action');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
resolveFilePath(inputPath) {
|
|
66
|
+
if (!this.workspace.permissions.read) {
|
|
67
|
+
throw new Error('Read permission not granted for uploads');
|
|
68
|
+
}
|
|
69
|
+
const workspaceRoot = path.resolve(this.workspace.path);
|
|
70
|
+
const allowedPaths = this.workspace.permissions.allowedPaths || [];
|
|
71
|
+
const canReadOutside = this.workspace.isTemp || this.workspace.permissions.unrestrictedFileAccess;
|
|
72
|
+
const isPathAllowed = (absolutePath) => {
|
|
73
|
+
if (allowedPaths.length === 0)
|
|
74
|
+
return false;
|
|
75
|
+
const normalizedPath = path.normalize(absolutePath);
|
|
76
|
+
return allowedPaths.some((allowed) => {
|
|
77
|
+
const normalizedAllowed = path.normalize(allowed);
|
|
78
|
+
return normalizedPath === normalizedAllowed || normalizedPath.startsWith(normalizedAllowed + path.sep);
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
const candidate = path.isAbsolute(inputPath)
|
|
82
|
+
? path.normalize(inputPath)
|
|
83
|
+
: path.resolve(workspaceRoot, inputPath);
|
|
84
|
+
const relative = path.relative(workspaceRoot, candidate);
|
|
85
|
+
const isInsideWorkspace = !(relative.startsWith('..') || path.isAbsolute(relative));
|
|
86
|
+
if (!isInsideWorkspace && !canReadOutside && !isPathAllowed(candidate)) {
|
|
87
|
+
throw new Error('File path must be inside the workspace or in Allowed Paths');
|
|
88
|
+
}
|
|
89
|
+
if (!fs.existsSync(candidate)) {
|
|
90
|
+
throw new Error(`File not found: ${inputPath}`);
|
|
91
|
+
}
|
|
92
|
+
const stats = fs.statSync(candidate);
|
|
93
|
+
if (!stats.isFile()) {
|
|
94
|
+
throw new Error(`Path is not a file: ${inputPath}`);
|
|
95
|
+
}
|
|
96
|
+
return candidate;
|
|
97
|
+
}
|
|
98
|
+
async executeAction(input) {
|
|
99
|
+
const settings = google_drive_manager_1.GoogleDriveSettingsManager.loadSettings();
|
|
100
|
+
if (!settings.enabled) {
|
|
101
|
+
throw new Error('Google Drive integration is disabled. Enable it in Settings > Integrations > Google Drive.');
|
|
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, google_drive_api_1.googleDriveRequest)(settings, {
|
|
111
|
+
method: 'GET',
|
|
112
|
+
path: '/about',
|
|
113
|
+
query: { fields: 'user' },
|
|
114
|
+
});
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
case 'list_files': {
|
|
118
|
+
const query = input.query || 'trashed = false';
|
|
119
|
+
result = await (0, google_drive_api_1.googleDriveRequest)(settings, {
|
|
120
|
+
method: 'GET',
|
|
121
|
+
path: '/files',
|
|
122
|
+
query: {
|
|
123
|
+
q: query,
|
|
124
|
+
pageSize: input.page_size,
|
|
125
|
+
pageToken: input.page_token,
|
|
126
|
+
fields: input.fields || DEFAULT_LIST_FIELDS,
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
case 'get_file': {
|
|
132
|
+
if (!input.file_id)
|
|
133
|
+
throw new Error('Missing file_id for get_file');
|
|
134
|
+
result = await (0, google_drive_api_1.googleDriveRequest)(settings, {
|
|
135
|
+
method: 'GET',
|
|
136
|
+
path: `/files/${input.file_id}`,
|
|
137
|
+
query: {
|
|
138
|
+
fields: input.fields || DEFAULT_FILE_FIELDS,
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
case 'create_folder': {
|
|
144
|
+
if (!input.name)
|
|
145
|
+
throw new Error('Missing name for create_folder');
|
|
146
|
+
await this.requireApproval('Create a Google Drive folder', {
|
|
147
|
+
action: 'create_folder',
|
|
148
|
+
parent_id: input.parent_id || 'root',
|
|
149
|
+
name: input.name,
|
|
150
|
+
});
|
|
151
|
+
result = await (0, google_drive_api_1.googleDriveRequest)(settings, {
|
|
152
|
+
method: 'POST',
|
|
153
|
+
path: '/files',
|
|
154
|
+
query: { fields: DEFAULT_FILE_FIELDS },
|
|
155
|
+
body: {
|
|
156
|
+
name: input.name,
|
|
157
|
+
mimeType: 'application/vnd.google-apps.folder',
|
|
158
|
+
parents: input.parent_id ? [input.parent_id] : undefined,
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
case 'upload_file': {
|
|
164
|
+
if (!input.file_path)
|
|
165
|
+
throw new Error('Missing file_path for upload_file');
|
|
166
|
+
const resolved = this.resolveFilePath(input.file_path);
|
|
167
|
+
const data = fs.readFileSync(resolved);
|
|
168
|
+
const fileName = input.name || path.basename(resolved);
|
|
169
|
+
const contentType = (mime_types_1.default.lookup(fileName) || 'application/octet-stream');
|
|
170
|
+
await this.requireApproval(`Upload file to Google Drive: ${fileName}`, {
|
|
171
|
+
action: 'upload_file',
|
|
172
|
+
parent_id: input.parent_id || 'root',
|
|
173
|
+
file: fileName,
|
|
174
|
+
});
|
|
175
|
+
const created = await (0, google_drive_api_1.googleDriveRequest)(settings, {
|
|
176
|
+
method: 'POST',
|
|
177
|
+
path: '/files',
|
|
178
|
+
query: { fields: DEFAULT_FILE_FIELDS },
|
|
179
|
+
body: {
|
|
180
|
+
name: fileName,
|
|
181
|
+
parents: input.parent_id ? [input.parent_id] : undefined,
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
const fileId = created.data?.id;
|
|
185
|
+
if (!fileId) {
|
|
186
|
+
throw new Error('Failed to create Google Drive file record');
|
|
187
|
+
}
|
|
188
|
+
const uploaded = await (0, google_drive_api_1.googleDriveUpload)(settings, fileId, data, contentType);
|
|
189
|
+
result = {
|
|
190
|
+
status: uploaded.status,
|
|
191
|
+
data: uploaded.data || created.data,
|
|
192
|
+
raw: uploaded.raw,
|
|
193
|
+
};
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
case 'delete_file': {
|
|
197
|
+
if (!input.file_id)
|
|
198
|
+
throw new Error('Missing file_id for delete_file');
|
|
199
|
+
await this.requireApproval('Delete a Google Drive file', {
|
|
200
|
+
action: 'delete_file',
|
|
201
|
+
file_id: input.file_id,
|
|
202
|
+
});
|
|
203
|
+
result = await (0, google_drive_api_1.googleDriveRequest)(settings, {
|
|
204
|
+
method: 'DELETE',
|
|
205
|
+
path: `/files/${input.file_id}`,
|
|
206
|
+
});
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
default:
|
|
210
|
+
throw new Error(`Unsupported action: ${action}`);
|
|
211
|
+
}
|
|
212
|
+
this.daemon.logEvent(this.taskId, 'tool_result', {
|
|
213
|
+
tool: 'google_drive_action',
|
|
214
|
+
action,
|
|
215
|
+
status: result?.status,
|
|
216
|
+
hasData: result?.data ? true : false,
|
|
217
|
+
});
|
|
218
|
+
return {
|
|
219
|
+
success: true,
|
|
220
|
+
action,
|
|
221
|
+
status: result?.status,
|
|
222
|
+
data: result?.data,
|
|
223
|
+
raw: result?.raw,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
exports.GoogleDriveTools = GoogleDriveTools;
|
|
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.GrepTools = void 0;
|
|
37
37
|
const fs = __importStar(require("fs"));
|
|
38
|
+
const fsPromises = __importStar(require("fs/promises"));
|
|
38
39
|
const path = __importStar(require("path"));
|
|
39
40
|
/**
|
|
40
41
|
* GrepTools provides powerful regex-based content search
|
|
@@ -61,6 +62,7 @@ class GrepTools {
|
|
|
61
62
|
name: 'grep',
|
|
62
63
|
description: 'Powerful regex-based content search across files. ' +
|
|
63
64
|
'Supports full regex syntax (e.g., "async function.*fetch", "class\\s+\\w+"). ' +
|
|
65
|
+
'Searches text files only; binary formats like PDF/DOCX are skipped. ' +
|
|
64
66
|
'Use this to find code patterns, function definitions, imports, etc. ' +
|
|
65
67
|
'PREFERRED over search_files for content search.',
|
|
66
68
|
input_schema: {
|
|
@@ -110,6 +112,17 @@ class GrepTools {
|
|
|
110
112
|
message: `Grep search: "${pattern}"${searchPath ? ` in ${searchPath}` : ''}${globPattern ? ` (${globPattern})` : ''}`,
|
|
111
113
|
});
|
|
112
114
|
try {
|
|
115
|
+
if ((await this.isDocumentHeavyWorkspace()) && (!globPattern || /\.(pdf|docx)\b/i.test(globPattern))) {
|
|
116
|
+
return {
|
|
117
|
+
success: true,
|
|
118
|
+
pattern,
|
|
119
|
+
matches: [],
|
|
120
|
+
totalMatches: 0,
|
|
121
|
+
filesSearched: 0,
|
|
122
|
+
truncated: false,
|
|
123
|
+
warning: 'Workspace appears document-heavy (PDF/DOCX). The grep tool only searches text files. Use read_file for those documents.',
|
|
124
|
+
};
|
|
125
|
+
}
|
|
113
126
|
// Compile regex
|
|
114
127
|
let regex;
|
|
115
128
|
try {
|
|
@@ -289,7 +302,8 @@ class GrepTools {
|
|
|
289
302
|
}
|
|
290
303
|
// Apply glob filter if specified
|
|
291
304
|
if (globRegex) {
|
|
292
|
-
|
|
305
|
+
const normalizedRelative = relativePath.split(path.sep).join('/');
|
|
306
|
+
if (!globRegex.test(normalizedRelative) && !globRegex.test(entry.name)) {
|
|
293
307
|
continue;
|
|
294
308
|
}
|
|
295
309
|
}
|
|
@@ -354,16 +368,8 @@ class GrepTools {
|
|
|
354
368
|
* Convert glob pattern to regex
|
|
355
369
|
*/
|
|
356
370
|
globToRegex(pattern) {
|
|
357
|
-
// Handle brace expansion
|
|
358
371
|
const expandedPatterns = this.expandBraces(pattern);
|
|
359
|
-
const regexParts = expandedPatterns.map((p) =>
|
|
360
|
-
let regex = p
|
|
361
|
-
.replace(/[.+^${}()|[\]\\]/g, '\\$&')
|
|
362
|
-
.replace(/\\\*\\\*/g, '.*')
|
|
363
|
-
.replace(/\\\*/g, '[^/]*')
|
|
364
|
-
.replace(/\\\?/g, '[^/]');
|
|
365
|
-
return regex;
|
|
366
|
-
});
|
|
372
|
+
const regexParts = expandedPatterns.map((p) => this.globPatternToRegex(p));
|
|
367
373
|
const combined = regexParts.length > 1 ? `(${regexParts.join('|')})` : regexParts[0];
|
|
368
374
|
return new RegExp(`^${combined}$`, 'i');
|
|
369
375
|
}
|
|
@@ -383,5 +389,79 @@ class GrepTools {
|
|
|
383
389
|
}
|
|
384
390
|
return results;
|
|
385
391
|
}
|
|
392
|
+
/**
|
|
393
|
+
* Heuristic: detect workspaces dominated by PDF/DOCX files
|
|
394
|
+
*/
|
|
395
|
+
async isDocumentHeavyWorkspace() {
|
|
396
|
+
try {
|
|
397
|
+
const entries = await fsPromises.readdir(this.workspace.path, { withFileTypes: true });
|
|
398
|
+
let fileCount = 0;
|
|
399
|
+
let docCount = 0;
|
|
400
|
+
const maxEntries = 200;
|
|
401
|
+
for (const entry of entries) {
|
|
402
|
+
if (fileCount >= maxEntries)
|
|
403
|
+
break;
|
|
404
|
+
if (!entry.isFile())
|
|
405
|
+
continue;
|
|
406
|
+
fileCount++;
|
|
407
|
+
const ext = path.extname(entry.name).toLowerCase();
|
|
408
|
+
if (ext === '.pdf' || ext === '.docx') {
|
|
409
|
+
docCount++;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (fileCount < 5)
|
|
413
|
+
return false;
|
|
414
|
+
return docCount / fileCount >= 0.5;
|
|
415
|
+
}
|
|
416
|
+
catch {
|
|
417
|
+
return false;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Convert a glob pattern to a regex string (without delimiters)
|
|
422
|
+
*/
|
|
423
|
+
globPatternToRegex(pattern) {
|
|
424
|
+
let regex = '';
|
|
425
|
+
let i = 0;
|
|
426
|
+
while (i < pattern.length) {
|
|
427
|
+
const char = pattern[i];
|
|
428
|
+
if (char === '*') {
|
|
429
|
+
const isDoubleStar = pattern[i + 1] === '*';
|
|
430
|
+
if (isDoubleStar) {
|
|
431
|
+
i += 2;
|
|
432
|
+
if (pattern[i] === '/') {
|
|
433
|
+
regex += '(?:.*/)?';
|
|
434
|
+
i += 1;
|
|
435
|
+
}
|
|
436
|
+
else {
|
|
437
|
+
regex += '.*';
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
regex += '[^/]*';
|
|
442
|
+
i += 1;
|
|
443
|
+
}
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
if (char === '?') {
|
|
447
|
+
regex += '[^/]';
|
|
448
|
+
i += 1;
|
|
449
|
+
continue;
|
|
450
|
+
}
|
|
451
|
+
if ('+^${}()|[]\\.'.includes(char)) {
|
|
452
|
+
regex += `\\${char}`;
|
|
453
|
+
i += 1;
|
|
454
|
+
continue;
|
|
455
|
+
}
|
|
456
|
+
if (char === '/') {
|
|
457
|
+
regex += '/';
|
|
458
|
+
i += 1;
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
461
|
+
regex += char;
|
|
462
|
+
i += 1;
|
|
463
|
+
}
|
|
464
|
+
return regex;
|
|
465
|
+
}
|
|
386
466
|
}
|
|
387
467
|
exports.GrepTools = GrepTools;
|
|
@@ -51,9 +51,19 @@ class ImageTools {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
else {
|
|
54
|
-
|
|
54
|
+
const payload = {
|
|
55
55
|
action: 'generate_image',
|
|
56
56
|
error: result.error,
|
|
57
|
+
};
|
|
58
|
+
if (result.error?.includes('Gemini API key not configured')) {
|
|
59
|
+
payload.actionHint = {
|
|
60
|
+
type: 'open_settings',
|
|
61
|
+
label: 'Set up Gemini API key',
|
|
62
|
+
target: 'gemini',
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
this.daemon.logEvent(this.taskId, 'error', {
|
|
66
|
+
...payload,
|
|
57
67
|
});
|
|
58
68
|
}
|
|
59
69
|
return result;
|