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,109 @@
1
+ "use strict";
2
+ /**
3
+ * SharePoint API helpers (Microsoft Graph)
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SHAREPOINT_API_BASE = void 0;
7
+ exports.sharepointRequest = sharepointRequest;
8
+ exports.testSharePointConnection = testSharePointConnection;
9
+ exports.SHAREPOINT_API_BASE = 'https://graph.microsoft.com/v1.0';
10
+ const DEFAULT_TIMEOUT_MS = 20000;
11
+ function parseJsonSafe(text) {
12
+ const trimmed = text.trim();
13
+ if (!trimmed)
14
+ return undefined;
15
+ try {
16
+ return JSON.parse(trimmed);
17
+ }
18
+ catch {
19
+ return undefined;
20
+ }
21
+ }
22
+ function formatGraphError(status, data, fallback) {
23
+ const message = data?.error?.message ||
24
+ data?.message ||
25
+ fallback ||
26
+ 'Microsoft Graph error';
27
+ return `Microsoft Graph error ${status}: ${message}`;
28
+ }
29
+ async function sharepointRequest(settings, options) {
30
+ if (!settings.accessToken) {
31
+ throw new Error('SharePoint access token not configured. Add it in Settings > Integrations > SharePoint.');
32
+ }
33
+ const params = new URLSearchParams();
34
+ if (options.query) {
35
+ for (const [key, value] of Object.entries(options.query)) {
36
+ if (value === undefined || value === null)
37
+ continue;
38
+ params.set(key, String(value));
39
+ }
40
+ }
41
+ const queryString = params.toString();
42
+ const url = `${exports.SHAREPOINT_API_BASE}${options.path}${queryString ? `?${queryString}` : ''}`;
43
+ const headers = {
44
+ Authorization: `Bearer ${settings.accessToken}`,
45
+ ...(options.headers || {}),
46
+ };
47
+ const isBinaryBody = options.body instanceof Uint8Array || options.body instanceof ArrayBuffer || Buffer.isBuffer(options.body);
48
+ if (options.body && !isBinaryBody && options.method !== 'GET' && options.method !== 'DELETE') {
49
+ headers['Content-Type'] = headers['Content-Type'] || 'application/json';
50
+ }
51
+ const timeoutMs = options.timeoutMs ?? settings.timeoutMs ?? DEFAULT_TIMEOUT_MS;
52
+ const controller = new AbortController();
53
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
54
+ try {
55
+ const response = await fetch(url, {
56
+ method: options.method,
57
+ headers,
58
+ body: options.body
59
+ ? isBinaryBody
60
+ ? options.body
61
+ : JSON.stringify(options.body)
62
+ : undefined,
63
+ signal: controller.signal,
64
+ });
65
+ const rawText = typeof response.text === 'function' ? await response.text() : '';
66
+ const data = rawText ? parseJsonSafe(rawText) : undefined;
67
+ if (!response.ok) {
68
+ throw new Error(formatGraphError(response.status, data, response.statusText));
69
+ }
70
+ return {
71
+ status: response.status,
72
+ data: data ?? undefined,
73
+ raw: rawText || undefined,
74
+ };
75
+ }
76
+ catch (error) {
77
+ if (error?.name === 'AbortError') {
78
+ throw new Error('SharePoint API request timed out');
79
+ }
80
+ throw error;
81
+ }
82
+ finally {
83
+ clearTimeout(timeout);
84
+ }
85
+ }
86
+ function extractUserInfo(data) {
87
+ if (!data || typeof data !== 'object')
88
+ return {};
89
+ const name = data.displayName || data.name || undefined;
90
+ const userId = data.id || undefined;
91
+ return { name, userId };
92
+ }
93
+ async function testSharePointConnection(settings) {
94
+ try {
95
+ const result = await sharepointRequest(settings, { method: 'GET', path: '/me' });
96
+ const extracted = extractUserInfo(result.data);
97
+ return {
98
+ success: true,
99
+ name: extracted.name,
100
+ userId: extracted.userId,
101
+ };
102
+ }
103
+ catch (error) {
104
+ return {
105
+ success: false,
106
+ error: error?.message || 'Failed to connect to SharePoint',
107
+ };
108
+ }
109
+ }
@@ -4,10 +4,11 @@
4
4
  * Provides type-safe validation to prevent malformed input attacks
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.MCPRegistrySearchSchema = exports.MCPSettingsSchema = exports.MCPServerUpdateSchema = exports.MCPServerConfigSchema = exports.MCPAuthConfigSchema = exports.MCPTransportTypeSchema = exports.StringIdSchema = exports.UUIDSchema = exports.FilePathSchema = exports.GeneratePairingSchema = exports.RevokeAccessSchema = exports.GrantAccessSchema = exports.UpdateChannelSchema = exports.ChannelConfigSchema = exports.AddChannelSchema = exports.AddEmailChannelSchema = exports.AddBlueBubblesChannelSchema = exports.AddLineChannelSchema = exports.AddTwitchChannelSchema = exports.AddMatrixChannelSchema = exports.AddMattermostChannelSchema = exports.AddSignalChannelSchema = exports.AddImessageChannelSchema = exports.SignalTrustModeSchema = exports.SignalModeSchema = exports.GroupPolicySchema = exports.DmPolicySchema = exports.AddWhatsAppChannelSchema = exports.AddSlackChannelSchema = exports.AddDiscordChannelSchema = exports.AddTelegramChannelSchema = exports.SecurityModeSchema = exports.GuardrailSettingsSchema = exports.XSettingsSchema = exports.SearchSettingsSchema = exports.SearchProviderTypeSchema = exports.LLMSettingsSchema = exports.OpenAISettingsSchema = exports.OpenRouterSettingsSchema = exports.GeminiSettingsSchema = exports.OllamaSettingsSchema = exports.BedrockSettingsSchema = exports.AnthropicSettingsSchema = exports.LLMProviderTypeSchema = exports.ApprovalResponseSchema = exports.TaskMessageSchema = exports.TaskRenameSchema = exports.TaskCreateSchema = exports.SuccessCriteriaSchema = exports.WorkspaceCreateSchema = void 0;
8
- exports.HookMappingSchema = exports.HookMappingChannelSchema = void 0;
7
+ exports.AddChannelSchema = exports.AddEmailChannelSchema = exports.AddBlueBubblesChannelSchema = exports.AddLineChannelSchema = exports.AddTwitchChannelSchema = exports.AddMatrixChannelSchema = exports.AddMattermostChannelSchema = exports.AddSignalChannelSchema = exports.AddImessageChannelSchema = exports.SignalTrustModeSchema = exports.SignalModeSchema = exports.GroupPolicySchema = exports.DmPolicySchema = exports.AddWhatsAppChannelSchema = exports.AddSlackChannelSchema = exports.AddDiscordChannelSchema = exports.AddTelegramChannelSchema = exports.SecurityModeSchema = exports.GuardrailSettingsSchema = exports.SharePointSettingsSchema = exports.DropboxSettingsSchema = exports.GoogleDriveSettingsSchema = exports.OneDriveSettingsSchema = exports.BoxSettingsSchema = exports.NotionSettingsSchema = exports.XSettingsSchema = exports.SearchSettingsSchema = exports.SearchProviderTypeSchema = exports.LLMSettingsSchema = exports.CustomProvidersSchema = exports.CustomProviderConfigSchema = exports.KimiSettingsSchema = exports.XAISettingsSchema = exports.GroqSettingsSchema = exports.AzureSettingsSchema = exports.OpenAISettingsSchema = exports.OpenRouterSettingsSchema = exports.GeminiSettingsSchema = exports.OllamaSettingsSchema = exports.BedrockSettingsSchema = exports.AnthropicSettingsSchema = exports.LLMProviderTypeSchema = exports.ApprovalResponseSchema = exports.FileImportDataSchema = exports.FileImportSchema = exports.TaskMessageSchema = exports.TaskRenameSchema = exports.TaskCreateSchema = exports.SuccessCriteriaSchema = exports.WorkspaceCreateSchema = void 0;
8
+ exports.HookMappingSchema = exports.HookMappingChannelSchema = exports.MCPConnectorOAuthSchema = exports.MCPRegistrySearchSchema = exports.MCPSettingsSchema = exports.MCPServerUpdateSchema = exports.MCPServerConfigSchema = exports.MCPAuthConfigSchema = exports.MCPTransportTypeSchema = exports.StringIdSchema = exports.UUIDSchema = exports.FilePathSchema = exports.GeneratePairingSchema = exports.RevokeAccessSchema = exports.GrantAccessSchema = exports.UpdateChannelSchema = exports.ChannelConfigSchema = void 0;
9
9
  exports.validateInput = validateInput;
10
10
  const zod_1 = require("zod");
11
+ const types_1 = require("../../shared/types");
11
12
  // Common validation patterns
12
13
  const MAX_STRING_LENGTH = 10000;
13
14
  const MAX_PATH_LENGTH = 4096;
@@ -54,13 +55,25 @@ exports.TaskMessageSchema = zod_1.z.object({
54
55
  taskId: zod_1.z.string().uuid(),
55
56
  message: zod_1.z.string().min(1).max(MAX_PROMPT_LENGTH),
56
57
  });
58
+ exports.FileImportSchema = zod_1.z.object({
59
+ workspaceId: zod_1.z.string().refine((val) => val === TEMP_WORKSPACE_ID || zod_1.z.string().uuid().safeParse(val).success, { message: 'Must be a valid UUID or temp workspace ID' }),
60
+ files: zod_1.z.array(zod_1.z.string().min(1).max(MAX_PATH_LENGTH)).min(1).max(20),
61
+ });
62
+ exports.FileImportDataSchema = zod_1.z.object({
63
+ workspaceId: zod_1.z.string().refine((val) => val === TEMP_WORKSPACE_ID || zod_1.z.string().uuid().safeParse(val).success, { message: 'Must be a valid UUID or temp workspace ID' }),
64
+ files: zod_1.z.array(zod_1.z.object({
65
+ name: zod_1.z.string().min(1).max(MAX_PATH_LENGTH),
66
+ data: zod_1.z.string().min(1),
67
+ mimeType: zod_1.z.string().max(200).optional(),
68
+ })).min(1).max(20),
69
+ });
57
70
  // ============ Approval Schemas ============
58
71
  exports.ApprovalResponseSchema = zod_1.z.object({
59
72
  approvalId: zod_1.z.string().uuid(),
60
73
  approved: zod_1.z.boolean(),
61
74
  });
62
75
  // ============ LLM Settings Schemas ============
63
- exports.LLMProviderTypeSchema = zod_1.z.enum(['anthropic', 'bedrock', 'ollama', 'gemini', 'openrouter', 'openai']);
76
+ exports.LLMProviderTypeSchema = zod_1.z.enum(types_1.LLM_PROVIDER_TYPES);
64
77
  exports.AnthropicSettingsSchema = zod_1.z.object({
65
78
  apiKey: zod_1.z.string().max(500).optional(),
66
79
  }).optional();
@@ -85,6 +98,7 @@ exports.GeminiSettingsSchema = zod_1.z.object({
85
98
  exports.OpenRouterSettingsSchema = zod_1.z.object({
86
99
  apiKey: zod_1.z.string().max(500).optional(),
87
100
  model: zod_1.z.string().max(200).optional(),
101
+ baseUrl: zod_1.z.string().max(500).optional(),
88
102
  }).optional();
89
103
  exports.OpenAISettingsSchema = zod_1.z.object({
90
104
  apiKey: zod_1.z.string().max(500).optional(),
@@ -95,6 +109,34 @@ exports.OpenAISettingsSchema = zod_1.z.object({
95
109
  tokenExpiresAt: zod_1.z.number().optional(),
96
110
  authMethod: zod_1.z.enum(['api_key', 'oauth']).optional(),
97
111
  }).optional();
112
+ exports.AzureSettingsSchema = zod_1.z.object({
113
+ apiKey: zod_1.z.string().max(500).optional(),
114
+ endpoint: zod_1.z.string().max(500).optional(),
115
+ deployment: zod_1.z.string().max(200).optional(),
116
+ deployments: zod_1.z.array(zod_1.z.string().max(200)).max(50).optional(),
117
+ apiVersion: zod_1.z.string().max(200).optional(),
118
+ }).optional();
119
+ exports.GroqSettingsSchema = zod_1.z.object({
120
+ apiKey: zod_1.z.string().max(500).optional(),
121
+ model: zod_1.z.string().max(200).optional(),
122
+ baseUrl: zod_1.z.string().max(500).optional(),
123
+ }).optional();
124
+ exports.XAISettingsSchema = zod_1.z.object({
125
+ apiKey: zod_1.z.string().max(500).optional(),
126
+ model: zod_1.z.string().max(200).optional(),
127
+ baseUrl: zod_1.z.string().max(500).optional(),
128
+ }).optional();
129
+ exports.KimiSettingsSchema = zod_1.z.object({
130
+ apiKey: zod_1.z.string().max(500).optional(),
131
+ model: zod_1.z.string().max(200).optional(),
132
+ baseUrl: zod_1.z.string().max(500).optional(),
133
+ }).optional();
134
+ exports.CustomProviderConfigSchema = zod_1.z.object({
135
+ apiKey: zod_1.z.string().max(500).optional(),
136
+ model: zod_1.z.string().max(200).optional(),
137
+ baseUrl: zod_1.z.string().max(500).optional(),
138
+ });
139
+ exports.CustomProvidersSchema = zod_1.z.record(zod_1.z.string(), exports.CustomProviderConfigSchema).optional();
98
140
  exports.LLMSettingsSchema = zod_1.z.object({
99
141
  providerType: exports.LLMProviderTypeSchema,
100
142
  modelKey: zod_1.z.string().max(200),
@@ -104,6 +146,11 @@ exports.LLMSettingsSchema = zod_1.z.object({
104
146
  gemini: exports.GeminiSettingsSchema,
105
147
  openrouter: exports.OpenRouterSettingsSchema,
106
148
  openai: exports.OpenAISettingsSchema,
149
+ azure: exports.AzureSettingsSchema,
150
+ groq: exports.GroqSettingsSchema,
151
+ xai: exports.XAISettingsSchema,
152
+ kimi: exports.KimiSettingsSchema,
153
+ customProviders: exports.CustomProvidersSchema,
107
154
  });
108
155
  // ============ Search Settings Schemas ============
109
156
  exports.SearchProviderTypeSchema = zod_1.z.enum(['tavily', 'brave', 'serpapi', 'google']).nullable();
@@ -138,6 +185,46 @@ exports.XSettingsSchema = zod_1.z.object({
138
185
  cookieTimeoutMs: zod_1.z.number().int().min(1000).max(120000).optional(),
139
186
  quoteDepth: zod_1.z.number().int().min(0).max(5).optional(),
140
187
  });
188
+ // ============ Notion Settings Schema ============
189
+ exports.NotionSettingsSchema = zod_1.z.object({
190
+ enabled: zod_1.z.boolean().default(false),
191
+ apiKey: zod_1.z.string().max(2000).optional(),
192
+ notionVersion: zod_1.z.string().max(50).optional(),
193
+ timeoutMs: zod_1.z.number().int().min(1000).max(120000).optional(),
194
+ });
195
+ // ============ Box Settings Schema ============
196
+ exports.BoxSettingsSchema = zod_1.z.object({
197
+ enabled: zod_1.z.boolean().default(false),
198
+ accessToken: zod_1.z.string().max(4000).optional(),
199
+ timeoutMs: zod_1.z.number().int().min(1000).max(120000).optional(),
200
+ });
201
+ // ============ OneDrive Settings Schema ============
202
+ exports.OneDriveSettingsSchema = zod_1.z.object({
203
+ enabled: zod_1.z.boolean().default(false),
204
+ accessToken: zod_1.z.string().max(4000).optional(),
205
+ driveId: zod_1.z.string().max(200).optional(),
206
+ timeoutMs: zod_1.z.number().int().min(1000).max(120000).optional(),
207
+ });
208
+ // ============ Google Drive Settings Schema ============
209
+ exports.GoogleDriveSettingsSchema = zod_1.z.object({
210
+ enabled: zod_1.z.boolean().default(false),
211
+ accessToken: zod_1.z.string().max(4000).optional(),
212
+ timeoutMs: zod_1.z.number().int().min(1000).max(120000).optional(),
213
+ });
214
+ // ============ Dropbox Settings Schema ============
215
+ exports.DropboxSettingsSchema = zod_1.z.object({
216
+ enabled: zod_1.z.boolean().default(false),
217
+ accessToken: zod_1.z.string().max(4000).optional(),
218
+ timeoutMs: zod_1.z.number().int().min(1000).max(120000).optional(),
219
+ });
220
+ // ============ SharePoint Settings Schema ============
221
+ exports.SharePointSettingsSchema = zod_1.z.object({
222
+ enabled: zod_1.z.boolean().default(false),
223
+ accessToken: zod_1.z.string().max(4000).optional(),
224
+ siteId: zod_1.z.string().max(500).optional(),
225
+ driveId: zod_1.z.string().max(500).optional(),
226
+ timeoutMs: zod_1.z.number().int().min(1000).max(120000).optional(),
227
+ });
141
228
  // ============ Guardrail Settings Schema ============
142
229
  exports.GuardrailSettingsSchema = zod_1.z.object({
143
230
  // Token budget
@@ -381,6 +468,14 @@ exports.MCPRegistrySearchSchema = zod_1.z.object({
381
468
  limit: zod_1.z.number().int().min(1).max(100).default(50),
382
469
  offset: zod_1.z.number().int().min(0).default(0),
383
470
  });
471
+ exports.MCPConnectorOAuthSchema = zod_1.z.object({
472
+ provider: zod_1.z.enum(['salesforce', 'jira', 'hubspot', 'zendesk']),
473
+ clientId: zod_1.z.string().min(1).max(500),
474
+ clientSecret: zod_1.z.string().max(500).optional(),
475
+ scopes: zod_1.z.array(zod_1.z.string().max(200)).max(50).optional(),
476
+ loginUrl: zod_1.z.string().url().max(500).optional(),
477
+ subdomain: zod_1.z.string().max(200).optional(),
478
+ });
384
479
  // ============ Hooks (Webhooks) Schemas ============
385
480
  exports.HookMappingChannelSchema = zod_1.z.enum(['telegram', 'discord', 'slack', 'whatsapp', 'imessage', 'signal', 'mattermost', 'matrix', 'twitch', 'line', 'bluebubbles', 'email', 'last']);
386
481
  exports.HookMappingSchema = zod_1.z.object({
@@ -47,7 +47,7 @@ function buildGlobalArgs(settings, json) {
47
47
  const args = [];
48
48
  if (settings.authMethod === 'manual') {
49
49
  if (!settings.authToken || !settings.ct0) {
50
- throw new Error('Missing auth_token or ct0. Add them in Settings > More Channels > X.');
50
+ throw new Error('Missing auth_token or ct0. Add them in Settings > X (Twitter).');
51
51
  }
52
52
  args.push('--auth-token', settings.authToken, '--ct0', settings.ct0);
53
53
  }
@@ -10,7 +10,256 @@
10
10
  Object.defineProperty(exports, "__esModule", { value: true });
11
11
  exports.DEFAULT_CHANNEL_CONTEXT = void 0;
12
12
  exports.getChannelMessage = getChannelMessage;
13
+ exports.getChannelUiCopy = getChannelUiCopy;
13
14
  exports.getCompletionMessage = getCompletionMessage;
15
+ const CHANNEL_UI_COPY = {
16
+ welcomeStandard: '👋 Welcome to CoWork! Send me a task whenever you are ready.',
17
+ welcomeBack: '👋 Welcome back!\n\nWorkspace: *{workspaceName}*\n\nSend me what you want to do.\n\nType /help for commands.',
18
+ welcomeNoWorkspace: '👋 Welcome to CoWork!\n\nFirst, add a workspace:\n`/addworkspace /path/to/project`\n\nOr add one from the desktop app.',
19
+ welcomeSingleWorkspace: '👋 Welcome to CoWork!\n\n✅ Workspace: *{workspaceName}*\n\nTell me what you want to do.\n\nExamples:\n• "Add dark mode support"\n• "Fix the login bug"\n• "Create a new API endpoint"',
20
+ welcomeSelectWorkspace: '👋 Welcome to CoWork!\n\nSelect a workspace to start:\n\n{workspaceList}\nReply with a number (e.g., `1`)',
21
+ workspaceSelected: '✅ *{workspaceName}* selected!',
22
+ workspaceSelectedExample: 'You can now send tasks.\n\nExample: "Create a new React component called Button"',
23
+ unauthorized: '⚠️ You are not authorized to use this bot. Please contact the administrator.',
24
+ pairingRequired: '🔐 Please enter your pairing code to get started.',
25
+ pairingPrompt: '🔐 Please provide a pairing code.\n\nUsage: `/pair <code>`',
26
+ pairingSuccess: '✅ Pairing successful! You can now use the bot.',
27
+ pairingFailed: '❌ {error}',
28
+ unknownCommand: 'Unknown command: {command}\n\nUse /help to see available commands.',
29
+ statusHeader: 'Online and ready.',
30
+ statusNoWorkspace: '⚠️ No workspace selected. Use /workspaces to see available workspaces.',
31
+ statusActiveTask: '🔄 Active task: {taskTitle} ({status})',
32
+ workspacesNone: '📁 No workspaces configured yet.\n\nAdd a workspace in the CoWork desktop app first, or use:\n`/addworkspace /path/to/your/project`',
33
+ workspacesHeader: '📁 *Available Workspaces*',
34
+ workspacesFooter: 'Reply with the number or name to select.\nExample: `1` or `myproject`',
35
+ workspacesSelectPrompt: 'Tap a workspace to select it:',
36
+ workspaceCurrent: '📁 Current workspace: *{workspaceName}*\n`{workspacePath}`\n\nUse `/workspaces` to see available workspaces.',
37
+ workspaceNoneSelected: 'No workspace selected. Use `/workspaces` to see available workspaces.',
38
+ workspaceNotFound: '❌ Workspace not found: "{selector}"\n\nUse /workspaces to see available workspaces.',
39
+ workspaceNotFoundShort: '❌ Workspace not found.',
40
+ workspaceSet: '✅ Workspace set to: *{workspaceName}*\n`{workspacePath}`\n\nYou can now send messages to create tasks in this workspace.',
41
+ workspaceAddUsage: '📁 *Add Workspace*\n\nUsage: `/addworkspace <path>`\n\nExample:\n`/addworkspace /Users/john/projects/myapp`\n`/addworkspace ~/Documents`',
42
+ workspacePathNotDir: '❌ Path is not a directory: `{workspacePath}`',
43
+ workspacePathNotFound: '❌ Directory not found: `{workspacePath}`',
44
+ workspaceAlreadyExists: '📁 Workspace already exists!\n\n✅ Selected: *{workspaceName}*\n`{workspacePath}`',
45
+ workspaceAdded: '✅ Workspace added and selected!\n\n📁 *{workspaceName}*\n`{workspacePath}`\n\nYou can now send messages to create tasks in this workspace.',
46
+ workspaceRemoveUsage: '❌ Please specify a workspace name to remove.\n\nUsage: `/removeworkspace <name>`',
47
+ workspaceRemoved: '✅ Workspace "{workspaceName}" removed successfully.',
48
+ taskStartAck: '🚀 Task started: "{taskTitle}"\n\nI\'ll update you when it\'s ready or if I need your input.',
49
+ taskStartAckSimple: 'I\'m on it — I\'ll check back soon.',
50
+ taskStartFailed: '❌ Failed to start task: {error}',
51
+ taskContinueFailed: '❌ Failed to send message. Use /newtask to start a new task.',
52
+ agentUnavailable: '❌ Agent not available. Please try again later.',
53
+ workspaceMissingForTask: '❌ Workspace not found. Please select a workspace with /workspace.',
54
+ approvalNone: '❌ No pending approval request.',
55
+ approvalApproved: '✅ Approved. Working on it.',
56
+ approvalDenied: '🛑 Denied. Action cancelled.',
57
+ approvalFailed: '❌ Failed to process approval.',
58
+ approvalButtonApprove: '✅ Approve',
59
+ approvalButtonDeny: '❌ Deny',
60
+ approvalRequiredTitle: 'Approval Required',
61
+ queueCleared: '✅ Queue cleared.\n\n• Running tasks cancelled: {running}\n• Queued tasks removed: {queued}\n\nBrowser sessions and other resources have been cleaned up.',
62
+ queueStatus: '{statusText}',
63
+ cancelled: '🛑 Task cancelled.',
64
+ cancelNoActive: 'No active task to cancel.',
65
+ newTaskReady: '🆕 Ready for a new task.\n\nSend me a message describing what you want to do.',
66
+ retryNone: '❌ No failed task found to retry.\n\nStart a new task by sending a message.',
67
+ retrying: '🔄 Retrying task...\n\nOriginal prompt: "{taskTitle}"',
68
+ historyNone: '📋 No task history found.\n\nStart a new task by sending a message.',
69
+ historyHeader: '📋 *Recent Tasks*\n\n{history}',
70
+ skillsNone: '📚 No skills available.\n\nSkills are stored in:\n`~/Library/Application Support/cowork-os/skills/`',
71
+ skillsLoadFailed: '❌ Failed to load skills.',
72
+ skillSpecify: '❌ Please specify a skill ID.\n\nUsage: `/skill <id>`\n\nUse /skills to see available skills.',
73
+ skillNotFound: '❌ Skill "{skillId}" not found.\n\nUse /skills to see available skills.',
74
+ skillToggle: '{emoji} *{skillName}* is now {statusText}',
75
+ debugStatus: '🐛 Debug mode is now {statusText}',
76
+ shellInvalidOption: '❌ Invalid option. Use `/shell on` or `/shell off`',
77
+ workspaceNotFoundForShell: '❌ Workspace not found.',
78
+ responseFailed: '❌ Failed to process response.',
79
+ helpCompact: `📚 *Commands*
80
+
81
+ *Basics*
82
+ /workspaces - Select workspace
83
+ /status - Current status
84
+ /newtask - Fresh start
85
+
86
+ *Tasks*
87
+ /cancel - Stop task
88
+ /approve or /yes - Approve action
89
+ /deny or /no - Reject action
90
+
91
+ *Settings*
92
+ /shell on|off - Shell access
93
+ /models - Change AI model
94
+
95
+ ━━━━━━━━━━━━━━━
96
+ 💡 Just send your task directly!
97
+ Example: "Add a login form"`,
98
+ helpFull: `📚 *Available Commands*
99
+
100
+ *Core*
101
+ /start - Start the bot
102
+ /help - Show this help message
103
+ /status - Check bot status and workspace
104
+ /version - Show version information
105
+
106
+ *Workspaces*
107
+ /workspaces - List available workspaces
108
+ /workspace <name> - Select a workspace
109
+ /addworkspace <path> - Add a new workspace
110
+ /removeworkspace <name> - Remove a workspace
111
+
112
+ *Tasks*
113
+ /newtask - Start a fresh task/conversation
114
+ /cancel - Cancel current task
115
+ /retry - Retry the last failed task
116
+ /history - Show recent task history
117
+ /approve - Approve pending action (or /yes, /y)
118
+ /deny - Reject pending action (or /no, /n)
119
+ /queue - View/clear task queue
120
+
121
+ *Models*
122
+ /providers - List available AI providers
123
+ /provider <name> - Show or change provider
124
+ /models - List available AI models
125
+ /model <name> - Show or change model
126
+
127
+ *Skills*
128
+ /skills - List available skills
129
+ /skill <name> - Toggle a skill on/off
130
+
131
+ *Settings*
132
+ /settings - View current settings
133
+ /shell - Enable/disable shell commands
134
+ /debug - Toggle debug mode
135
+
136
+ 💬 *Quick Start*
137
+ 1. \`/workspaces\` → \`/workspace <name>\`
138
+ 2. \`/shell on\` (if needed)
139
+ 3. Send your task message
140
+ 4. \`/newtask\` to start fresh`,
141
+ };
142
+ const PERSONA_CHANNEL_UI_OVERRIDES = {
143
+ companion: {
144
+ welcomeStandard: '👋 I\'m here. Send me a task whenever you\'re ready.',
145
+ welcomeBack: '👋 Welcome back.\n\nWorkspace: *{workspaceName}*\n\nTell me what you want to do.\n\nType /help for commands.',
146
+ welcomeNoWorkspace: '👋 I\'m here.\n\nAdd a workspace to begin:\n`/addworkspace /path/to/project`\n\nOr add one from the desktop app.',
147
+ welcomeSingleWorkspace: '👋 We\'re set.\n\n✅ Workspace: *{workspaceName}*\n\nTell me what you want to do.\n\nExamples:\n• "Add dark mode support"\n• "Fix the login bug"\n• "Create a new API endpoint"',
148
+ welcomeSelectWorkspace: '👋 Let\'s pick a workspace:\n\n{workspaceList}\nReply with a number (e.g., `1`)',
149
+ workspaceSelected: '✅ *{workspaceName}* selected.',
150
+ workspaceSelectedExample: 'You can send tasks now.\n\nExample: "Create a new React component called Button"',
151
+ pairingPrompt: '🔐 Share your pairing code so I can connect.\n\nUsage: `/pair <code>`',
152
+ pairingSuccess: '✅ Paired. I\'m ready.',
153
+ pairingFailed: '❌ {error}',
154
+ unknownCommand: 'I didn\'t recognize that command: {command}\n\nUse /help to see options.',
155
+ statusHeader: 'Here and ready.',
156
+ statusNoWorkspace: '⚠️ No workspace selected. Use /workspaces to choose one.',
157
+ workspacesNone: '📁 No workspaces yet.\n\nAdd one in the desktop app, or use:\n`/addworkspace /path/to/your/project`',
158
+ workspacesHeader: '📁 *Workspaces*',
159
+ workspacesFooter: 'Reply with a number or name.\nExample: `1` or `myproject`',
160
+ workspaceCurrent: '📁 Current workspace: *{workspaceName}*\n`{workspacePath}`\n\nUse `/workspaces` to switch.',
161
+ workspaceNoneSelected: 'No workspace selected yet. Use `/workspaces` to pick one.',
162
+ workspaceNotFound: '❌ I couldn\'t find "{selector}".\n\nUse /workspaces to see available workspaces.',
163
+ workspaceNotFoundShort: 'I couldn\'t find that workspace.',
164
+ workspaceSet: '✅ Workspace set: *{workspaceName}*\n`{workspacePath}`\n\nSend a message to start a task.',
165
+ workspaceAddUsage: '📁 *Add Workspace*\n\nUsage: `/addworkspace <path>`\n\nExample:\n`/addworkspace /Users/john/projects/myapp`\n`/addworkspace ~/Documents`',
166
+ workspaceAlreadyExists: '📁 Workspace already exists.\n\n✅ Selected: *{workspaceName}*\n`{workspacePath}`',
167
+ workspaceAdded: '✅ Workspace added and selected.\n\n📁 *{workspaceName}*\n`{workspacePath}`\n\nSend a message to start a task.',
168
+ workspaceRemoveUsage: 'Please specify a workspace name to remove.\n\nUsage: `/removeworkspace <name>`',
169
+ workspaceRemoved: 'Workspace "{workspaceName}" removed.',
170
+ taskStartAck: 'I\'m on it — "{taskTitle}".\n\nI\'ll check back soon or ask if I need input.',
171
+ taskStartAckSimple: 'I\'m on it. I\'ll check back soon.',
172
+ taskContinueFailed: 'I couldn\'t send that. Use /newtask to start fresh.',
173
+ agentUnavailable: 'I\'m not available right now. Try again in a moment.',
174
+ workspaceMissingForTask: 'I can\'t find a workspace. Use /workspace to select one.',
175
+ approvalNone: 'No pending approval right now.',
176
+ approvalApproved: 'Approved. I\'m working on it.',
177
+ approvalDenied: 'Okay. I cancelled that.',
178
+ approvalFailed: 'I couldn\'t process that approval.',
179
+ approvalButtonApprove: 'Approve',
180
+ approvalButtonDeny: 'Deny',
181
+ approvalRequiredTitle: 'Approval required',
182
+ queueCleared: 'Queue cleared.\n\n• Running tasks cancelled: {running}\n• Queued tasks removed: {queued}\n\nYou can start new tasks now.',
183
+ cancelled: 'Task cancelled.',
184
+ cancelNoActive: 'No active task to cancel.',
185
+ newTaskReady: 'Ready for a fresh task.\n\nSend me what you want to do.',
186
+ retryNone: 'No failed task to retry.\n\nSend a new task when you\'re ready.',
187
+ retrying: 'Retrying...\n\nOriginal prompt: "{taskTitle}"',
188
+ historyNone: 'No recent task history yet.',
189
+ historyHeader: 'Recent tasks:\n\n{history}',
190
+ skillsNone: 'No skills available yet.',
191
+ skillsLoadFailed: 'Couldn\'t load skills.',
192
+ skillSpecify: 'Please specify a skill ID.\n\nUsage: `/skill <id>`\n\nUse /skills to see available skills.',
193
+ skillNotFound: 'Skill "{skillId}" not found.\n\nUse /skills to see available skills.',
194
+ skillToggle: '{emoji} *{skillName}* is now {statusText}',
195
+ debugStatus: 'Debug mode is now {statusText}',
196
+ shellInvalidOption: 'Invalid option. Use `/shell on` or `/shell off`',
197
+ workspaceNotFoundForShell: 'I couldn\'t find that workspace.',
198
+ responseFailed: 'I couldn\'t process that response.',
199
+ helpCompact: `📚 *Commands*
200
+
201
+ *Basics*
202
+ /workspaces - Select workspace
203
+ /status - Current status
204
+ /newtask - Fresh start
205
+
206
+ *Tasks*
207
+ /cancel - Stop task
208
+ /approve or /yes - Approve action
209
+ /deny or /no - Reject action
210
+
211
+ *Settings*
212
+ /shell on|off - Shell access
213
+ /models - Change AI model
214
+
215
+ ━━━━━━━━━━━━━━━
216
+ 💡 Just send your task directly.
217
+ Example: "Add a login form"`,
218
+ helpFull: `📚 *Commands*
219
+
220
+ *Core*
221
+ /start - Start
222
+ /help - Help
223
+ /status - Status
224
+ /version - Version
225
+
226
+ *Workspaces*
227
+ /workspaces - List workspaces
228
+ /workspace <name> - Select workspace
229
+ /addworkspace <path> - Add workspace
230
+ /removeworkspace <name> - Remove workspace
231
+
232
+ *Tasks*
233
+ /newtask - New task
234
+ /cancel - Cancel current task
235
+ /retry - Retry last failed task
236
+ /history - Recent tasks
237
+ /approve - Approve (or /yes, /y)
238
+ /deny - Deny (or /no, /n)
239
+ /queue - View/clear queue
240
+
241
+ *Models*
242
+ /providers - List providers
243
+ /provider <name> - Change provider
244
+ /models - List models
245
+ /model <name> - Change model
246
+
247
+ *Skills*
248
+ /skills - List skills
249
+ /skill <name> - Toggle skill
250
+
251
+ *Settings*
252
+ /settings - Current settings
253
+ /shell - Toggle shell access
254
+ /debug - Toggle debug mode
255
+
256
+ 💬 *Quick Start*
257
+ 1. \`/workspaces\` → \`/workspace <name>\`
258
+ 2. \`/shell on\` if needed
259
+ 3. Send your task
260
+ 4. \`/newtask\` to reset`,
261
+ },
262
+ };
14
263
  /**
15
264
  * Message templates organized by personality type
16
265
  */
@@ -79,6 +328,17 @@ const CHANNEL_MESSAGES = {
79
328
  approvalNeeded: 'Approval needed.',
80
329
  },
81
330
  };
331
+ const PERSONA_CHANNEL_MESSAGE_OVERRIDES = {
332
+ companion: {
333
+ taskComplete: 'All set.',
334
+ taskCompleteWithResult: 'All set.\n\n{result}',
335
+ taskFailed: 'I hit a snag: {error}',
336
+ toolError: 'I ran into an issue with {tool}: {error}',
337
+ followUpProcessed: 'Got it. I\'m on it.',
338
+ followUpFailed: 'I couldn\'t complete that: {error}',
339
+ approvalNeeded: 'I need your OK on this.',
340
+ },
341
+ };
82
342
  /**
83
343
  * Emoji mappings for message types
84
344
  */
@@ -110,10 +370,13 @@ function addEmoji(message, key, emojiUsage) {
110
370
  * Get a personalized channel message
111
371
  */
112
372
  function getChannelMessage(key, ctx, replacements) {
113
- const { personality, emojiUsage, quirks } = ctx;
373
+ const { personality, emojiUsage, quirks, persona } = ctx;
114
374
  // Get base message for personality
115
375
  const messages = CHANNEL_MESSAGES[personality] || CHANNEL_MESSAGES.professional;
116
- let message = messages[key] || CHANNEL_MESSAGES.professional[key] || key;
376
+ const personaOverride = persona
377
+ ? PERSONA_CHANNEL_MESSAGE_OVERRIDES[persona]?.[key]
378
+ : undefined;
379
+ let message = personaOverride || messages[key] || CHANNEL_MESSAGES.professional[key] || key;
117
380
  // Replace placeholders
118
381
  if (replacements) {
119
382
  for (const [placeholder, value] of Object.entries(replacements)) {
@@ -128,6 +391,22 @@ function getChannelMessage(key, ctx, replacements) {
128
391
  }
129
392
  return message;
130
393
  }
394
+ /**
395
+ * Get channel UI copy with optional persona overrides
396
+ */
397
+ function getChannelUiCopy(key, ctx, replacements) {
398
+ const base = CHANNEL_UI_COPY[key] || key;
399
+ const override = ctx.persona
400
+ ? PERSONA_CHANNEL_UI_OVERRIDES[ctx.persona]?.[key]
401
+ : undefined;
402
+ let message = override || base;
403
+ if (replacements) {
404
+ for (const [placeholder, value] of Object.entries(replacements)) {
405
+ message = message.replace(new RegExp(`\\{${placeholder}\\}`, 'g'), String(value));
406
+ }
407
+ }
408
+ return message;
409
+ }
131
410
  /**
132
411
  * Get completion message with optional result and follow-up hint
133
412
  * This is specific to channel messages which may include additional hints
@@ -137,6 +416,7 @@ function getCompletionMessage(ctx, result, includeFollowUpHint = true) {
137
416
  let message = getChannelMessage(key, ctx, result ? { result } : undefined);
138
417
  // Add follow-up hint for channels that support it
139
418
  if (includeFollowUpHint && ctx.personality !== 'concise') {
419
+ const companionHint = 'Send another message to continue, or use /newtask for a clean start.';
140
420
  const hints = {
141
421
  professional: 'Send a follow-up message to continue, or use /newtask to start fresh.',
142
422
  friendly: 'Got more to do? Just send another message!',
@@ -146,7 +426,7 @@ function getCompletionMessage(ctx, result, includeFollowUpHint = true) {
146
426
  casual: 'What\'s next? Just hit me up.',
147
427
  custom: 'Send a follow-up message to continue.',
148
428
  };
149
- const hint = hints[ctx.personality];
429
+ const hint = ctx.persona === 'companion' ? companionHint : hints[ctx.personality];
150
430
  if (hint) {
151
431
  message = `${message}\n\n${hint}`;
152
432
  }
@@ -160,6 +440,7 @@ exports.DEFAULT_CHANNEL_CONTEXT = {
160
440
  agentName: 'CoWork',
161
441
  userName: undefined,
162
442
  personality: 'professional',
443
+ persona: undefined,
163
444
  emojiUsage: 'minimal',
164
445
  quirks: {
165
446
  catchphrase: undefined,