crewly 1.20.122 → 1.20.124

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 (225) hide show
  1. package/config/skills/agent/core/whatsapp-draft/SKILL.md +80 -0
  2. package/config/skills/agent/core/whatsapp-draft/execute.sh +84 -0
  3. package/config/skills/agent/core/whatsapp-draft/execute.test.sh +70 -0
  4. package/config/skills/agent/core/whatsapp-inbox/SKILL.md +75 -0
  5. package/config/skills/agent/core/whatsapp-inbox/execute.sh +87 -0
  6. package/config/skills/agent/core/whatsapp-inbox/execute.test.sh +68 -0
  7. package/config/skills/agent/core/whatsapp-read/SKILL.md +80 -0
  8. package/config/skills/agent/core/whatsapp-read/execute.sh +116 -0
  9. package/config/skills/agent/core/whatsapp-read/execute.test.sh +84 -0
  10. package/config/skills/agent/core/whatsapp-send/SKILL.md +70 -0
  11. package/config/skills/agent/core/whatsapp-send/execute.sh +84 -0
  12. package/config/skills/agent/core/whatsapp-send/execute.test.sh +79 -0
  13. package/dist/backend/backend/src/constants.d.ts +225 -0
  14. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  15. package/dist/backend/backend/src/constants.js +223 -0
  16. package/dist/backend/backend/src/constants.js.map +1 -1
  17. package/dist/backend/backend/src/controllers/harness/harness.controller.d.ts +54 -0
  18. package/dist/backend/backend/src/controllers/harness/harness.controller.d.ts.map +1 -0
  19. package/dist/backend/backend/src/controllers/harness/harness.controller.js +204 -0
  20. package/dist/backend/backend/src/controllers/harness/harness.controller.js.map +1 -0
  21. package/dist/backend/backend/src/controllers/harness/harness.routes.d.ts +27 -0
  22. package/dist/backend/backend/src/controllers/harness/harness.routes.d.ts.map +1 -0
  23. package/dist/backend/backend/src/controllers/harness/harness.routes.js +43 -0
  24. package/dist/backend/backend/src/controllers/harness/harness.routes.js.map +1 -0
  25. package/dist/backend/backend/src/controllers/whatsapp/whatsapp-inbox.controller.d.ts +73 -0
  26. package/dist/backend/backend/src/controllers/whatsapp/whatsapp-inbox.controller.d.ts.map +1 -0
  27. package/dist/backend/backend/src/controllers/whatsapp/whatsapp-inbox.controller.js +310 -0
  28. package/dist/backend/backend/src/controllers/whatsapp/whatsapp-inbox.controller.js.map +1 -0
  29. package/dist/backend/backend/src/controllers/whatsapp/whatsapp.controller.d.ts.map +1 -1
  30. package/dist/backend/backend/src/controllers/whatsapp/whatsapp.controller.js +53 -4
  31. package/dist/backend/backend/src/controllers/whatsapp/whatsapp.controller.js.map +1 -1
  32. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  33. package/dist/backend/backend/src/routes/api.routes.js +4 -0
  34. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  35. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +5 -0
  36. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  37. package/dist/backend/backend/src/services/agent/agent-registration.service.js +7 -0
  38. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  39. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
  40. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js +5 -0
  41. package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
  42. package/dist/backend/backend/src/services/cloud/cloud-client.service.d.ts +2 -1
  43. package/dist/backend/backend/src/services/cloud/cloud-client.service.d.ts.map +1 -1
  44. package/dist/backend/backend/src/services/cloud/cloud-client.service.js +4 -3
  45. package/dist/backend/backend/src/services/cloud/cloud-client.service.js.map +1 -1
  46. package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.d.ts.map +1 -1
  47. package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js +43 -1
  48. package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js.map +1 -1
  49. package/dist/backend/backend/src/services/harness/claude-config.utils.d.ts +67 -0
  50. package/dist/backend/backend/src/services/harness/claude-config.utils.d.ts.map +1 -0
  51. package/dist/backend/backend/src/services/harness/claude-config.utils.js +118 -0
  52. package/dist/backend/backend/src/services/harness/claude-config.utils.js.map +1 -0
  53. package/dist/backend/backend/src/services/harness/harness-api-key.service.d.ts +99 -0
  54. package/dist/backend/backend/src/services/harness/harness-api-key.service.d.ts.map +1 -0
  55. package/dist/backend/backend/src/services/harness/harness-api-key.service.js +157 -0
  56. package/dist/backend/backend/src/services/harness/harness-api-key.service.js.map +1 -0
  57. package/dist/backend/backend/src/services/harness/harness-credentials.store.d.ts +135 -0
  58. package/dist/backend/backend/src/services/harness/harness-credentials.store.d.ts.map +1 -0
  59. package/dist/backend/backend/src/services/harness/harness-credentials.store.js +208 -0
  60. package/dist/backend/backend/src/services/harness/harness-credentials.store.js.map +1 -0
  61. package/dist/backend/backend/src/services/harness/harness-exec.utils.d.ts +85 -0
  62. package/dist/backend/backend/src/services/harness/harness-exec.utils.d.ts.map +1 -0
  63. package/dist/backend/backend/src/services/harness/harness-exec.utils.js +183 -0
  64. package/dist/backend/backend/src/services/harness/harness-exec.utils.js.map +1 -0
  65. package/dist/backend/backend/src/services/harness/harness-install.service.d.ts +106 -0
  66. package/dist/backend/backend/src/services/harness/harness-install.service.d.ts.map +1 -0
  67. package/dist/backend/backend/src/services/harness/harness-install.service.js +205 -0
  68. package/dist/backend/backend/src/services/harness/harness-install.service.js.map +1 -0
  69. package/dist/backend/backend/src/services/harness/harness-registry.d.ts +86 -0
  70. package/dist/backend/backend/src/services/harness/harness-registry.d.ts.map +1 -0
  71. package/dist/backend/backend/src/services/harness/harness-registry.js +121 -0
  72. package/dist/backend/backend/src/services/harness/harness-registry.js.map +1 -0
  73. package/dist/backend/backend/src/services/harness/harness-status.service.d.ts +173 -0
  74. package/dist/backend/backend/src/services/harness/harness-status.service.d.ts.map +1 -0
  75. package/dist/backend/backend/src/services/harness/harness-status.service.js +324 -0
  76. package/dist/backend/backend/src/services/harness/harness-status.service.js.map +1 -0
  77. package/dist/backend/backend/src/services/harness/harness.service.d.ts +146 -0
  78. package/dist/backend/backend/src/services/harness/harness.service.d.ts.map +1 -0
  79. package/dist/backend/backend/src/services/harness/harness.service.js +193 -0
  80. package/dist/backend/backend/src/services/harness/harness.service.js.map +1 -0
  81. package/dist/backend/backend/src/services/harness/harness.types.d.ts +138 -0
  82. package/dist/backend/backend/src/services/harness/harness.types.d.ts.map +1 -0
  83. package/dist/backend/backend/src/services/harness/harness.types.js +51 -0
  84. package/dist/backend/backend/src/services/harness/harness.types.js.map +1 -0
  85. package/dist/backend/backend/src/services/harness/login-broker.service.d.ts +238 -0
  86. package/dist/backend/backend/src/services/harness/login-broker.service.d.ts.map +1 -0
  87. package/dist/backend/backend/src/services/harness/login-broker.service.js +495 -0
  88. package/dist/backend/backend/src/services/harness/login-broker.service.js.map +1 -0
  89. package/dist/backend/backend/src/services/harness/login-rules.d.ts +162 -0
  90. package/dist/backend/backend/src/services/harness/login-rules.d.ts.map +1 -0
  91. package/dist/backend/backend/src/services/harness/login-rules.js +344 -0
  92. package/dist/backend/backend/src/services/harness/login-rules.js.map +1 -0
  93. package/dist/backend/backend/src/services/harness/orc-harness.store.d.ts +59 -0
  94. package/dist/backend/backend/src/services/harness/orc-harness.store.d.ts.map +1 -0
  95. package/dist/backend/backend/src/services/harness/orc-harness.store.js +108 -0
  96. package/dist/backend/backend/src/services/harness/orc-harness.store.js.map +1 -0
  97. package/dist/backend/backend/src/services/whatsapp/index.d.ts +5 -1
  98. package/dist/backend/backend/src/services/whatsapp/index.d.ts.map +1 -1
  99. package/dist/backend/backend/src/services/whatsapp/index.js +5 -1
  100. package/dist/backend/backend/src/services/whatsapp/index.js.map +1 -1
  101. package/dist/backend/backend/src/services/whatsapp/whatsapp-connection-config.d.ts +59 -0
  102. package/dist/backend/backend/src/services/whatsapp/whatsapp-connection-config.d.ts.map +1 -0
  103. package/dist/backend/backend/src/services/whatsapp/whatsapp-connection-config.js +108 -0
  104. package/dist/backend/backend/src/services/whatsapp/whatsapp-connection-config.js.map +1 -0
  105. package/dist/backend/backend/src/services/whatsapp/whatsapp-draft-gate.d.ts +74 -0
  106. package/dist/backend/backend/src/services/whatsapp/whatsapp-draft-gate.d.ts.map +1 -0
  107. package/dist/backend/backend/src/services/whatsapp/whatsapp-draft-gate.js +82 -0
  108. package/dist/backend/backend/src/services/whatsapp/whatsapp-draft-gate.js.map +1 -0
  109. package/dist/backend/backend/src/services/whatsapp/whatsapp-inbox-capture.d.ts +184 -0
  110. package/dist/backend/backend/src/services/whatsapp/whatsapp-inbox-capture.d.ts.map +1 -0
  111. package/dist/backend/backend/src/services/whatsapp/whatsapp-inbox-capture.js +420 -0
  112. package/dist/backend/backend/src/services/whatsapp/whatsapp-inbox-capture.js.map +1 -0
  113. package/dist/backend/backend/src/services/whatsapp/whatsapp-inbox.store.d.ts +243 -0
  114. package/dist/backend/backend/src/services/whatsapp/whatsapp-inbox.store.d.ts.map +1 -0
  115. package/dist/backend/backend/src/services/whatsapp/whatsapp-inbox.store.js +538 -0
  116. package/dist/backend/backend/src/services/whatsapp/whatsapp-inbox.store.js.map +1 -0
  117. package/dist/backend/backend/src/services/whatsapp/whatsapp-initializer.d.ts +32 -2
  118. package/dist/backend/backend/src/services/whatsapp/whatsapp-initializer.d.ts.map +1 -1
  119. package/dist/backend/backend/src/services/whatsapp/whatsapp-initializer.js +65 -9
  120. package/dist/backend/backend/src/services/whatsapp/whatsapp-initializer.js.map +1 -1
  121. package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.d.ts.map +1 -1
  122. package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.js +11 -0
  123. package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.js.map +1 -1
  124. package/dist/backend/backend/src/services/whatsapp/whatsapp.service.d.ts +59 -1
  125. package/dist/backend/backend/src/services/whatsapp/whatsapp.service.d.ts.map +1 -1
  126. package/dist/backend/backend/src/services/whatsapp/whatsapp.service.js +159 -9
  127. package/dist/backend/backend/src/services/whatsapp/whatsapp.service.js.map +1 -1
  128. package/dist/backend/backend/src/types/whatsapp.types.d.ts +108 -0
  129. package/dist/backend/backend/src/types/whatsapp.types.d.ts.map +1 -1
  130. package/dist/backend/backend/src/types/whatsapp.types.js +9 -0
  131. package/dist/backend/backend/src/types/whatsapp.types.js.map +1 -1
  132. package/dist/backend/build-info.json +2 -2
  133. package/dist/cli/backend/src/constants.d.ts +225 -0
  134. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  135. package/dist/cli/backend/src/constants.js +223 -0
  136. package/dist/cli/backend/src/constants.js.map +1 -1
  137. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts +5 -0
  138. package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  139. package/dist/cli/backend/src/services/agent/agent-registration.service.js +7 -0
  140. package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
  141. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
  142. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js +5 -0
  143. package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
  144. package/dist/cli/backend/src/services/cloud/cloud-client.service.d.ts +2 -1
  145. package/dist/cli/backend/src/services/cloud/cloud-client.service.d.ts.map +1 -1
  146. package/dist/cli/backend/src/services/cloud/cloud-client.service.js +4 -3
  147. package/dist/cli/backend/src/services/cloud/cloud-client.service.js.map +1 -1
  148. package/dist/cli/backend/src/services/harness/claude-config.utils.d.ts +67 -0
  149. package/dist/cli/backend/src/services/harness/claude-config.utils.d.ts.map +1 -0
  150. package/dist/cli/backend/src/services/harness/claude-config.utils.js +118 -0
  151. package/dist/cli/backend/src/services/harness/claude-config.utils.js.map +1 -0
  152. package/dist/cli/backend/src/services/harness/harness-api-key.service.d.ts +99 -0
  153. package/dist/cli/backend/src/services/harness/harness-api-key.service.d.ts.map +1 -0
  154. package/dist/cli/backend/src/services/harness/harness-api-key.service.js +157 -0
  155. package/dist/cli/backend/src/services/harness/harness-api-key.service.js.map +1 -0
  156. package/dist/cli/backend/src/services/harness/harness-credentials.store.d.ts +135 -0
  157. package/dist/cli/backend/src/services/harness/harness-credentials.store.d.ts.map +1 -0
  158. package/dist/cli/backend/src/services/harness/harness-credentials.store.js +208 -0
  159. package/dist/cli/backend/src/services/harness/harness-credentials.store.js.map +1 -0
  160. package/dist/cli/backend/src/services/harness/harness-exec.utils.d.ts +85 -0
  161. package/dist/cli/backend/src/services/harness/harness-exec.utils.d.ts.map +1 -0
  162. package/dist/cli/backend/src/services/harness/harness-exec.utils.js +183 -0
  163. package/dist/cli/backend/src/services/harness/harness-exec.utils.js.map +1 -0
  164. package/dist/cli/backend/src/services/harness/harness-install.service.d.ts +106 -0
  165. package/dist/cli/backend/src/services/harness/harness-install.service.d.ts.map +1 -0
  166. package/dist/cli/backend/src/services/harness/harness-install.service.js +205 -0
  167. package/dist/cli/backend/src/services/harness/harness-install.service.js.map +1 -0
  168. package/dist/cli/backend/src/services/harness/harness-registry.d.ts +86 -0
  169. package/dist/cli/backend/src/services/harness/harness-registry.d.ts.map +1 -0
  170. package/dist/cli/backend/src/services/harness/harness-registry.js +121 -0
  171. package/dist/cli/backend/src/services/harness/harness-registry.js.map +1 -0
  172. package/dist/cli/backend/src/services/harness/harness-status.service.d.ts +173 -0
  173. package/dist/cli/backend/src/services/harness/harness-status.service.d.ts.map +1 -0
  174. package/dist/cli/backend/src/services/harness/harness-status.service.js +324 -0
  175. package/dist/cli/backend/src/services/harness/harness-status.service.js.map +1 -0
  176. package/dist/cli/backend/src/services/harness/harness.service.d.ts +146 -0
  177. package/dist/cli/backend/src/services/harness/harness.service.d.ts.map +1 -0
  178. package/dist/cli/backend/src/services/harness/harness.service.js +193 -0
  179. package/dist/cli/backend/src/services/harness/harness.service.js.map +1 -0
  180. package/dist/cli/backend/src/services/harness/harness.types.d.ts +138 -0
  181. package/dist/cli/backend/src/services/harness/harness.types.d.ts.map +1 -0
  182. package/dist/cli/backend/src/services/harness/harness.types.js +51 -0
  183. package/dist/cli/backend/src/services/harness/harness.types.js.map +1 -0
  184. package/dist/cli/backend/src/services/harness/login-broker.service.d.ts +238 -0
  185. package/dist/cli/backend/src/services/harness/login-broker.service.d.ts.map +1 -0
  186. package/dist/cli/backend/src/services/harness/login-broker.service.js +495 -0
  187. package/dist/cli/backend/src/services/harness/login-broker.service.js.map +1 -0
  188. package/dist/cli/backend/src/services/harness/login-rules.d.ts +162 -0
  189. package/dist/cli/backend/src/services/harness/login-rules.d.ts.map +1 -0
  190. package/dist/cli/backend/src/services/harness/login-rules.js +344 -0
  191. package/dist/cli/backend/src/services/harness/login-rules.js.map +1 -0
  192. package/dist/cli/backend/src/services/harness/orc-harness.store.d.ts +59 -0
  193. package/dist/cli/backend/src/services/harness/orc-harness.store.d.ts.map +1 -0
  194. package/dist/cli/backend/src/services/harness/orc-harness.store.js +108 -0
  195. package/dist/cli/backend/src/services/harness/orc-harness.store.js.map +1 -0
  196. package/dist/cli/cli/src/commands/harness-setup.d.ts +159 -0
  197. package/dist/cli/cli/src/commands/harness-setup.d.ts.map +1 -0
  198. package/dist/cli/cli/src/commands/harness-setup.js +377 -0
  199. package/dist/cli/cli/src/commands/harness-setup.js.map +1 -0
  200. package/dist/cli/cli/src/commands/harness.d.ts +56 -0
  201. package/dist/cli/cli/src/commands/harness.d.ts.map +1 -0
  202. package/dist/cli/cli/src/commands/harness.js +97 -0
  203. package/dist/cli/cli/src/commands/harness.js.map +1 -0
  204. package/dist/cli/cli/src/commands/onboard.d.ts +108 -50
  205. package/dist/cli/cli/src/commands/onboard.d.ts.map +1 -1
  206. package/dist/cli/cli/src/commands/onboard.js +200 -191
  207. package/dist/cli/cli/src/commands/onboard.js.map +1 -1
  208. package/dist/cli/cli/src/constants.d.ts +18 -0
  209. package/dist/cli/cli/src/constants.d.ts.map +1 -1
  210. package/dist/cli/cli/src/constants.js +18 -0
  211. package/dist/cli/cli/src/constants.js.map +1 -1
  212. package/dist/cli/cli/src/index.js +22 -3
  213. package/dist/cli/cli/src/index.js.map +1 -1
  214. package/dist/cli/cli/src/utils/harness-engine.d.ts +99 -0
  215. package/dist/cli/cli/src/utils/harness-engine.d.ts.map +1 -0
  216. package/dist/cli/cli/src/utils/harness-engine.js +143 -0
  217. package/dist/cli/cli/src/utils/harness-engine.js.map +1 -0
  218. package/dist/cli/cli/src/utils/prompt-io.d.ts +25 -0
  219. package/dist/cli/cli/src/utils/prompt-io.d.ts.map +1 -0
  220. package/dist/cli/cli/src/utils/prompt-io.js +47 -0
  221. package/dist/cli/cli/src/utils/prompt-io.js.map +1 -0
  222. package/frontend/dist/assets/{index-8327e63e.css → index-0a2f783c.css} +1 -1
  223. package/frontend/dist/assets/{index-07e338a9.js → index-aaf65055.js} +309 -309
  224. package/frontend/dist/index.html +2 -2
  225. package/package.json +1 -1
@@ -0,0 +1,420 @@
1
+ /**
2
+ * WhatsApp Inbox Capture
3
+ *
4
+ * Turns Baileys events into inbox-store rows. Used only in `inbox` mode.
5
+ * Unlike the assistant path (`WhatsAppService.handleIncomingMessage`) nothing
6
+ * is dropped for being the owner's own message, a group message, media, or
7
+ * from a contact outside `allowedContacts` — the inbox has to know whether
8
+ * the owner already replied, and it is the owner's own account.
9
+ *
10
+ * Media are never downloaded: a message is recorded as its kind plus caption
11
+ * (or file name for documents).
12
+ *
13
+ * Baileys shapes relied on (v7, `@whiskeysockets/baileys` typings):
14
+ * - `messages.upsert`: `{ messages: WAMessage[], type: 'notify' | 'append' }`
15
+ * - `messaging-history.set`: `{ chats: Chat[], contacts: Contact[], messages: WAMessage[], syncType? }`
16
+ * - `contacts.upsert` / `contacts.update`: `Contact[]` (`id`, `name` = address book, `notify` = their pushName)
17
+ * - `chats.upsert` / `chats.update`: `Chat[]` (`id`, `name`, `conversationTimestamp`)
18
+ * - `groups.upsert` / `groups.update`: `GroupMetadata[]` (`id`, `subject`)
19
+ * - `WAMessage.key.remoteJidAlt` / `participantAlt` (v7 LID↔PN alternates)
20
+ * - `messageTimestamp`: seconds, as number, numeric string or protobuf Long
21
+ *
22
+ * @module services/whatsapp/whatsapp-inbox-capture
23
+ */
24
+ import { WHATSAPP_CONSTANTS } from '../../constants.js';
25
+ /** Milliseconds per second (Baileys timestamps are seconds). */
26
+ const MS_PER_SECOND = 1000;
27
+ /** Max wrapper depth unwrapped (ephemeral → viewOnce → ...), as Baileys does. */
28
+ const MAX_UNWRAP_DEPTH = 5;
29
+ /** Wrapper message keys whose `.message` holds the real content. */
30
+ const WRAPPER_KEYS = [
31
+ 'ephemeralMessage',
32
+ 'viewOnceMessage',
33
+ 'viewOnceMessageV2',
34
+ 'viewOnceMessageV2Extension',
35
+ 'documentWithCaptionMessage',
36
+ 'editedMessage',
37
+ ];
38
+ /**
39
+ * Content keys that are not user-visible messages (receipts of protocol
40
+ * work, reactions, key distribution). A message carrying only these is not
41
+ * stored.
42
+ */
43
+ const NON_MESSAGE_KEYS = new Set([
44
+ 'protocolMessage',
45
+ 'reactionMessage',
46
+ 'senderKeyDistributionMessage',
47
+ 'messageContextInfo',
48
+ 'pollUpdateMessage',
49
+ 'keepInChatMessage',
50
+ 'encReactionMessage',
51
+ ]);
52
+ /**
53
+ * Narrow an unknown to a plain object.
54
+ *
55
+ * @param v - Anything
56
+ * @returns The object, or undefined
57
+ */
58
+ function asRec(v) {
59
+ return v && typeof v === 'object' ? v : undefined;
60
+ }
61
+ /**
62
+ * Read a non-empty string field.
63
+ *
64
+ * @param v - Anything
65
+ * @returns The string, or undefined when absent/blank
66
+ */
67
+ function str(v) {
68
+ return typeof v === 'string' && v.length > 0 ? v : undefined;
69
+ }
70
+ /**
71
+ * Convert a Baileys timestamp (seconds as number, numeric string, or
72
+ * protobuf Long with `toNumber()` / `low`+`high`) to epoch ms.
73
+ *
74
+ * @param ts - Raw timestamp
75
+ * @returns Epoch ms, or null when unparseable / non-positive
76
+ */
77
+ export function toEpochMs(ts) {
78
+ let seconds = null;
79
+ if (typeof ts === 'number')
80
+ seconds = ts;
81
+ else if (typeof ts === 'bigint')
82
+ seconds = Number(ts);
83
+ else if (typeof ts === 'string' && /^\d+$/.test(ts))
84
+ seconds = Number(ts);
85
+ else {
86
+ const r = asRec(ts);
87
+ if (r && typeof r.toNumber === 'function')
88
+ seconds = r.toNumber();
89
+ else if (r && typeof r.low === 'number') {
90
+ const high = typeof r.high === 'number' ? r.high : 0;
91
+ seconds = high * 2 ** 32 + (r.low >>> 0);
92
+ }
93
+ }
94
+ if (seconds === null || !Number.isFinite(seconds) || seconds <= 0)
95
+ return null;
96
+ return Math.round(seconds * MS_PER_SECOND);
97
+ }
98
+ /**
99
+ * Whether a JID is a group chat.
100
+ *
101
+ * @param jid - JID
102
+ * @returns True for `...@g.us`
103
+ */
104
+ export function isGroupJid(jid) {
105
+ return jid.endsWith(WHATSAPP_CONSTANTS.GROUP_JID_SUFFIX);
106
+ }
107
+ /**
108
+ * Pick the canonical JID for a person: prefer the phone-number form when
109
+ * Baileys supplies it as the alternate of a LID, so the same person's
110
+ * messages (some keyed by LID, some by phone number) land in one chat.
111
+ *
112
+ * @param jid - Primary JID (`remoteJid` / `participant`)
113
+ * @param alt - Alternate JID (`remoteJidAlt` / `participantAlt`)
114
+ * @returns The canonical JID
115
+ */
116
+ export function canonicalJid(jid, alt) {
117
+ if (jid.endsWith(WHATSAPP_CONSTANTS.LID_JID_SUFFIX) && alt && alt.endsWith(WHATSAPP_CONSTANTS.USER_JID_SUFFIX)) {
118
+ return alt;
119
+ }
120
+ return jid;
121
+ }
122
+ /**
123
+ * Strip wrapper messages (disappearing, view-once, edited, doc-with-caption).
124
+ *
125
+ * @param content - `WAMessage.message`
126
+ * @returns The innermost content object, or undefined
127
+ */
128
+ export function unwrapMessageContent(content) {
129
+ let cur = asRec(content);
130
+ for (let i = 0; i < MAX_UNWRAP_DEPTH && cur; i++) {
131
+ let inner;
132
+ for (const k of WRAPPER_KEYS) {
133
+ inner = asRec(asRec(cur[k])?.message);
134
+ if (inner)
135
+ break;
136
+ }
137
+ if (!inner)
138
+ break;
139
+ cur = inner;
140
+ }
141
+ return cur;
142
+ }
143
+ /**
144
+ * Classify message content into a stored kind and its text/caption.
145
+ *
146
+ * @param content - `WAMessage.message` (wrappers allowed)
147
+ * @returns `{ kind, text }`, or null when this is not a user-visible message
148
+ * (protocol message, reaction, empty envelope)
149
+ */
150
+ export function classifyMessageContent(content) {
151
+ const c = unwrapMessageContent(content);
152
+ if (!c)
153
+ return null;
154
+ const K = WHATSAPP_CONSTANTS.MESSAGE_KINDS;
155
+ const conversation = str(c.conversation);
156
+ if (conversation)
157
+ return { kind: K.TEXT, text: conversation };
158
+ const ext = asRec(c.extendedTextMessage);
159
+ if (ext)
160
+ return { kind: K.TEXT, text: str(ext.text) ?? '' };
161
+ const image = asRec(c.imageMessage);
162
+ if (image)
163
+ return { kind: K.IMAGE, text: str(image.caption) ?? '' };
164
+ const video = asRec(c.videoMessage) ?? asRec(c.ptvMessage);
165
+ if (video)
166
+ return { kind: K.VIDEO, text: str(video.caption) ?? '' };
167
+ const doc = asRec(c.documentMessage);
168
+ if (doc)
169
+ return { kind: K.DOCUMENT, text: str(doc.caption) ?? str(doc.fileName) ?? str(doc.title) ?? '' };
170
+ if (asRec(c.audioMessage))
171
+ return { kind: K.AUDIO, text: '' };
172
+ if (asRec(c.stickerMessage))
173
+ return { kind: K.STICKER, text: '' };
174
+ const visibleKeys = Object.keys(c).filter((k) => c[k] !== null && c[k] !== undefined && !NON_MESSAGE_KEYS.has(k));
175
+ if (visibleKeys.length === 0)
176
+ return null;
177
+ return { kind: K.OTHER, text: '' };
178
+ }
179
+ /**
180
+ * Parse a Baileys `WAMessage` into an inbox row.
181
+ *
182
+ * @param raw - The WAMessage
183
+ * @param ownJid - The connected account's JID (sender of `fromMe` messages), if known
184
+ * @returns The parsed message, or null when it is not storable (no id/chat,
185
+ * status broadcast, protocol-only content, no timestamp)
186
+ */
187
+ export function parseBaileysMessage(raw, ownJid) {
188
+ const r = asRec(raw);
189
+ const key = asRec(r?.key);
190
+ const remoteJid = str(key?.remoteJid);
191
+ const id = str(key?.id);
192
+ if (!r || !key || !remoteJid || !id)
193
+ return null;
194
+ if (remoteJid === WHATSAPP_CONSTANTS.STATUS_BROADCAST_JID)
195
+ return null;
196
+ const classified = classifyMessageContent(r.message);
197
+ if (!classified)
198
+ return null;
199
+ const ts = toEpochMs(r.messageTimestamp);
200
+ if (ts === null)
201
+ return null;
202
+ const fromMe = key.fromMe === true;
203
+ const chatId = canonicalJid(remoteJid, str(key.remoteJidAlt));
204
+ const isGroup = isGroupJid(chatId);
205
+ const participant = str(key.participant);
206
+ const pushName = fromMe ? null : (str(r.pushName) ?? null);
207
+ let senderJid;
208
+ if (fromMe)
209
+ senderJid = ownJid ?? null;
210
+ else if (isGroup)
211
+ senderJid = participant ? canonicalJid(participant, str(key.participantAlt)) : null;
212
+ else
213
+ senderJid = chatId;
214
+ return {
215
+ message: {
216
+ id,
217
+ chatId,
218
+ fromMe,
219
+ senderJid,
220
+ senderName: pushName,
221
+ text: classified.text,
222
+ ts,
223
+ kind: classified.kind,
224
+ },
225
+ isGroup,
226
+ pushName,
227
+ };
228
+ }
229
+ /**
230
+ * Chat row from a Baileys `Contact`: the address-book name outranks the
231
+ * contact's own pushName (`notify`) and business `verifiedName`.
232
+ *
233
+ * @param contact - Contact (full or partial update)
234
+ * @returns Upsert input, or null when the contact names nothing useful
235
+ */
236
+ export function chatFromContact(contact) {
237
+ const c = asRec(contact);
238
+ const rawId = str(c?.id);
239
+ if (!c || !rawId)
240
+ return null;
241
+ const id = canonicalJid(rawId, str(c.phoneNumber));
242
+ const R = WHATSAPP_CONSTANTS.NAME_RANKS;
243
+ const saved = str(c.name);
244
+ if (saved)
245
+ return { id, name: saved, nameRank: R.CONTACT };
246
+ const other = str(c.notify) ?? str(c.verifiedName);
247
+ if (other)
248
+ return { id, name: other, nameRank: R.PUSH_NAME };
249
+ return null;
250
+ }
251
+ /**
252
+ * Chat row from a Baileys `Chat` (history sync, `chats.upsert/update`).
253
+ *
254
+ * @param chat - Chat
255
+ * @returns Upsert input, or null without an id / for the status pseudo-chat
256
+ */
257
+ export function chatFromChat(chat) {
258
+ const c = asRec(chat);
259
+ const id = str(c?.id);
260
+ if (!c || !id || id === WHATSAPP_CONSTANTS.STATUS_BROADCAST_JID)
261
+ return null;
262
+ return {
263
+ id,
264
+ name: str(c.name) ?? null,
265
+ nameRank: WHATSAPP_CONSTANTS.NAME_RANKS.CHAT,
266
+ isGroup: isGroupJid(id),
267
+ lastMessageAt: toEpochMs(c.conversationTimestamp),
268
+ };
269
+ }
270
+ /**
271
+ * Chat row from Baileys `GroupMetadata` (subject = group name).
272
+ *
273
+ * @param group - Group metadata (full or partial)
274
+ * @returns Upsert input, or null without an id
275
+ */
276
+ export function chatFromGroup(group) {
277
+ const g = asRec(group);
278
+ const id = str(g?.id);
279
+ if (!g || !id)
280
+ return null;
281
+ return { id, name: str(g.subject) ?? null, nameRank: WHATSAPP_CONSTANTS.NAME_RANKS.CHAT, isGroup: true };
282
+ }
283
+ /**
284
+ * Writes Baileys events into a {@link WhatsAppInboxStore}.
285
+ *
286
+ * Every handler is defensive: a malformed payload is skipped, never thrown,
287
+ * because it runs inside the socket's event loop.
288
+ */
289
+ export class WhatsAppInboxCapture {
290
+ store;
291
+ opts;
292
+ groupLookups = new Set();
293
+ /**
294
+ * @param store - Destination store
295
+ * @param opts - Own-JID accessor, group-subject fetcher, clock
296
+ */
297
+ constructor(store, opts = {}) {
298
+ this.store = store;
299
+ this.opts = opts;
300
+ }
301
+ /**
302
+ * Store one message and name its chat.
303
+ *
304
+ * @param raw - A WAMessage
305
+ * @returns True when stored
306
+ */
307
+ captureMessage(raw) {
308
+ const parsed = parseBaileysMessage(raw, this.opts.getOwnJid?.() ?? null);
309
+ if (!parsed)
310
+ return false;
311
+ const { message, isGroup, pushName } = parsed;
312
+ // In a 1:1 chat the sender's pushName is a (weak) name for the chat.
313
+ this.store.upsertChat({
314
+ id: message.chatId,
315
+ isGroup,
316
+ name: !isGroup ? pushName : null,
317
+ nameRank: WHATSAPP_CONSTANTS.NAME_RANKS.PUSH_NAME,
318
+ lastMessageAt: message.ts,
319
+ });
320
+ this.store.upsertMessage(message);
321
+ if (isGroup)
322
+ this.maybeFetchGroupName(message.chatId);
323
+ return true;
324
+ }
325
+ /**
326
+ * Handle `messages.upsert` (both `notify` and `append`: own messages sent
327
+ * from the phone and backfills arrive as `append`).
328
+ *
329
+ * @param upsert - `{ messages, type }`
330
+ * @returns Number of messages stored
331
+ */
332
+ onMessagesUpsert(upsert) {
333
+ const messages = asRec(upsert)?.messages;
334
+ if (!Array.isArray(messages))
335
+ return 0;
336
+ let n = 0;
337
+ for (const m of messages)
338
+ if (this.captureMessage(m))
339
+ n++;
340
+ return n;
341
+ }
342
+ /**
343
+ * Handle `messaging-history.set`: seed chats, contact names and recent
344
+ * messages. Messages older than `HISTORY_SYNC_MAX_AGE_MS` are skipped.
345
+ *
346
+ * @param payload - `{ chats, contacts, messages }`
347
+ * @returns Number of messages stored
348
+ */
349
+ onHistorySet(payload) {
350
+ const p = asRec(payload);
351
+ if (!p)
352
+ return 0;
353
+ const chats = (Array.isArray(p.chats) ? p.chats : []).map(chatFromChat).filter((c) => c !== null);
354
+ const contacts = (Array.isArray(p.contacts) ? p.contacts : [])
355
+ .map(chatFromContact)
356
+ .filter((c) => c !== null);
357
+ this.store.upsertChats([...chats, ...contacts]);
358
+ const cutoff = (this.opts.now?.() ?? Date.now()) - WHATSAPP_CONSTANTS.HISTORY_SYNC_MAX_AGE_MS;
359
+ const ownJid = this.opts.getOwnJid?.() ?? null;
360
+ const parsed = (Array.isArray(p.messages) ? p.messages : [])
361
+ .map((m) => parseBaileysMessage(m, ownJid))
362
+ .filter((m) => m !== null && m.message.ts >= cutoff);
363
+ this.store.upsertChats(parsed
364
+ .filter((m) => !m.isGroup && m.pushName)
365
+ .map((m) => ({ id: m.message.chatId, name: m.pushName, nameRank: WHATSAPP_CONSTANTS.NAME_RANKS.PUSH_NAME })));
366
+ return this.store.upsertMessages(parsed.map((m) => m.message));
367
+ }
368
+ /**
369
+ * Handle `contacts.upsert` / `contacts.update`.
370
+ *
371
+ * @param contacts - Contact list
372
+ */
373
+ onContacts(contacts) {
374
+ if (!Array.isArray(contacts))
375
+ return;
376
+ this.store.upsertChats(contacts.map(chatFromContact).filter((c) => c !== null));
377
+ }
378
+ /**
379
+ * Handle `chats.upsert` / `chats.update`.
380
+ *
381
+ * @param chats - Chat list
382
+ */
383
+ onChats(chats) {
384
+ if (!Array.isArray(chats))
385
+ return;
386
+ this.store.upsertChats(chats.map(chatFromChat).filter((c) => c !== null));
387
+ }
388
+ /**
389
+ * Handle `groups.upsert` / `groups.update`.
390
+ *
391
+ * @param groups - Group metadata list
392
+ */
393
+ onGroups(groups) {
394
+ if (!Array.isArray(groups))
395
+ return;
396
+ this.store.upsertChats(groups.map(chatFromGroup).filter((c) => c !== null));
397
+ }
398
+ /**
399
+ * Look a group's subject up once per process when we have no name for it.
400
+ *
401
+ * @param jid - Group JID
402
+ */
403
+ maybeFetchGroupName(jid) {
404
+ const fetcher = this.opts.fetchGroupSubject;
405
+ if (!fetcher || this.groupLookups.has(jid))
406
+ return;
407
+ if (this.store.getChat(jid)?.name)
408
+ return;
409
+ this.groupLookups.add(jid);
410
+ fetcher(jid)
411
+ .then((subject) => {
412
+ if (subject)
413
+ this.store.upsertChat({ id: jid, name: subject, nameRank: WHATSAPP_CONSTANTS.NAME_RANKS.CHAT, isGroup: true });
414
+ })
415
+ .catch(() => {
416
+ // Best effort — the chat keeps its JID as the label.
417
+ });
418
+ }
419
+ }
420
+ //# sourceMappingURL=whatsapp-inbox-capture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whatsapp-inbox-capture.js","sourceRoot":"","sources":["../../../../../../backend/src/services/whatsapp/whatsapp-inbox-capture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,243 @@
1
+ /**
2
+ * WhatsApp Inbox Store
3
+ *
4
+ * Local SQLite store behind the WhatsApp inbox connector: the chats and
5
+ * messages captured from the owner's personal account (read-only), and the
6
+ * reply drafts agents propose. Lives at `~/.crewly/whatsapp/inbox.db`
7
+ * (resolved through `getCrewlyHomePath()`, so `CREWLY_HOME` isolates it).
8
+ *
9
+ * Nothing in here talks to WhatsApp. Sending a draft is the controller's
10
+ * job, gated on the owner's confirmation; this store only records the
11
+ * draft's lifecycle (`pending` → `sending` → `sent` / back to `pending`,
12
+ * or `discarded`) with an atomic claim so a draft can never be sent twice.
13
+ *
14
+ * @module services/whatsapp/whatsapp-inbox.store
15
+ */
16
+ import type { WhatsAppDraft, WhatsAppDraftStatus, WhatsAppInboxChat, WhatsAppInboxEntry, WhatsAppInboxMessage, WhatsAppSearchHit } from '../../types/whatsapp.types.js';
17
+ /** In-memory database name accepted by better-sqlite3 (tests). */
18
+ export declare const IN_MEMORY_DB = ":memory:";
19
+ /** Input for {@link WhatsAppInboxStore.upsertChat}. */
20
+ export interface UpsertChatInput {
21
+ /** Chat JID */
22
+ id: string;
23
+ /** Display name, if this source knows one */
24
+ name?: string | null;
25
+ /** Provenance of `name` (see `WHATSAPP_CONSTANTS.NAME_RANKS`); a lower rank never overwrites a higher one */
26
+ nameRank?: number;
27
+ /** Whether the chat is a group (defaults from the JID suffix) */
28
+ isGroup?: boolean;
29
+ /** Epoch ms of the newest message this source knows of (only ever moves forward) */
30
+ lastMessageAt?: number | null;
31
+ }
32
+ /** Options for {@link WhatsAppInboxStore.listInbox}. */
33
+ export interface ListInboxOptions {
34
+ /** Row cap */
35
+ limit: number;
36
+ /** Include group chats (default false — groups are noisy) */
37
+ includeGroups?: boolean;
38
+ }
39
+ /**
40
+ * Resolve the default inbox database path under the Crewly home.
41
+ *
42
+ * @returns Absolute path to `<crewly home>/whatsapp/inbox.db`
43
+ */
44
+ export declare function getDefaultInboxDbPath(): string;
45
+ /**
46
+ * Format a draft sequence number as its human code.
47
+ *
48
+ * @param seq - Monotonic sequence number
49
+ * @returns Code such as `W12`
50
+ */
51
+ export declare function formatDraftCode(seq: number): string;
52
+ /**
53
+ * Parse a user-typed draft code (`W12`, `w12`, `#W12`, `12`) into its sequence number.
54
+ *
55
+ * @param raw - The code as typed
56
+ * @returns The sequence number, or null when the text is not a draft code
57
+ */
58
+ export declare function parseDraftCode(raw: string): number | null;
59
+ /**
60
+ * SQLite-backed store for the WhatsApp inbox and reply drafts.
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * const store = new WhatsAppInboxStore(':memory:');
65
+ * store.upsertMessage({ id: 'm1', chatId: '1@s.whatsapp.net', fromMe: false, senderJid: null,
66
+ * senderName: 'Ann', text: 'hi', ts: Date.now(), kind: 'text' });
67
+ * store.listInbox({ limit: 20 }); // → [{ chat, unansweredCount: 1, ... }]
68
+ * ```
69
+ */
70
+ export declare class WhatsAppInboxStore {
71
+ private readonly db;
72
+ /**
73
+ * Open (and migrate) the inbox database.
74
+ *
75
+ * @param dbPath - File path, or `:memory:` for tests. The parent directory
76
+ * is created owner-only (0700) and the file is chmod 0600.
77
+ * @throws NativeBindingFatalError when better-sqlite3 cannot load
78
+ */
79
+ constructor(dbPath?: string);
80
+ /**
81
+ * Close the database handle.
82
+ */
83
+ close(): void;
84
+ /**
85
+ * Insert or update a chat.
86
+ *
87
+ * The name only changes when the new source ranks at least as high as the
88
+ * one that set the current name (an address-book name is never replaced by
89
+ * a pushName). `lastMessageAt` only moves forward.
90
+ *
91
+ * @param input - Chat fields known by this source
92
+ */
93
+ upsertChat(input: UpsertChatInput): void;
94
+ /**
95
+ * Insert or update one message (idempotent on the message id) and advance
96
+ * its chat's `lastMessageAt`, creating the chat row if needed.
97
+ *
98
+ * A re-delivered message keeps its original `fromMe`, chat and timestamp;
99
+ * text, kind and a newly learned sender name are refreshed (edits, late
100
+ * pushNames).
101
+ *
102
+ * @param msg - The message
103
+ */
104
+ upsertMessage(msg: WhatsAppInboxMessage): void;
105
+ /**
106
+ * Upsert many messages in one transaction (history sync).
107
+ *
108
+ * @param msgs - Messages
109
+ * @returns How many were written
110
+ */
111
+ upsertMessages(msgs: WhatsAppInboxMessage[]): number;
112
+ /**
113
+ * Upsert many chats in one transaction.
114
+ *
115
+ * @param chats - Chats
116
+ */
117
+ upsertChats(chats: UpsertChatInput[]): void;
118
+ /**
119
+ * Look up one chat.
120
+ *
121
+ * @param id - Chat JID
122
+ * @returns The chat, or null
123
+ */
124
+ getChat(id: string): WhatsAppInboxChat | null;
125
+ /**
126
+ * Chats that need a reply: the newest message is not the owner's.
127
+ *
128
+ * `unansweredCount` counts inbound messages after the owner's last message
129
+ * in that chat (all of them when the owner never wrote there).
130
+ *
131
+ * @param opts - Limit and whether to include groups
132
+ * @returns Entries, newest first
133
+ */
134
+ listInbox(opts: ListInboxOptions): WhatsAppInboxEntry[];
135
+ /**
136
+ * Recent chats, optionally filtered by name or JID substring.
137
+ *
138
+ * @param opts - Limit and optional query
139
+ * @returns Chats, most recently active first (chats with no messages last)
140
+ */
141
+ listChats(opts: {
142
+ limit: number;
143
+ q?: string;
144
+ }): WhatsAppInboxChat[];
145
+ /**
146
+ * One page of a chat's messages, in chronological order.
147
+ *
148
+ * @param chatId - Chat JID
149
+ * @param opts - Page size and an exclusive upper bound (epoch ms) for paging back
150
+ * @returns The newest `limit` messages older than `before`, oldest first
151
+ */
152
+ listMessages(chatId: string, opts: {
153
+ limit: number;
154
+ before?: number;
155
+ }): WhatsAppInboxMessage[];
156
+ /**
157
+ * Substring search over message text (case-insensitive for ASCII).
158
+ *
159
+ * @param q - Search text (must be non-empty)
160
+ * @param limit - Row cap
161
+ * @returns Hits, newest first
162
+ */
163
+ search(q: string, limit: number): WhatsAppSearchHit[];
164
+ /**
165
+ * Record a reply draft with the next monotonic code.
166
+ *
167
+ * @param input - Recipient, text, author session (null = owner) and clock
168
+ * @returns The stored draft (status `pending`)
169
+ */
170
+ createDraft(input: {
171
+ chatId: string;
172
+ text: string;
173
+ createdBy: string | null;
174
+ now: number;
175
+ }): WhatsAppDraft;
176
+ /**
177
+ * Look up a draft by its opaque id.
178
+ *
179
+ * @param id - Draft id
180
+ * @returns The draft, or null
181
+ */
182
+ getDraftById(id: string): WhatsAppDraft | null;
183
+ /**
184
+ * Look up a draft by id or by human code (`W12`, `12`, `#W12`).
185
+ *
186
+ * @param ref - Id or code
187
+ * @returns The draft, or null
188
+ */
189
+ findDraft(ref: string): WhatsAppDraft | null;
190
+ /**
191
+ * List drafts, newest first.
192
+ *
193
+ * @param opts - Optional status filter and row cap
194
+ * @returns Drafts
195
+ */
196
+ listDrafts(opts: {
197
+ status?: WhatsAppDraftStatus;
198
+ limit: number;
199
+ }): WhatsAppDraft[];
200
+ /**
201
+ * Atomically move a draft from `pending` to `sending`.
202
+ *
203
+ * Only one caller can win: this is what makes "a draft can't be sent twice"
204
+ * hold under concurrent requests.
205
+ *
206
+ * @param id - Draft id
207
+ * @returns True when this caller now holds the send claim
208
+ */
209
+ claimDraftForSend(id: string): boolean;
210
+ /**
211
+ * Mark a claimed draft as sent.
212
+ *
213
+ * @param id - Draft id
214
+ * @param now - Epoch ms of the send
215
+ */
216
+ markDraftSent(id: string, now: number): void;
217
+ /**
218
+ * Return a claimed draft to `pending` after a failed send, keeping the error.
219
+ *
220
+ * @param id - Draft id
221
+ * @param error - Why the send failed
222
+ */
223
+ releaseDraftClaim(id: string, error: string): void;
224
+ /**
225
+ * Discard a pending draft.
226
+ *
227
+ * @param id - Draft id
228
+ * @param now - Epoch ms
229
+ * @returns True when the draft was pending and is now discarded
230
+ */
231
+ discardDraft(id: string, now: number): boolean;
232
+ }
233
+ /**
234
+ * Get the process-wide inbox store, opening it on first use.
235
+ *
236
+ * @returns The store at {@link getDefaultInboxDbPath}
237
+ */
238
+ export declare function getWhatsAppInboxStore(): WhatsAppInboxStore;
239
+ /**
240
+ * Close and forget the process-wide store (tests, shutdown).
241
+ */
242
+ export declare function resetWhatsAppInboxStore(): void;
243
+ //# sourceMappingURL=whatsapp-inbox.store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whatsapp-inbox.store.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/whatsapp/whatsapp-inbox.store.ts"],"names":[],"mappings":"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"}