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.
Files changed (252) hide show
  1. package/README.md +372 -10
  2. package/connectors/README.md +20 -0
  3. package/connectors/asana-mcp/README.md +24 -0
  4. package/connectors/asana-mcp/dist/index.js +427 -0
  5. package/connectors/asana-mcp/package.json +15 -0
  6. package/connectors/asana-mcp/src/index.ts +553 -0
  7. package/connectors/asana-mcp/tsconfig.json +13 -0
  8. package/connectors/hubspot-mcp/README.md +35 -0
  9. package/connectors/hubspot-mcp/dist/index.js +454 -0
  10. package/connectors/hubspot-mcp/package.json +15 -0
  11. package/connectors/hubspot-mcp/src/index.ts +562 -0
  12. package/connectors/hubspot-mcp/tsconfig.json +13 -0
  13. package/connectors/jira-mcp/README.md +49 -0
  14. package/connectors/jira-mcp/dist/index.js +588 -0
  15. package/connectors/jira-mcp/package.json +15 -0
  16. package/connectors/jira-mcp/src/index.ts +711 -0
  17. package/connectors/jira-mcp/tsconfig.json +13 -0
  18. package/connectors/linear-mcp/README.md +22 -0
  19. package/connectors/linear-mcp/dist/index.js +402 -0
  20. package/connectors/linear-mcp/package.json +15 -0
  21. package/connectors/linear-mcp/src/index.ts +522 -0
  22. package/connectors/linear-mcp/tsconfig.json +13 -0
  23. package/connectors/okta-mcp/README.md +24 -0
  24. package/connectors/okta-mcp/dist/index.js +411 -0
  25. package/connectors/okta-mcp/package.json +15 -0
  26. package/connectors/okta-mcp/src/index.ts +520 -0
  27. package/connectors/okta-mcp/tsconfig.json +13 -0
  28. package/connectors/salesforce-mcp/README.md +47 -0
  29. package/connectors/salesforce-mcp/dist/index.js +584 -0
  30. package/connectors/salesforce-mcp/package.json +15 -0
  31. package/connectors/salesforce-mcp/src/index.ts +722 -0
  32. package/connectors/salesforce-mcp/tsconfig.json +13 -0
  33. package/connectors/servicenow-mcp/README.md +26 -0
  34. package/connectors/servicenow-mcp/dist/index.js +400 -0
  35. package/connectors/servicenow-mcp/package.json +15 -0
  36. package/connectors/servicenow-mcp/src/index.ts +500 -0
  37. package/connectors/servicenow-mcp/tsconfig.json +13 -0
  38. package/connectors/templates/mcp-connector/README.md +31 -0
  39. package/connectors/templates/mcp-connector/package.json +15 -0
  40. package/connectors/templates/mcp-connector/src/index.ts +330 -0
  41. package/connectors/templates/mcp-connector/tsconfig.json +13 -0
  42. package/connectors/zendesk-mcp/README.md +40 -0
  43. package/connectors/zendesk-mcp/dist/index.js +431 -0
  44. package/connectors/zendesk-mcp/package.json +15 -0
  45. package/connectors/zendesk-mcp/src/index.ts +543 -0
  46. package/connectors/zendesk-mcp/tsconfig.json +13 -0
  47. package/dist/electron/electron/agent/custom-skill-loader.js +31 -1
  48. package/dist/electron/electron/agent/daemon.js +189 -13
  49. package/dist/electron/electron/agent/executor.js +895 -78
  50. package/dist/electron/electron/agent/llm/anthropic-compatible-provider.js +177 -0
  51. package/dist/electron/electron/agent/llm/azure-openai-provider.js +328 -0
  52. package/dist/electron/electron/agent/llm/bedrock-provider.js +49 -9
  53. package/dist/electron/electron/agent/llm/github-copilot-provider.js +97 -0
  54. package/dist/electron/electron/agent/llm/groq-provider.js +33 -0
  55. package/dist/electron/electron/agent/llm/index.js +13 -1
  56. package/dist/electron/electron/agent/llm/kimi-provider.js +33 -0
  57. package/dist/electron/electron/agent/llm/openai-compatible-provider.js +116 -0
  58. package/dist/electron/electron/agent/llm/openai-compatible.js +111 -0
  59. package/dist/electron/electron/agent/llm/openai-oauth.js +2 -1
  60. package/dist/electron/electron/agent/llm/openrouter-provider.js +1 -1
  61. package/dist/electron/electron/agent/llm/provider-factory.js +350 -4
  62. package/dist/electron/electron/agent/llm/types.js +66 -1
  63. package/dist/electron/electron/agent/llm/xai-provider.js +33 -0
  64. package/dist/electron/electron/agent/search/provider-factory.js +38 -2
  65. package/dist/electron/electron/agent/tools/box-tools.js +231 -0
  66. package/dist/electron/electron/agent/tools/builtin-settings.js +28 -0
  67. package/dist/electron/electron/agent/tools/dropbox-tools.js +237 -0
  68. package/dist/electron/electron/agent/tools/file-tools.js +66 -3
  69. package/dist/electron/electron/agent/tools/google-drive-tools.js +227 -0
  70. package/dist/electron/electron/agent/tools/grep-tools.js +90 -10
  71. package/dist/electron/electron/agent/tools/image-tools.js +11 -1
  72. package/dist/electron/electron/agent/tools/notion-tools.js +312 -0
  73. package/dist/electron/electron/agent/tools/onedrive-tools.js +217 -0
  74. package/dist/electron/electron/agent/tools/registry.js +548 -10
  75. package/dist/electron/electron/agent/tools/search-tools.js +28 -10
  76. package/dist/electron/electron/agent/tools/sharepoint-tools.js +243 -0
  77. package/dist/electron/electron/agent/tools/shell-tools.js +12 -3
  78. package/dist/electron/electron/agent/tools/x-tools.js +1 -1
  79. package/dist/electron/electron/agents/agent-dispatch.js +63 -0
  80. package/dist/electron/electron/database/repositories.js +19 -5
  81. package/dist/electron/electron/database/schema.js +8 -0
  82. package/dist/electron/electron/gateway/channels/whatsapp.js +55 -0
  83. package/dist/electron/electron/gateway/index.js +75 -1
  84. package/dist/electron/electron/gateway/router.js +209 -154
  85. package/dist/electron/electron/ipc/canvas-handlers.js +5 -0
  86. package/dist/electron/electron/ipc/handlers.js +763 -267
  87. package/dist/electron/electron/main.js +63 -0
  88. package/dist/electron/electron/mcp/oauth/connector-oauth.js +333 -0
  89. package/dist/electron/electron/mcp/registry/MCPRegistryManager.js +503 -154
  90. package/dist/electron/electron/memory/MemoryService.js +2 -1
  91. package/dist/electron/electron/preload.js +78 -1
  92. package/dist/electron/electron/settings/appearance-manager.js +18 -1
  93. package/dist/electron/electron/settings/box-manager.js +54 -0
  94. package/dist/electron/electron/settings/dropbox-manager.js +54 -0
  95. package/dist/electron/electron/settings/google-drive-manager.js +54 -0
  96. package/dist/electron/electron/settings/notion-manager.js +56 -0
  97. package/dist/electron/electron/settings/onedrive-manager.js +54 -0
  98. package/dist/electron/electron/settings/sharepoint-manager.js +54 -0
  99. package/dist/electron/electron/utils/box-api.js +153 -0
  100. package/dist/electron/electron/utils/dropbox-api.js +144 -0
  101. package/dist/electron/electron/utils/env-migration.js +19 -0
  102. package/dist/electron/electron/utils/google-drive-api.js +152 -0
  103. package/dist/electron/electron/utils/notion-api.js +103 -0
  104. package/dist/electron/electron/utils/onedrive-api.js +113 -0
  105. package/dist/electron/electron/utils/sharepoint-api.js +109 -0
  106. package/dist/electron/electron/utils/validation.js +98 -3
  107. package/dist/electron/electron/utils/x-cli.js +1 -1
  108. package/dist/electron/shared/channelMessages.js +284 -3
  109. package/dist/electron/shared/llm-provider-catalog.js +198 -0
  110. package/dist/electron/shared/types.js +90 -1
  111. package/package.json +14 -3
  112. package/resources/skills/nano-banana-pro.json +4 -4
  113. package/resources/skills/openai-image-gen.json +3 -3
  114. package/resources/skills/scripts/gen.py +163 -0
  115. package/resources/skills/scripts/generate_image.py +91 -0
  116. package/src/electron/agent/custom-skill-loader.ts +34 -1
  117. package/src/electron/agent/daemon.ts +210 -14
  118. package/src/electron/agent/executor.ts +1124 -85
  119. package/src/electron/agent/llm/anthropic-compatible-provider.ts +214 -0
  120. package/src/electron/agent/llm/azure-openai-provider.ts +388 -0
  121. package/src/electron/agent/llm/bedrock-provider.ts +62 -9
  122. package/src/electron/agent/llm/github-copilot-provider.ts +117 -0
  123. package/src/electron/agent/llm/groq-provider.ts +39 -0
  124. package/src/electron/agent/llm/index.ts +6 -0
  125. package/src/electron/agent/llm/kimi-provider.ts +39 -0
  126. package/src/electron/agent/llm/openai-compatible-provider.ts +153 -0
  127. package/src/electron/agent/llm/openai-compatible.ts +133 -0
  128. package/src/electron/agent/llm/openai-oauth.ts +2 -1
  129. package/src/electron/agent/llm/openrouter-provider.ts +2 -1
  130. package/src/electron/agent/llm/provider-factory.ts +459 -6
  131. package/src/electron/agent/llm/types.ts +95 -1
  132. package/src/electron/agent/llm/xai-provider.ts +39 -0
  133. package/src/electron/agent/search/provider-factory.ts +43 -2
  134. package/src/electron/agent/tools/box-tools.ts +239 -0
  135. package/src/electron/agent/tools/builtin-settings.ts +36 -0
  136. package/src/electron/agent/tools/dropbox-tools.ts +237 -0
  137. package/src/electron/agent/tools/file-tools.ts +66 -3
  138. package/src/electron/agent/tools/gmail-tools.ts +240 -0
  139. package/src/electron/agent/tools/google-calendar-tools.ts +258 -0
  140. package/src/electron/agent/tools/google-drive-tools.ts +228 -0
  141. package/src/electron/agent/tools/grep-tools.ts +97 -12
  142. package/src/electron/agent/tools/image-tools.ts +11 -1
  143. package/src/electron/agent/tools/notion-tools.ts +330 -0
  144. package/src/electron/agent/tools/onedrive-tools.ts +217 -0
  145. package/src/electron/agent/tools/registry.ts +794 -10
  146. package/src/electron/agent/tools/search-tools.ts +29 -11
  147. package/src/electron/agent/tools/sharepoint-tools.ts +247 -0
  148. package/src/electron/agent/tools/shell-tools.ts +11 -3
  149. package/src/electron/agent/tools/x-tools.ts +1 -1
  150. package/src/electron/agents/agent-dispatch.ts +79 -0
  151. package/src/electron/database/SecureSettingsRepository.ts +7 -1
  152. package/src/electron/database/repositories.ts +58 -6
  153. package/src/electron/database/schema.ts +8 -0
  154. package/src/electron/gateway/channels/discord.ts +4 -0
  155. package/src/electron/gateway/channels/google-chat.ts +3 -0
  156. package/src/electron/gateway/channels/line.ts +3 -0
  157. package/src/electron/gateway/channels/matrix-client.ts +15 -0
  158. package/src/electron/gateway/channels/matrix.ts +31 -0
  159. package/src/electron/gateway/channels/mattermost.ts +3 -0
  160. package/src/electron/gateway/channels/signal.ts +3 -0
  161. package/src/electron/gateway/channels/slack.ts +9 -4
  162. package/src/electron/gateway/channels/teams.ts +4 -0
  163. package/src/electron/gateway/channels/telegram.ts +2 -0
  164. package/src/electron/gateway/channels/twitch.ts +2 -0
  165. package/src/electron/gateway/channels/types.ts +8 -0
  166. package/src/electron/gateway/channels/whatsapp.ts +66 -0
  167. package/src/electron/gateway/index.ts +95 -2
  168. package/src/electron/gateway/router.ts +231 -161
  169. package/src/electron/gateway/security.ts +21 -9
  170. package/src/electron/ipc/canvas-handlers.ts +10 -0
  171. package/src/electron/ipc/handlers.ts +848 -292
  172. package/src/electron/main.ts +35 -0
  173. package/src/electron/mcp/oauth/connector-oauth.ts +448 -0
  174. package/src/electron/mcp/registry/MCPRegistryManager.ts +343 -12
  175. package/src/electron/memory/MemoryService.ts +7 -1
  176. package/src/electron/preload.ts +200 -5
  177. package/src/electron/settings/appearance-manager.ts +20 -2
  178. package/src/electron/settings/box-manager.ts +58 -0
  179. package/src/electron/settings/dropbox-manager.ts +58 -0
  180. package/src/electron/settings/google-workspace-manager.ts +59 -0
  181. package/src/electron/settings/notion-manager.ts +60 -0
  182. package/src/electron/settings/onedrive-manager.ts +58 -0
  183. package/src/electron/settings/sharepoint-manager.ts +58 -0
  184. package/src/electron/utils/box-api.ts +184 -0
  185. package/src/electron/utils/dropbox-api.ts +171 -0
  186. package/src/electron/utils/env-migration.ts +22 -0
  187. package/src/electron/utils/gmail-api.ts +121 -0
  188. package/src/electron/utils/google-calendar-api.ts +115 -0
  189. package/src/electron/utils/google-workspace-api.ts +228 -0
  190. package/src/electron/utils/google-workspace-auth.ts +109 -0
  191. package/src/electron/utils/google-workspace-oauth.ts +232 -0
  192. package/src/electron/utils/notion-api.ts +126 -0
  193. package/src/electron/utils/onedrive-api.ts +137 -0
  194. package/src/electron/utils/sharepoint-api.ts +132 -0
  195. package/src/electron/utils/validation.ts +128 -1
  196. package/src/electron/utils/x-cli.ts +1 -1
  197. package/src/renderer/App.tsx +119 -8
  198. package/src/renderer/components/ActivityFeedItem.tsx +34 -17
  199. package/src/renderer/components/AgentWorkingStatePanel.tsx +7 -5
  200. package/src/renderer/components/AppearanceSettings.tsx +37 -2
  201. package/src/renderer/components/BlueBubblesSettings.tsx +18 -7
  202. package/src/renderer/components/BoxSettings.tsx +203 -0
  203. package/src/renderer/components/BrowserView.tsx +101 -0
  204. package/src/renderer/components/BuiltinToolsSettings.tsx +105 -0
  205. package/src/renderer/components/CanvasPreview.tsx +68 -1
  206. package/src/renderer/components/ConnectorEnvModal.tsx +116 -0
  207. package/src/renderer/components/ConnectorSetupModal.tsx +566 -0
  208. package/src/renderer/components/ConnectorsSettings.tsx +397 -0
  209. package/src/renderer/components/ControlPlaneSettings.tsx +2 -0
  210. package/src/renderer/components/DiscordSettings.tsx +18 -7
  211. package/src/renderer/components/DropboxSettings.tsx +202 -0
  212. package/src/renderer/components/EmailSettings.tsx +18 -7
  213. package/src/renderer/components/FileViewer.tsx +21 -13
  214. package/src/renderer/components/GoogleChatSettings.tsx +17 -7
  215. package/src/renderer/components/GoogleWorkspaceSettings.tsx +332 -0
  216. package/src/renderer/components/ImessageSettings.tsx +22 -11
  217. package/src/renderer/components/LineIcons.tsx +376 -0
  218. package/src/renderer/components/LineSettings.tsx +18 -7
  219. package/src/renderer/components/MCPSettings.tsx +56 -0
  220. package/src/renderer/components/MainContent.tsx +740 -76
  221. package/src/renderer/components/MatrixSettings.tsx +18 -7
  222. package/src/renderer/components/MattermostSettings.tsx +18 -7
  223. package/src/renderer/components/NodesSettings.tsx +58 -99
  224. package/src/renderer/components/NotificationPanel.tsx +25 -11
  225. package/src/renderer/components/NotionSettings.tsx +231 -0
  226. package/src/renderer/components/Onboarding/Onboarding.tsx +13 -1
  227. package/src/renderer/components/OnboardingModal.tsx +70 -1
  228. package/src/renderer/components/OneDriveSettings.tsx +212 -0
  229. package/src/renderer/components/RightPanel.tsx +141 -28
  230. package/src/renderer/components/ScheduledTasksSettings.tsx +10 -62
  231. package/src/renderer/components/SearchSettings.tsx +118 -114
  232. package/src/renderer/components/Settings.tsx +1425 -651
  233. package/src/renderer/components/SharePointSettings.tsx +224 -0
  234. package/src/renderer/components/Sidebar.tsx +94 -19
  235. package/src/renderer/components/SignalSettings.tsx +18 -7
  236. package/src/renderer/components/SkillHubBrowser.tsx +144 -185
  237. package/src/renderer/components/SlackSettings.tsx +18 -7
  238. package/src/renderer/components/TaskQuickActions.tsx +11 -6
  239. package/src/renderer/components/TaskTimeline.tsx +58 -26
  240. package/src/renderer/components/TeamsSettings.tsx +18 -7
  241. package/src/renderer/components/TelegramSettings.tsx +18 -7
  242. package/src/renderer/components/ThemeIcon.tsx +16 -0
  243. package/src/renderer/components/TwitchSettings.tsx +18 -7
  244. package/src/renderer/components/VoiceSettings.tsx +30 -74
  245. package/src/renderer/components/WhatsAppSettings.tsx +48 -37
  246. package/src/renderer/components/WorkingStateHistory.tsx +7 -5
  247. package/src/renderer/components/WorkspaceSelector.tsx +42 -13
  248. package/src/renderer/hooks/useOnboardingFlow.ts +21 -0
  249. package/src/renderer/styles/index.css +2333 -209
  250. package/src/shared/channelMessages.ts +367 -4
  251. package/src/shared/llm-provider-catalog.ts +217 -0
  252. 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
- if (!globRegex.test(relativePath) && !globRegex.test(entry.name)) {
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
- this.daemon.logEvent(this.taskId, 'error', {
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;