whale-code 6.5.4 → 6.5.6

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 (853) hide show
  1. package/README.md +39 -31
  2. package/bin/{swagmanager-mcp.js → whale-code.js} +17 -2
  3. package/dist/cli/app.js +148 -72
  4. package/dist/cli/app.js.map +1 -0
  5. package/dist/cli/chat/AgentSelector.js +105 -10
  6. package/dist/cli/chat/AgentSelector.js.map +1 -0
  7. package/dist/cli/chat/ChatApp.d.ts +31 -0
  8. package/dist/cli/chat/ChatApp.js +539 -286
  9. package/dist/cli/chat/ChatApp.js.map +1 -0
  10. package/dist/cli/chat/ChatInput.js +1088 -770
  11. package/dist/cli/chat/ChatInput.js.map +1 -0
  12. package/dist/cli/chat/MarkdownText.js +39 -14
  13. package/dist/cli/chat/MarkdownText.js.map +1 -0
  14. package/dist/cli/chat/MemoryManager.js +181 -46
  15. package/dist/cli/chat/MemoryManager.js.map +1 -0
  16. package/dist/cli/chat/MessageList.d.ts +2 -3
  17. package/dist/cli/chat/MessageList.js +186 -45
  18. package/dist/cli/chat/MessageList.js.map +1 -0
  19. package/dist/cli/chat/ModelSelector.js +282 -63
  20. package/dist/cli/chat/ModelSelector.js.map +1 -0
  21. package/dist/cli/chat/NodeManager.js +165 -75
  22. package/dist/cli/chat/NodeManager.js.map +1 -0
  23. package/dist/cli/chat/NodeSelector.js +171 -30
  24. package/dist/cli/chat/NodeSelector.js.map +1 -0
  25. package/dist/cli/chat/PlanApproval.js +281 -57
  26. package/dist/cli/chat/PlanApproval.js.map +1 -0
  27. package/dist/cli/chat/RewindViewer.js +559 -144
  28. package/dist/cli/chat/RewindViewer.js.map +1 -0
  29. package/dist/cli/chat/SessionManager.js +137 -30
  30. package/dist/cli/chat/SessionManager.js.map +1 -0
  31. package/dist/cli/chat/SlashMenu.js +293 -164
  32. package/dist/cli/chat/SlashMenu.js.map +1 -0
  33. package/dist/cli/chat/StatusBar.js +172 -9
  34. package/dist/cli/chat/StatusBar.js.map +1 -0
  35. package/dist/cli/chat/StoreSelector.js +147 -18
  36. package/dist/cli/chat/StoreSelector.js.map +1 -0
  37. package/dist/cli/chat/StreamingText.d.ts +1 -5
  38. package/dist/cli/chat/StreamingText.js +22 -7
  39. package/dist/cli/chat/StreamingText.js.map +1 -0
  40. package/dist/cli/chat/SubagentPanel.d.ts +1 -2
  41. package/dist/cli/chat/SubagentPanel.js +612 -72
  42. package/dist/cli/chat/SubagentPanel.js.map +1 -0
  43. package/dist/cli/chat/TeamPanel.d.ts +1 -0
  44. package/dist/cli/chat/TeamPanel.js +230 -30
  45. package/dist/cli/chat/TeamPanel.js.map +1 -0
  46. package/dist/cli/chat/ThemeSelector.js +84 -24
  47. package/dist/cli/chat/ThemeSelector.js.map +1 -0
  48. package/dist/cli/chat/ToolIndicator.js +1476 -371
  49. package/dist/cli/chat/ToolIndicator.js.map +1 -0
  50. package/dist/cli/chat/hooks/useAgentLoop.d.ts +1 -0
  51. package/dist/cli/chat/hooks/useAgentLoop.js +481 -367
  52. package/dist/cli/chat/hooks/useAgentLoop.js.map +1 -0
  53. package/dist/cli/chat/hooks/useSlashCommands.d.ts +3 -14
  54. package/dist/cli/chat/hooks/useSlashCommands.js +744 -572
  55. package/dist/cli/chat/hooks/useSlashCommands.js.map +1 -0
  56. package/dist/cli/commands/config-cmd.js +56 -57
  57. package/dist/cli/commands/config-cmd.js.map +1 -0
  58. package/dist/cli/commands/db.js +184 -169
  59. package/dist/cli/commands/db.js.map +1 -0
  60. package/dist/cli/commands/doctor.js +212 -122
  61. package/dist/cli/commands/doctor.js.map +1 -0
  62. package/dist/cli/commands/init.js +211 -244
  63. package/dist/cli/commands/init.js.map +1 -0
  64. package/dist/cli/commands/mcp.js +127 -122
  65. package/dist/cli/commands/mcp.js.map +1 -0
  66. package/dist/cli/login/LoginApp.js +355 -141
  67. package/dist/cli/login/LoginApp.js.map +1 -0
  68. package/dist/cli/print-mode.js +196 -177
  69. package/dist/cli/print-mode.js.map +1 -0
  70. package/dist/cli/serve-mode.js +615 -530
  71. package/dist/cli/serve-mode.js.map +1 -0
  72. package/dist/cli/services/agent-config.d.ts +29 -0
  73. package/dist/cli/services/agent-config.js +91 -0
  74. package/dist/cli/services/agent-config.js.map +1 -0
  75. package/dist/cli/services/agent-definitions.d.ts +4 -1
  76. package/dist/cli/services/agent-definitions.js +97 -56
  77. package/dist/cli/services/agent-definitions.js.map +1 -0
  78. package/dist/cli/services/agent-events.js +225 -162
  79. package/dist/cli/services/agent-events.js.map +1 -0
  80. package/dist/cli/services/agent-loop.js +978 -669
  81. package/dist/cli/services/agent-loop.js.map +1 -0
  82. package/dist/cli/services/agent-worker-base.d.ts +35 -5
  83. package/dist/cli/services/agent-worker-base.js +337 -153
  84. package/dist/cli/services/agent-worker-base.js.map +1 -0
  85. package/dist/cli/services/api-retry.js +69 -64
  86. package/dist/cli/services/api-retry.js.map +1 -0
  87. package/dist/cli/services/auth-service.d.ts +3 -3
  88. package/dist/cli/services/auth-service.js +209 -132
  89. package/dist/cli/services/auth-service.js.map +1 -0
  90. package/dist/cli/services/background-processes.js +343 -267
  91. package/dist/cli/services/background-processes.js.map +1 -0
  92. package/dist/cli/services/browser-auth.d.ts +2 -2
  93. package/dist/cli/services/browser-auth.js +159 -118
  94. package/dist/cli/services/browser-auth.js.map +1 -0
  95. package/dist/cli/services/claude-md-loader.js +40 -36
  96. package/dist/cli/services/claude-md-loader.js.map +1 -0
  97. package/dist/cli/services/config-store.d.ts +9 -4
  98. package/dist/cli/services/config-store.js +164 -117
  99. package/dist/cli/services/config-store.js.map +1 -0
  100. package/dist/cli/services/debug-log.d.ts +1 -1
  101. package/dist/cli/services/debug-log.js +34 -35
  102. package/dist/cli/services/debug-log.js.map +1 -0
  103. package/dist/cli/services/env-detect.d.ts +7 -0
  104. package/dist/cli/services/env-detect.js +9 -0
  105. package/dist/cli/services/env-detect.js.map +1 -0
  106. package/dist/cli/services/error-logger.d.ts +2 -3
  107. package/dist/cli/services/error-logger.js +189 -180
  108. package/dist/cli/services/error-logger.js.map +1 -0
  109. package/dist/cli/services/file-history.d.ts +1 -1
  110. package/dist/cli/services/file-history.js +50 -54
  111. package/dist/cli/services/file-history.js.map +1 -0
  112. package/dist/cli/services/format-server-response.js +332 -372
  113. package/dist/cli/services/format-server-response.js.map +1 -0
  114. package/dist/cli/services/git-context.js +61 -45
  115. package/dist/cli/services/git-context.js.map +1 -0
  116. package/dist/cli/services/hooks.d.ts +2 -2
  117. package/dist/cli/services/hooks.js +195 -180
  118. package/dist/cli/services/hooks.js.map +1 -0
  119. package/dist/cli/services/ink-incremental.d.ts +19 -0
  120. package/dist/cli/services/ink-incremental.js +59 -0
  121. package/dist/cli/services/ink-incremental.js.map +1 -0
  122. package/dist/cli/services/ink-resize-fix.js +54 -44
  123. package/dist/cli/services/ink-resize-fix.js.map +1 -0
  124. package/dist/cli/services/ink-sync-output.d.ts +12 -0
  125. package/dist/cli/services/ink-sync-output.js +16 -0
  126. package/dist/cli/services/ink-sync-output.js.map +1 -0
  127. package/dist/cli/services/interactive-tools.js +268 -212
  128. package/dist/cli/services/interactive-tools.js.map +1 -0
  129. package/dist/cli/services/keybinding-manager.d.ts +11 -1
  130. package/dist/cli/services/keybinding-manager.js +126 -63
  131. package/dist/cli/services/keybinding-manager.js.map +1 -0
  132. package/dist/cli/services/local-tools.d.ts +1 -1
  133. package/dist/cli/services/local-tools.js +939 -656
  134. package/dist/cli/services/local-tools.js.map +1 -0
  135. package/dist/cli/services/lsp-manager.js +757 -594
  136. package/dist/cli/services/lsp-manager.js.map +1 -0
  137. package/dist/cli/services/mcp-client.d.ts +1 -1
  138. package/dist/cli/services/mcp-client.js +173 -134
  139. package/dist/cli/services/mcp-client.js.map +1 -0
  140. package/dist/cli/services/memory-manager.js +53 -40
  141. package/dist/cli/services/memory-manager.js.map +1 -0
  142. package/dist/cli/services/model-manager.js +55 -40
  143. package/dist/cli/services/model-manager.js.map +1 -0
  144. package/dist/cli/services/model-router.js +115 -85
  145. package/dist/cli/services/model-router.js.map +1 -0
  146. package/dist/cli/services/paths.d.ts +30 -0
  147. package/dist/cli/services/paths.js +81 -0
  148. package/dist/cli/services/paths.js.map +1 -0
  149. package/dist/cli/services/permission-modes.js +32 -25
  150. package/dist/cli/services/permission-modes.js.map +1 -0
  151. package/dist/cli/services/rewind.js +182 -168
  152. package/dist/cli/services/rewind.js.map +1 -0
  153. package/dist/cli/services/ripgrep.js +115 -115
  154. package/dist/cli/services/ripgrep.js.map +1 -0
  155. package/dist/cli/services/sandbox.d.ts +1 -1
  156. package/dist/cli/services/sandbox.js +58 -37
  157. package/dist/cli/services/sandbox.js.map +1 -0
  158. package/dist/cli/services/server-tools.js +738 -565
  159. package/dist/cli/services/server-tools.js.map +1 -0
  160. package/dist/cli/services/session-persistence.js +69 -74
  161. package/dist/cli/services/session-persistence.js.map +1 -0
  162. package/dist/cli/services/subagent-worker.js +42 -27
  163. package/dist/cli/services/subagent-worker.js.map +1 -0
  164. package/dist/cli/services/subagent.d.ts +2 -0
  165. package/dist/cli/services/subagent.js +606 -430
  166. package/dist/cli/services/subagent.js.map +1 -0
  167. package/dist/cli/services/system-prompt.js +86 -78
  168. package/dist/cli/services/system-prompt.js.map +1 -0
  169. package/dist/cli/services/task-decomposer.d.ts +1 -1
  170. package/dist/cli/services/task-decomposer.js +172 -139
  171. package/dist/cli/services/task-decomposer.js.map +1 -0
  172. package/dist/cli/services/team-lead.d.ts +2 -2
  173. package/dist/cli/services/team-lead.js +727 -529
  174. package/dist/cli/services/team-lead.js.map +1 -0
  175. package/dist/cli/services/team-state.js +319 -319
  176. package/dist/cli/services/team-state.js.map +1 -0
  177. package/dist/cli/services/teammate.d.ts +8 -2
  178. package/dist/cli/services/teammate.js +862 -560
  179. package/dist/cli/services/teammate.js.map +1 -0
  180. package/dist/cli/services/telemetry.d.ts +6 -1
  181. package/dist/cli/services/telemetry.js +180 -157
  182. package/dist/cli/services/telemetry.js.map +1 -0
  183. package/dist/cli/services/tools/agent-tools.d.ts +3 -3
  184. package/dist/cli/services/tools/agent-tools.js +480 -322
  185. package/dist/cli/services/tools/agent-tools.js.map +1 -0
  186. package/dist/cli/services/tools/file-ops.js +563 -450
  187. package/dist/cli/services/tools/file-ops.js.map +1 -0
  188. package/dist/cli/services/tools/search-tools.js +231 -162
  189. package/dist/cli/services/tools/search-tools.js.map +1 -0
  190. package/dist/cli/services/tools/shell-exec.js +197 -151
  191. package/dist/cli/services/tools/shell-exec.js.map +1 -0
  192. package/dist/cli/services/tools/task-manager.js +206 -173
  193. package/dist/cli/services/tools/task-manager.js.map +1 -0
  194. package/dist/cli/services/tools/web-tools.js +388 -341
  195. package/dist/cli/services/tools/web-tools.js.map +1 -0
  196. package/dist/cli/setup/SetupApp.d.ts +2 -2
  197. package/dist/cli/setup/SetupApp.js +608 -160
  198. package/dist/cli/setup/SetupApp.js.map +1 -0
  199. package/dist/cli/shared/ErrorBoundary.d.ts +22 -0
  200. package/dist/cli/shared/ErrorBoundary.js +73 -0
  201. package/dist/cli/shared/ErrorBoundary.js.map +1 -0
  202. package/dist/cli/shared/MatrixIntro.js +66 -69
  203. package/dist/cli/shared/MatrixIntro.js.map +1 -0
  204. package/dist/cli/shared/SpinnerSlot.d.ts +14 -0
  205. package/dist/cli/shared/SpinnerSlot.js +63 -0
  206. package/dist/cli/shared/SpinnerSlot.js.map +1 -0
  207. package/dist/cli/shared/Theme.d.ts +1 -1
  208. package/dist/cli/shared/Theme.js +136 -92
  209. package/dist/cli/shared/Theme.js.map +1 -0
  210. package/dist/cli/shared/WhaleBanner.js +99 -11
  211. package/dist/cli/shared/WhaleBanner.js.map +1 -0
  212. package/dist/cli/shared/markdown.d.ts +3 -1
  213. package/dist/cli/shared/markdown.js +736 -674
  214. package/dist/cli/shared/markdown.js.map +1 -0
  215. package/dist/cli/shared/marked-terminal.d.js +2 -0
  216. package/dist/cli/shared/marked-terminal.d.js.map +1 -0
  217. package/dist/cli/shared/theme-manager.js +99 -90
  218. package/dist/cli/shared/theme-manager.js.map +1 -0
  219. package/dist/cli/shared/theme-presets.js +256 -254
  220. package/dist/cli/shared/theme-presets.js.map +1 -0
  221. package/dist/cli/status/StatusApp.js +235 -86
  222. package/dist/cli/status/StatusApp.js.map +1 -0
  223. package/dist/cli/stores/StoreApp.js +275 -65
  224. package/dist/cli/stores/StoreApp.js.map +1 -0
  225. package/dist/index.d.ts +2 -2
  226. package/dist/index.js +509 -396
  227. package/dist/index.js.map +1 -0
  228. package/dist/local-agent/connection.d.ts +2 -2
  229. package/dist/local-agent/connection.js +352 -293
  230. package/dist/local-agent/connection.js.map +1 -0
  231. package/dist/local-agent/discovery.js +259 -122
  232. package/dist/local-agent/discovery.js.map +1 -0
  233. package/dist/local-agent/executor.js +216 -193
  234. package/dist/local-agent/executor.js.map +1 -0
  235. package/dist/local-agent/index.d.ts +2 -2
  236. package/dist/local-agent/index.js +156 -156
  237. package/dist/local-agent/index.js.map +1 -0
  238. package/dist/node/adapters/base.js +18 -8
  239. package/dist/node/adapters/base.js.map +1 -0
  240. package/dist/node/adapters/discord.js +286 -275
  241. package/dist/node/adapters/discord.js.map +1 -0
  242. package/dist/node/adapters/email.js +189 -202
  243. package/dist/node/adapters/email.js.map +1 -0
  244. package/dist/node/adapters/imessage.js +145 -142
  245. package/dist/node/adapters/imessage.js.map +1 -0
  246. package/dist/node/adapters/slack.js +237 -236
  247. package/dist/node/adapters/slack.js.map +1 -0
  248. package/dist/node/adapters/sms.js +149 -151
  249. package/dist/node/adapters/sms.js.map +1 -0
  250. package/dist/node/adapters/telegram.js +88 -92
  251. package/dist/node/adapters/telegram.js.map +1 -0
  252. package/dist/node/adapters/webchat.js +160 -136
  253. package/dist/node/adapters/webchat.js.map +1 -0
  254. package/dist/node/adapters/whatsapp.js +212 -215
  255. package/dist/node/adapters/whatsapp.js.map +1 -0
  256. package/dist/node/cli.js +884 -653
  257. package/dist/node/cli.js.map +1 -0
  258. package/dist/node/config.js +20 -18
  259. package/dist/node/config.js.map +1 -0
  260. package/dist/node/gateway-client.js +191 -181
  261. package/dist/node/gateway-client.js.map +1 -0
  262. package/dist/node/portal/clipboard.js +161 -130
  263. package/dist/node/portal/clipboard.js.map +1 -0
  264. package/dist/node/portal/discovery.js +51 -45
  265. package/dist/node/portal/discovery.js.map +1 -0
  266. package/dist/node/portal/forward.js +64 -58
  267. package/dist/node/portal/forward.js.map +1 -0
  268. package/dist/node/portal/index.js +246 -221
  269. package/dist/node/portal/index.js.map +1 -0
  270. package/dist/node/portal/multiplexer.js +192 -182
  271. package/dist/node/portal/multiplexer.js.map +1 -0
  272. package/dist/node/portal/permissions.js +102 -70
  273. package/dist/node/portal/permissions.js.map +1 -0
  274. package/dist/node/portal/protocol.js +153 -116
  275. package/dist/node/portal/protocol.js.map +1 -0
  276. package/dist/node/portal/screen.js +80 -69
  277. package/dist/node/portal/screen.js.map +1 -0
  278. package/dist/node/portal/session.js +124 -117
  279. package/dist/node/portal/session.js.map +1 -0
  280. package/dist/node/portal/shell.js +140 -113
  281. package/dist/node/portal/shell.js.map +1 -0
  282. package/dist/node/portal/stream.js +77 -75
  283. package/dist/node/portal/stream.js.map +1 -0
  284. package/dist/node/portal/transfer.js +190 -167
  285. package/dist/node/portal/transfer.js.map +1 -0
  286. package/dist/node/portal/ui.js +124 -99
  287. package/dist/node/portal/ui.js.map +1 -0
  288. package/dist/node/remote-desktop/compile-helper.js +50 -45
  289. package/dist/node/remote-desktop/compile-helper.js.map +1 -0
  290. package/dist/node/remote-desktop/index.js +215 -187
  291. package/dist/node/remote-desktop/index.js.map +1 -0
  292. package/dist/node/remote-desktop/protocol.js +45 -29
  293. package/dist/node/remote-desktop/protocol.js.map +1 -0
  294. package/dist/node/runtime.js +493 -410
  295. package/dist/node/runtime.js.map +1 -0
  296. package/dist/server/handlers/__test-utils__/test-db.js +39 -89
  297. package/dist/server/handlers/__test-utils__/test-db.js.map +1 -0
  298. package/dist/server/handlers/analytics.js +467 -261
  299. package/dist/server/handlers/analytics.js.map +1 -0
  300. package/dist/server/handlers/api-docs.d.ts +6 -0
  301. package/dist/server/handlers/api-docs.js +1613 -0
  302. package/dist/server/handlers/api-docs.js.map +1 -0
  303. package/dist/server/handlers/api-keys.js +295 -232
  304. package/dist/server/handlers/api-keys.js.map +1 -0
  305. package/dist/server/handlers/billing.js +330 -239
  306. package/dist/server/handlers/billing.js.map +1 -0
  307. package/dist/server/handlers/browser.js +468 -395
  308. package/dist/server/handlers/browser.js.map +1 -0
  309. package/dist/server/handlers/catalog.js +1377 -978
  310. package/dist/server/handlers/catalog.js.map +1 -0
  311. package/dist/server/handlers/clickhouse.js +157 -109
  312. package/dist/server/handlers/clickhouse.js.map +1 -0
  313. package/dist/server/handlers/comms.d.ts +0 -53
  314. package/dist/server/handlers/comms.js +1443 -970
  315. package/dist/server/handlers/comms.js.map +1 -0
  316. package/dist/server/handlers/creations.js +461 -394
  317. package/dist/server/handlers/creations.js.map +1 -0
  318. package/dist/server/handlers/crm.js +1082 -791
  319. package/dist/server/handlers/crm.js.map +1 -0
  320. package/dist/server/handlers/discovery.js +251 -232
  321. package/dist/server/handlers/discovery.js.map +1 -0
  322. package/dist/server/handlers/embeddings.js +241 -164
  323. package/dist/server/handlers/embeddings.js.map +1 -0
  324. package/dist/server/handlers/enrichment.js +887 -718
  325. package/dist/server/handlers/enrichment.js.map +1 -0
  326. package/dist/server/handlers/image-gen.js +467 -376
  327. package/dist/server/handlers/image-gen.js.map +1 -0
  328. package/dist/server/handlers/inventory.js +797 -424
  329. package/dist/server/handlers/inventory.js.map +1 -0
  330. package/dist/server/handlers/kali.js +272 -230
  331. package/dist/server/handlers/kali.js.map +1 -0
  332. package/dist/server/handlers/llm-providers.js +803 -580
  333. package/dist/server/handlers/llm-providers.js.map +1 -0
  334. package/dist/server/handlers/local-agent.js +133 -105
  335. package/dist/server/handlers/local-agent.js.map +1 -0
  336. package/dist/server/handlers/media.js +1179 -857
  337. package/dist/server/handlers/media.js.map +1 -0
  338. package/dist/server/handlers/meta-ads.js +2669 -2093
  339. package/dist/server/handlers/meta-ads.js.map +1 -0
  340. package/dist/server/handlers/nodes.js +1321 -913
  341. package/dist/server/handlers/nodes.js.map +1 -0
  342. package/dist/server/handlers/operations.js +183 -157
  343. package/dist/server/handlers/operations.js.map +1 -0
  344. package/dist/server/handlers/platform.js +346 -210
  345. package/dist/server/handlers/platform.js.map +1 -0
  346. package/dist/server/handlers/remove-bg.js +118 -86
  347. package/dist/server/handlers/remove-bg.js.map +1 -0
  348. package/dist/server/handlers/storefront.js +586 -446
  349. package/dist/server/handlers/storefront.js.map +1 -0
  350. package/dist/server/handlers/supply-chain.js +546 -326
  351. package/dist/server/handlers/supply-chain.js.map +1 -0
  352. package/dist/server/handlers/transcription.js +106 -97
  353. package/dist/server/handlers/transcription.js.map +1 -0
  354. package/dist/server/handlers/video-gen.js +593 -424
  355. package/dist/server/handlers/video-gen.js.map +1 -0
  356. package/dist/server/handlers/voice.js +1458 -1017
  357. package/dist/server/handlers/voice.js.map +1 -0
  358. package/dist/server/handlers/workflow-steps.js +2837 -2116
  359. package/dist/server/handlers/workflow-steps.js.map +1 -0
  360. package/dist/server/handlers/workflows.js +1630 -933
  361. package/dist/server/handlers/workflows.js.map +1 -0
  362. package/dist/server/index.js +3166 -2390
  363. package/dist/server/index.js.map +1 -0
  364. package/dist/server/lib/batch-client.js +471 -409
  365. package/dist/server/lib/batch-client.js.map +1 -0
  366. package/dist/server/lib/clickhouse-buffer.js +118 -104
  367. package/dist/server/lib/clickhouse-buffer.js.map +1 -0
  368. package/dist/server/lib/clickhouse-client.js +107 -107
  369. package/dist/server/lib/clickhouse-client.js.map +1 -0
  370. package/dist/server/lib/coa-renderer.js +1786 -356
  371. package/dist/server/lib/coa-renderer.js.map +1 -0
  372. package/dist/server/lib/code-worker-pool.js +227 -177
  373. package/dist/server/lib/code-worker-pool.js.map +1 -0
  374. package/dist/server/lib/code-worker.js +174 -164
  375. package/dist/server/lib/code-worker.js.map +1 -0
  376. package/dist/server/lib/compaction-service.d.ts +2 -12
  377. package/dist/server/lib/compaction-service.js +74 -184
  378. package/dist/server/lib/compaction-service.js.map +1 -0
  379. package/dist/server/lib/logger.js +36 -24
  380. package/dist/server/lib/logger.js.map +1 -0
  381. package/dist/server/lib/otel.js +101 -80
  382. package/dist/server/lib/otel.js.map +1 -0
  383. package/dist/server/lib/pdf-renderer.d.ts +1 -1
  384. package/dist/server/lib/pdf-renderer.js +954 -776
  385. package/dist/server/lib/pdf-renderer.js.map +1 -0
  386. package/dist/server/lib/prompt-sanitizer.js +188 -108
  387. package/dist/server/lib/prompt-sanitizer.js.map +1 -0
  388. package/dist/server/lib/provider-capabilities.js +136 -138
  389. package/dist/server/lib/provider-capabilities.js.map +1 -0
  390. package/dist/server/lib/provider-failover.js +190 -168
  391. package/dist/server/lib/provider-failover.js.map +1 -0
  392. package/dist/server/lib/rate-limiter.js +186 -117
  393. package/dist/server/lib/rate-limiter.js.map +1 -0
  394. package/dist/server/lib/react-pdf-layout.js +551 -382
  395. package/dist/server/lib/react-pdf-layout.js.map +1 -0
  396. package/dist/server/lib/server-agent-loop.d.ts +9 -0
  397. package/dist/server/lib/server-agent-loop.js +906 -624
  398. package/dist/server/lib/server-agent-loop.js.map +1 -0
  399. package/dist/server/lib/server-subagent.d.ts +2 -0
  400. package/dist/server/lib/server-subagent.js +260 -162
  401. package/dist/server/lib/server-subagent.js.map +1 -0
  402. package/dist/server/lib/session-checkpoint.js +105 -96
  403. package/dist/server/lib/session-checkpoint.js.map +1 -0
  404. package/dist/server/lib/ssrf-guard.js +193 -184
  405. package/dist/server/lib/ssrf-guard.js.map +1 -0
  406. package/dist/server/lib/supabase-client.js +94 -82
  407. package/dist/server/lib/supabase-client.js.map +1 -0
  408. package/dist/server/lib/template-resolver.js +154 -176
  409. package/dist/server/lib/template-resolver.js.map +1 -0
  410. package/dist/server/lib/utils.js +242 -133
  411. package/dist/server/lib/utils.js.map +1 -0
  412. package/dist/server/local-agent-gateway.d.ts +2 -2
  413. package/dist/server/local-agent-gateway.js +785 -627
  414. package/dist/server/local-agent-gateway.js.map +1 -0
  415. package/dist/server/providers/anthropic.js +254 -176
  416. package/dist/server/providers/anthropic.js.map +1 -0
  417. package/dist/server/providers/bedrock.js +221 -162
  418. package/dist/server/providers/bedrock.js.map +1 -0
  419. package/dist/server/providers/gemini.js +548 -418
  420. package/dist/server/providers/gemini.js.map +1 -0
  421. package/dist/server/providers/openai.js +571 -437
  422. package/dist/server/providers/openai.js.map +1 -0
  423. package/dist/server/providers/registry.js +23 -18
  424. package/dist/server/providers/registry.js.map +1 -0
  425. package/dist/server/providers/shared.js +123 -95
  426. package/dist/server/providers/shared.js.map +1 -0
  427. package/dist/server/providers/types.js +1 -11
  428. package/dist/server/providers/types.js.map +1 -0
  429. package/dist/server/proxy-handlers.js +209 -165
  430. package/dist/server/proxy-handlers.js.map +1 -0
  431. package/dist/server/tool-router.d.ts +13 -0
  432. package/dist/server/tool-router.js +960 -598
  433. package/dist/server/tool-router.js.map +1 -0
  434. package/dist/server/validation.js +248 -188
  435. package/dist/server/validation.js.map +1 -0
  436. package/dist/server/worker.js +202 -133
  437. package/dist/server/worker.js.map +1 -0
  438. package/dist/setup.d.ts +2 -2
  439. package/dist/setup.js +151 -147
  440. package/dist/setup.js.map +1 -0
  441. package/dist/shared/agent-core.d.ts +191 -24
  442. package/dist/shared/agent-core.js +971 -462
  443. package/dist/shared/agent-core.js.map +1 -0
  444. package/dist/shared/anthropic-types.js +1 -6
  445. package/dist/shared/anthropic-types.js.map +1 -0
  446. package/dist/shared/api-client.d.ts +17 -9
  447. package/dist/shared/api-client.js +419 -327
  448. package/dist/shared/api-client.js.map +1 -0
  449. package/dist/shared/compaction.d.ts +36 -0
  450. package/dist/shared/compaction.js +138 -0
  451. package/dist/shared/compaction.js.map +1 -0
  452. package/dist/shared/constants.js +67 -64
  453. package/dist/shared/constants.js.map +1 -0
  454. package/dist/shared/sse-parser.js +221 -219
  455. package/dist/shared/sse-parser.js.map +1 -0
  456. package/dist/shared/tool-dispatch.d.ts +4 -2
  457. package/dist/shared/tool-dispatch.js +226 -165
  458. package/dist/shared/tool-dispatch.js.map +1 -0
  459. package/dist/shared/types.js +1 -6
  460. package/dist/shared/types.js.map +1 -0
  461. package/dist/types/cli-highlight.d.js +2 -0
  462. package/dist/types/cli-highlight.d.js.map +1 -0
  463. package/dist/types/diff.d.js +2 -0
  464. package/dist/types/diff.d.js.map +1 -0
  465. package/dist/types/pdf-parse.d.js +2 -0
  466. package/dist/types/pdf-parse.d.js.map +1 -0
  467. package/dist/updater.d.ts +1 -1
  468. package/dist/updater.js +118 -92
  469. package/dist/updater.js.map +1 -0
  470. package/dist/webchat/widget.js +227 -380
  471. package/dist/webchat/widget.js.map +1 -0
  472. package/package.json +22 -10
  473. package/vendor/ink/build/ansi-tokenizer.d.ts +38 -0
  474. package/vendor/ink/build/ansi-tokenizer.js +316 -0
  475. package/vendor/ink/build/ansi-tokenizer.js.map +1 -0
  476. package/vendor/ink/build/apply-styles.js +175 -0
  477. package/vendor/ink/build/build-layout.js +77 -0
  478. package/vendor/ink/build/calculate-wrapped-text.js +53 -0
  479. package/vendor/ink/build/colorize.d.ts +3 -0
  480. package/vendor/ink/build/colorize.js +48 -0
  481. package/vendor/ink/build/colorize.js.map +1 -0
  482. package/vendor/ink/build/components/AccessibilityContext.d.ts +3 -0
  483. package/vendor/ink/build/components/AccessibilityContext.js +5 -0
  484. package/vendor/ink/build/components/AccessibilityContext.js.map +1 -0
  485. package/vendor/ink/build/components/App.d.ts +18 -0
  486. package/vendor/ink/build/components/App.js +351 -0
  487. package/vendor/ink/build/components/App.js.map +1 -0
  488. package/vendor/ink/build/components/AppContext.d.ts +15 -0
  489. package/vendor/ink/build/components/AppContext.js +11 -0
  490. package/vendor/ink/build/components/AppContext.js.map +1 -0
  491. package/vendor/ink/build/components/BackgroundContext.d.ts +4 -0
  492. package/vendor/ink/build/components/BackgroundContext.js +3 -0
  493. package/vendor/ink/build/components/BackgroundContext.js.map +1 -0
  494. package/vendor/ink/build/components/Box.d.ts +117 -0
  495. package/vendor/ink/build/components/Box.js +34 -0
  496. package/vendor/ink/build/components/Box.js.map +1 -0
  497. package/vendor/ink/build/components/Color.js +62 -0
  498. package/vendor/ink/build/components/Cursor.d.ts +83 -0
  499. package/vendor/ink/build/components/Cursor.js +53 -0
  500. package/vendor/ink/build/components/Cursor.js.map +1 -0
  501. package/vendor/ink/build/components/CursorContext.d.ts +11 -0
  502. package/vendor/ink/build/components/CursorContext.js +8 -0
  503. package/vendor/ink/build/components/CursorContext.js.map +1 -0
  504. package/vendor/ink/build/components/ErrorBoundary.d.ts +18 -0
  505. package/vendor/ink/build/components/ErrorBoundary.js +23 -0
  506. package/vendor/ink/build/components/ErrorBoundary.js.map +1 -0
  507. package/vendor/ink/build/components/ErrorOverview.d.ts +6 -0
  508. package/vendor/ink/build/components/ErrorOverview.js +84 -0
  509. package/vendor/ink/build/components/ErrorOverview.js.map +1 -0
  510. package/vendor/ink/build/components/FocusContext.d.ts +16 -0
  511. package/vendor/ink/build/components/FocusContext.js +17 -0
  512. package/vendor/ink/build/components/FocusContext.js.map +1 -0
  513. package/vendor/ink/build/components/Newline.d.ts +13 -0
  514. package/vendor/ink/build/components/Newline.js +8 -0
  515. package/vendor/ink/build/components/Newline.js.map +1 -0
  516. package/vendor/ink/build/components/Spacer.d.ts +7 -0
  517. package/vendor/ink/build/components/Spacer.js +11 -0
  518. package/vendor/ink/build/components/Spacer.js.map +1 -0
  519. package/vendor/ink/build/components/Static.d.ts +24 -0
  520. package/vendor/ink/build/components/Static.js +28 -0
  521. package/vendor/ink/build/components/Static.js.map +1 -0
  522. package/vendor/ink/build/components/StderrContext.d.ts +15 -0
  523. package/vendor/ink/build/components/StderrContext.js +13 -0
  524. package/vendor/ink/build/components/StderrContext.js.map +1 -0
  525. package/vendor/ink/build/components/StdinContext.d.ts +22 -0
  526. package/vendor/ink/build/components/StdinContext.js +19 -0
  527. package/vendor/ink/build/components/StdinContext.js.map +1 -0
  528. package/vendor/ink/build/components/StdoutContext.d.ts +15 -0
  529. package/vendor/ink/build/components/StdoutContext.js +13 -0
  530. package/vendor/ink/build/components/StdoutContext.js.map +1 -0
  531. package/vendor/ink/build/components/Text.d.ts +55 -0
  532. package/vendor/ink/build/components/Text.js +50 -0
  533. package/vendor/ink/build/components/Text.js.map +1 -0
  534. package/vendor/ink/build/components/Transform.d.ts +16 -0
  535. package/vendor/ink/build/components/Transform.js +15 -0
  536. package/vendor/ink/build/components/Transform.js.map +1 -0
  537. package/vendor/ink/build/cursor-helpers.d.ts +38 -0
  538. package/vendor/ink/build/cursor-helpers.js +56 -0
  539. package/vendor/ink/build/cursor-helpers.js.map +1 -0
  540. package/vendor/ink/build/devtools-window-polyfill.d.ts +1 -0
  541. package/vendor/ink/build/devtools-window-polyfill.js +65 -0
  542. package/vendor/ink/build/devtools-window-polyfill.js.map +1 -0
  543. package/vendor/ink/build/devtools.d.ts +1 -0
  544. package/vendor/ink/build/devtools.js +11 -0
  545. package/vendor/ink/build/devtools.js.map +1 -0
  546. package/vendor/ink/build/dom.d.ts +56 -0
  547. package/vendor/ink/build/dom.js +124 -0
  548. package/vendor/ink/build/dom.js.map +1 -0
  549. package/vendor/ink/build/experimental/apply-style.js +140 -0
  550. package/vendor/ink/build/experimental/dom.js +123 -0
  551. package/vendor/ink/build/experimental/output.js +91 -0
  552. package/vendor/ink/build/experimental/reconciler.js +141 -0
  553. package/vendor/ink/build/experimental/renderer.js +81 -0
  554. package/vendor/ink/build/get-max-width.d.ts +3 -0
  555. package/vendor/ink/build/get-max-width.js +10 -0
  556. package/vendor/ink/build/get-max-width.js.map +1 -0
  557. package/vendor/ink/build/hooks/use-app.d.ts +5 -0
  558. package/vendor/ink/build/hooks/use-app.js +8 -0
  559. package/vendor/ink/build/hooks/use-app.js.map +1 -0
  560. package/vendor/ink/build/hooks/use-cursor.d.ts +12 -0
  561. package/vendor/ink/build/hooks/use-cursor.js +29 -0
  562. package/vendor/ink/build/hooks/use-cursor.js.map +1 -0
  563. package/vendor/ink/build/hooks/use-focus-manager.d.ts +28 -0
  564. package/vendor/ink/build/hooks/use-focus-manager.js +17 -0
  565. package/vendor/ink/build/hooks/use-focus-manager.js.map +1 -0
  566. package/vendor/ink/build/hooks/use-focus.d.ts +29 -0
  567. package/vendor/ink/build/hooks/use-focus.js +42 -0
  568. package/vendor/ink/build/hooks/use-focus.js.map +1 -0
  569. package/vendor/ink/build/hooks/use-input.d.ts +131 -0
  570. package/vendor/ink/build/hooks/use-input.js +124 -0
  571. package/vendor/ink/build/hooks/use-input.js.map +1 -0
  572. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.d.ts +5 -0
  573. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.js +11 -0
  574. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.js.map +1 -0
  575. package/vendor/ink/build/hooks/use-stderr.d.ts +5 -0
  576. package/vendor/ink/build/hooks/use-stderr.js +8 -0
  577. package/vendor/ink/build/hooks/use-stderr.js.map +1 -0
  578. package/vendor/ink/build/hooks/use-stdin.d.ts +5 -0
  579. package/vendor/ink/build/hooks/use-stdin.js +8 -0
  580. package/vendor/ink/build/hooks/use-stdin.js.map +1 -0
  581. package/vendor/ink/build/hooks/use-stdout.d.ts +5 -0
  582. package/vendor/ink/build/hooks/use-stdout.js +8 -0
  583. package/vendor/ink/build/hooks/use-stdout.js.map +1 -0
  584. package/vendor/ink/build/hooks/useInput.js +38 -0
  585. package/vendor/ink/build/index.d.ts +34 -0
  586. package/vendor/ink/build/index.js +20 -0
  587. package/vendor/ink/build/index.js.map +1 -0
  588. package/vendor/ink/build/ink.d.ts +90 -0
  589. package/vendor/ink/build/ink.js +654 -0
  590. package/vendor/ink/build/ink.js.map +1 -0
  591. package/vendor/ink/build/input-parser.d.ts +7 -0
  592. package/vendor/ink/build/input-parser.js +154 -0
  593. package/vendor/ink/build/input-parser.js.map +1 -0
  594. package/vendor/ink/build/instance.js +205 -0
  595. package/vendor/ink/build/instances.d.ts +3 -0
  596. package/vendor/ink/build/instances.js +8 -0
  597. package/vendor/ink/build/instances.js.map +1 -0
  598. package/vendor/ink/build/kitty-keyboard.d.ts +23 -0
  599. package/vendor/ink/build/kitty-keyboard.js +32 -0
  600. package/vendor/ink/build/kitty-keyboard.js.map +1 -0
  601. package/vendor/ink/build/layout.d.ts +7 -0
  602. package/vendor/ink/build/layout.js +33 -0
  603. package/vendor/ink/build/layout.js.map +1 -0
  604. package/vendor/ink/build/log-update.d.ts +19 -0
  605. package/vendor/ink/build/log-update.js +243 -0
  606. package/vendor/ink/build/log-update.js.map +1 -0
  607. package/vendor/ink/build/measure-element.d.ts +16 -0
  608. package/vendor/ink/build/measure-element.js +9 -0
  609. package/vendor/ink/build/measure-element.js.map +1 -0
  610. package/vendor/ink/build/measure-text.d.ts +6 -0
  611. package/vendor/ink/build/measure-text.js +21 -0
  612. package/vendor/ink/build/measure-text.js.map +1 -0
  613. package/vendor/ink/build/options.d.ts +52 -0
  614. package/vendor/ink/build/options.js +2 -0
  615. package/vendor/ink/build/options.js.map +1 -0
  616. package/vendor/ink/build/output.d.ts +35 -0
  617. package/vendor/ink/build/output.js +183 -0
  618. package/vendor/ink/build/output.js.map +1 -0
  619. package/vendor/ink/build/parse-keypress.d.ts +22 -0
  620. package/vendor/ink/build/parse-keypress.js +493 -0
  621. package/vendor/ink/build/parse-keypress.js.map +1 -0
  622. package/vendor/ink/build/reconciler.d.ts +4 -0
  623. package/vendor/ink/build/reconciler.js +274 -0
  624. package/vendor/ink/build/reconciler.js.map +1 -0
  625. package/vendor/ink/build/render-background.d.ts +4 -0
  626. package/vendor/ink/build/render-background.js +25 -0
  627. package/vendor/ink/build/render-background.js.map +1 -0
  628. package/vendor/ink/build/render-border.d.ts +4 -0
  629. package/vendor/ink/build/render-border.js +73 -0
  630. package/vendor/ink/build/render-border.js.map +1 -0
  631. package/vendor/ink/build/render-node-to-output.d.ts +14 -0
  632. package/vendor/ink/build/render-node-to-output.js +147 -0
  633. package/vendor/ink/build/render-node-to-output.js.map +1 -0
  634. package/vendor/ink/build/render-to-string.d.ts +38 -0
  635. package/vendor/ink/build/render-to-string.js +115 -0
  636. package/vendor/ink/build/render-to-string.js.map +1 -0
  637. package/vendor/ink/build/render.d.ts +121 -0
  638. package/vendor/ink/build/render.js +55 -0
  639. package/vendor/ink/build/render.js.map +1 -0
  640. package/vendor/ink/build/renderer.d.ts +8 -0
  641. package/vendor/ink/build/renderer.js +55 -0
  642. package/vendor/ink/build/renderer.js.map +1 -0
  643. package/vendor/ink/build/sanitize-ansi.d.ts +2 -0
  644. package/vendor/ink/build/sanitize-ansi.js +27 -0
  645. package/vendor/ink/build/sanitize-ansi.js.map +1 -0
  646. package/vendor/ink/build/screen-reader-update.d.ts +13 -0
  647. package/vendor/ink/build/screen-reader-update.js +38 -0
  648. package/vendor/ink/build/screen-reader-update.js.map +1 -0
  649. package/vendor/ink/build/squash-text-nodes.d.ts +3 -0
  650. package/vendor/ink/build/squash-text-nodes.js +36 -0
  651. package/vendor/ink/build/squash-text-nodes.js.map +1 -0
  652. package/vendor/ink/build/styles.d.ts +240 -0
  653. package/vendor/ink/build/styles.js +232 -0
  654. package/vendor/ink/build/styles.js.map +1 -0
  655. package/vendor/ink/build/utils.d.ts +2 -0
  656. package/vendor/ink/build/utils.js +4 -0
  657. package/vendor/ink/build/utils.js.map +1 -0
  658. package/vendor/ink/build/wrap-text.d.ts +3 -0
  659. package/vendor/ink/build/wrap-text.js +31 -0
  660. package/vendor/ink/build/wrap-text.js.map +1 -0
  661. package/vendor/ink/build/write-synchronized.d.ts +4 -0
  662. package/vendor/ink/build/write-synchronized.js +7 -0
  663. package/vendor/ink/build/write-synchronized.js.map +1 -0
  664. package/vendor/ink/license +10 -0
  665. package/vendor/ink/node_modules/@types/node/LICENSE +21 -0
  666. package/vendor/ink/node_modules/@types/node/README.md +15 -0
  667. package/vendor/ink/node_modules/@types/node/assert/strict.d.ts +105 -0
  668. package/vendor/ink/node_modules/@types/node/assert.d.ts +955 -0
  669. package/vendor/ink/node_modules/@types/node/async_hooks.d.ts +623 -0
  670. package/vendor/ink/node_modules/@types/node/buffer.buffer.d.ts +466 -0
  671. package/vendor/ink/node_modules/@types/node/buffer.d.ts +1810 -0
  672. package/vendor/ink/node_modules/@types/node/child_process.d.ts +1428 -0
  673. package/vendor/ink/node_modules/@types/node/cluster.d.ts +486 -0
  674. package/vendor/ink/node_modules/@types/node/compatibility/iterators.d.ts +21 -0
  675. package/vendor/ink/node_modules/@types/node/console.d.ts +151 -0
  676. package/vendor/ink/node_modules/@types/node/constants.d.ts +20 -0
  677. package/vendor/ink/node_modules/@types/node/crypto.d.ts +4065 -0
  678. package/vendor/ink/node_modules/@types/node/dgram.d.ts +564 -0
  679. package/vendor/ink/node_modules/@types/node/diagnostics_channel.d.ts +576 -0
  680. package/vendor/ink/node_modules/@types/node/dns/promises.d.ts +503 -0
  681. package/vendor/ink/node_modules/@types/node/dns.d.ts +922 -0
  682. package/vendor/ink/node_modules/@types/node/domain.d.ts +166 -0
  683. package/vendor/ink/node_modules/@types/node/events.d.ts +1054 -0
  684. package/vendor/ink/node_modules/@types/node/fs/promises.d.ts +1329 -0
  685. package/vendor/ink/node_modules/@types/node/fs.d.ts +4676 -0
  686. package/vendor/ink/node_modules/@types/node/globals.d.ts +150 -0
  687. package/vendor/ink/node_modules/@types/node/globals.typedarray.d.ts +101 -0
  688. package/vendor/ink/node_modules/@types/node/http.d.ts +2167 -0
  689. package/vendor/ink/node_modules/@types/node/http2.d.ts +2480 -0
  690. package/vendor/ink/node_modules/@types/node/https.d.ts +405 -0
  691. package/vendor/ink/node_modules/@types/node/index.d.ts +115 -0
  692. package/vendor/ink/node_modules/@types/node/inspector/promises.d.ts +41 -0
  693. package/vendor/ink/node_modules/@types/node/inspector.d.ts +224 -0
  694. package/vendor/ink/node_modules/@types/node/inspector.generated.d.ts +4226 -0
  695. package/vendor/ink/node_modules/@types/node/module.d.ts +819 -0
  696. package/vendor/ink/node_modules/@types/node/net.d.ts +933 -0
  697. package/vendor/ink/node_modules/@types/node/os.d.ts +507 -0
  698. package/vendor/ink/node_modules/@types/node/package.json +155 -0
  699. package/vendor/ink/node_modules/@types/node/path/posix.d.ts +8 -0
  700. package/vendor/ink/node_modules/@types/node/path/win32.d.ts +8 -0
  701. package/vendor/ink/node_modules/@types/node/path.d.ts +187 -0
  702. package/vendor/ink/node_modules/@types/node/perf_hooks.d.ts +643 -0
  703. package/vendor/ink/node_modules/@types/node/process.d.ts +2156 -0
  704. package/vendor/ink/node_modules/@types/node/punycode.d.ts +117 -0
  705. package/vendor/ink/node_modules/@types/node/querystring.d.ts +152 -0
  706. package/vendor/ink/node_modules/@types/node/quic.d.ts +910 -0
  707. package/vendor/ink/node_modules/@types/node/readline/promises.d.ts +161 -0
  708. package/vendor/ink/node_modules/@types/node/readline.d.ts +541 -0
  709. package/vendor/ink/node_modules/@types/node/repl.d.ts +415 -0
  710. package/vendor/ink/node_modules/@types/node/sea.d.ts +162 -0
  711. package/vendor/ink/node_modules/@types/node/sqlite.d.ts +955 -0
  712. package/vendor/ink/node_modules/@types/node/stream/consumers.d.ts +38 -0
  713. package/vendor/ink/node_modules/@types/node/stream/promises.d.ts +211 -0
  714. package/vendor/ink/node_modules/@types/node/stream/web.d.ts +296 -0
  715. package/vendor/ink/node_modules/@types/node/stream.d.ts +1760 -0
  716. package/vendor/ink/node_modules/@types/node/string_decoder.d.ts +67 -0
  717. package/vendor/ink/node_modules/@types/node/test/reporters.d.ts +96 -0
  718. package/vendor/ink/node_modules/@types/node/test.d.ts +2240 -0
  719. package/vendor/ink/node_modules/@types/node/timers/promises.d.ts +108 -0
  720. package/vendor/ink/node_modules/@types/node/timers.d.ts +159 -0
  721. package/vendor/ink/node_modules/@types/node/tls.d.ts +1198 -0
  722. package/vendor/ink/node_modules/@types/node/trace_events.d.ts +197 -0
  723. package/vendor/ink/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +462 -0
  724. package/vendor/ink/node_modules/@types/node/ts5.6/compatibility/float16array.d.ts +71 -0
  725. package/vendor/ink/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +36 -0
  726. package/vendor/ink/node_modules/@types/node/ts5.6/index.d.ts +117 -0
  727. package/vendor/ink/node_modules/@types/node/ts5.7/compatibility/float16array.d.ts +72 -0
  728. package/vendor/ink/node_modules/@types/node/ts5.7/index.d.ts +117 -0
  729. package/vendor/ink/node_modules/@types/node/tty.d.ts +250 -0
  730. package/vendor/ink/node_modules/@types/node/url.d.ts +519 -0
  731. package/vendor/ink/node_modules/@types/node/util/types.d.ts +558 -0
  732. package/vendor/ink/node_modules/@types/node/util.d.ts +1662 -0
  733. package/vendor/ink/node_modules/@types/node/v8.d.ts +983 -0
  734. package/vendor/ink/node_modules/@types/node/vm.d.ts +1208 -0
  735. package/vendor/ink/node_modules/@types/node/wasi.d.ts +202 -0
  736. package/vendor/ink/node_modules/@types/node/web-globals/abortcontroller.d.ts +59 -0
  737. package/vendor/ink/node_modules/@types/node/web-globals/blob.d.ts +23 -0
  738. package/vendor/ink/node_modules/@types/node/web-globals/console.d.ts +9 -0
  739. package/vendor/ink/node_modules/@types/node/web-globals/crypto.d.ts +39 -0
  740. package/vendor/ink/node_modules/@types/node/web-globals/domexception.d.ts +68 -0
  741. package/vendor/ink/node_modules/@types/node/web-globals/encoding.d.ts +11 -0
  742. package/vendor/ink/node_modules/@types/node/web-globals/events.d.ts +106 -0
  743. package/vendor/ink/node_modules/@types/node/web-globals/fetch.d.ts +69 -0
  744. package/vendor/ink/node_modules/@types/node/web-globals/importmeta.d.ts +13 -0
  745. package/vendor/ink/node_modules/@types/node/web-globals/messaging.d.ts +23 -0
  746. package/vendor/ink/node_modules/@types/node/web-globals/navigator.d.ts +25 -0
  747. package/vendor/ink/node_modules/@types/node/web-globals/performance.d.ts +45 -0
  748. package/vendor/ink/node_modules/@types/node/web-globals/storage.d.ts +24 -0
  749. package/vendor/ink/node_modules/@types/node/web-globals/streams.d.ts +115 -0
  750. package/vendor/ink/node_modules/@types/node/web-globals/timers.d.ts +44 -0
  751. package/vendor/ink/node_modules/@types/node/web-globals/url.d.ts +24 -0
  752. package/vendor/ink/node_modules/@types/node/worker_threads.d.ts +717 -0
  753. package/vendor/ink/node_modules/@types/node/zlib.d.ts +618 -0
  754. package/vendor/ink/node_modules/node-pty/LICENSE +69 -0
  755. package/vendor/ink/node_modules/node-pty/README.md +164 -0
  756. package/vendor/ink/node_modules/node-pty/binding.gyp +150 -0
  757. package/vendor/ink/node_modules/node-pty/lib/conpty_console_list_agent.js +25 -0
  758. package/vendor/ink/node_modules/node-pty/lib/eventEmitter2.js +47 -0
  759. package/vendor/ink/node_modules/node-pty/lib/index.js +52 -0
  760. package/vendor/ink/node_modules/node-pty/lib/interfaces.js +7 -0
  761. package/vendor/ink/node_modules/node-pty/lib/shared/conout.js +11 -0
  762. package/vendor/ink/node_modules/node-pty/lib/terminal.js +190 -0
  763. package/vendor/ink/node_modules/node-pty/lib/types.js +7 -0
  764. package/vendor/ink/node_modules/node-pty/lib/unixTerminal.js +349 -0
  765. package/vendor/ink/node_modules/node-pty/lib/utils.js +39 -0
  766. package/vendor/ink/node_modules/node-pty/lib/windowsConoutConnection.js +125 -0
  767. package/vendor/ink/node_modules/node-pty/lib/windowsPtyAgent.js +287 -0
  768. package/vendor/ink/node_modules/node-pty/lib/windowsTerminal.js +201 -0
  769. package/vendor/ink/node_modules/node-pty/lib/worker/conoutSocketWorker.js +22 -0
  770. package/vendor/ink/node_modules/node-pty/package.json +65 -0
  771. package/vendor/ink/node_modules/node-pty/prebuilds/darwin-arm64/pty.node +0 -0
  772. package/vendor/ink/node_modules/node-pty/prebuilds/darwin-arm64/spawn-helper +0 -0
  773. package/vendor/ink/node_modules/node-pty/prebuilds/darwin-x64/pty.node +0 -0
  774. package/vendor/ink/node_modules/node-pty/prebuilds/darwin-x64/spawn-helper +0 -0
  775. package/vendor/ink/node_modules/node-pty/prebuilds/linux-arm64/pty.node +0 -0
  776. package/vendor/ink/node_modules/node-pty/prebuilds/linux-x64/pty.node +0 -0
  777. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty/OpenConsole.exe +0 -0
  778. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty/conpty.dll +0 -0
  779. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty.node +0 -0
  780. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty.pdb +0 -0
  781. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty_console_list.node +0 -0
  782. package/vendor/ink/node_modules/node-pty/prebuilds/win32-arm64/conpty_console_list.pdb +0 -0
  783. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty/OpenConsole.exe +0 -0
  784. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty/conpty.dll +0 -0
  785. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty.node +0 -0
  786. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty.pdb +0 -0
  787. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty_console_list.node +0 -0
  788. package/vendor/ink/node_modules/node-pty/prebuilds/win32-x64/conpty_console_list.pdb +0 -0
  789. package/vendor/ink/node_modules/node-pty/scripts/post-install.js +76 -0
  790. package/vendor/ink/node_modules/node-pty/scripts/prebuild.js +34 -0
  791. package/vendor/ink/node_modules/node-pty/src/unix/pty.cc +875 -0
  792. package/vendor/ink/node_modules/node-pty/src/unix/spawn-helper.cc +23 -0
  793. package/vendor/ink/node_modules/node-pty/src/win/conpty.cc +582 -0
  794. package/vendor/ink/node_modules/node-pty/src/win/conpty.h +41 -0
  795. package/vendor/ink/node_modules/node-pty/src/win/conpty_console_list.cc +44 -0
  796. package/vendor/ink/node_modules/node-pty/src/win/path_util.cc +95 -0
  797. package/vendor/ink/node_modules/node-pty/src/win/path_util.h +26 -0
  798. package/vendor/ink/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-arm64/OpenConsole.exe +0 -0
  799. package/vendor/ink/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-arm64/conpty.dll +0 -0
  800. package/vendor/ink/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-x64/OpenConsole.exe +0 -0
  801. package/vendor/ink/node_modules/node-pty/third_party/conpty/1.23.251008001/win10-x64/conpty.dll +0 -0
  802. package/vendor/ink/node_modules/node-pty/typings/node-pty.d.ts +215 -0
  803. package/vendor/ink/node_modules/undici-types/LICENSE +21 -0
  804. package/vendor/ink/node_modules/undici-types/README.md +6 -0
  805. package/vendor/ink/node_modules/undici-types/agent.d.ts +32 -0
  806. package/vendor/ink/node_modules/undici-types/api.d.ts +43 -0
  807. package/vendor/ink/node_modules/undici-types/balanced-pool.d.ts +30 -0
  808. package/vendor/ink/node_modules/undici-types/cache-interceptor.d.ts +173 -0
  809. package/vendor/ink/node_modules/undici-types/cache.d.ts +36 -0
  810. package/vendor/ink/node_modules/undici-types/client-stats.d.ts +15 -0
  811. package/vendor/ink/node_modules/undici-types/client.d.ts +108 -0
  812. package/vendor/ink/node_modules/undici-types/connector.d.ts +34 -0
  813. package/vendor/ink/node_modules/undici-types/content-type.d.ts +21 -0
  814. package/vendor/ink/node_modules/undici-types/cookies.d.ts +30 -0
  815. package/vendor/ink/node_modules/undici-types/diagnostics-channel.d.ts +74 -0
  816. package/vendor/ink/node_modules/undici-types/dispatcher.d.ts +276 -0
  817. package/vendor/ink/node_modules/undici-types/env-http-proxy-agent.d.ts +22 -0
  818. package/vendor/ink/node_modules/undici-types/errors.d.ts +161 -0
  819. package/vendor/ink/node_modules/undici-types/eventsource.d.ts +66 -0
  820. package/vendor/ink/node_modules/undici-types/fetch.d.ts +211 -0
  821. package/vendor/ink/node_modules/undici-types/formdata.d.ts +108 -0
  822. package/vendor/ink/node_modules/undici-types/global-dispatcher.d.ts +9 -0
  823. package/vendor/ink/node_modules/undici-types/global-origin.d.ts +7 -0
  824. package/vendor/ink/node_modules/undici-types/h2c-client.d.ts +73 -0
  825. package/vendor/ink/node_modules/undici-types/handlers.d.ts +15 -0
  826. package/vendor/ink/node_modules/undici-types/header.d.ts +160 -0
  827. package/vendor/ink/node_modules/undici-types/index.d.ts +88 -0
  828. package/vendor/ink/node_modules/undici-types/interceptors.d.ts +73 -0
  829. package/vendor/ink/node_modules/undici-types/mock-agent.d.ts +68 -0
  830. package/vendor/ink/node_modules/undici-types/mock-call-history.d.ts +111 -0
  831. package/vendor/ink/node_modules/undici-types/mock-client.d.ts +27 -0
  832. package/vendor/ink/node_modules/undici-types/mock-errors.d.ts +12 -0
  833. package/vendor/ink/node_modules/undici-types/mock-interceptor.d.ts +94 -0
  834. package/vendor/ink/node_modules/undici-types/mock-pool.d.ts +27 -0
  835. package/vendor/ink/node_modules/undici-types/package.json +55 -0
  836. package/vendor/ink/node_modules/undici-types/patch.d.ts +29 -0
  837. package/vendor/ink/node_modules/undici-types/pool-stats.d.ts +19 -0
  838. package/vendor/ink/node_modules/undici-types/pool.d.ts +41 -0
  839. package/vendor/ink/node_modules/undici-types/proxy-agent.d.ts +29 -0
  840. package/vendor/ink/node_modules/undici-types/readable.d.ts +68 -0
  841. package/vendor/ink/node_modules/undici-types/retry-agent.d.ts +8 -0
  842. package/vendor/ink/node_modules/undici-types/retry-handler.d.ts +125 -0
  843. package/vendor/ink/node_modules/undici-types/round-robin-pool.d.ts +41 -0
  844. package/vendor/ink/node_modules/undici-types/snapshot-agent.d.ts +109 -0
  845. package/vendor/ink/node_modules/undici-types/util.d.ts +18 -0
  846. package/vendor/ink/node_modules/undici-types/utility.d.ts +7 -0
  847. package/vendor/ink/node_modules/undici-types/webidl.d.ts +341 -0
  848. package/vendor/ink/node_modules/undici-types/websocket.d.ts +186 -0
  849. package/vendor/ink/package.json +201 -0
  850. package/vendor/ink/readme.md +2636 -0
  851. package/bin/swag-agent.js +0 -9
  852. package/dist/server/lib/pg-rate-limiter.d.ts +0 -21
  853. package/dist/server/lib/pg-rate-limiter.js +0 -86
@@ -2,751 +2,920 @@
2
2
  // Integrates with PDL (Person Enrichment), Bright Data (LinkedIn), HIBP (Breach Check),
3
3
  // DeHashed, and xonPlus (real-time breach monitoring).
4
4
  // All external API keys are fetched via decrypt_secret RPC from encrypted store secrets.
5
+
5
6
  // ---- Helpers ----
7
+
6
8
  async function getSecret(sb, name, storeId) {
7
- const { data, error } = await sb.rpc("decrypt_secret", { p_name: name, p_store_id: storeId });
8
- if (error || !data)
9
- return null;
10
- return data;
9
+ const {
10
+ data,
11
+ error
12
+ } = await sb.rpc("decrypt_secret", {
13
+ p_name: name,
14
+ p_store_id: storeId
15
+ });
16
+ if (error || !data) return null;
17
+ return data;
11
18
  }
12
19
  function nowISO() {
13
- return new Date().toISOString();
20
+ return new Date().toISOString();
14
21
  }
22
+
15
23
  // ---- Main Handler ----
24
+
16
25
  export async function handleEnrichment(sb, args, storeId) {
17
- const sid = storeId;
18
- const action = args.action;
19
- if (!action) {
20
- return { success: false, error: "action is required" };
21
- }
22
- switch (action) {
23
- // ---- ENRICH_PERSON: PDL Person Enrichment API ----
24
- case "enrich_person": {
25
- const customerId = args.customer_id;
26
- if (!customerId)
27
- return { success: false, error: "customer_id is required" };
28
- const apiKey = await getSecret(sb, "pdl_api_key", sid);
29
- if (!apiKey)
30
- return { success: false, error: "PDL API key not configured. Add 'pdl_api_key' to store secrets." };
31
- // Build PDL query params from available identifiers
32
- const params = {};
33
- if (args.email)
34
- params.email = args.email;
35
- if (args.phone)
36
- params.phone = args.phone;
37
- if (args.first_name)
38
- params.first_name = args.first_name;
39
- if (args.last_name)
40
- params.last_name = args.last_name;
41
- if (args.linkedin_url)
42
- params.profile = args.linkedin_url;
43
- if (args.location)
44
- params.location = args.location;
45
- if (Object.keys(params).length === 0) {
46
- return { success: false, error: "At least one identifier required: email, phone, first_name+last_name, or linkedin_url" };
47
- }
48
- try {
49
- const queryString = new URLSearchParams(params).toString();
50
- const resp = await fetch(`https://api.peopledatalabs.com/v5/person/enrich?${queryString}`, {
51
- method: "GET",
52
- headers: {
53
- "X-Api-Key": apiKey,
54
- "Accept": "application/json",
55
- },
56
- });
57
- if (!resp.ok) {
58
- const text = await resp.text().catch(() => "");
59
- if (resp.status === 404) {
60
- return { success: true, data: null, error: "No enrichment data found for this person" };
61
- }
62
- return { success: false, error: `PDL API error ${resp.status}: ${text.substring(0, 500)}` };
63
- }
64
- const pdlData = await resp.json();
65
- // Store enrichment profile
66
- const profile = {
67
- customer_id: customerId,
68
- store_id: sid,
69
- enrichment_source: "pdl",
70
- enrichment_data: pdlData,
71
- enriched_at: nowISO(),
72
- updated_at: nowISO(),
73
- };
74
- // Extract common fields if present
75
- if (pdlData.full_name)
76
- profile.full_name = pdlData.full_name;
77
- if (pdlData.job_title)
78
- profile.job_title = pdlData.job_title;
79
- if (pdlData.job_company_name)
80
- profile.company = pdlData.job_company_name;
81
- if (pdlData.linkedin_url)
82
- profile.linkedin_url = pdlData.linkedin_url;
83
- if (pdlData.location_name)
84
- profile.location = pdlData.location_name;
85
- if (pdlData.gender)
86
- profile.gender = pdlData.gender;
87
- if (pdlData.birth_year)
88
- profile.birth_year = pdlData.birth_year;
89
- // Upsert — update if already exists for this customer+store
90
- const { data: existing } = await sb.from("customer_enrichment_profiles")
91
- .select("id")
92
- .eq("customer_id", customerId)
93
- .eq("store_id", sid)
94
- .maybeSingle();
95
- let result;
96
- if (existing) {
97
- const { data, error } = await sb.from("customer_enrichment_profiles")
98
- .update(profile)
99
- .eq("id", existing.id)
100
- .select()
101
- .single();
102
- result = { data, error };
103
- }
104
- else {
105
- profile.created_at = nowISO();
106
- const { data, error } = await sb.from("customer_enrichment_profiles")
107
- .insert(profile)
108
- .select()
109
- .single();
110
- result = { data, error };
111
- }
112
- if (result.error)
113
- return { success: false, error: `Failed to store enrichment: ${result.error.message}` };
114
- return { success: true, data: result.data };
115
- }
116
- catch (err) {
117
- const msg = err instanceof Error ? err.message : String(err);
118
- return { success: false, error: `PDL enrichment failed: ${msg}` };
119
- }
26
+ const sid = storeId;
27
+ const action = args.action;
28
+ if (!action) {
29
+ return {
30
+ success: false,
31
+ error: "action is required"
32
+ };
33
+ }
34
+ switch (action) {
35
+ // ---- ENRICH_PERSON: PDL Person Enrichment API ----
36
+ case "enrich_person":
37
+ {
38
+ const customerId = args.customer_id;
39
+ if (!customerId) return {
40
+ success: false,
41
+ error: "customer_id is required"
42
+ };
43
+ const apiKey = await getSecret(sb, "pdl_api_key", sid);
44
+ if (!apiKey) return {
45
+ success: false,
46
+ error: "PDL API key not configured. Add 'pdl_api_key' to store secrets."
47
+ };
48
+
49
+ // Build PDL query params from available identifiers
50
+ const params = {};
51
+ if (args.email) params.email = args.email;
52
+ if (args.phone) params.phone = args.phone;
53
+ if (args.first_name) params.first_name = args.first_name;
54
+ if (args.last_name) params.last_name = args.last_name;
55
+ if (args.linkedin_url) params.profile = args.linkedin_url;
56
+ if (args.location) params.location = args.location;
57
+ if (Object.keys(params).length === 0) {
58
+ return {
59
+ success: false,
60
+ error: "At least one identifier required: email, phone, first_name+last_name, or linkedin_url"
61
+ };
120
62
  }
121
- // ---- ENRICH_LINKEDIN: Bright Data LinkedIn scraper ----
122
- case "enrich_linkedin": {
123
- const customerId = args.customer_id;
124
- const linkedinUrl = args.linkedin_url;
125
- if (!customerId)
126
- return { success: false, error: "customer_id is required" };
127
- if (!linkedinUrl)
128
- return { success: false, error: "linkedin_url is required" };
129
- const apiKey = await getSecret(sb, "brightdata_api_key", sid);
130
- if (!apiKey)
131
- return { success: false, error: "Bright Data API key not configured. Add 'brightdata_api_key' to store secrets." };
132
- const datasetId = await getSecret(sb, "brightdata_dataset_id", sid) || "gd_l1viktl72bvl7bjuj0";
133
- try {
134
- // Bright Data Scraper API — synchronous LinkedIn profile collection
135
- const resp = await fetch(`https://api.brightdata.com/datasets/v3/scrape?dataset_id=${datasetId}&notify=false&include_errors=true`, {
136
- method: "POST",
137
- headers: {
138
- Authorization: `Bearer ${apiKey}`,
139
- "Content-Type": "application/json",
140
- },
141
- body: JSON.stringify({ input: [{ url: linkedinUrl }] }),
142
- });
143
- if (!resp.ok) {
144
- const text = await resp.text().catch(() => "");
145
- if (resp.status === 404) {
146
- return { success: true, data: null, error: "No LinkedIn profile found at this URL" };
147
- }
148
- return { success: false, error: `Bright Data API error ${resp.status}: ${text.substring(0, 500)}` };
149
- }
150
- const bdResult = await resp.json();
151
- // Bright Data returns an array of results
152
- const profileData = Array.isArray(bdResult) ? bdResult[0] : bdResult;
153
- if (!profileData || profileData.error) {
154
- return { success: true, data: null, error: profileData?.error || "No data returned for this profile" };
155
- }
156
- // Store as enrichment profile with source=brightdata
157
- const profile = {
158
- customer_id: customerId,
159
- store_id: sid,
160
- enrichment_source: "brightdata",
161
- enrichment_data: profileData,
162
- enriched_at: nowISO(),
163
- updated_at: nowISO(),
164
- };
165
- // Extract common fields from Bright Data response
166
- if (profileData.name || profileData.full_name)
167
- profile.full_name = profileData.name || profileData.full_name;
168
- if (profileData.position || profileData.job_title)
169
- profile.job_title = profileData.position || profileData.job_title;
170
- if (profileData.current_company || profileData.company)
171
- profile.company = profileData.current_company || profileData.company;
172
- if (profileData.headline)
173
- profile.headline = profileData.headline;
174
- if (profileData.location)
175
- profile.location = profileData.location;
176
- profile.linkedin_url = linkedinUrl;
177
- // Upsert — update if already exists for this customer+store+source
178
- const { data: existing } = await sb.from("customer_enrichment_profiles")
179
- .select("id")
180
- .eq("customer_id", customerId)
181
- .eq("store_id", sid)
182
- .eq("enrichment_source", "brightdata")
183
- .maybeSingle();
184
- let result;
185
- if (existing) {
186
- const { data, error } = await sb.from("customer_enrichment_profiles")
187
- .update(profile)
188
- .eq("id", existing.id)
189
- .select()
190
- .single();
191
- result = { data, error };
192
- }
193
- else {
194
- profile.created_at = nowISO();
195
- const { data, error } = await sb.from("customer_enrichment_profiles")
196
- .insert(profile)
197
- .select()
198
- .single();
199
- result = { data, error };
200
- }
201
- if (result.error)
202
- return { success: false, error: `Failed to store enrichment: ${result.error.message}` };
203
- return { success: true, data: result.data };
63
+ try {
64
+ const queryString = new URLSearchParams(params).toString();
65
+ const resp = await fetch(`https://api.peopledatalabs.com/v5/person/enrich?${queryString}`, {
66
+ method: "GET",
67
+ headers: {
68
+ "X-Api-Key": apiKey,
69
+ "Accept": "application/json"
204
70
  }
205
- catch (err) {
206
- const msg = err instanceof Error ? err.message : String(err);
207
- return { success: false, error: `Bright Data enrichment failed: ${msg}` };
71
+ });
72
+ if (!resp.ok) {
73
+ const text = await resp.text().catch(() => "");
74
+ if (resp.status === 404) {
75
+ return {
76
+ success: true,
77
+ data: null,
78
+ error: "No enrichment data found for this person"
79
+ };
208
80
  }
81
+ return {
82
+ success: false,
83
+ error: `PDL API error ${resp.status}: ${text.substring(0, 500)}`
84
+ };
85
+ }
86
+ const pdlData = await resp.json();
87
+
88
+ // Store enrichment profile
89
+ const profile = {
90
+ customer_id: customerId,
91
+ store_id: sid,
92
+ enrichment_source: "pdl",
93
+ enrichment_data: pdlData,
94
+ enriched_at: nowISO(),
95
+ updated_at: nowISO()
96
+ };
97
+
98
+ // Extract common fields if present
99
+ if (pdlData.full_name) profile.full_name = pdlData.full_name;
100
+ if (pdlData.job_title) profile.job_title = pdlData.job_title;
101
+ if (pdlData.job_company_name) profile.company = pdlData.job_company_name;
102
+ if (pdlData.linkedin_url) profile.linkedin_url = pdlData.linkedin_url;
103
+ if (pdlData.location_name) profile.location = pdlData.location_name;
104
+ if (pdlData.gender) profile.gender = pdlData.gender;
105
+ if (pdlData.birth_year) profile.birth_year = pdlData.birth_year;
106
+
107
+ // Upsert — update if already exists for this customer+store
108
+ const {
109
+ data: existing
110
+ } = await sb.from("customer_enrichment_profiles").select("id").eq("customer_id", customerId).eq("store_id", sid).maybeSingle();
111
+ let result;
112
+ if (existing) {
113
+ const {
114
+ data,
115
+ error
116
+ } = await sb.from("customer_enrichment_profiles").update(profile).eq("id", existing.id).select().single();
117
+ result = {
118
+ data,
119
+ error
120
+ };
121
+ } else {
122
+ profile.created_at = nowISO();
123
+ const {
124
+ data,
125
+ error
126
+ } = await sb.from("customer_enrichment_profiles").insert(profile).select().single();
127
+ result = {
128
+ data,
129
+ error
130
+ };
131
+ }
132
+ if (result.error) return {
133
+ success: false,
134
+ error: `Failed to store enrichment: ${result.error.message}`
135
+ };
136
+ return {
137
+ success: true,
138
+ data: result.data
139
+ };
140
+ } catch (err) {
141
+ const msg = err instanceof Error ? err.message : String(err);
142
+ return {
143
+ success: false,
144
+ error: `PDL enrichment failed: ${msg}`
145
+ };
209
146
  }
210
- // ---- CHECK_XONPLUS: xonPlus real-time breach monitoring ----
211
- case "check_xonplus": {
212
- const customerId = args.customer_id;
213
- const email = args.email;
214
- if (!customerId)
215
- return { success: false, error: "customer_id is required" };
216
- if (!email)
217
- return { success: false, error: "email is required" };
218
- const apiKey = await getSecret(sb, "xonplus_api_key", sid);
219
- if (!apiKey)
220
- return { success: false, error: "xonPlus API key not configured. Add 'xonplus_api_key' to store secrets." };
221
- try {
222
- const resp = await fetch(`https://api.xposedornot.com/v1/check-email/${encodeURIComponent(email)}`, {
223
- method: "GET",
224
- headers: {
225
- "x-api-key": apiKey,
226
- Accept: "application/json",
227
- },
228
- });
229
- if (!resp.ok) {
230
- const text = await resp.text().catch(() => "");
231
- if (resp.status === 404) {
232
- return { success: true, data: { email, total_breaches: 0, breaches: [] } };
233
- }
234
- return { success: false, error: `xonPlus API error ${resp.status}: ${text.substring(0, 500)}` };
235
- }
236
- const xonData = await resp.json();
237
- const breaches = (xonData.breaches || xonData.ExposedBreaches?.breaches_details || []);
238
- // Store each breach record
239
- const inserted = [];
240
- for (const breach of breaches) {
241
- const record = {
242
- customer_id: customerId,
243
- store_id: sid,
244
- breach_name: breach.breach || breach.name || "unknown",
245
- breach_domain: breach.domain || null,
246
- breach_date: breach.xposed_date || breach.date || null,
247
- data_classes: breach.xposed_data ? breach.xposed_data.split(",").map((s) => s.trim()) : null,
248
- breach_source: "xonplus",
249
- raw_data: breach,
250
- discovered_at: nowISO(),
251
- created_at: nowISO(),
252
- };
253
- // Deduplicate by customer_id + breach_name + breach_source
254
- const { data: existing } = await sb.from("customer_breach_records")
255
- .select("id")
256
- .eq("customer_id", customerId)
257
- .eq("breach_name", record.breach_name)
258
- .eq("breach_source", "xonplus")
259
- .maybeSingle();
260
- if (!existing) {
261
- const { data, error } = await sb.from("customer_breach_records")
262
- .insert(record)
263
- .select()
264
- .single();
265
- if (!error && data)
266
- inserted.push(data);
267
- }
268
- }
269
- return {
270
- success: true,
271
- data: {
272
- email,
273
- total_breaches: breaches.length,
274
- new_breaches: inserted.length,
275
- risk_metrics: xonData.BreachMetrics || null,
276
- breaches: inserted.length > 0 ? inserted : breaches,
277
- },
278
- };
279
- }
280
- catch (err) {
281
- const msg = err instanceof Error ? err.message : String(err);
282
- return { success: false, error: `xonPlus breach check failed: ${msg}` };
147
+ }
148
+
149
+ // ---- ENRICH_LINKEDIN: Bright Data LinkedIn scraper ----
150
+ case "enrich_linkedin":
151
+ {
152
+ const customerId = args.customer_id;
153
+ const linkedinUrl = args.linkedin_url;
154
+ if (!customerId) return {
155
+ success: false,
156
+ error: "customer_id is required"
157
+ };
158
+ if (!linkedinUrl) return {
159
+ success: false,
160
+ error: "linkedin_url is required"
161
+ };
162
+ const apiKey = await getSecret(sb, "brightdata_api_key", sid);
163
+ if (!apiKey) return {
164
+ success: false,
165
+ error: "Bright Data API key not configured. Add 'brightdata_api_key' to store secrets."
166
+ };
167
+ const datasetId = (await getSecret(sb, "brightdata_dataset_id", sid)) || "gd_l1viktl72bvl7bjuj0";
168
+ try {
169
+ // Bright Data Scraper API synchronous LinkedIn profile collection
170
+ const resp = await fetch(`https://api.brightdata.com/datasets/v3/scrape?dataset_id=${datasetId}&notify=false&include_errors=true`, {
171
+ method: "POST",
172
+ headers: {
173
+ Authorization: `Bearer ${apiKey}`,
174
+ "Content-Type": "application/json"
175
+ },
176
+ body: JSON.stringify({
177
+ input: [{
178
+ url: linkedinUrl
179
+ }]
180
+ })
181
+ });
182
+ if (!resp.ok) {
183
+ const text = await resp.text().catch(() => "");
184
+ if (resp.status === 404) {
185
+ return {
186
+ success: true,
187
+ data: null,
188
+ error: "No LinkedIn profile found at this URL"
189
+ };
283
190
  }
191
+ return {
192
+ success: false,
193
+ error: `Bright Data API error ${resp.status}: ${text.substring(0, 500)}`
194
+ };
195
+ }
196
+ const bdResult = await resp.json();
197
+ // Bright Data returns an array of results
198
+ const profileData = Array.isArray(bdResult) ? bdResult[0] : bdResult;
199
+ if (!profileData || profileData.error) {
200
+ return {
201
+ success: true,
202
+ data: null,
203
+ error: profileData?.error || "No data returned for this profile"
204
+ };
205
+ }
206
+
207
+ // Store as enrichment profile with source=brightdata
208
+ const profile = {
209
+ customer_id: customerId,
210
+ store_id: sid,
211
+ enrichment_source: "brightdata",
212
+ enrichment_data: profileData,
213
+ enriched_at: nowISO(),
214
+ updated_at: nowISO()
215
+ };
216
+
217
+ // Extract common fields from Bright Data response
218
+ if (profileData.name || profileData.full_name) profile.full_name = profileData.name || profileData.full_name;
219
+ if (profileData.position || profileData.job_title) profile.job_title = profileData.position || profileData.job_title;
220
+ if (profileData.current_company || profileData.company) profile.company = profileData.current_company || profileData.company;
221
+ if (profileData.headline) profile.headline = profileData.headline;
222
+ if (profileData.location) profile.location = profileData.location;
223
+ profile.linkedin_url = linkedinUrl;
224
+
225
+ // Upsert — update if already exists for this customer+store+source
226
+ const {
227
+ data: existing
228
+ } = await sb.from("customer_enrichment_profiles").select("id").eq("customer_id", customerId).eq("store_id", sid).eq("enrichment_source", "brightdata").maybeSingle();
229
+ let result;
230
+ if (existing) {
231
+ const {
232
+ data,
233
+ error
234
+ } = await sb.from("customer_enrichment_profiles").update(profile).eq("id", existing.id).select().single();
235
+ result = {
236
+ data,
237
+ error
238
+ };
239
+ } else {
240
+ profile.created_at = nowISO();
241
+ const {
242
+ data,
243
+ error
244
+ } = await sb.from("customer_enrichment_profiles").insert(profile).select().single();
245
+ result = {
246
+ data,
247
+ error
248
+ };
249
+ }
250
+ if (result.error) return {
251
+ success: false,
252
+ error: `Failed to store enrichment: ${result.error.message}`
253
+ };
254
+ return {
255
+ success: true,
256
+ data: result.data
257
+ };
258
+ } catch (err) {
259
+ const msg = err instanceof Error ? err.message : String(err);
260
+ return {
261
+ success: false,
262
+ error: `Bright Data enrichment failed: ${msg}`
263
+ };
284
264
  }
285
- // ---- CHECK_BREACHES: HIBP Breach Check ----
286
- case "check_breaches": {
287
- const customerId = args.customer_id;
288
- const email = args.email;
289
- if (!customerId)
290
- return { success: false, error: "customer_id is required" };
291
- if (!email)
292
- return { success: false, error: "email is required" };
293
- const apiKey = await getSecret(sb, "hibp_api_key", sid);
294
- if (!apiKey)
295
- return { success: false, error: "HIBP API key not configured. Add 'hibp_api_key' to store secrets." };
296
- try {
297
- const resp = await fetch(`https://haveibeenpwned.com/api/v3/breachedaccount/${encodeURIComponent(email)}?truncateResponse=false`, {
298
- method: "GET",
299
- headers: {
300
- "hibp-api-key": apiKey,
301
- "User-Agent": "SwagManager-DataProtection",
302
- Accept: "application/json",
303
- },
304
- });
305
- let breaches = [];
306
- if (resp.status === 404) {
307
- // No breaches found — that's good
308
- breaches = [];
309
- }
310
- else if (!resp.ok) {
311
- const text = await resp.text().catch(() => "");
312
- return { success: false, error: `HIBP API error ${resp.status}: ${text.substring(0, 500)}` };
313
- }
314
- else {
315
- breaches = await resp.json();
316
- }
317
- // Store each breach record
318
- const inserted = [];
319
- for (const breach of breaches) {
320
- const record = {
321
- customer_id: customerId,
322
- store_id: sid,
323
- breach_name: breach.Name,
324
- breach_domain: breach.Domain,
325
- breach_date: breach.BreachDate,
326
- data_classes: breach.DataClasses,
327
- description: breach.Description,
328
- is_verified: breach.IsVerified,
329
- breach_source: "hibp",
330
- discovered_at: nowISO(),
331
- created_at: nowISO(),
332
- };
333
- // Upsert by customer_id + breach_name to avoid duplicates
334
- const { data: existing } = await sb.from("customer_breach_records")
335
- .select("id")
336
- .eq("customer_id", customerId)
337
- .eq("breach_name", breach.Name)
338
- .maybeSingle();
339
- if (!existing) {
340
- const { data, error } = await sb.from("customer_breach_records")
341
- .insert(record)
342
- .select()
343
- .single();
344
- if (!error && data)
345
- inserted.push(data);
346
- }
347
- }
348
- return {
349
- success: true,
350
- data: {
351
- email,
352
- total_breaches: breaches.length,
353
- new_breaches: inserted.length,
354
- breaches: inserted.length > 0 ? inserted : breaches,
355
- },
356
- };
265
+ }
266
+
267
+ // ---- CHECK_XONPLUS: xonPlus real-time breach monitoring ----
268
+ case "check_xonplus":
269
+ {
270
+ const customerId = args.customer_id;
271
+ const email = args.email;
272
+ if (!customerId) return {
273
+ success: false,
274
+ error: "customer_id is required"
275
+ };
276
+ if (!email) return {
277
+ success: false,
278
+ error: "email is required"
279
+ };
280
+ const apiKey = await getSecret(sb, "xonplus_api_key", sid);
281
+ if (!apiKey) return {
282
+ success: false,
283
+ error: "xonPlus API key not configured. Add 'xonplus_api_key' to store secrets."
284
+ };
285
+ try {
286
+ const resp = await fetch(`https://api.xposedornot.com/v1/check-email/${encodeURIComponent(email)}`, {
287
+ method: "GET",
288
+ headers: {
289
+ "x-api-key": apiKey,
290
+ Accept: "application/json"
357
291
  }
358
- catch (err) {
359
- const msg = err instanceof Error ? err.message : String(err);
360
- return { success: false, error: `HIBP breach check failed: ${msg}` };
361
- }
362
- }
363
- // ---- CHECK_DEHASHED: DeHashed credential exposure search ----
364
- case "check_dehashed": {
365
- const customerId = args.customer_id;
366
- const email = args.email;
367
- if (!customerId)
368
- return { success: false, error: "customer_id is required" };
369
- if (!email)
370
- return { success: false, error: "email is required" };
371
- const apiKey = await getSecret(sb, "dehashed_api_key", sid);
372
- if (!apiKey)
373
- return { success: false, error: "DeHashed API key not configured. Add 'dehashed_api_key' to store secrets." };
374
- try {
375
- const resp = await fetch("https://api.dehashed.com/v2/search", {
376
- method: "POST",
377
- headers: {
378
- "Content-Type": "application/json",
379
- "DeHashed-Api-Key": apiKey,
380
- },
381
- body: JSON.stringify({
382
- query: `email:"${email}"`,
383
- page: 1,
384
- size: 100,
385
- wildcard: false,
386
- regex: false,
387
- de_dupe: true,
388
- }),
389
- });
390
- if (!resp.ok) {
391
- const text = await resp.text().catch(() => "");
392
- return { success: false, error: `DeHashed API error ${resp.status}: ${text.substring(0, 500)}` };
292
+ });
293
+ if (!resp.ok) {
294
+ const text = await resp.text().catch(() => "");
295
+ if (resp.status === 404) {
296
+ return {
297
+ success: true,
298
+ data: {
299
+ email,
300
+ total_breaches: 0,
301
+ breaches: []
393
302
  }
394
- const result = await resp.json();
395
- const entries = (result.entries || []);
396
- // Store each as a breach record with source=dehashed
397
- const inserted = [];
398
- for (const entry of entries) {
399
- const record = {
400
- customer_id: customerId,
401
- store_id: sid,
402
- breach_name: entry.database_name || "unknown",
403
- breach_domain: entry.domain || null,
404
- breach_date: entry.obtained_date || null,
405
- data_classes: entry.type ? [entry.type] : null,
406
- breach_source: "dehashed",
407
- raw_data: entry,
408
- discovered_at: nowISO(),
409
- created_at: nowISO(),
410
- };
411
- const { data, error } = await sb.from("customer_breach_records")
412
- .insert(record)
413
- .select()
414
- .single();
415
- if (!error && data)
416
- inserted.push(data);
417
- }
418
- return {
419
- success: true,
420
- data: {
421
- email,
422
- total_results: entries.length,
423
- stored: inserted.length,
424
- entries: inserted,
425
- },
426
- };
427
- }
428
- catch (err) {
429
- const msg = err instanceof Error ? err.message : String(err);
430
- return { success: false, error: `DeHashed check failed: ${msg}` };
303
+ };
431
304
  }
432
- }
433
- // ---- GET_ENRICHMENT: Read enrichment profiles ----
434
- case "get_enrichment": {
435
- const customerId = args.customer_id;
436
- if (!customerId)
437
- return { success: false, error: "customer_id is required" };
438
- let q = sb.from("customer_enrichment_profiles")
439
- .select("*")
440
- .eq("customer_id", customerId)
441
- .eq("store_id", sid)
442
- .order("enriched_at", { ascending: false });
443
- if (args.source)
444
- q = q.eq("enrichment_source", args.source);
445
- const limit = args.limit || 10;
446
- q = q.limit(limit);
447
- const { data, error } = await q;
448
- return error
449
- ? { success: false, error: error.message }
450
- : { success: true, data: { count: data?.length, records: data } };
451
- }
452
- // ---- GET_BREACHES: Read breach records ----
453
- case "get_breaches": {
454
- const customerId = args.customer_id;
455
- if (!customerId)
456
- return { success: false, error: "customer_id is required" };
457
- let q = sb.from("customer_breach_records")
458
- .select("*")
459
- .eq("customer_id", customerId)
460
- .eq("store_id", sid)
461
- .order("discovered_at", { ascending: false });
462
- if (args.source)
463
- q = q.eq("breach_source", args.source);
464
- const limit = args.limit || 50;
465
- q = q.limit(limit);
466
- const { data, error } = await q;
467
- return error
468
- ? { success: false, error: error.message }
469
- : { success: true, data: { count: data?.length, records: data } };
470
- }
471
- // ---- GET_EXPOSURES: Read broker exposures ----
472
- case "get_exposures": {
473
- const customerId = args.customer_id;
474
- if (!customerId)
475
- return { success: false, error: "customer_id is required" };
476
- let q = sb.from("customer_exposures")
477
- .select("*")
478
- .eq("customer_id", customerId)
479
- .eq("store_id", sid)
480
- .order("first_seen_at", { ascending: false });
481
- if (args.status)
482
- q = q.eq("status", args.status);
483
- if (args.source_name || args.broker)
484
- q = q.eq("source_name", (args.source_name || args.broker));
485
- const limit = args.limit || 50;
486
- q = q.limit(limit);
487
- const { data, error } = await q;
488
- return error
489
- ? { success: false, error: error.message }
490
- : { success: true, data: { count: data?.length, records: data } };
491
- }
492
- // ---- GET_REMOVAL_STATUS: Read removal requests ----
493
- case "get_removal_status": {
494
- const customerId = args.customer_id;
495
- if (!customerId)
496
- return { success: false, error: "customer_id is required" };
497
- let q = sb.from("customer_removal_requests")
498
- .select("*")
499
- .eq("customer_id", customerId)
500
- .eq("store_id", sid)
501
- .order("created_at", { ascending: false });
502
- if (args.status)
503
- q = q.eq("status", args.status);
504
- const limit = args.limit || 50;
505
- q = q.limit(limit);
506
- const { data, error } = await q;
507
- return error
508
- ? { success: false, error: error.message }
509
- : { success: true, data: { count: data?.length, records: data } };
510
- }
511
- // ---- GET_RISK_SCORE: Read latest risk score ----
512
- case "get_risk_score": {
513
- const customerId = args.customer_id;
514
- if (!customerId)
515
- return { success: false, error: "customer_id is required" };
516
- const { data, error } = await sb.from("customer_risk_scores")
517
- .select("*")
518
- .eq("customer_id", customerId)
519
- .eq("store_id", sid)
520
- .order("calculated_at", { ascending: false })
521
- .limit(1)
522
- .maybeSingle();
523
- return error
524
- ? { success: false, error: error.message }
525
- : { success: true, data };
526
- }
527
- // ---- STORE_SCAN_RESULTS: Insert scan results ----
528
- case "store_scan_results": {
529
- const customerId = args.customer_id;
530
- if (!customerId)
531
- return { success: false, error: "customer_id is required" };
305
+ return {
306
+ success: false,
307
+ error: `xonPlus API error ${resp.status}: ${text.substring(0, 500)}`
308
+ };
309
+ }
310
+ const xonData = await resp.json();
311
+ const breaches = xonData.breaches || xonData.ExposedBreaches?.breaches_details || [];
312
+
313
+ // Store each breach record
314
+ const inserted = [];
315
+ for (const breach of breaches) {
532
316
  const record = {
533
- customer_id: customerId,
534
- store_id: sid,
535
- scan_type: args.scan_type || "discovery",
536
- scan_data: args.scan_data || {},
537
- broker_count: args.broker_count ?? 0,
538
- exposure_count: args.exposure_count ?? 0,
539
- status: args.status || "completed",
540
- created_at: nowISO(),
317
+ customer_id: customerId,
318
+ store_id: sid,
319
+ breach_name: breach.breach || breach.name || "unknown",
320
+ breach_domain: breach.domain || null,
321
+ breach_date: breach.xposed_date || breach.date || null,
322
+ data_classes: breach.xposed_data ? breach.xposed_data.split(",").map(s => s.trim()) : null,
323
+ breach_source: "xonplus",
324
+ raw_data: breach,
325
+ discovered_at: nowISO(),
326
+ created_at: nowISO()
541
327
  };
542
- if (args.scan_id)
543
- record.scan_id = args.scan_id;
544
- if (args.file_path)
545
- record.file_path = args.file_path;
546
- const { data, error } = await sb.from("customer_scan_results")
547
- .insert(record)
548
- .select()
549
- .single();
550
- return error
551
- ? { success: false, error: `Failed to store scan results: ${error.message}` }
552
- : { success: true, data };
328
+
329
+ // Deduplicate by customer_id + breach_name + breach_source
330
+ const {
331
+ data: existing
332
+ } = await sb.from("customer_breach_records").select("id").eq("customer_id", customerId).eq("breach_name", record.breach_name).eq("breach_source", "xonplus").maybeSingle();
333
+ if (!existing) {
334
+ const {
335
+ data,
336
+ error
337
+ } = await sb.from("customer_breach_records").insert(record).select().single();
338
+ if (!error && data) inserted.push(data);
339
+ }
340
+ }
341
+ return {
342
+ success: true,
343
+ data: {
344
+ email,
345
+ total_breaches: breaches.length,
346
+ new_breaches: inserted.length,
347
+ risk_metrics: xonData.BreachMetrics || null,
348
+ breaches: inserted.length > 0 ? inserted : breaches
349
+ }
350
+ };
351
+ } catch (err) {
352
+ const msg = err instanceof Error ? err.message : String(err);
353
+ return {
354
+ success: false,
355
+ error: `xonPlus breach check failed: ${msg}`
356
+ };
553
357
  }
554
- // ---- STORE_EXPOSURE: Insert a broker exposure ----
555
- case "store_exposure": {
556
- const customerId = args.customer_id;
557
- const sourceName = (args.source_name || args.broker);
558
- if (!customerId)
559
- return { success: false, error: "customer_id is required" };
560
- if (!sourceName)
561
- return { success: false, error: "source_name is required" };
562
- // Check for existing exposure to avoid duplicates
563
- const { data: existing } = await sb.from("customer_exposures")
564
- .select("id")
565
- .eq("customer_id", customerId)
566
- .eq("store_id", sid)
567
- .eq("source_name", sourceName)
568
- .maybeSingle();
569
- if (existing) {
570
- // Update existing record
571
- const updates = {};
572
- if (args.source_url)
573
- updates.source_url = args.source_url;
574
- if (args.data_types_exposed)
575
- updates.data_types_exposed = args.data_types_exposed;
576
- if (args.status)
577
- updates.status = args.status;
578
- const { data, error } = await sb.from("customer_exposures")
579
- .update(updates)
580
- .eq("id", existing.id)
581
- .select()
582
- .single();
583
- return error
584
- ? { success: false, error: `Failed to update exposure: ${error.message}` }
585
- : { success: true, data: { ...data, _note: "Updated existing exposure record" } };
358
+ }
359
+
360
+ // ---- CHECK_BREACHES: HIBP Breach Check ----
361
+ case "check_breaches":
362
+ {
363
+ const customerId = args.customer_id;
364
+ const email = args.email;
365
+ if (!customerId) return {
366
+ success: false,
367
+ error: "customer_id is required"
368
+ };
369
+ if (!email) return {
370
+ success: false,
371
+ error: "email is required"
372
+ };
373
+ const apiKey = await getSecret(sb, "hibp_api_key", sid);
374
+ if (!apiKey) return {
375
+ success: false,
376
+ error: "HIBP API key not configured. Add 'hibp_api_key' to store secrets."
377
+ };
378
+ try {
379
+ const resp = await fetch(`https://haveibeenpwned.com/api/v3/breachedaccount/${encodeURIComponent(email)}?truncateResponse=false`, {
380
+ method: "GET",
381
+ headers: {
382
+ "hibp-api-key": apiKey,
383
+ "User-Agent": "WhaleTools-DataProtection",
384
+ Accept: "application/json"
586
385
  }
386
+ });
387
+ let breaches = [];
388
+ if (resp.status === 404) {
389
+ // No breaches found — that's good
390
+ breaches = [];
391
+ } else if (!resp.ok) {
392
+ const text = await resp.text().catch(() => "");
393
+ return {
394
+ success: false,
395
+ error: `HIBP API error ${resp.status}: ${text.substring(0, 500)}`
396
+ };
397
+ } else {
398
+ breaches = await resp.json();
399
+ }
400
+
401
+ // Store each breach record
402
+ const inserted = [];
403
+ for (const breach of breaches) {
587
404
  const record = {
588
- customer_id: customerId,
589
- store_id: sid,
590
- source_name: sourceName,
591
- source_type: args.source_type || "data_broker",
592
- status: args.status || "found",
593
- first_seen_at: nowISO(),
594
- created_at: nowISO(),
405
+ customer_id: customerId,
406
+ store_id: sid,
407
+ breach_name: breach.Name,
408
+ breach_domain: breach.Domain,
409
+ breach_date: breach.BreachDate,
410
+ data_classes: breach.DataClasses,
411
+ description: breach.Description,
412
+ is_verified: breach.IsVerified,
413
+ breach_source: "hibp",
414
+ discovered_at: nowISO(),
415
+ created_at: nowISO()
595
416
  };
596
- if (args.source_url)
597
- record.source_url = args.source_url;
598
- if (args.data_types_exposed)
599
- record.data_types_exposed = args.data_types_exposed;
600
- if (args.scan_id)
601
- record.scan_id = args.scan_id;
602
- const { data, error } = await sb.from("customer_exposures")
603
- .insert(record)
604
- .select()
605
- .single();
606
- return error
607
- ? { success: false, error: `Failed to store exposure: ${error.message}` }
608
- : { success: true, data };
609
- }
610
- // ---- UPDATE_EXPOSURE_STATUS: Update exposure status ----
611
- case "update_exposure_status": {
612
- const exposureId = args.exposure_id;
613
- if (!exposureId)
614
- return { success: false, error: "exposure_id is required" };
615
- const updates = {};
616
- if (args.status)
617
- updates.status = args.status;
618
- if (args.status === "removed") {
619
- updates.removed_at = nowISO();
417
+
418
+ // Upsert by customer_id + breach_name to avoid duplicates
419
+ const {
420
+ data: existing
421
+ } = await sb.from("customer_breach_records").select("id").eq("customer_id", customerId).eq("breach_name", breach.Name).maybeSingle();
422
+ if (!existing) {
423
+ const {
424
+ data,
425
+ error
426
+ } = await sb.from("customer_breach_records").insert(record).select().single();
427
+ if (!error && data) inserted.push(data);
428
+ }
429
+ }
430
+ return {
431
+ success: true,
432
+ data: {
433
+ email,
434
+ total_breaches: breaches.length,
435
+ new_breaches: inserted.length,
436
+ breaches: inserted.length > 0 ? inserted : breaches
620
437
  }
621
- const { data, error } = await sb.from("customer_exposures")
622
- .update(updates)
623
- .eq("id", exposureId)
624
- .eq("store_id", sid)
625
- .select()
626
- .single();
627
- return error
628
- ? { success: false, error: `Failed to update exposure: ${error.message}` }
629
- : { success: true, data };
438
+ };
439
+ } catch (err) {
440
+ const msg = err instanceof Error ? err.message : String(err);
441
+ return {
442
+ success: false,
443
+ error: `HIBP breach check failed: ${msg}`
444
+ };
630
445
  }
631
- // ---- STORE_REMOVAL_REQUEST: Insert a removal request ----
632
- case "store_removal_request": {
633
- const customerId = args.customer_id;
634
- const brokerName = (args.broker_name || args.source_name || args.broker);
635
- if (!customerId)
636
- return { success: false, error: "customer_id is required" };
637
- if (!brokerName)
638
- return { success: false, error: "source_name is required" };
446
+ }
447
+
448
+ // ---- CHECK_DEHASHED: DeHashed credential exposure search ----
449
+ case "check_dehashed":
450
+ {
451
+ const customerId = args.customer_id;
452
+ const email = args.email;
453
+ if (!customerId) return {
454
+ success: false,
455
+ error: "customer_id is required"
456
+ };
457
+ if (!email) return {
458
+ success: false,
459
+ error: "email is required"
460
+ };
461
+ const apiKey = await getSecret(sb, "dehashed_api_key", sid);
462
+ if (!apiKey) return {
463
+ success: false,
464
+ error: "DeHashed API key not configured. Add 'dehashed_api_key' to store secrets."
465
+ };
466
+ try {
467
+ const resp = await fetch("https://api.dehashed.com/v2/search", {
468
+ method: "POST",
469
+ headers: {
470
+ "Content-Type": "application/json",
471
+ "DeHashed-Api-Key": apiKey
472
+ },
473
+ body: JSON.stringify({
474
+ query: `email:"${email}"`,
475
+ page: 1,
476
+ size: 100,
477
+ wildcard: false,
478
+ regex: false,
479
+ de_dupe: true
480
+ })
481
+ });
482
+ if (!resp.ok) {
483
+ const text = await resp.text().catch(() => "");
484
+ return {
485
+ success: false,
486
+ error: `DeHashed API error ${resp.status}: ${text.substring(0, 500)}`
487
+ };
488
+ }
489
+ const result = await resp.json();
490
+ const entries = result.entries || [];
491
+
492
+ // Store each as a breach record with source=dehashed
493
+ const inserted = [];
494
+ for (const entry of entries) {
639
495
  const record = {
640
- customer_id: customerId,
641
- store_id: sid,
642
- broker_name: brokerName,
643
- removal_method: args.removal_method || args.method || "manual",
644
- status: args.status || "pending",
645
- created_at: nowISO(),
646
- updated_at: nowISO(),
496
+ customer_id: customerId,
497
+ store_id: sid,
498
+ breach_name: entry.database_name || "unknown",
499
+ breach_domain: entry.domain || null,
500
+ breach_date: entry.obtained_date || null,
501
+ data_classes: entry.type ? [entry.type] : null,
502
+ breach_source: "dehashed",
503
+ raw_data: entry,
504
+ discovered_at: nowISO(),
505
+ created_at: nowISO()
647
506
  };
648
- if (args.exposure_id)
649
- record.exposure_id = args.exposure_id;
650
- if (args.request_data)
651
- record.request_data = args.request_data;
652
- if (args.submitted_at)
653
- record.submitted_at = args.submitted_at;
654
- if (args.confirmation_id)
655
- record.confirmation_id = args.confirmation_id;
656
- const { data, error } = await sb.from("customer_removal_requests")
657
- .insert(record)
658
- .select()
659
- .single();
660
- return error
661
- ? { success: false, error: `Failed to store removal request: ${error.message}` }
662
- : { success: true, data };
507
+ const {
508
+ data,
509
+ error
510
+ } = await sb.from("customer_breach_records").insert(record).select().single();
511
+ if (!error && data) inserted.push(data);
512
+ }
513
+ return {
514
+ success: true,
515
+ data: {
516
+ email,
517
+ total_results: entries.length,
518
+ stored: inserted.length,
519
+ entries: inserted
520
+ }
521
+ };
522
+ } catch (err) {
523
+ const msg = err instanceof Error ? err.message : String(err);
524
+ return {
525
+ success: false,
526
+ error: `DeHashed check failed: ${msg}`
527
+ };
663
528
  }
664
- // ---- CALCULATE_RISK_SCORE: Compute and store a risk score ----
665
- case "calculate_risk_score": {
666
- const customerId = args.customer_id;
667
- if (!customerId)
668
- return { success: false, error: "customer_id is required" };
669
- // Gather data for risk calculation
670
- const [exposuresResult, breachesResult, removalsResult] = await Promise.all([
671
- sb.from("customer_exposures")
672
- .select("id, source_name, status")
673
- .eq("customer_id", customerId)
674
- .eq("store_id", sid),
675
- sb.from("customer_breach_records")
676
- .select("id, breach_name, data_classes, is_verified")
677
- .eq("customer_id", customerId)
678
- .eq("store_id", sid),
679
- sb.from("customer_removal_requests")
680
- .select("id, status, broker_name")
681
- .eq("customer_id", customerId)
682
- .eq("store_id", sid),
683
- ]);
684
- const exposures = exposuresResult.data || [];
685
- const breaches = breachesResult.data || [];
686
- const removals = removalsResult.data || [];
687
- // Score calculation:
688
- // - Each active exposure: +10 points
689
- // - Each removed exposure: -5 points (still contributes slightly)
690
- // - Each breach: +15 points
691
- // - Each sensitive breach: +25 points (instead of 15)
692
- // - Each verified breach: +5 bonus
693
- // - Each completed removal: -8 points
694
- // - Base floor: 0, cap: 100
695
- let score = 0;
696
- // Exposure scoring
697
- const activeExposures = exposures.filter((e) => e.status !== "removed");
698
- const removedExposures = exposures.filter((e) => e.status === "removed");
699
- score += activeExposures.length * 10;
700
- score += removedExposures.length * 2;
701
- // Breach scoring
702
- for (const breach of breaches) {
703
- score += 15;
704
- if (breach.is_verified) {
705
- score += 5;
706
- }
529
+ }
530
+
531
+ // ---- GET_ENRICHMENT: Read enrichment profiles ----
532
+ case "get_enrichment":
533
+ {
534
+ const customerId = args.customer_id;
535
+ if (!customerId) return {
536
+ success: false,
537
+ error: "customer_id is required"
538
+ };
539
+ let q = sb.from("customer_enrichment_profiles").select("*").eq("customer_id", customerId).eq("store_id", sid).order("enriched_at", {
540
+ ascending: false
541
+ });
542
+ if (args.source) q = q.eq("enrichment_source", args.source);
543
+ const limit = args.limit || 10;
544
+ q = q.limit(limit);
545
+ const {
546
+ data,
547
+ error
548
+ } = await q;
549
+ return error ? {
550
+ success: false,
551
+ error: error.message
552
+ } : {
553
+ success: true,
554
+ data: {
555
+ count: data?.length,
556
+ records: data
557
+ }
558
+ };
559
+ }
560
+
561
+ // ---- GET_BREACHES: Read breach records ----
562
+ case "get_breaches":
563
+ {
564
+ const customerId = args.customer_id;
565
+ if (!customerId) return {
566
+ success: false,
567
+ error: "customer_id is required"
568
+ };
569
+ let q = sb.from("customer_breach_records").select("*").eq("customer_id", customerId).eq("store_id", sid).order("discovered_at", {
570
+ ascending: false
571
+ });
572
+ if (args.source) q = q.eq("breach_source", args.source);
573
+ const limit = args.limit || 50;
574
+ q = q.limit(limit);
575
+ const {
576
+ data,
577
+ error
578
+ } = await q;
579
+ return error ? {
580
+ success: false,
581
+ error: error.message
582
+ } : {
583
+ success: true,
584
+ data: {
585
+ count: data?.length,
586
+ records: data
587
+ }
588
+ };
589
+ }
590
+
591
+ // ---- GET_EXPOSURES: Read broker exposures ----
592
+ case "get_exposures":
593
+ {
594
+ const customerId = args.customer_id;
595
+ if (!customerId) return {
596
+ success: false,
597
+ error: "customer_id is required"
598
+ };
599
+ let q = sb.from("customer_exposures").select("*").eq("customer_id", customerId).eq("store_id", sid).order("first_seen_at", {
600
+ ascending: false
601
+ });
602
+ if (args.status) q = q.eq("status", args.status);
603
+ if (args.source_name || args.broker) q = q.eq("source_name", args.source_name || args.broker);
604
+ const limit = args.limit || 50;
605
+ q = q.limit(limit);
606
+ const {
607
+ data,
608
+ error
609
+ } = await q;
610
+ return error ? {
611
+ success: false,
612
+ error: error.message
613
+ } : {
614
+ success: true,
615
+ data: {
616
+ count: data?.length,
617
+ records: data
618
+ }
619
+ };
620
+ }
621
+
622
+ // ---- GET_REMOVAL_STATUS: Read removal requests ----
623
+ case "get_removal_status":
624
+ {
625
+ const customerId = args.customer_id;
626
+ if (!customerId) return {
627
+ success: false,
628
+ error: "customer_id is required"
629
+ };
630
+ let q = sb.from("customer_removal_requests").select("*").eq("customer_id", customerId).eq("store_id", sid).order("created_at", {
631
+ ascending: false
632
+ });
633
+ if (args.status) q = q.eq("status", args.status);
634
+ const limit = args.limit || 50;
635
+ q = q.limit(limit);
636
+ const {
637
+ data,
638
+ error
639
+ } = await q;
640
+ return error ? {
641
+ success: false,
642
+ error: error.message
643
+ } : {
644
+ success: true,
645
+ data: {
646
+ count: data?.length,
647
+ records: data
648
+ }
649
+ };
650
+ }
651
+
652
+ // ---- GET_RISK_SCORE: Read latest risk score ----
653
+ case "get_risk_score":
654
+ {
655
+ const customerId = args.customer_id;
656
+ if (!customerId) return {
657
+ success: false,
658
+ error: "customer_id is required"
659
+ };
660
+ const {
661
+ data,
662
+ error
663
+ } = await sb.from("customer_risk_scores").select("*").eq("customer_id", customerId).eq("store_id", sid).order("calculated_at", {
664
+ ascending: false
665
+ }).limit(1).maybeSingle();
666
+ return error ? {
667
+ success: false,
668
+ error: error.message
669
+ } : {
670
+ success: true,
671
+ data
672
+ };
673
+ }
674
+
675
+ // ---- STORE_SCAN_RESULTS: Insert scan results ----
676
+ case "store_scan_results":
677
+ {
678
+ const customerId = args.customer_id;
679
+ if (!customerId) return {
680
+ success: false,
681
+ error: "customer_id is required"
682
+ };
683
+ const record = {
684
+ customer_id: customerId,
685
+ store_id: sid,
686
+ scan_type: args.scan_type || "discovery",
687
+ scan_data: args.scan_data || {},
688
+ broker_count: args.broker_count ?? 0,
689
+ exposure_count: args.exposure_count ?? 0,
690
+ status: args.status || "completed",
691
+ created_at: nowISO()
692
+ };
693
+ if (args.scan_id) record.scan_id = args.scan_id;
694
+ if (args.file_path) record.file_path = args.file_path;
695
+ const {
696
+ data,
697
+ error
698
+ } = await sb.from("customer_scan_results").insert(record).select().single();
699
+ return error ? {
700
+ success: false,
701
+ error: `Failed to store scan results: ${error.message}`
702
+ } : {
703
+ success: true,
704
+ data
705
+ };
706
+ }
707
+
708
+ // ---- STORE_EXPOSURE: Insert a broker exposure ----
709
+ case "store_exposure":
710
+ {
711
+ const customerId = args.customer_id;
712
+ const sourceName = args.source_name || args.broker;
713
+ if (!customerId) return {
714
+ success: false,
715
+ error: "customer_id is required"
716
+ };
717
+ if (!sourceName) return {
718
+ success: false,
719
+ error: "source_name is required"
720
+ };
721
+
722
+ // Check for existing exposure to avoid duplicates
723
+ const {
724
+ data: existing
725
+ } = await sb.from("customer_exposures").select("id").eq("customer_id", customerId).eq("store_id", sid).eq("source_name", sourceName).maybeSingle();
726
+ if (existing) {
727
+ // Update existing record
728
+ const updates = {};
729
+ if (args.source_url) updates.source_url = args.source_url;
730
+ if (args.data_types_exposed) updates.data_types_exposed = args.data_types_exposed;
731
+ if (args.status) updates.status = args.status;
732
+ const {
733
+ data,
734
+ error
735
+ } = await sb.from("customer_exposures").update(updates).eq("id", existing.id).select().single();
736
+ return error ? {
737
+ success: false,
738
+ error: `Failed to update exposure: ${error.message}`
739
+ } : {
740
+ success: true,
741
+ data: {
742
+ ...data,
743
+ _note: "Updated existing exposure record"
707
744
  }
708
- // Removal credit
709
- const completedRemovals = removals.filter((r) => r.status === "completed" || r.status === "confirmed");
710
- score -= completedRemovals.length * 8;
711
- // Clamp to 0-100
712
- score = Math.max(0, Math.min(100, score));
713
- // Determine risk level
714
- let riskLevel;
715
- if (score >= 75)
716
- riskLevel = "critical";
717
- else if (score >= 50)
718
- riskLevel = "high";
719
- else if (score >= 25)
720
- riskLevel = "medium";
721
- else
722
- riskLevel = "low";
723
- const riskRecord = {
724
- customer_id: customerId,
725
- store_id: sid,
726
- overall_score: score,
727
- risk_level: riskLevel,
728
- factors: {
729
- active_exposures: activeExposures.length,
730
- removed_exposures: removedExposures.length,
731
- total_breaches: breaches.length,
732
- completed_removals: completedRemovals.length,
733
- pending_removals: removals.filter((r) => r.status === "pending").length,
734
- },
735
- calculated_at: nowISO(),
736
- created_at: nowISO(),
737
- };
738
- const { data, error } = await sb.from("customer_risk_scores")
739
- .insert(riskRecord)
740
- .select()
741
- .single();
742
- return error
743
- ? { success: false, error: `Failed to store risk score: ${error.message}` }
744
- : { success: true, data };
745
+ };
745
746
  }
746
- default:
747
- return {
748
- success: false,
749
- error: `Unknown enrichment action: ${action}. Valid: enrich_person, enrich_linkedin, check_breaches, check_dehashed, check_xonplus, get_enrichment, get_breaches, get_exposures, get_removal_status, get_risk_score, store_scan_results, store_exposure, update_exposure_status, store_removal_request, calculate_risk_score`,
750
- };
751
- }
747
+ const record = {
748
+ customer_id: customerId,
749
+ store_id: sid,
750
+ source_name: sourceName,
751
+ source_type: args.source_type || "data_broker",
752
+ status: args.status || "found",
753
+ first_seen_at: nowISO(),
754
+ created_at: nowISO()
755
+ };
756
+ if (args.source_url) record.source_url = args.source_url;
757
+ if (args.data_types_exposed) record.data_types_exposed = args.data_types_exposed;
758
+ if (args.scan_id) record.scan_id = args.scan_id;
759
+ const {
760
+ data,
761
+ error
762
+ } = await sb.from("customer_exposures").insert(record).select().single();
763
+ return error ? {
764
+ success: false,
765
+ error: `Failed to store exposure: ${error.message}`
766
+ } : {
767
+ success: true,
768
+ data
769
+ };
770
+ }
771
+
772
+ // ---- UPDATE_EXPOSURE_STATUS: Update exposure status ----
773
+ case "update_exposure_status":
774
+ {
775
+ const exposureId = args.exposure_id;
776
+ if (!exposureId) return {
777
+ success: false,
778
+ error: "exposure_id is required"
779
+ };
780
+ const updates = {};
781
+ if (args.status) updates.status = args.status;
782
+ if (args.status === "removed") {
783
+ updates.removed_at = nowISO();
784
+ }
785
+ const {
786
+ data,
787
+ error
788
+ } = await sb.from("customer_exposures").update(updates).eq("id", exposureId).eq("store_id", sid).select().single();
789
+ return error ? {
790
+ success: false,
791
+ error: `Failed to update exposure: ${error.message}`
792
+ } : {
793
+ success: true,
794
+ data
795
+ };
796
+ }
797
+
798
+ // ---- STORE_REMOVAL_REQUEST: Insert a removal request ----
799
+ case "store_removal_request":
800
+ {
801
+ const customerId = args.customer_id;
802
+ const brokerName = args.broker_name || args.source_name || args.broker;
803
+ if (!customerId) return {
804
+ success: false,
805
+ error: "customer_id is required"
806
+ };
807
+ if (!brokerName) return {
808
+ success: false,
809
+ error: "source_name is required"
810
+ };
811
+ const record = {
812
+ customer_id: customerId,
813
+ store_id: sid,
814
+ broker_name: brokerName,
815
+ removal_method: args.removal_method || args.method || "manual",
816
+ status: args.status || "pending",
817
+ created_at: nowISO(),
818
+ updated_at: nowISO()
819
+ };
820
+ if (args.exposure_id) record.exposure_id = args.exposure_id;
821
+ if (args.request_data) record.request_data = args.request_data;
822
+ if (args.submitted_at) record.submitted_at = args.submitted_at;
823
+ if (args.confirmation_id) record.confirmation_id = args.confirmation_id;
824
+ const {
825
+ data,
826
+ error
827
+ } = await sb.from("customer_removal_requests").insert(record).select().single();
828
+ return error ? {
829
+ success: false,
830
+ error: `Failed to store removal request: ${error.message}`
831
+ } : {
832
+ success: true,
833
+ data
834
+ };
835
+ }
836
+
837
+ // ---- CALCULATE_RISK_SCORE: Compute and store a risk score ----
838
+ case "calculate_risk_score":
839
+ {
840
+ const customerId = args.customer_id;
841
+ if (!customerId) return {
842
+ success: false,
843
+ error: "customer_id is required"
844
+ };
845
+
846
+ // Gather data for risk calculation
847
+ const [exposuresResult, breachesResult, removalsResult] = await Promise.all([sb.from("customer_exposures").select("id, source_name, status").eq("customer_id", customerId).eq("store_id", sid), sb.from("customer_breach_records").select("id, breach_name, data_classes, is_verified").eq("customer_id", customerId).eq("store_id", sid), sb.from("customer_removal_requests").select("id, status, broker_name").eq("customer_id", customerId).eq("store_id", sid)]);
848
+ const exposures = exposuresResult.data || [];
849
+ const breaches = breachesResult.data || [];
850
+ const removals = removalsResult.data || [];
851
+
852
+ // Score calculation:
853
+ // - Each active exposure: +10 points
854
+ // - Each removed exposure: -5 points (still contributes slightly)
855
+ // - Each breach: +15 points
856
+ // - Each sensitive breach: +25 points (instead of 15)
857
+ // - Each verified breach: +5 bonus
858
+ // - Each completed removal: -8 points
859
+ // - Base floor: 0, cap: 100
860
+
861
+ let score = 0;
862
+
863
+ // Exposure scoring
864
+ const activeExposures = exposures.filter(e => e.status !== "removed");
865
+ const removedExposures = exposures.filter(e => e.status === "removed");
866
+ score += activeExposures.length * 10;
867
+ score += removedExposures.length * 2;
868
+
869
+ // Breach scoring
870
+ for (const breach of breaches) {
871
+ score += 15;
872
+ if (breach.is_verified) {
873
+ score += 5;
874
+ }
875
+ }
876
+
877
+ // Removal credit
878
+ const completedRemovals = removals.filter(r => r.status === "completed" || r.status === "confirmed");
879
+ score -= completedRemovals.length * 8;
880
+
881
+ // Clamp to 0-100
882
+ score = Math.max(0, Math.min(100, score));
883
+
884
+ // Determine risk level
885
+ let riskLevel;
886
+ if (score >= 75) riskLevel = "critical";else if (score >= 50) riskLevel = "high";else if (score >= 25) riskLevel = "medium";else riskLevel = "low";
887
+ const riskRecord = {
888
+ customer_id: customerId,
889
+ store_id: sid,
890
+ overall_score: score,
891
+ risk_level: riskLevel,
892
+ factors: {
893
+ active_exposures: activeExposures.length,
894
+ removed_exposures: removedExposures.length,
895
+ total_breaches: breaches.length,
896
+ completed_removals: completedRemovals.length,
897
+ pending_removals: removals.filter(r => r.status === "pending").length
898
+ },
899
+ calculated_at: nowISO(),
900
+ created_at: nowISO()
901
+ };
902
+ const {
903
+ data,
904
+ error
905
+ } = await sb.from("customer_risk_scores").insert(riskRecord).select().single();
906
+ return error ? {
907
+ success: false,
908
+ error: `Failed to store risk score: ${error.message}`
909
+ } : {
910
+ success: true,
911
+ data
912
+ };
913
+ }
914
+ default:
915
+ return {
916
+ success: false,
917
+ error: `Unknown enrichment action: ${action}. Valid: enrich_person, enrich_linkedin, check_breaches, check_dehashed, check_xonplus, get_enrichment, get_breaches, get_exposures, get_removal_status, get_risk_score, store_scan_results, store_exposure, update_exposure_status, store_removal_request, calculate_risk_score`
918
+ };
919
+ }
752
920
  }
921
+ //# sourceMappingURL=enrichment.js.map