crewly 1.1.2 → 1.2.0

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 (216) hide show
  1. package/README.md +6 -6
  2. package/config/roles/ops/prompt.md +140 -0
  3. package/config/roles/ops/role.json +13 -0
  4. package/config/skills/agent/browse-stealth/execute.sh +84 -0
  5. package/config/skills/agent/browse-stealth/instructions.md +108 -0
  6. package/config/skills/agent/browse-stealth/launch-chrome-cdp.sh +141 -0
  7. package/config/skills/agent/browse-stealth/skill.json +20 -0
  8. package/config/skills/agent/browse-stealth/stealth-browse.py +330 -0
  9. package/config/skills/agent/competitor-content-tracker/execute.sh +232 -0
  10. package/config/skills/agent/competitor-content-tracker/instructions.md +210 -0
  11. package/config/skills/agent/competitor-content-tracker/skill.json +22 -0
  12. package/config/skills/agent/content-calendar/execute.sh +294 -0
  13. package/config/skills/agent/content-calendar/instructions.md +122 -0
  14. package/config/skills/agent/content-calendar/skill.json +22 -0
  15. package/config/skills/agent/content-repurposer/execute.sh +194 -0
  16. package/config/skills/agent/content-repurposer/instructions.md +69 -0
  17. package/config/skills/agent/content-repurposer/skill.json +22 -0
  18. package/config/skills/agent/content-writer/execute.sh +311 -0
  19. package/config/skills/agent/content-writer/instructions.md +124 -0
  20. package/config/skills/agent/content-writer/skill.json +22 -0
  21. package/config/skills/agent/core/generate-pdf/execute.sh +88 -0
  22. package/config/skills/agent/core/generate-pdf/instructions.md +46 -0
  23. package/config/skills/agent/core/generate-pdf/skill.json +20 -0
  24. package/config/skills/agent/core/report-status/execute.sh +6 -0
  25. package/config/skills/agent/trend-monitor/execute.sh +211 -0
  26. package/config/skills/agent/trend-monitor/instructions.md +207 -0
  27. package/config/skills/agent/trend-monitor/skill.json +22 -0
  28. package/config/skills/agent/vnc-browser/execute.sh +261 -0
  29. package/config/skills/agent/vnc-browser/instructions.md +102 -0
  30. package/config/skills/agent/vnc-browser/skill.json +20 -0
  31. package/config/skills/orchestrator/delegate-task/execute.sh +63 -4
  32. package/config/skills/orchestrator/delegate-task/instructions.md +60 -0
  33. package/config/skills/orchestrator/delegate-task/skill.json +4 -4
  34. package/config/skills/orchestrator/reply-slack/execute.sh +2 -0
  35. package/config/skills/orchestrator/send-key/execute.sh +19 -6
  36. package/config/skills/orchestrator/send-key/instructions.md +44 -0
  37. package/config/skills/orchestrator/send-key/skill.json +20 -0
  38. package/config/skills/orchestrator/send-message/execute.sh +9 -1
  39. package/config/skills/registry.json +256 -0
  40. package/config/templates/code-review-team/README.md +176 -0
  41. package/config/templates/code-review-team/team-config.json +16 -0
  42. package/config/templates/code-review-team.json +62 -0
  43. package/config/templates/content-generation-team/README.md +128 -0
  44. package/config/templates/content-generation-team/team-config.json +21 -0
  45. package/config/templates/content-generation-team.json +67 -0
  46. package/config/templates/demo-team.json +22 -0
  47. package/config/templates/social-media-ops-team/README.md +145 -0
  48. package/config/templates/social-media-ops-team/team-config.json +21 -0
  49. package/config/templates/social-media-ops-team.json +67 -0
  50. package/dist/backend/backend/src/constants.d.ts +69 -6
  51. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  52. package/dist/backend/backend/src/constants.js +75 -6
  53. package/dist/backend/backend/src/constants.js.map +1 -1
  54. package/dist/backend/backend/src/controllers/index.d.ts.map +1 -1
  55. package/dist/backend/backend/src/controllers/index.js +2 -0
  56. package/dist/backend/backend/src/controllers/index.js.map +1 -1
  57. package/dist/backend/backend/src/controllers/messaging/messenger.routes.d.ts +8 -0
  58. package/dist/backend/backend/src/controllers/messaging/messenger.routes.d.ts.map +1 -1
  59. package/dist/backend/backend/src/controllers/messaging/messenger.routes.js +110 -63
  60. package/dist/backend/backend/src/controllers/messaging/messenger.routes.js.map +1 -1
  61. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
  62. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +31 -4
  63. package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
  64. package/dist/backend/backend/src/controllers/oauth/oauth.routes.d.ts +8 -0
  65. package/dist/backend/backend/src/controllers/oauth/oauth.routes.d.ts.map +1 -1
  66. package/dist/backend/backend/src/controllers/oauth/oauth.routes.js +127 -111
  67. package/dist/backend/backend/src/controllers/oauth/oauth.routes.js.map +1 -1
  68. package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts +34 -0
  69. package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts.map +1 -1
  70. package/dist/backend/backend/src/controllers/task-management/task-management.controller.js +219 -2
  71. package/dist/backend/backend/src/controllers/task-management/task-management.controller.js.map +1 -1
  72. package/dist/backend/backend/src/controllers/user/user.routes.d.ts +7 -0
  73. package/dist/backend/backend/src/controllers/user/user.routes.d.ts.map +1 -1
  74. package/dist/backend/backend/src/controllers/user/user.routes.js +45 -38
  75. package/dist/backend/backend/src/controllers/user/user.routes.js.map +1 -1
  76. package/dist/backend/backend/src/controllers/whatsapp/index.d.ts +17 -0
  77. package/dist/backend/backend/src/controllers/whatsapp/index.d.ts.map +1 -0
  78. package/dist/backend/backend/src/controllers/whatsapp/index.js +18 -0
  79. package/dist/backend/backend/src/controllers/whatsapp/index.js.map +1 -0
  80. package/dist/backend/backend/src/controllers/whatsapp/whatsapp.controller.d.ts +12 -0
  81. package/dist/backend/backend/src/controllers/whatsapp/whatsapp.controller.d.ts.map +1 -0
  82. package/dist/backend/backend/src/controllers/whatsapp/whatsapp.controller.js +185 -0
  83. package/dist/backend/backend/src/controllers/whatsapp/whatsapp.controller.js.map +1 -0
  84. package/dist/backend/backend/src/index.d.ts +5 -0
  85. package/dist/backend/backend/src/index.d.ts.map +1 -1
  86. package/dist/backend/backend/src/index.js +35 -0
  87. package/dist/backend/backend/src/index.js.map +1 -1
  88. package/dist/backend/backend/src/routes/modules/task-management.routes.d.ts.map +1 -1
  89. package/dist/backend/backend/src/routes/modules/task-management.routes.js +4 -0
  90. package/dist/backend/backend/src/routes/modules/task-management.routes.js.map +1 -1
  91. package/dist/backend/backend/src/services/agent/agent-heartbeat.service.js +1 -1
  92. package/dist/backend/backend/src/services/agent/agent-heartbeat.service.js.map +1 -1
  93. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +14 -3
  94. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  95. package/dist/backend/backend/src/services/agent/agent-registration.service.js +160 -29
  96. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  97. package/dist/backend/backend/src/services/agent/claude-runtime.service.d.ts +4 -3
  98. package/dist/backend/backend/src/services/agent/claude-runtime.service.d.ts.map +1 -1
  99. package/dist/backend/backend/src/services/agent/claude-runtime.service.js +29 -4
  100. package/dist/backend/backend/src/services/agent/claude-runtime.service.js.map +1 -1
  101. package/dist/backend/backend/src/services/agent/context-window-monitor.service.d.ts.map +1 -1
  102. package/dist/backend/backend/src/services/agent/context-window-monitor.service.js +11 -0
  103. package/dist/backend/backend/src/services/agent/context-window-monitor.service.js.map +1 -1
  104. package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.d.ts +32 -2
  105. package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.d.ts.map +1 -1
  106. package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js +69 -8
  107. package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js.map +1 -1
  108. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -1
  109. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js +14 -2
  110. package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js.map +1 -1
  111. package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.d.ts.map +1 -1
  112. package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.js +11 -2
  113. package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.js.map +1 -1
  114. package/dist/backend/backend/src/services/messaging/adapters/discord-messenger.adapter.d.ts +18 -0
  115. package/dist/backend/backend/src/services/messaging/adapters/discord-messenger.adapter.d.ts.map +1 -1
  116. package/dist/backend/backend/src/services/messaging/adapters/discord-messenger.adapter.js +28 -4
  117. package/dist/backend/backend/src/services/messaging/adapters/discord-messenger.adapter.js.map +1 -1
  118. package/dist/backend/backend/src/services/messaging/adapters/slack-messenger.adapter.js +2 -2
  119. package/dist/backend/backend/src/services/messaging/adapters/slack-messenger.adapter.js.map +1 -1
  120. package/dist/backend/backend/src/services/messaging/adapters/telegram-messenger.adapter.d.ts +18 -0
  121. package/dist/backend/backend/src/services/messaging/adapters/telegram-messenger.adapter.d.ts.map +1 -1
  122. package/dist/backend/backend/src/services/messaging/adapters/telegram-messenger.adapter.js +26 -4
  123. package/dist/backend/backend/src/services/messaging/adapters/telegram-messenger.adapter.js.map +1 -1
  124. package/dist/backend/backend/src/services/messaging/messenger-adapter.interface.d.ts +28 -2
  125. package/dist/backend/backend/src/services/messaging/messenger-adapter.interface.d.ts.map +1 -1
  126. package/dist/backend/backend/src/services/messaging/messenger-registry.service.d.ts +33 -2
  127. package/dist/backend/backend/src/services/messaging/messenger-registry.service.d.ts.map +1 -1
  128. package/dist/backend/backend/src/services/messaging/messenger-registry.service.js +33 -0
  129. package/dist/backend/backend/src/services/messaging/messenger-registry.service.js.map +1 -1
  130. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.d.ts.map +1 -1
  131. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js +4 -2
  132. package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js.map +1 -1
  133. package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.d.ts.map +1 -1
  134. package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.js +4 -3
  135. package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.js.map +1 -1
  136. package/dist/backend/backend/src/services/project/task-tracking.service.d.ts +27 -0
  137. package/dist/backend/backend/src/services/project/task-tracking.service.d.ts.map +1 -1
  138. package/dist/backend/backend/src/services/project/task-tracking.service.js +54 -0
  139. package/dist/backend/backend/src/services/project/task-tracking.service.js.map +1 -1
  140. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +36 -6
  141. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
  142. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +238 -36
  143. package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
  144. package/dist/backend/backend/src/services/slack/slack.service.d.ts.map +1 -1
  145. package/dist/backend/backend/src/services/slack/slack.service.js +6 -4
  146. package/dist/backend/backend/src/services/slack/slack.service.js.map +1 -1
  147. package/dist/backend/backend/src/services/user/user-identity.service.d.ts +44 -0
  148. package/dist/backend/backend/src/services/user/user-identity.service.d.ts.map +1 -1
  149. package/dist/backend/backend/src/services/user/user-identity.service.js +75 -8
  150. package/dist/backend/backend/src/services/user/user-identity.service.js.map +1 -1
  151. package/dist/backend/backend/src/services/whatsapp/index.d.ts +11 -0
  152. package/dist/backend/backend/src/services/whatsapp/index.d.ts.map +1 -0
  153. package/dist/backend/backend/src/services/whatsapp/index.js +11 -0
  154. package/dist/backend/backend/src/services/whatsapp/index.js.map +1 -0
  155. package/dist/backend/backend/src/services/whatsapp/whatsapp-initializer.d.ts +66 -0
  156. package/dist/backend/backend/src/services/whatsapp/whatsapp-initializer.d.ts.map +1 -0
  157. package/dist/backend/backend/src/services/whatsapp/whatsapp-initializer.js +96 -0
  158. package/dist/backend/backend/src/services/whatsapp/whatsapp-initializer.js.map +1 -0
  159. package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.d.ts +109 -0
  160. package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.d.ts.map +1 -0
  161. package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.js +234 -0
  162. package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.js.map +1 -0
  163. package/dist/backend/backend/src/services/whatsapp/whatsapp.service.d.ts +127 -0
  164. package/dist/backend/backend/src/services/whatsapp/whatsapp.service.d.ts.map +1 -0
  165. package/dist/backend/backend/src/services/whatsapp/whatsapp.service.js +347 -0
  166. package/dist/backend/backend/src/services/whatsapp/whatsapp.service.js.map +1 -0
  167. package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts.map +1 -1
  168. package/dist/backend/backend/src/services/workflow/scheduler.service.js +4 -0
  169. package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
  170. package/dist/backend/backend/src/types/index.d.ts +1 -0
  171. package/dist/backend/backend/src/types/index.d.ts.map +1 -1
  172. package/dist/backend/backend/src/types/index.js.map +1 -1
  173. package/dist/backend/backend/src/types/slack.types.d.ts +24 -0
  174. package/dist/backend/backend/src/types/slack.types.d.ts.map +1 -1
  175. package/dist/backend/backend/src/types/slack.types.js.map +1 -1
  176. package/dist/backend/backend/src/types/task-tracking.types.d.ts +4 -0
  177. package/dist/backend/backend/src/types/task-tracking.types.d.ts.map +1 -1
  178. package/dist/backend/backend/src/types/task-tracking.types.js.map +1 -1
  179. package/dist/backend/backend/src/types/whatsapp.types.d.ts +84 -0
  180. package/dist/backend/backend/src/types/whatsapp.types.d.ts.map +1 -0
  181. package/dist/backend/backend/src/types/whatsapp.types.js +33 -0
  182. package/dist/backend/backend/src/types/whatsapp.types.js.map +1 -0
  183. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts +11 -0
  184. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts.map +1 -1
  185. package/dist/backend/backend/src/websocket/terminal.gateway.js +35 -1
  186. package/dist/backend/backend/src/websocket/terminal.gateway.js.map +1 -1
  187. package/dist/cli/backend/src/constants.d.ts +69 -6
  188. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  189. package/dist/cli/backend/src/constants.js +75 -6
  190. package/dist/cli/backend/src/constants.js.map +1 -1
  191. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -1
  192. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js +14 -2
  193. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js.map +1 -1
  194. package/dist/cli/backend/src/types/index.d.ts +1 -0
  195. package/dist/cli/backend/src/types/index.d.ts.map +1 -1
  196. package/dist/cli/backend/src/types/index.js.map +1 -1
  197. package/dist/cli/cli/src/commands/publish.d.ts.map +1 -1
  198. package/dist/cli/cli/src/commands/publish.js +17 -15
  199. package/dist/cli/cli/src/commands/publish.js.map +1 -1
  200. package/dist/cli/cli/src/index.js +2 -2
  201. package/dist/cli/cli/src/index.js.map +1 -1
  202. package/dist/cli/cli/src/utils/gh-submit.d.ts +46 -0
  203. package/dist/cli/cli/src/utils/gh-submit.d.ts.map +1 -0
  204. package/dist/cli/cli/src/utils/gh-submit.js +167 -0
  205. package/dist/cli/cli/src/utils/gh-submit.js.map +1 -0
  206. package/dist/cli/cli/src/utils/marketplace.d.ts.map +1 -1
  207. package/dist/cli/cli/src/utils/marketplace.js +13 -5
  208. package/dist/cli/cli/src/utils/marketplace.js.map +1 -1
  209. package/dist/cli/cli/src/utils/templates.d.ts +3 -2
  210. package/dist/cli/cli/src/utils/templates.d.ts.map +1 -1
  211. package/dist/cli/cli/src/utils/templates.js +5 -4
  212. package/dist/cli/cli/src/utils/templates.js.map +1 -1
  213. package/frontend/dist/assets/{index-45eeea99.js → index-a23214ae.js} +241 -241
  214. package/frontend/dist/assets/{index-6972eeee.css → index-c407fe13.css} +1 -1
  215. package/frontend/dist/index.html +2 -2
  216. package/package.json +3 -1
@@ -0,0 +1,96 @@
1
+ /**
2
+ * WhatsApp Initializer
3
+ *
4
+ * Handles automatic WhatsApp connection on application startup.
5
+ * Checks for environment variables and initializes if configured.
6
+ *
7
+ * @module services/whatsapp/initializer
8
+ */
9
+ import { getWhatsAppService } from './whatsapp.service.js';
10
+ import { getWhatsAppOrchestratorBridge } from './whatsapp-orchestrator-bridge.js';
11
+ import { LoggerService } from '../core/logger.service.js';
12
+ const logger = LoggerService.getInstance().createComponentLogger('WhatsAppInitializer');
13
+ /**
14
+ * Check if WhatsApp is configured via environment variables.
15
+ *
16
+ * @returns True if WHATSAPP_ENABLED is set to 'true'
17
+ */
18
+ export function isWhatsAppConfigured() {
19
+ return process.env.WHATSAPP_ENABLED === 'true';
20
+ }
21
+ /**
22
+ * Get WhatsApp configuration from environment variables.
23
+ *
24
+ * @returns WhatsAppConfig object or null if not configured
25
+ */
26
+ export function getWhatsAppConfigFromEnv() {
27
+ if (!isWhatsAppConfigured()) {
28
+ return null;
29
+ }
30
+ return {
31
+ phoneNumber: process.env.WHATSAPP_PHONE_NUMBER,
32
+ authStatePath: process.env.WHATSAPP_AUTH_PATH,
33
+ allowedContacts: process.env.WHATSAPP_ALLOWED_CONTACTS?.split(',').filter(Boolean),
34
+ };
35
+ }
36
+ /**
37
+ * Initialize WhatsApp integration if configured via environment variables.
38
+ *
39
+ * This function is designed to be called during application startup.
40
+ * It safely handles cases where WhatsApp is not configured.
41
+ *
42
+ * @param options - Optional initialization options
43
+ * @returns Result object indicating success or failure
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * const result = await initializeWhatsAppIfConfigured({
48
+ * messageQueueService: myService,
49
+ * });
50
+ * if (result.success) {
51
+ * console.log('WhatsApp connected!');
52
+ * }
53
+ * ```
54
+ */
55
+ export async function initializeWhatsAppIfConfigured(options) {
56
+ const config = getWhatsAppConfigFromEnv();
57
+ if (!config) {
58
+ logger.info('Not configured — skipping initialization');
59
+ return { attempted: false, success: false };
60
+ }
61
+ try {
62
+ const whatsappService = getWhatsAppService();
63
+ await whatsappService.initialize(config);
64
+ const bridge = getWhatsAppOrchestratorBridge();
65
+ if (options?.messageQueueService) {
66
+ bridge.setMessageQueueService(options.messageQueueService);
67
+ }
68
+ await bridge.initialize();
69
+ logger.info('Successfully initialized');
70
+ return { attempted: true, success: true };
71
+ }
72
+ catch (error) {
73
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
74
+ logger.error('Failed to initialize', { error: errorMessage });
75
+ return { attempted: true, success: false, error: errorMessage };
76
+ }
77
+ }
78
+ /**
79
+ * Gracefully shutdown WhatsApp integration.
80
+ * Call this during application shutdown to disconnect cleanly.
81
+ */
82
+ export async function shutdownWhatsApp() {
83
+ try {
84
+ const whatsappService = getWhatsAppService();
85
+ if (whatsappService.isConnected()) {
86
+ await whatsappService.disconnect();
87
+ logger.info('Disconnected');
88
+ }
89
+ }
90
+ catch (error) {
91
+ logger.error('Error during shutdown', {
92
+ error: error instanceof Error ? error.message : String(error),
93
+ });
94
+ }
95
+ }
96
+ //# sourceMappingURL=whatsapp-initializer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whatsapp-initializer.js","sourceRoot":"","sources":["../../../../../../backend/src/services/whatsapp/whatsapp-initializer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * WhatsApp-Orchestrator Bridge
3
+ *
4
+ * Routes messages between WhatsApp and the Crewly orchestrator,
5
+ * enabling mobile control of AI teams via WhatsApp.
6
+ *
7
+ * @module services/whatsapp/bridge
8
+ */
9
+ import { EventEmitter } from 'events';
10
+ import type { MessageQueueService } from '../messaging/message-queue.service.js';
11
+ /**
12
+ * Bridge configuration
13
+ */
14
+ export interface WhatsAppBridgeConfig {
15
+ /** Orchestrator session name */
16
+ orchestratorSession: string;
17
+ /** Maximum response length before truncation */
18
+ maxResponseLength: number;
19
+ /** Response timeout in ms */
20
+ responseTimeoutMs: number;
21
+ }
22
+ /**
23
+ * WhatsAppOrchestratorBridge class
24
+ *
25
+ * Routes messages between WhatsApp and the Crewly orchestrator.
26
+ * Mirrors the SlackOrchestratorBridge pattern with WhatsApp-specific handling.
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * const bridge = getWhatsAppOrchestratorBridge();
31
+ * await bridge.initialize();
32
+ * ```
33
+ */
34
+ export declare class WhatsAppOrchestratorBridge extends EventEmitter {
35
+ private logger;
36
+ private whatsappService;
37
+ private chatService;
38
+ private messageQueueService;
39
+ private config;
40
+ private initialized;
41
+ private boundMessageHandler;
42
+ /**
43
+ * Create a new WhatsAppOrchestratorBridge
44
+ *
45
+ * @param config - Partial configuration to override defaults
46
+ */
47
+ constructor(config?: Partial<WhatsAppBridgeConfig>);
48
+ /**
49
+ * Initialize the bridge.
50
+ * Sets up message listeners for WhatsApp incoming messages.
51
+ */
52
+ initialize(): Promise<void>;
53
+ /**
54
+ * Check if bridge is initialized
55
+ *
56
+ * @returns True if initialized
57
+ */
58
+ isInitialized(): boolean;
59
+ /**
60
+ * Set the message queue service for enqueuing messages to the orchestrator.
61
+ *
62
+ * @param service - The MessageQueueService instance
63
+ */
64
+ setMessageQueueService(service: MessageQueueService): void;
65
+ /**
66
+ * Get current configuration
67
+ *
68
+ * @returns A copy of the current configuration
69
+ */
70
+ getConfig(): WhatsAppBridgeConfig;
71
+ /**
72
+ * Handle incoming WhatsApp message.
73
+ * Routes the message to the orchestrator and sends the response back.
74
+ *
75
+ * @param message - Incoming WhatsApp message
76
+ */
77
+ private handleWhatsAppMessage;
78
+ /**
79
+ * Send message to orchestrator via the message queue and wait for response.
80
+ *
81
+ * @param message - Message text to send
82
+ * @param context - Conversation context
83
+ * @returns Orchestrator response or offline/error message
84
+ */
85
+ private sendToOrchestrator;
86
+ /**
87
+ * Cleanup bridge resources.
88
+ * Removes only this bridge's event listener and resets initialization state.
89
+ */
90
+ cleanup(): void;
91
+ /**
92
+ * Send a text response back to a WhatsApp chat.
93
+ *
94
+ * @param chatId - Destination chat JID
95
+ * @param text - Response text
96
+ */
97
+ sendWhatsAppResponse(chatId: string, text: string): Promise<void>;
98
+ }
99
+ /**
100
+ * Get WhatsApp bridge singleton
101
+ *
102
+ * @returns WhatsAppOrchestratorBridge instance
103
+ */
104
+ export declare function getWhatsAppOrchestratorBridge(): WhatsAppOrchestratorBridge;
105
+ /**
106
+ * Reset WhatsApp bridge singleton (for testing)
107
+ */
108
+ export declare function resetWhatsAppOrchestratorBridge(): void;
109
+ //# sourceMappingURL=whatsapp-orchestrator-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whatsapp-orchestrator-bridge.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/whatsapp/whatsapp-orchestrator-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAWtC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAIjF;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,gCAAgC;IAChC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gDAAgD;IAChD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,6BAA6B;IAC7B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAcD;;;;;;;;;;;GAWG;AACH,qBAAa,0BAA2B,SAAQ,YAAY;IAC1D,OAAO,CAAC,MAAM,CAAuE;IACrF,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,mBAAmB,CAAoC;IAC/D,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,mBAAmB,CAAsE;IAEjG;;;;OAIG;gBACS,MAAM,GAAE,OAAO,CAAC,oBAAoB,CAAM;IAOtD;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAUjC;;;;OAIG;IACH,aAAa,IAAI,OAAO;IAIxB;;;;OAIG;IACH,sBAAsB,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI;IAI1D;;;;OAIG;IACH,SAAS,IAAI,oBAAoB;IAIjC;;;;;OAKG;YACW,qBAAqB;IAiCnC;;;;;;OAMG;YACW,kBAAkB;IAgEhC;;;OAGG;IACH,OAAO,IAAI,IAAI;IAQf;;;;;OAKG;IACG,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAYxE;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,IAAI,0BAA0B,CAK1E;AAED;;GAEG;AACH,wBAAgB,+BAA+B,IAAI,IAAI,CAEtD"}
@@ -0,0 +1,234 @@
1
+ /**
2
+ * WhatsApp-Orchestrator Bridge
3
+ *
4
+ * Routes messages between WhatsApp and the Crewly orchestrator,
5
+ * enabling mobile control of AI teams via WhatsApp.
6
+ *
7
+ * @module services/whatsapp/bridge
8
+ */
9
+ import { EventEmitter } from 'events';
10
+ import { getWhatsAppService } from './whatsapp.service.js';
11
+ import { getChatService } from '../chat/chat.service.js';
12
+ import { isOrchestratorActive, getOrchestratorOfflineMessage, } from '../orchestrator/index.js';
13
+ import { ORCHESTRATOR_SESSION_NAME, MESSAGE_QUEUE_CONSTANTS, WHATSAPP_CONSTANTS } from '../../constants.js';
14
+ import { LoggerService } from '../core/logger.service.js';
15
+ /**
16
+ * Default bridge configuration
17
+ */
18
+ const DEFAULT_CONFIG = {
19
+ orchestratorSession: ORCHESTRATOR_SESSION_NAME,
20
+ maxResponseLength: WHATSAPP_CONSTANTS.MAX_RESPONSE_LENGTH,
21
+ responseTimeoutMs: (MESSAGE_QUEUE_CONSTANTS?.DEFAULT_MESSAGE_TIMEOUT ?? WHATSAPP_CONSTANTS.DEFAULT_FALLBACK_TIMEOUT_MS) + WHATSAPP_CONSTANTS.RESPONSE_TIMEOUT_BUFFER_MS,
22
+ };
23
+ /** WhatsApp bridge singleton */
24
+ let bridgeInstance = null;
25
+ /**
26
+ * WhatsAppOrchestratorBridge class
27
+ *
28
+ * Routes messages between WhatsApp and the Crewly orchestrator.
29
+ * Mirrors the SlackOrchestratorBridge pattern with WhatsApp-specific handling.
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * const bridge = getWhatsAppOrchestratorBridge();
34
+ * await bridge.initialize();
35
+ * ```
36
+ */
37
+ export class WhatsAppOrchestratorBridge extends EventEmitter {
38
+ logger = LoggerService.getInstance().createComponentLogger('WhatsAppBridge');
39
+ whatsappService;
40
+ chatService;
41
+ messageQueueService = null;
42
+ config;
43
+ initialized = false;
44
+ boundMessageHandler = null;
45
+ /**
46
+ * Create a new WhatsAppOrchestratorBridge
47
+ *
48
+ * @param config - Partial configuration to override defaults
49
+ */
50
+ constructor(config = {}) {
51
+ super();
52
+ this.whatsappService = getWhatsAppService();
53
+ this.chatService = getChatService();
54
+ this.config = { ...DEFAULT_CONFIG, ...config };
55
+ }
56
+ /**
57
+ * Initialize the bridge.
58
+ * Sets up message listeners for WhatsApp incoming messages.
59
+ */
60
+ async initialize() {
61
+ if (this.initialized)
62
+ return;
63
+ this.boundMessageHandler = this.handleWhatsAppMessage.bind(this);
64
+ this.whatsappService.on('message', this.boundMessageHandler);
65
+ this.initialized = true;
66
+ this.logger.info('Initialized');
67
+ }
68
+ /**
69
+ * Check if bridge is initialized
70
+ *
71
+ * @returns True if initialized
72
+ */
73
+ isInitialized() {
74
+ return this.initialized;
75
+ }
76
+ /**
77
+ * Set the message queue service for enqueuing messages to the orchestrator.
78
+ *
79
+ * @param service - The MessageQueueService instance
80
+ */
81
+ setMessageQueueService(service) {
82
+ this.messageQueueService = service;
83
+ }
84
+ /**
85
+ * Get current configuration
86
+ *
87
+ * @returns A copy of the current configuration
88
+ */
89
+ getConfig() {
90
+ return { ...this.config };
91
+ }
92
+ /**
93
+ * Handle incoming WhatsApp message.
94
+ * Routes the message to the orchestrator and sends the response back.
95
+ *
96
+ * @param message - Incoming WhatsApp message
97
+ */
98
+ async handleWhatsAppMessage(message) {
99
+ this.logger.info('Received message', {
100
+ from: message.contactName || message.from,
101
+ preview: message.text.substring(0, 50),
102
+ });
103
+ try {
104
+ const context = this.whatsappService.getConversationContext(message.chatId, message.contactName || message.from);
105
+ const response = await this.sendToOrchestrator(message.text, context);
106
+ await this.sendWhatsAppResponse(message.chatId, response);
107
+ this.emit('message_handled', { message, response });
108
+ }
109
+ catch (error) {
110
+ this.logger.error('Error handling message', {
111
+ error: error instanceof Error ? error.message : String(error),
112
+ });
113
+ try {
114
+ await this.sendWhatsAppResponse(message.chatId, `Sorry, I encountered an error: ${error instanceof Error ? error.message : String(error)}`);
115
+ }
116
+ catch {
117
+ // Silent fail on error response
118
+ }
119
+ this.emit('error', error);
120
+ }
121
+ }
122
+ /**
123
+ * Send message to orchestrator via the message queue and wait for response.
124
+ *
125
+ * @param message - Message text to send
126
+ * @param context - Conversation context
127
+ * @returns Orchestrator response or offline/error message
128
+ */
129
+ async sendToOrchestrator(message, context) {
130
+ try {
131
+ const isActive = await isOrchestratorActive();
132
+ if (!isActive) {
133
+ this.logger.info('Orchestrator is not active, returning offline message');
134
+ return getOrchestratorOfflineMessage(true);
135
+ }
136
+ // Capture reference to avoid race condition with non-null assertion
137
+ const mqService = this.messageQueueService;
138
+ if (!mqService) {
139
+ this.logger.error('Message queue service not configured');
140
+ return 'The WhatsApp bridge is not properly configured. Please restart the server.';
141
+ }
142
+ // Store message in chat service
143
+ const result = await this.chatService.sendMessage({
144
+ content: message,
145
+ conversationId: context?.conversationId,
146
+ metadata: {
147
+ source: 'whatsapp',
148
+ chatId: context?.chatId,
149
+ contactName: context?.contactName,
150
+ },
151
+ });
152
+ // Enqueue with a resolve callback for response routing
153
+ const response = await new Promise((resolve) => {
154
+ const timeoutId = setTimeout(() => {
155
+ resolve('The orchestrator is taking longer than expected. Please try again.');
156
+ }, this.config.responseTimeoutMs);
157
+ try {
158
+ mqService.enqueue({
159
+ content: message,
160
+ conversationId: result.conversation.id,
161
+ source: 'whatsapp',
162
+ sourceMetadata: {
163
+ whatsappResolve: (resp) => {
164
+ clearTimeout(timeoutId);
165
+ resolve(resp);
166
+ },
167
+ chatId: context?.chatId,
168
+ contactName: context?.contactName,
169
+ },
170
+ });
171
+ }
172
+ catch (enqueueErr) {
173
+ clearTimeout(timeoutId);
174
+ resolve(`Failed to enqueue message: ${enqueueErr instanceof Error ? enqueueErr.message : String(enqueueErr)}`);
175
+ }
176
+ });
177
+ return response;
178
+ }
179
+ catch (error) {
180
+ this.logger.error('Error sending to orchestrator', {
181
+ error: error instanceof Error ? error.message : String(error),
182
+ });
183
+ throw error;
184
+ }
185
+ }
186
+ /**
187
+ * Cleanup bridge resources.
188
+ * Removes only this bridge's event listener and resets initialization state.
189
+ */
190
+ cleanup() {
191
+ if (this.boundMessageHandler) {
192
+ this.whatsappService.removeListener('message', this.boundMessageHandler);
193
+ this.boundMessageHandler = null;
194
+ }
195
+ this.initialized = false;
196
+ }
197
+ /**
198
+ * Send a text response back to a WhatsApp chat.
199
+ *
200
+ * @param chatId - Destination chat JID
201
+ * @param text - Response text
202
+ */
203
+ async sendWhatsAppResponse(chatId, text) {
204
+ const trimmed = text?.trim();
205
+ if (!trimmed)
206
+ return;
207
+ try {
208
+ await this.whatsappService.sendMessage({ to: chatId, text: trimmed });
209
+ }
210
+ catch (err) {
211
+ this.logger.error('Failed to send WhatsApp response', {
212
+ error: err instanceof Error ? err.message : String(err),
213
+ });
214
+ }
215
+ }
216
+ }
217
+ /**
218
+ * Get WhatsApp bridge singleton
219
+ *
220
+ * @returns WhatsAppOrchestratorBridge instance
221
+ */
222
+ export function getWhatsAppOrchestratorBridge() {
223
+ if (!bridgeInstance) {
224
+ bridgeInstance = new WhatsAppOrchestratorBridge();
225
+ }
226
+ return bridgeInstance;
227
+ }
228
+ /**
229
+ * Reset WhatsApp bridge singleton (for testing)
230
+ */
231
+ export function resetWhatsAppOrchestratorBridge() {
232
+ bridgeInstance = null;
233
+ }
234
+ //# sourceMappingURL=whatsapp-orchestrator-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whatsapp-orchestrator-bridge.js","sourceRoot":"","sources":["../../../../../../backend/src/services/whatsapp/whatsapp-orchestrator-bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * WhatsApp Service
3
+ *
4
+ * Manages WhatsApp connection via Baileys (WhatsApp Web multi-device protocol).
5
+ * Handles QR code pairing, auth state persistence, and bidirectional messaging.
6
+ *
7
+ * @module services/whatsapp
8
+ */
9
+ import { EventEmitter } from 'events';
10
+ import type { WhatsAppConfig, WhatsAppIncomingMessage, WhatsAppOutgoingMessage, WhatsAppServiceStatus, WhatsAppConversationContext } from '../../types/whatsapp.types.js';
11
+ /**
12
+ * Events emitted by WhatsAppService
13
+ */
14
+ export interface WhatsAppServiceEvents {
15
+ message: (message: WhatsAppIncomingMessage) => void;
16
+ qr: (qrCode: string) => void;
17
+ connected: () => void;
18
+ disconnected: (reason?: string) => void;
19
+ error: (error: Error) => void;
20
+ }
21
+ /**
22
+ * WhatsApp Service singleton
23
+ *
24
+ * Manages the Baileys WebSocket connection, QR pairing flow,
25
+ * and message send/receive lifecycle.
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const service = getWhatsAppService();
30
+ * await service.initialize({ allowedContacts: ['+1234567890'] });
31
+ * service.on('message', (msg) => console.log(msg.text));
32
+ * ```
33
+ */
34
+ export declare class WhatsAppService extends EventEmitter {
35
+ private logger;
36
+ private sock;
37
+ private config;
38
+ private connected;
39
+ private currentQrCode;
40
+ private messagesSent;
41
+ private messagesReceived;
42
+ private phoneNumber;
43
+ private conversationContexts;
44
+ private reconnectAttempts;
45
+ private reconnectTimer;
46
+ private static readonly MAX_RECONNECT_DELAY_MS;
47
+ private static readonly MAX_RECONNECT_ATTEMPTS;
48
+ /**
49
+ * Initialize the WhatsApp connection.
50
+ * Sets up Baileys socket, auth state persistence, and event handlers.
51
+ *
52
+ * @param config - WhatsApp configuration
53
+ */
54
+ initialize(config: WhatsAppConfig): Promise<void>;
55
+ /**
56
+ * Process an incoming Baileys message and emit as WhatsAppIncomingMessage.
57
+ *
58
+ * Extracts text from various WhatsApp message types (conversation, extendedTextMessage),
59
+ * validates the sender against the allowed contacts list, and emits a normalized
60
+ * message event for the bridge to handle.
61
+ *
62
+ * Messages are silently ignored if:
63
+ * - Sent by this account (fromMe = true)
64
+ * - No text content present (images, stickers, etc.)
65
+ * - Sender not in allowedContacts list (when configured)
66
+ *
67
+ * @param rawMsg - Raw Baileys message object containing key, message content, and metadata
68
+ */
69
+ private handleIncomingMessage;
70
+ /**
71
+ * Send a text message via WhatsApp.
72
+ *
73
+ * @param msg - Outgoing message with destination and text
74
+ * @throws Error if not connected or message too long
75
+ */
76
+ sendMessage(msg: WhatsAppOutgoingMessage): Promise<void>;
77
+ /**
78
+ * Send a file (document) via WhatsApp.
79
+ *
80
+ * @param chatId - Destination chat JID
81
+ * @param filePath - Absolute path to the file on disk
82
+ * @param caption - Optional caption for the file
83
+ * @throws Error if not connected or file too large
84
+ */
85
+ sendFile(chatId: string, filePath: string, caption?: string): Promise<void>;
86
+ /**
87
+ * Disconnect from WhatsApp gracefully.
88
+ */
89
+ disconnect(): Promise<void>;
90
+ /**
91
+ * Get current connection status.
92
+ *
93
+ * @returns WhatsApp service status object
94
+ */
95
+ getStatus(): WhatsAppServiceStatus;
96
+ /**
97
+ * Check if WhatsApp is currently connected.
98
+ *
99
+ * @returns True if connected
100
+ */
101
+ isConnected(): boolean;
102
+ /**
103
+ * Get the current QR code for pairing.
104
+ *
105
+ * @returns QR code string or null if not pending
106
+ */
107
+ getQRCode(): string | null;
108
+ /**
109
+ * Get or create a conversation context for a chat.
110
+ *
111
+ * @param chatId - Chat JID
112
+ * @param contactName - Contact display name
113
+ * @returns Conversation context for message routing
114
+ */
115
+ getConversationContext(chatId: string, contactName: string): WhatsAppConversationContext;
116
+ }
117
+ /**
118
+ * Get WhatsApp service singleton
119
+ *
120
+ * @returns WhatsAppService instance
121
+ */
122
+ export declare function getWhatsAppService(): WhatsAppService;
123
+ /**
124
+ * Reset WhatsApp service singleton (for testing)
125
+ */
126
+ export declare function resetWhatsAppService(): void;
127
+ //# sourceMappingURL=whatsapp.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whatsapp.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/whatsapp/whatsapp.service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAItC,OAAO,KAAK,EACV,cAAc,EACd,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,EACrB,2BAA2B,EAC5B,MAAM,+BAA+B,CAAC;AAKvC;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,IAAI,CAAC;IACpD,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,YAAY,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC/B;AAaD;;;;;;;;;;;;GAYG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,MAAM,CAAwE;IACtF,OAAO,CAAC,IAAI,CAA8B;IAC1C,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,oBAAoB,CAAuD;IACnF,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAS;IACvD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAM;IAEpD;;;;;OAKG;IACG,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IA4HvD;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,qBAAqB;IAkD7B;;;;;OAKG;IACG,WAAW,CAAC,GAAG,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAc9D;;;;;;;OAOG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBjF;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAuBjC;;;;OAIG;IACH,SAAS,IAAI,qBAAqB;IAUlC;;;;OAIG;IACH,WAAW,IAAI,OAAO;IAItB;;;;OAIG;IACH,SAAS,IAAI,MAAM,GAAG,IAAI;IAI1B;;;;;;OAMG;IACH,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,2BAA2B;CAczF;AAKD;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,CAKpD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}