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.
Files changed (170) hide show
  1. package/README.md +293 -6
  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/daemon.js +25 -0
  48. package/dist/electron/electron/agent/executor.js +181 -26
  49. package/dist/electron/electron/agent/llm/anthropic-compatible-provider.js +177 -0
  50. package/dist/electron/electron/agent/llm/github-copilot-provider.js +97 -0
  51. package/dist/electron/electron/agent/llm/groq-provider.js +33 -0
  52. package/dist/electron/electron/agent/llm/index.js +11 -1
  53. package/dist/electron/electron/agent/llm/kimi-provider.js +33 -0
  54. package/dist/electron/electron/agent/llm/openai-compatible-provider.js +116 -0
  55. package/dist/electron/electron/agent/llm/openai-compatible.js +111 -0
  56. package/dist/electron/electron/agent/llm/openai-oauth.js +2 -1
  57. package/dist/electron/electron/agent/llm/openrouter-provider.js +1 -1
  58. package/dist/electron/electron/agent/llm/provider-factory.js +318 -4
  59. package/dist/electron/electron/agent/llm/types.js +66 -1
  60. package/dist/electron/electron/agent/llm/xai-provider.js +33 -0
  61. package/dist/electron/electron/agent/tools/box-tools.js +231 -0
  62. package/dist/electron/electron/agent/tools/builtin-settings.js +28 -0
  63. package/dist/electron/electron/agent/tools/dropbox-tools.js +237 -0
  64. package/dist/electron/electron/agent/tools/google-drive-tools.js +227 -0
  65. package/dist/electron/electron/agent/tools/notion-tools.js +312 -0
  66. package/dist/electron/electron/agent/tools/onedrive-tools.js +217 -0
  67. package/dist/electron/electron/agent/tools/registry.js +541 -0
  68. package/dist/electron/electron/agent/tools/sharepoint-tools.js +243 -0
  69. package/dist/electron/electron/agent/tools/shell-tools.js +12 -3
  70. package/dist/electron/electron/agent/tools/x-tools.js +1 -1
  71. package/dist/electron/electron/gateway/index.js +1 -0
  72. package/dist/electron/electron/gateway/router.js +123 -143
  73. package/dist/electron/electron/ipc/canvas-handlers.js +5 -0
  74. package/dist/electron/electron/ipc/handlers.js +627 -158
  75. package/dist/electron/electron/main.js +63 -0
  76. package/dist/electron/electron/mcp/oauth/connector-oauth.js +333 -0
  77. package/dist/electron/electron/mcp/registry/MCPRegistryManager.js +503 -154
  78. package/dist/electron/electron/memory/MemoryService.js +1 -1
  79. package/dist/electron/electron/preload.js +74 -1
  80. package/dist/electron/electron/settings/box-manager.js +54 -0
  81. package/dist/electron/electron/settings/dropbox-manager.js +54 -0
  82. package/dist/electron/electron/settings/google-drive-manager.js +54 -0
  83. package/dist/electron/electron/settings/notion-manager.js +56 -0
  84. package/dist/electron/electron/settings/onedrive-manager.js +54 -0
  85. package/dist/electron/electron/settings/sharepoint-manager.js +54 -0
  86. package/dist/electron/electron/utils/box-api.js +153 -0
  87. package/dist/electron/electron/utils/dropbox-api.js +144 -0
  88. package/dist/electron/electron/utils/env-migration.js +19 -0
  89. package/dist/electron/electron/utils/google-drive-api.js +152 -0
  90. package/dist/electron/electron/utils/notion-api.js +103 -0
  91. package/dist/electron/electron/utils/onedrive-api.js +113 -0
  92. package/dist/electron/electron/utils/sharepoint-api.js +109 -0
  93. package/dist/electron/electron/utils/validation.js +82 -3
  94. package/dist/electron/electron/utils/x-cli.js +1 -1
  95. package/dist/electron/shared/channelMessages.js +284 -3
  96. package/dist/electron/shared/llm-provider-catalog.js +198 -0
  97. package/dist/electron/shared/types.js +88 -1
  98. package/package.json +12 -2
  99. package/src/electron/agent/executor.ts +205 -28
  100. package/src/electron/agent/llm/anthropic-compatible-provider.ts +214 -0
  101. package/src/electron/agent/llm/github-copilot-provider.ts +117 -0
  102. package/src/electron/agent/llm/groq-provider.ts +39 -0
  103. package/src/electron/agent/llm/index.ts +5 -0
  104. package/src/electron/agent/llm/kimi-provider.ts +39 -0
  105. package/src/electron/agent/llm/openai-compatible-provider.ts +153 -0
  106. package/src/electron/agent/llm/openai-compatible.ts +133 -0
  107. package/src/electron/agent/llm/openai-oauth.ts +2 -1
  108. package/src/electron/agent/llm/openrouter-provider.ts +2 -1
  109. package/src/electron/agent/llm/provider-factory.ts +414 -6
  110. package/src/electron/agent/llm/types.ts +90 -1
  111. package/src/electron/agent/llm/xai-provider.ts +39 -0
  112. package/src/electron/agent/tools/box-tools.ts +239 -0
  113. package/src/electron/agent/tools/builtin-settings.ts +34 -0
  114. package/src/electron/agent/tools/dropbox-tools.ts +237 -0
  115. package/src/electron/agent/tools/google-drive-tools.ts +228 -0
  116. package/src/electron/agent/tools/notion-tools.ts +330 -0
  117. package/src/electron/agent/tools/onedrive-tools.ts +217 -0
  118. package/src/electron/agent/tools/registry.ts +565 -0
  119. package/src/electron/agent/tools/sharepoint-tools.ts +247 -0
  120. package/src/electron/agent/tools/shell-tools.ts +11 -3
  121. package/src/electron/agent/tools/x-tools.ts +1 -1
  122. package/src/electron/database/SecureSettingsRepository.ts +7 -1
  123. package/src/electron/gateway/index.ts +1 -0
  124. package/src/electron/gateway/router.ts +134 -149
  125. package/src/electron/ipc/canvas-handlers.ts +10 -0
  126. package/src/electron/ipc/handlers.ts +673 -153
  127. package/src/electron/main.ts +35 -0
  128. package/src/electron/mcp/oauth/connector-oauth.ts +448 -0
  129. package/src/electron/mcp/registry/MCPRegistryManager.ts +343 -12
  130. package/src/electron/memory/MemoryService.ts +5 -1
  131. package/src/electron/preload.ts +167 -4
  132. package/src/electron/settings/box-manager.ts +58 -0
  133. package/src/electron/settings/dropbox-manager.ts +58 -0
  134. package/src/electron/settings/google-drive-manager.ts +58 -0
  135. package/src/electron/settings/notion-manager.ts +60 -0
  136. package/src/electron/settings/onedrive-manager.ts +58 -0
  137. package/src/electron/settings/sharepoint-manager.ts +58 -0
  138. package/src/electron/utils/box-api.ts +184 -0
  139. package/src/electron/utils/dropbox-api.ts +171 -0
  140. package/src/electron/utils/env-migration.ts +22 -0
  141. package/src/electron/utils/google-drive-api.ts +183 -0
  142. package/src/electron/utils/notion-api.ts +126 -0
  143. package/src/electron/utils/onedrive-api.ts +137 -0
  144. package/src/electron/utils/sharepoint-api.ts +132 -0
  145. package/src/electron/utils/validation.ts +102 -1
  146. package/src/electron/utils/x-cli.ts +1 -1
  147. package/src/renderer/App.tsx +20 -2
  148. package/src/renderer/components/BoxSettings.tsx +203 -0
  149. package/src/renderer/components/BrowserView.tsx +101 -0
  150. package/src/renderer/components/BuiltinToolsSettings.tsx +105 -0
  151. package/src/renderer/components/CanvasPreview.tsx +68 -1
  152. package/src/renderer/components/ConnectorEnvModal.tsx +116 -0
  153. package/src/renderer/components/ConnectorSetupModal.tsx +566 -0
  154. package/src/renderer/components/ConnectorsSettings.tsx +397 -0
  155. package/src/renderer/components/DropboxSettings.tsx +202 -0
  156. package/src/renderer/components/GoogleDriveSettings.tsx +201 -0
  157. package/src/renderer/components/MCPSettings.tsx +56 -0
  158. package/src/renderer/components/MainContent.tsx +270 -34
  159. package/src/renderer/components/NotionSettings.tsx +231 -0
  160. package/src/renderer/components/Onboarding/Onboarding.tsx +13 -1
  161. package/src/renderer/components/OnboardingModal.tsx +70 -1
  162. package/src/renderer/components/OneDriveSettings.tsx +212 -0
  163. package/src/renderer/components/Settings.tsx +611 -8
  164. package/src/renderer/components/SharePointSettings.tsx +224 -0
  165. package/src/renderer/components/Sidebar.tsx +25 -9
  166. package/src/renderer/hooks/useOnboardingFlow.ts +21 -0
  167. package/src/renderer/styles/index.css +438 -25
  168. package/src/shared/channelMessages.ts +367 -4
  169. package/src/shared/llm-provider-catalog.ts +217 -0
  170. package/src/shared/types.ts +226 -1
@@ -1,4 +1,5 @@
1
1
  import { contextBridge, ipcRenderer } from 'electron';
2
+ import type { LLMProviderType } from '../shared/types';
2
3
 
3
4
  // IPC Channel names - inlined to avoid require() issues in sandboxed preload
4
5
  const IPC_CHANNELS = {
@@ -35,6 +36,9 @@ const IPC_CHANNELS = {
35
36
  LLM_GET_GEMINI_MODELS: 'llm:getGeminiModels',
36
37
  LLM_GET_OPENROUTER_MODELS: 'llm:getOpenRouterModels',
37
38
  LLM_GET_OPENAI_MODELS: 'llm:getOpenAIModels',
39
+ LLM_GET_GROQ_MODELS: 'llm:getGroqModels',
40
+ LLM_GET_XAI_MODELS: 'llm:getXAIModels',
41
+ LLM_GET_KIMI_MODELS: 'llm:getKimiModels',
38
42
  LLM_OPENAI_OAUTH_START: 'llm:openaiOAuthStart',
39
43
  LLM_OPENAI_OAUTH_LOGOUT: 'llm:openaiOAuthLogout',
40
44
  LLM_GET_BEDROCK_MODELS: 'llm:getBedrockModels',
@@ -60,6 +64,36 @@ const IPC_CHANNELS = {
60
64
  X_SAVE_SETTINGS: 'x:saveSettings',
61
65
  X_TEST_CONNECTION: 'x:testConnection',
62
66
  X_GET_STATUS: 'x:getStatus',
67
+ // Notion Settings
68
+ NOTION_GET_SETTINGS: 'notion:getSettings',
69
+ NOTION_SAVE_SETTINGS: 'notion:saveSettings',
70
+ NOTION_TEST_CONNECTION: 'notion:testConnection',
71
+ NOTION_GET_STATUS: 'notion:getStatus',
72
+ // Box Settings
73
+ BOX_GET_SETTINGS: 'box:getSettings',
74
+ BOX_SAVE_SETTINGS: 'box:saveSettings',
75
+ BOX_TEST_CONNECTION: 'box:testConnection',
76
+ BOX_GET_STATUS: 'box:getStatus',
77
+ // OneDrive Settings
78
+ ONEDRIVE_GET_SETTINGS: 'onedrive:getSettings',
79
+ ONEDRIVE_SAVE_SETTINGS: 'onedrive:saveSettings',
80
+ ONEDRIVE_TEST_CONNECTION: 'onedrive:testConnection',
81
+ ONEDRIVE_GET_STATUS: 'onedrive:getStatus',
82
+ // Google Drive Settings
83
+ GOOGLE_DRIVE_GET_SETTINGS: 'googleDrive:getSettings',
84
+ GOOGLE_DRIVE_SAVE_SETTINGS: 'googleDrive:saveSettings',
85
+ GOOGLE_DRIVE_TEST_CONNECTION: 'googleDrive:testConnection',
86
+ GOOGLE_DRIVE_GET_STATUS: 'googleDrive:getStatus',
87
+ // Dropbox Settings
88
+ DROPBOX_GET_SETTINGS: 'dropbox:getSettings',
89
+ DROPBOX_SAVE_SETTINGS: 'dropbox:saveSettings',
90
+ DROPBOX_TEST_CONNECTION: 'dropbox:testConnection',
91
+ DROPBOX_GET_STATUS: 'dropbox:getStatus',
92
+ // SharePoint Settings
93
+ SHAREPOINT_GET_SETTINGS: 'sharepoint:getSettings',
94
+ SHAREPOINT_SAVE_SETTINGS: 'sharepoint:saveSettings',
95
+ SHAREPOINT_TEST_CONNECTION: 'sharepoint:testConnection',
96
+ SHAREPOINT_GET_STATUS: 'sharepoint:getStatus',
63
97
  // App Updates
64
98
  APP_CHECK_UPDATES: 'app:checkUpdates',
65
99
  APP_DOWNLOAD_UPDATE: 'app:downloadUpdate',
@@ -127,6 +161,7 @@ const IPC_CHANNELS = {
127
161
  MCP_GET_SERVER_TOOLS: 'mcp:getServerTools',
128
162
  MCP_TEST_SERVER: 'mcp:testServer',
129
163
  MCP_SERVER_STATUS_CHANGE: 'mcp:serverStatusChange',
164
+ MCP_CONNECTOR_OAUTH_START: 'mcp:connectorOAuthStart',
130
165
  // MCP Registry
131
166
  MCP_REGISTRY_FETCH: 'mcp:registryFetch',
132
167
  MCP_REGISTRY_SEARCH: 'mcp:registrySearch',
@@ -228,6 +263,7 @@ const IPC_CHANNELS = {
228
263
  CANVAS_EXPORT_HTML: 'canvas:exportHTML',
229
264
  CANVAS_EXPORT_TO_FOLDER: 'canvas:exportToFolder',
230
265
  CANVAS_OPEN_IN_BROWSER: 'canvas:openInBrowser',
266
+ CANVAS_OPEN_URL: 'canvas:openUrl',
231
267
  CANVAS_GET_SESSION_DIR: 'canvas:getSessionDir',
232
268
  // Mobile Companion Nodes
233
269
  NODE_LIST: 'node:list',
@@ -606,6 +642,8 @@ interface BuiltinToolsSettings {
606
642
  image: ToolCategoryConfig;
607
643
  };
608
644
  toolOverrides: Record<string, { enabled: boolean; priority?: 'high' | 'normal' | 'low' }>;
645
+ toolTimeouts: Record<string, number>;
646
+ toolAutoApprove: Record<string, boolean>;
609
647
  version: string;
610
648
  }
611
649
 
@@ -1388,11 +1426,13 @@ interface UpdateContextPolicyOptions {
1388
1426
  contextBridge.exposeInMainWorld('electronAPI', {
1389
1427
  // Dialog APIs
1390
1428
  selectFolder: () => ipcRenderer.invoke('dialog:selectFolder'),
1429
+ selectFiles: () => ipcRenderer.invoke('dialog:selectFiles'),
1391
1430
 
1392
1431
  // File APIs
1393
1432
  openFile: (filePath: string, workspacePath?: string) => ipcRenderer.invoke('file:open', filePath, workspacePath),
1394
1433
  showInFinder: (filePath: string, workspacePath?: string) => ipcRenderer.invoke('file:showInFinder', filePath, workspacePath),
1395
1434
  readFileForViewer: (filePath: string, workspacePath?: string) => ipcRenderer.invoke('file:readForViewer', { filePath, workspacePath }),
1435
+ importFilesToWorkspace: (data: { workspaceId: string; files: string[] }) => ipcRenderer.invoke('file:importToWorkspace', data),
1396
1436
 
1397
1437
  // Shell APIs
1398
1438
  openExternal: (url: string) => ipcRenderer.invoke('shell:openExternal', url),
@@ -1451,8 +1491,11 @@ contextBridge.exposeInMainWorld('electronAPI', {
1451
1491
  setLLMModel: (modelKey: string) => ipcRenderer.invoke(IPC_CHANNELS.LLM_SET_MODEL, modelKey),
1452
1492
  getOllamaModels: (baseUrl?: string) => ipcRenderer.invoke(IPC_CHANNELS.LLM_GET_OLLAMA_MODELS, baseUrl),
1453
1493
  getGeminiModels: (apiKey?: string) => ipcRenderer.invoke(IPC_CHANNELS.LLM_GET_GEMINI_MODELS, apiKey),
1454
- getOpenRouterModels: (apiKey?: string) => ipcRenderer.invoke(IPC_CHANNELS.LLM_GET_OPENROUTER_MODELS, apiKey),
1494
+ getOpenRouterModels: (apiKey?: string, baseUrl?: string) => ipcRenderer.invoke(IPC_CHANNELS.LLM_GET_OPENROUTER_MODELS, apiKey, baseUrl),
1455
1495
  getOpenAIModels: (apiKey?: string) => ipcRenderer.invoke(IPC_CHANNELS.LLM_GET_OPENAI_MODELS, apiKey),
1496
+ getGroqModels: (apiKey?: string, baseUrl?: string) => ipcRenderer.invoke(IPC_CHANNELS.LLM_GET_GROQ_MODELS, apiKey, baseUrl),
1497
+ getXAIModels: (apiKey?: string, baseUrl?: string) => ipcRenderer.invoke(IPC_CHANNELS.LLM_GET_XAI_MODELS, apiKey, baseUrl),
1498
+ getKimiModels: (apiKey?: string, baseUrl?: string) => ipcRenderer.invoke(IPC_CHANNELS.LLM_GET_KIMI_MODELS, apiKey, baseUrl),
1456
1499
  openaiOAuthStart: () => ipcRenderer.invoke(IPC_CHANNELS.LLM_OPENAI_OAUTH_START),
1457
1500
  openaiOAuthLogout: () => ipcRenderer.invoke(IPC_CHANNELS.LLM_OPENAI_OAUTH_LOGOUT),
1458
1501
  getBedrockModels: (config?: { region?: string; accessKeyId?: string; secretAccessKey?: string; profile?: string }) =>
@@ -1508,6 +1551,42 @@ contextBridge.exposeInMainWorld('electronAPI', {
1508
1551
  testXConnection: () => ipcRenderer.invoke(IPC_CHANNELS.X_TEST_CONNECTION),
1509
1552
  getXStatus: () => ipcRenderer.invoke(IPC_CHANNELS.X_GET_STATUS),
1510
1553
 
1554
+ // Notion Settings APIs
1555
+ getNotionSettings: () => ipcRenderer.invoke(IPC_CHANNELS.NOTION_GET_SETTINGS),
1556
+ saveNotionSettings: (settings: any) => ipcRenderer.invoke(IPC_CHANNELS.NOTION_SAVE_SETTINGS, settings),
1557
+ testNotionConnection: () => ipcRenderer.invoke(IPC_CHANNELS.NOTION_TEST_CONNECTION),
1558
+ getNotionStatus: () => ipcRenderer.invoke(IPC_CHANNELS.NOTION_GET_STATUS),
1559
+
1560
+ // Box Settings APIs
1561
+ getBoxSettings: () => ipcRenderer.invoke(IPC_CHANNELS.BOX_GET_SETTINGS),
1562
+ saveBoxSettings: (settings: any) => ipcRenderer.invoke(IPC_CHANNELS.BOX_SAVE_SETTINGS, settings),
1563
+ testBoxConnection: () => ipcRenderer.invoke(IPC_CHANNELS.BOX_TEST_CONNECTION),
1564
+ getBoxStatus: () => ipcRenderer.invoke(IPC_CHANNELS.BOX_GET_STATUS),
1565
+
1566
+ // OneDrive Settings APIs
1567
+ getOneDriveSettings: () => ipcRenderer.invoke(IPC_CHANNELS.ONEDRIVE_GET_SETTINGS),
1568
+ saveOneDriveSettings: (settings: any) => ipcRenderer.invoke(IPC_CHANNELS.ONEDRIVE_SAVE_SETTINGS, settings),
1569
+ testOneDriveConnection: () => ipcRenderer.invoke(IPC_CHANNELS.ONEDRIVE_TEST_CONNECTION),
1570
+ getOneDriveStatus: () => ipcRenderer.invoke(IPC_CHANNELS.ONEDRIVE_GET_STATUS),
1571
+
1572
+ // Google Drive Settings APIs
1573
+ getGoogleDriveSettings: () => ipcRenderer.invoke(IPC_CHANNELS.GOOGLE_DRIVE_GET_SETTINGS),
1574
+ saveGoogleDriveSettings: (settings: any) => ipcRenderer.invoke(IPC_CHANNELS.GOOGLE_DRIVE_SAVE_SETTINGS, settings),
1575
+ testGoogleDriveConnection: () => ipcRenderer.invoke(IPC_CHANNELS.GOOGLE_DRIVE_TEST_CONNECTION),
1576
+ getGoogleDriveStatus: () => ipcRenderer.invoke(IPC_CHANNELS.GOOGLE_DRIVE_GET_STATUS),
1577
+
1578
+ // Dropbox Settings APIs
1579
+ getDropboxSettings: () => ipcRenderer.invoke(IPC_CHANNELS.DROPBOX_GET_SETTINGS),
1580
+ saveDropboxSettings: (settings: any) => ipcRenderer.invoke(IPC_CHANNELS.DROPBOX_SAVE_SETTINGS, settings),
1581
+ testDropboxConnection: () => ipcRenderer.invoke(IPC_CHANNELS.DROPBOX_TEST_CONNECTION),
1582
+ getDropboxStatus: () => ipcRenderer.invoke(IPC_CHANNELS.DROPBOX_GET_STATUS),
1583
+
1584
+ // SharePoint Settings APIs
1585
+ getSharePointSettings: () => ipcRenderer.invoke(IPC_CHANNELS.SHAREPOINT_GET_SETTINGS),
1586
+ saveSharePointSettings: (settings: any) => ipcRenderer.invoke(IPC_CHANNELS.SHAREPOINT_SAVE_SETTINGS, settings),
1587
+ testSharePointConnection: () => ipcRenderer.invoke(IPC_CHANNELS.SHAREPOINT_TEST_CONNECTION),
1588
+ getSharePointStatus: () => ipcRenderer.invoke(IPC_CHANNELS.SHAREPOINT_GET_STATUS),
1589
+
1511
1590
  // App Update APIs
1512
1591
  getAppVersion: () => ipcRenderer.invoke(IPC_CHANNELS.APP_GET_VERSION),
1513
1592
  checkForUpdates: () => ipcRenderer.invoke(IPC_CHANNELS.APP_CHECK_UPDATES),
@@ -1609,6 +1688,10 @@ contextBridge.exposeInMainWorld('electronAPI', {
1609
1688
  getMCPServerTools: (serverId: string) => ipcRenderer.invoke(IPC_CHANNELS.MCP_GET_SERVER_TOOLS, serverId),
1610
1689
  testMCPServer: (serverId: string) => ipcRenderer.invoke(IPC_CHANNELS.MCP_TEST_SERVER, serverId),
1611
1690
 
1691
+ // MCP Connector OAuth
1692
+ startConnectorOAuth: (payload: { provider: 'salesforce' | 'jira' | 'hubspot' | 'zendesk'; clientId: string; clientSecret?: string; scopes?: string[]; loginUrl?: string; subdomain?: string }) =>
1693
+ ipcRenderer.invoke(IPC_CHANNELS.MCP_CONNECTOR_OAUTH_START, payload),
1694
+
1612
1695
  // MCP Status change event listener
1613
1696
  onMCPStatusChange: (callback: (status: any[]) => void) => {
1614
1697
  const subscription = (_: any, data: any) => callback(data);
@@ -1791,6 +1874,8 @@ contextBridge.exposeInMainWorld('electronAPI', {
1791
1874
  ipcRenderer.invoke(IPC_CHANNELS.CANVAS_EXPORT_TO_FOLDER, data),
1792
1875
  canvasOpenInBrowser: (sessionId: string) =>
1793
1876
  ipcRenderer.invoke(IPC_CHANNELS.CANVAS_OPEN_IN_BROWSER, sessionId),
1877
+ canvasOpenUrl: (data: { sessionId: string; url: string; show?: boolean }) =>
1878
+ ipcRenderer.invoke(IPC_CHANNELS.CANVAS_OPEN_URL, data),
1794
1879
  canvasGetSessionDir: (sessionId: string) =>
1795
1880
  ipcRenderer.invoke(IPC_CHANNELS.CANVAS_GET_SESSION_DIR, sessionId),
1796
1881
  onCanvasEvent: (callback: (event: CanvasEvent) => void) => {
@@ -2149,9 +2234,11 @@ export type {
2149
2234
 
2150
2235
  export interface ElectronAPI {
2151
2236
  selectFolder: () => Promise<string | null>;
2237
+ selectFiles: () => Promise<Array<{ path: string; name: string; size: number; mimeType?: string }>>;
2152
2238
  openFile: (filePath: string, workspacePath?: string) => Promise<string>;
2153
2239
  showInFinder: (filePath: string, workspacePath?: string) => Promise<void>;
2154
2240
  readFileForViewer: (filePath: string, workspacePath?: string) => Promise<FileViewerResult>;
2241
+ importFilesToWorkspace: (data: { workspaceId: string; files: string[] }) => Promise<Array<{ relativePath: string; fileName: string; size: number; mimeType?: string }>>;
2155
2242
  openExternal: (url: string) => Promise<void>;
2156
2243
  createTask: (data: any) => Promise<any>;
2157
2244
  getTask: (id: string) => Promise<any>;
@@ -2182,16 +2269,24 @@ export interface ElectronAPI {
2182
2269
  testLLMProvider: (config: any) => Promise<{ success: boolean; error?: string }>;
2183
2270
  getLLMModels: () => Promise<Array<{ key: string; displayName: string; description: string }>>;
2184
2271
  getLLMConfigStatus: () => Promise<{
2185
- currentProvider: 'anthropic' | 'bedrock' | 'ollama';
2272
+ currentProvider: LLMProviderType;
2186
2273
  currentModel: string;
2187
- providers: Array<{ type: 'anthropic' | 'bedrock' | 'ollama'; name: string; configured: boolean; source?: string }>;
2274
+ providers: Array<{
2275
+ type: LLMProviderType;
2276
+ name: string;
2277
+ configured: boolean;
2278
+ source?: string;
2279
+ }>;
2188
2280
  models: Array<{ key: string; displayName: string; description: string }>;
2189
2281
  }>;
2190
2282
  setLLMModel: (modelKey: string) => Promise<{ success: boolean }>;
2191
2283
  getOllamaModels: (baseUrl?: string) => Promise<Array<{ name: string; size: number; modified: string }>>;
2192
2284
  getGeminiModels: (apiKey?: string) => Promise<Array<{ name: string; displayName: string; description: string }>>;
2193
- getOpenRouterModels: (apiKey?: string) => Promise<Array<{ id: string; name: string; context_length: number }>>;
2285
+ getOpenRouterModels: (apiKey?: string, baseUrl?: string) => Promise<Array<{ id: string; name: string; context_length: number }>>;
2194
2286
  getOpenAIModels: (apiKey?: string) => Promise<Array<{ id: string; name: string; description: string }>>;
2287
+ getGroqModels: (apiKey?: string, baseUrl?: string) => Promise<Array<{ id: string; name: string }>>;
2288
+ getXAIModels: (apiKey?: string, baseUrl?: string) => Promise<Array<{ id: string; name: string }>>;
2289
+ getKimiModels: (apiKey?: string, baseUrl?: string) => Promise<Array<{ id: string; name: string }>>;
2195
2290
  openaiOAuthStart: () => Promise<{ success: boolean; error?: string }>;
2196
2291
  openaiOAuthLogout: () => Promise<{ success: boolean }>;
2197
2292
  getBedrockModels: (config?: { region?: string; accessKeyId?: string; secretAccessKey?: string; profile?: string }) => Promise<Array<{ id: string; name: string; provider: string; description: string }>>;
@@ -2250,6 +2345,64 @@ export interface ElectronAPI {
2250
2345
  saveXSettings: (settings: any) => Promise<{ success: boolean }>;
2251
2346
  testXConnection: () => Promise<{ success: boolean; error?: string; username?: string; userId?: string }>;
2252
2347
  getXStatus: () => Promise<{ installed: boolean; connected: boolean; username?: string; error?: string }>;
2348
+ // Notion Settings
2349
+ getNotionSettings: () => Promise<{
2350
+ enabled: boolean;
2351
+ apiKey?: string;
2352
+ notionVersion?: string;
2353
+ timeoutMs?: number;
2354
+ }>;
2355
+ saveNotionSettings: (settings: any) => Promise<{ success: boolean }>;
2356
+ testNotionConnection: () => Promise<{ success: boolean; error?: string; name?: string; userId?: string }>;
2357
+ getNotionStatus: () => Promise<{ configured: boolean; connected: boolean; name?: string; error?: string }>;
2358
+ // Box Settings
2359
+ getBoxSettings: () => Promise<{
2360
+ enabled: boolean;
2361
+ accessToken?: string;
2362
+ timeoutMs?: number;
2363
+ }>;
2364
+ saveBoxSettings: (settings: any) => Promise<{ success: boolean }>;
2365
+ testBoxConnection: () => Promise<{ success: boolean; error?: string; name?: string; userId?: string }>;
2366
+ getBoxStatus: () => Promise<{ configured: boolean; connected: boolean; name?: string; error?: string }>;
2367
+ // OneDrive Settings
2368
+ getOneDriveSettings: () => Promise<{
2369
+ enabled: boolean;
2370
+ accessToken?: string;
2371
+ driveId?: string;
2372
+ timeoutMs?: number;
2373
+ }>;
2374
+ saveOneDriveSettings: (settings: any) => Promise<{ success: boolean }>;
2375
+ testOneDriveConnection: () => Promise<{ success: boolean; error?: string; name?: string; userId?: string; driveId?: string }>;
2376
+ getOneDriveStatus: () => Promise<{ configured: boolean; connected: boolean; name?: string; error?: string }>;
2377
+ // Google Drive Settings
2378
+ getGoogleDriveSettings: () => Promise<{
2379
+ enabled: boolean;
2380
+ accessToken?: string;
2381
+ timeoutMs?: number;
2382
+ }>;
2383
+ saveGoogleDriveSettings: (settings: any) => Promise<{ success: boolean }>;
2384
+ testGoogleDriveConnection: () => Promise<{ success: boolean; error?: string; name?: string; userId?: string; email?: string }>;
2385
+ getGoogleDriveStatus: () => Promise<{ configured: boolean; connected: boolean; name?: string; error?: string }>;
2386
+ // Dropbox Settings
2387
+ getDropboxSettings: () => Promise<{
2388
+ enabled: boolean;
2389
+ accessToken?: string;
2390
+ timeoutMs?: number;
2391
+ }>;
2392
+ saveDropboxSettings: (settings: any) => Promise<{ success: boolean }>;
2393
+ testDropboxConnection: () => Promise<{ success: boolean; error?: string; name?: string; userId?: string; email?: string }>;
2394
+ getDropboxStatus: () => Promise<{ configured: boolean; connected: boolean; name?: string; error?: string }>;
2395
+ // SharePoint Settings
2396
+ getSharePointSettings: () => Promise<{
2397
+ enabled: boolean;
2398
+ accessToken?: string;
2399
+ siteId?: string;
2400
+ driveId?: string;
2401
+ timeoutMs?: number;
2402
+ }>;
2403
+ saveSharePointSettings: (settings: any) => Promise<{ success: boolean }>;
2404
+ testSharePointConnection: () => Promise<{ success: boolean; error?: string; name?: string; userId?: string }>;
2405
+ getSharePointStatus: () => Promise<{ configured: boolean; connected: boolean; name?: string; error?: string }>;
2253
2406
  // App Updates
2254
2407
  getAppVersion: () => Promise<{
2255
2408
  version: string;
@@ -2466,6 +2619,15 @@ export interface ElectronAPI {
2466
2619
  getMCPAllTools: () => Promise<MCPTool[]>;
2467
2620
  getMCPServerTools: (serverId: string) => Promise<MCPTool[]>;
2468
2621
  testMCPServer: (serverId: string) => Promise<{ success: boolean; error?: string; tools?: number }>;
2622
+ startConnectorOAuth: (payload: { provider: 'salesforce' | 'jira' | 'hubspot' | 'zendesk'; clientId: string; clientSecret?: string; scopes?: string[]; loginUrl?: string; subdomain?: string }) => Promise<{
2623
+ provider: 'salesforce' | 'jira' | 'hubspot' | 'zendesk';
2624
+ accessToken: string;
2625
+ refreshToken?: string;
2626
+ expiresIn?: number;
2627
+ tokenType?: string;
2628
+ instanceUrl?: string;
2629
+ resources?: Array<{ id: string; name: string; url: string; scopes?: string[] }>;
2630
+ }>;
2469
2631
  onMCPStatusChange: (callback: (status: MCPServerStatus[]) => void) => () => void;
2470
2632
  // MCP Registry
2471
2633
  fetchMCPRegistry: () => Promise<MCPRegistry>;
@@ -2579,6 +2741,7 @@ export interface ElectronAPI {
2579
2741
  canvasExportHTML: (sessionId: string) => Promise<{ content: string; filename: string }>;
2580
2742
  canvasExportToFolder: (data: { sessionId: string; targetDir: string }) => Promise<{ files: string[]; targetDir: string }>;
2581
2743
  canvasOpenInBrowser: (sessionId: string) => Promise<{ success: boolean; path: string }>;
2744
+ canvasOpenUrl: (data: { sessionId: string; url: string; show?: boolean }) => Promise<{ success: boolean; url: string }>;
2582
2745
  canvasGetSessionDir: (sessionId: string) => Promise<string | null>;
2583
2746
  onCanvasEvent: (callback: (event: CanvasEvent) => void) => () => void;
2584
2747
 
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Box Settings Manager
3
+ *
4
+ * Stores Box integration settings in encrypted database.
5
+ */
6
+
7
+ import { SecureSettingsRepository } from '../database/SecureSettingsRepository';
8
+ import { BoxSettingsData } from '../../shared/types';
9
+
10
+ const DEFAULT_SETTINGS: BoxSettingsData = {
11
+ enabled: false,
12
+ timeoutMs: 20000,
13
+ };
14
+
15
+ export class BoxSettingsManager {
16
+ private static cachedSettings: BoxSettingsData | null = null;
17
+
18
+ static loadSettings(): BoxSettingsData {
19
+ if (this.cachedSettings) {
20
+ return this.cachedSettings;
21
+ }
22
+
23
+ let settings: BoxSettingsData = { ...DEFAULT_SETTINGS };
24
+
25
+ try {
26
+ if (SecureSettingsRepository.isInitialized()) {
27
+ const repository = SecureSettingsRepository.getInstance();
28
+ const stored = repository.load<BoxSettingsData>('box');
29
+ if (stored) {
30
+ settings = { ...DEFAULT_SETTINGS, ...stored };
31
+ }
32
+ }
33
+ } catch (error) {
34
+ console.error('[BoxSettingsManager] Failed to load settings:', error);
35
+ }
36
+
37
+ this.cachedSettings = settings;
38
+ return settings;
39
+ }
40
+
41
+ static saveSettings(settings: BoxSettingsData): void {
42
+ try {
43
+ if (!SecureSettingsRepository.isInitialized()) {
44
+ throw new Error('SecureSettingsRepository not initialized');
45
+ }
46
+ const repository = SecureSettingsRepository.getInstance();
47
+ repository.save('box', settings);
48
+ this.cachedSettings = settings;
49
+ console.log('[BoxSettingsManager] Settings saved');
50
+ } catch (error) {
51
+ console.error('[BoxSettingsManager] Failed to save settings:', error);
52
+ }
53
+ }
54
+
55
+ static clearCache(): void {
56
+ this.cachedSettings = null;
57
+ }
58
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Dropbox Settings Manager
3
+ *
4
+ * Stores Dropbox integration settings in encrypted database.
5
+ */
6
+
7
+ import { SecureSettingsRepository } from '../database/SecureSettingsRepository';
8
+ import { DropboxSettingsData } from '../../shared/types';
9
+
10
+ const DEFAULT_SETTINGS: DropboxSettingsData = {
11
+ enabled: false,
12
+ timeoutMs: 20000,
13
+ };
14
+
15
+ export class DropboxSettingsManager {
16
+ private static cachedSettings: DropboxSettingsData | null = null;
17
+
18
+ static loadSettings(): DropboxSettingsData {
19
+ if (this.cachedSettings) {
20
+ return this.cachedSettings;
21
+ }
22
+
23
+ let settings: DropboxSettingsData = { ...DEFAULT_SETTINGS };
24
+
25
+ try {
26
+ if (SecureSettingsRepository.isInitialized()) {
27
+ const repository = SecureSettingsRepository.getInstance();
28
+ const stored = repository.load<DropboxSettingsData>('dropbox');
29
+ if (stored) {
30
+ settings = { ...DEFAULT_SETTINGS, ...stored };
31
+ }
32
+ }
33
+ } catch (error) {
34
+ console.error('[DropboxSettingsManager] Failed to load settings:', error);
35
+ }
36
+
37
+ this.cachedSettings = settings;
38
+ return settings;
39
+ }
40
+
41
+ static saveSettings(settings: DropboxSettingsData): void {
42
+ try {
43
+ if (!SecureSettingsRepository.isInitialized()) {
44
+ throw new Error('SecureSettingsRepository not initialized');
45
+ }
46
+ const repository = SecureSettingsRepository.getInstance();
47
+ repository.save('dropbox', settings);
48
+ this.cachedSettings = settings;
49
+ console.log('[DropboxSettingsManager] Settings saved');
50
+ } catch (error) {
51
+ console.error('[DropboxSettingsManager] Failed to save settings:', error);
52
+ }
53
+ }
54
+
55
+ static clearCache(): void {
56
+ this.cachedSettings = null;
57
+ }
58
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Google Drive Settings Manager
3
+ *
4
+ * Stores Google Drive integration settings in encrypted database.
5
+ */
6
+
7
+ import { SecureSettingsRepository } from '../database/SecureSettingsRepository';
8
+ import { GoogleDriveSettingsData } from '../../shared/types';
9
+
10
+ const DEFAULT_SETTINGS: GoogleDriveSettingsData = {
11
+ enabled: false,
12
+ timeoutMs: 20000,
13
+ };
14
+
15
+ export class GoogleDriveSettingsManager {
16
+ private static cachedSettings: GoogleDriveSettingsData | null = null;
17
+
18
+ static loadSettings(): GoogleDriveSettingsData {
19
+ if (this.cachedSettings) {
20
+ return this.cachedSettings;
21
+ }
22
+
23
+ let settings: GoogleDriveSettingsData = { ...DEFAULT_SETTINGS };
24
+
25
+ try {
26
+ if (SecureSettingsRepository.isInitialized()) {
27
+ const repository = SecureSettingsRepository.getInstance();
28
+ const stored = repository.load<GoogleDriveSettingsData>('google-drive');
29
+ if (stored) {
30
+ settings = { ...DEFAULT_SETTINGS, ...stored };
31
+ }
32
+ }
33
+ } catch (error) {
34
+ console.error('[GoogleDriveSettingsManager] Failed to load settings:', error);
35
+ }
36
+
37
+ this.cachedSettings = settings;
38
+ return settings;
39
+ }
40
+
41
+ static saveSettings(settings: GoogleDriveSettingsData): void {
42
+ try {
43
+ if (!SecureSettingsRepository.isInitialized()) {
44
+ throw new Error('SecureSettingsRepository not initialized');
45
+ }
46
+ const repository = SecureSettingsRepository.getInstance();
47
+ repository.save('google-drive', settings);
48
+ this.cachedSettings = settings;
49
+ console.log('[GoogleDriveSettingsManager] Settings saved');
50
+ } catch (error) {
51
+ console.error('[GoogleDriveSettingsManager] Failed to save settings:', error);
52
+ }
53
+ }
54
+
55
+ static clearCache(): void {
56
+ this.cachedSettings = null;
57
+ }
58
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Notion Settings Manager
3
+ *
4
+ * Stores Notion integration settings in encrypted database.
5
+ */
6
+
7
+ import { SecureSettingsRepository } from '../database/SecureSettingsRepository';
8
+ import { NotionSettingsData } from '../../shared/types';
9
+ import { DEFAULT_NOTION_VERSION } from '../utils/notion-api';
10
+
11
+ const DEFAULT_SETTINGS: NotionSettingsData = {
12
+ enabled: false,
13
+ notionVersion: DEFAULT_NOTION_VERSION,
14
+ timeoutMs: 20000,
15
+ };
16
+
17
+ export class NotionSettingsManager {
18
+ private static cachedSettings: NotionSettingsData | null = null;
19
+
20
+ static loadSettings(): NotionSettingsData {
21
+ if (this.cachedSettings) {
22
+ return this.cachedSettings;
23
+ }
24
+
25
+ let settings: NotionSettingsData = { ...DEFAULT_SETTINGS };
26
+
27
+ try {
28
+ if (SecureSettingsRepository.isInitialized()) {
29
+ const repository = SecureSettingsRepository.getInstance();
30
+ const stored = repository.load<NotionSettingsData>('notion');
31
+ if (stored) {
32
+ settings = { ...DEFAULT_SETTINGS, ...stored };
33
+ }
34
+ }
35
+ } catch (error) {
36
+ console.error('[NotionSettingsManager] Failed to load settings:', error);
37
+ }
38
+
39
+ this.cachedSettings = settings;
40
+ return settings;
41
+ }
42
+
43
+ static saveSettings(settings: NotionSettingsData): void {
44
+ try {
45
+ if (!SecureSettingsRepository.isInitialized()) {
46
+ throw new Error('SecureSettingsRepository not initialized');
47
+ }
48
+ const repository = SecureSettingsRepository.getInstance();
49
+ repository.save('notion', settings);
50
+ this.cachedSettings = settings;
51
+ console.log('[NotionSettingsManager] Settings saved');
52
+ } catch (error) {
53
+ console.error('[NotionSettingsManager] Failed to save settings:', error);
54
+ }
55
+ }
56
+
57
+ static clearCache(): void {
58
+ this.cachedSettings = null;
59
+ }
60
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * OneDrive Settings Manager
3
+ *
4
+ * Stores OneDrive integration settings in encrypted database.
5
+ */
6
+
7
+ import { SecureSettingsRepository } from '../database/SecureSettingsRepository';
8
+ import { OneDriveSettingsData } from '../../shared/types';
9
+
10
+ const DEFAULT_SETTINGS: OneDriveSettingsData = {
11
+ enabled: false,
12
+ timeoutMs: 20000,
13
+ };
14
+
15
+ export class OneDriveSettingsManager {
16
+ private static cachedSettings: OneDriveSettingsData | null = null;
17
+
18
+ static loadSettings(): OneDriveSettingsData {
19
+ if (this.cachedSettings) {
20
+ return this.cachedSettings;
21
+ }
22
+
23
+ let settings: OneDriveSettingsData = { ...DEFAULT_SETTINGS };
24
+
25
+ try {
26
+ if (SecureSettingsRepository.isInitialized()) {
27
+ const repository = SecureSettingsRepository.getInstance();
28
+ const stored = repository.load<OneDriveSettingsData>('onedrive');
29
+ if (stored) {
30
+ settings = { ...DEFAULT_SETTINGS, ...stored };
31
+ }
32
+ }
33
+ } catch (error) {
34
+ console.error('[OneDriveSettingsManager] Failed to load settings:', error);
35
+ }
36
+
37
+ this.cachedSettings = settings;
38
+ return settings;
39
+ }
40
+
41
+ static saveSettings(settings: OneDriveSettingsData): void {
42
+ try {
43
+ if (!SecureSettingsRepository.isInitialized()) {
44
+ throw new Error('SecureSettingsRepository not initialized');
45
+ }
46
+ const repository = SecureSettingsRepository.getInstance();
47
+ repository.save('onedrive', settings);
48
+ this.cachedSettings = settings;
49
+ console.log('[OneDriveSettingsManager] Settings saved');
50
+ } catch (error) {
51
+ console.error('[OneDriveSettingsManager] Failed to save settings:', error);
52
+ }
53
+ }
54
+
55
+ static clearCache(): void {
56
+ this.cachedSettings = null;
57
+ }
58
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * SharePoint Settings Manager
3
+ *
4
+ * Stores SharePoint integration settings in encrypted database.
5
+ */
6
+
7
+ import { SecureSettingsRepository } from '../database/SecureSettingsRepository';
8
+ import { SharePointSettingsData } from '../../shared/types';
9
+
10
+ const DEFAULT_SETTINGS: SharePointSettingsData = {
11
+ enabled: false,
12
+ timeoutMs: 20000,
13
+ };
14
+
15
+ export class SharePointSettingsManager {
16
+ private static cachedSettings: SharePointSettingsData | null = null;
17
+
18
+ static loadSettings(): SharePointSettingsData {
19
+ if (this.cachedSettings) {
20
+ return this.cachedSettings;
21
+ }
22
+
23
+ let settings: SharePointSettingsData = { ...DEFAULT_SETTINGS };
24
+
25
+ try {
26
+ if (SecureSettingsRepository.isInitialized()) {
27
+ const repository = SecureSettingsRepository.getInstance();
28
+ const stored = repository.load<SharePointSettingsData>('sharepoint');
29
+ if (stored) {
30
+ settings = { ...DEFAULT_SETTINGS, ...stored };
31
+ }
32
+ }
33
+ } catch (error) {
34
+ console.error('[SharePointSettingsManager] Failed to load settings:', error);
35
+ }
36
+
37
+ this.cachedSettings = settings;
38
+ return settings;
39
+ }
40
+
41
+ static saveSettings(settings: SharePointSettingsData): void {
42
+ try {
43
+ if (!SecureSettingsRepository.isInitialized()) {
44
+ throw new Error('SecureSettingsRepository not initialized');
45
+ }
46
+ const repository = SecureSettingsRepository.getInstance();
47
+ repository.save('sharepoint', settings);
48
+ this.cachedSettings = settings;
49
+ console.log('[SharePointSettingsManager] Settings saved');
50
+ } catch (error) {
51
+ console.error('[SharePointSettingsManager] Failed to save settings:', error);
52
+ }
53
+ }
54
+
55
+ static clearCache(): void {
56
+ this.cachedSettings = null;
57
+ }
58
+ }