@vellumai/assistant 0.7.0 → 0.7.1

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 (666) hide show
  1. package/ARCHITECTURE.md +6 -7
  2. package/Dockerfile +1 -0
  3. package/README.md +2 -2
  4. package/__tests__/permissions/gateway-threshold-reader.test.ts +79 -139
  5. package/bun.lock +3 -0
  6. package/docs/architecture/security.md +18 -16
  7. package/knip.json +1 -0
  8. package/node_modules/@vellumai/skill-host-contracts/__tests__/client.test.ts +1 -5
  9. package/node_modules/@vellumai/skill-host-contracts/src/assistant-event.ts +0 -5
  10. package/node_modules/@vellumai/skill-host-contracts/src/client.ts +10 -16
  11. package/node_modules/@vellumai/skill-host-contracts/src/skill-host.ts +1 -9
  12. package/node_modules/@vellumai/skill-host-contracts/src/tool-types.ts +12 -12
  13. package/node_modules/@vellumai/slack-text/bun.lock +24 -0
  14. package/node_modules/@vellumai/slack-text/package.json +18 -0
  15. package/node_modules/@vellumai/slack-text/src/index.test.ts +153 -0
  16. package/node_modules/@vellumai/slack-text/src/index.ts +235 -0
  17. package/node_modules/@vellumai/slack-text/tsconfig.json +20 -0
  18. package/openapi.yaml +294 -107
  19. package/package.json +4 -2
  20. package/scripts/generate-openapi.ts +16 -111
  21. package/src/__tests__/agent-wake-override-profile.test.ts +23 -1
  22. package/src/__tests__/anthropic-provider.test.ts +56 -13
  23. package/src/__tests__/app-conversation-ids-backfill.test.ts +278 -0
  24. package/src/__tests__/app-conversation-ids.test.ts +151 -0
  25. package/src/__tests__/approval-cascade.test.ts +0 -15
  26. package/src/__tests__/approval-routes-http.test.ts +6 -17
  27. package/src/__tests__/assistant-event-hub.test.ts +126 -77
  28. package/src/__tests__/assistant-event.test.ts +0 -5
  29. package/src/__tests__/assistant-events-sse-hardening.test.ts +37 -15
  30. package/src/__tests__/assistant-feature-flags-integration.test.ts +0 -29
  31. package/src/__tests__/background-shell-host-bash.test.ts +34 -43
  32. package/src/__tests__/call-controller.test.ts +1 -1
  33. package/src/__tests__/call-site-routing-provider.test.ts +193 -0
  34. package/src/__tests__/channel-approval-routes.test.ts +10 -296
  35. package/src/__tests__/channel-approvals.test.ts +25 -17
  36. package/src/__tests__/channel-guardian.test.ts +100 -146
  37. package/src/__tests__/checker.test.ts +20 -34
  38. package/src/__tests__/compact-event-conversation-id-guard.test.ts +50 -0
  39. package/src/__tests__/compaction-events.test.ts +2 -0
  40. package/src/__tests__/config-schema.test.ts +6 -48
  41. package/src/__tests__/config-watcher.test.ts +12 -0
  42. package/src/__tests__/connection-policy.test.ts +1 -52
  43. package/src/__tests__/contacts-write.test.ts +2 -64
  44. package/src/__tests__/context-image-dimensions.test.ts +1 -1
  45. package/src/__tests__/context-search-memory-source.test.ts +120 -1
  46. package/src/__tests__/context-search-memory-v2-source.test.ts +383 -0
  47. package/src/__tests__/context-search-pkb-source.test.ts +49 -0
  48. package/src/__tests__/context-search-workspace-source.test.ts +9 -22
  49. package/src/__tests__/context-window-manager.test.ts +46 -0
  50. package/src/__tests__/conversation-agent-loop-inference-profile.test.ts +2 -0
  51. package/src/__tests__/conversation-agent-loop-overflow.test.ts +102 -29
  52. package/src/__tests__/conversation-agent-loop.test.ts +980 -13
  53. package/src/__tests__/conversation-analysis-routes.test.ts +12 -10
  54. package/src/__tests__/conversation-attention-telegram.test.ts +11 -3
  55. package/src/__tests__/conversation-confirmation-signals.test.ts +0 -291
  56. package/src/__tests__/conversation-history-web-search.test.ts +4 -3
  57. package/src/__tests__/conversation-inference-profile-route.test.ts +12 -23
  58. package/src/__tests__/conversation-lifecycle.test.ts +4 -4
  59. package/src/__tests__/conversation-process-callsite.test.ts +79 -2
  60. package/src/__tests__/conversation-queue.test.ts +3 -8
  61. package/src/__tests__/conversation-routes-disk-view.test.ts +1 -161
  62. package/src/__tests__/conversation-routes-guardian-reply.test.ts +0 -32
  63. package/src/__tests__/conversation-routes-slash-commands.test.ts +75 -66
  64. package/src/__tests__/conversation-runtime-assembly.test.ts +257 -3
  65. package/src/__tests__/conversation-slash-commands.test.ts +24 -4
  66. package/src/__tests__/conversation-slash-queue.test.ts +2 -0
  67. package/src/__tests__/conversation-speed-override.test.ts +0 -3
  68. package/src/__tests__/conversation-starter-routes.test.ts +79 -2
  69. package/src/__tests__/conversation-surfaces-standalone-payloads.test.ts +12 -5
  70. package/src/__tests__/conversation-surfaces-standalone.test.ts +18 -14
  71. package/src/__tests__/conversation-surfaces-state-update.test.ts +3 -2
  72. package/src/__tests__/conversation-tool-setup-app-refresh.test.ts +8 -46
  73. package/src/__tests__/conversation-usage.test.ts +253 -3
  74. package/src/__tests__/credential-execution-shell-lockdown.test.ts +0 -39
  75. package/src/__tests__/credential-health-service.test.ts +68 -0
  76. package/src/__tests__/credential-security-e2e.test.ts +4 -3
  77. package/src/__tests__/credential-security-invariants.test.ts +1 -5
  78. package/src/__tests__/credential-token-resolver.test.ts +180 -0
  79. package/src/__tests__/cu-unified-flow.test.ts +33 -16
  80. package/src/__tests__/daemon-assistant-events.test.ts +34 -21
  81. package/src/__tests__/daemon-credential-client.test.ts +4 -1
  82. package/src/__tests__/db-connection-isolation.test.ts +125 -0
  83. package/src/__tests__/db-migration-rollback.test.ts +101 -0
  84. package/src/__tests__/db-slack-compaction-watermark-migration.test.ts +169 -0
  85. package/src/__tests__/deterministic-verification-control-plane.test.ts +7 -80
  86. package/src/__tests__/document-conversations.test.ts +332 -0
  87. package/src/__tests__/embedding-managed-proxy-selection.test.ts +2 -2
  88. package/src/__tests__/emit-event-signal.test.ts +4 -6
  89. package/src/__tests__/events-client-registration.test.ts +193 -49
  90. package/src/__tests__/filing-service.test.ts +58 -7
  91. package/src/__tests__/first-greeting.test.ts +156 -150
  92. package/src/__tests__/fixtures/mock-chrome-extension.ts +108 -66
  93. package/src/__tests__/get-skill-detail-audit.test.ts +3 -8
  94. package/src/__tests__/guardian-binding-drift-heal.test.ts +1 -1
  95. package/src/__tests__/guardian-dispatch.test.ts +1 -1
  96. package/src/__tests__/guardian-grant-minting.test.ts +7 -2
  97. package/src/__tests__/guardian-routing-invariants.test.ts +7 -2
  98. package/src/__tests__/guardian-routing-state.test.ts +1 -1
  99. package/src/__tests__/handlers-skills-memory-v2-reseed.test.ts +32 -11
  100. package/src/__tests__/handlers-user-message-approval-consumption.test.ts +2 -83
  101. package/src/__tests__/headless-browser-mode.test.ts +4 -9
  102. package/src/__tests__/headless-browser-navigate.test.ts +21 -20
  103. package/src/__tests__/heartbeat-service.test.ts +289 -7
  104. package/src/__tests__/helpers/channel-test-adapter.ts +2 -2
  105. package/src/__tests__/helpers/create-guardian-binding.ts +91 -0
  106. package/src/__tests__/host-bash-proxy.test.ts +46 -122
  107. package/src/__tests__/host-browser-e2e-cloud.test.ts +36 -497
  108. package/src/__tests__/host-browser-e2e-self-hosted-capability.test.ts +26 -96
  109. package/src/__tests__/host-browser-proxy.test.ts +111 -185
  110. package/src/__tests__/host-browser-routes.test.ts +45 -75
  111. package/src/__tests__/host-browser-ws-events-e2e.test.ts +26 -30
  112. package/src/__tests__/host-cu-proxy.test.ts +56 -111
  113. package/src/__tests__/host-file-proxy.test.ts +44 -98
  114. package/src/__tests__/host-file-read-tool.test.ts +42 -21
  115. package/src/__tests__/host-shell-tool.test.ts +33 -68
  116. package/src/__tests__/host-transfer-pending-interactions.test.ts +2 -18
  117. package/src/__tests__/host-transfer-proxy.test.ts +43 -53
  118. package/src/__tests__/http-user-message-parity.test.ts +0 -6
  119. package/src/__tests__/inbound-slack-persistence.test.ts +31 -0
  120. package/src/__tests__/injector-chain.test.ts +10 -5
  121. package/src/__tests__/injector-pkb-v2-silenced.test.ts +124 -0
  122. package/src/__tests__/inline-command-runner.test.ts +0 -66
  123. package/src/__tests__/inline-skill-load-permissions.test.ts +0 -2
  124. package/src/__tests__/install-skill-routing.test.ts +1 -13
  125. package/src/__tests__/llm-callsite-catalog.test.ts +34 -0
  126. package/src/__tests__/llm-catalog-parity.test.ts +90 -0
  127. package/src/__tests__/llm-context-resolution.test.ts +180 -0
  128. package/src/__tests__/llm-resolver.test.ts +80 -12
  129. package/src/__tests__/llm-usage-store.test.ts +269 -4
  130. package/src/__tests__/log-export-routes.test.ts +89 -0
  131. package/src/__tests__/managed-profile-guard.test.ts +225 -0
  132. package/src/__tests__/managed-skill-lifecycle.test.ts +0 -10
  133. package/src/__tests__/manual-token-reconciliation.test.ts +334 -0
  134. package/src/__tests__/memory-v2-static-injector.test.ts +95 -0
  135. package/src/__tests__/migration-cross-version-compatibility.test.ts +197 -291
  136. package/src/__tests__/migration-export-http.test.ts +33 -26
  137. package/src/__tests__/migration-export-streaming.test.ts +18 -10
  138. package/src/__tests__/migration-export-to-gcs.test.ts +49 -9
  139. package/src/__tests__/migration-import-commit-http.test.ts +66 -21
  140. package/src/__tests__/migration-import-from-gcs.test.ts +50 -9
  141. package/src/__tests__/migration-import-from-url.test.ts +20 -6
  142. package/src/__tests__/migration-import-preflight-http.test.ts +95 -95
  143. package/src/__tests__/migration-parity-persistence.test.ts +62 -25
  144. package/src/__tests__/migration-transport.test.ts +115 -23
  145. package/src/__tests__/migration-validate-http.test.ts +105 -80
  146. package/src/__tests__/migration-wizard.test.ts +133 -27
  147. package/src/__tests__/non-member-access-request.test.ts +1 -1
  148. package/src/__tests__/notification-guardian-path.test.ts +1 -1
  149. package/src/__tests__/oauth-store.test.ts +19 -0
  150. package/src/__tests__/platform-bash-auto-approve.test.ts +21 -12
  151. package/src/__tests__/prechat-onboarding-contract.test.ts +31 -7
  152. package/src/__tests__/pricing.test.ts +68 -4
  153. package/src/__tests__/process-message-background-slack.test.ts +331 -0
  154. package/src/__tests__/provider-managed-proxy-integration.test.ts +153 -17
  155. package/src/__tests__/provider-send-message-override-profile.test.ts +50 -0
  156. package/src/__tests__/provider-usage-tracking.test.ts +208 -0
  157. package/src/__tests__/reaction-persistence.test.ts +9 -6
  158. package/src/__tests__/rebind-secrets-screen.test.ts +53 -16
  159. package/src/__tests__/recording-handler.test.ts +64 -81
  160. package/src/__tests__/regenerate-fire-and-forget-trace.test.ts +4 -3
  161. package/src/__tests__/relay-server.test.ts +18 -13
  162. package/src/__tests__/require-fresh-approval.test.ts +13 -22
  163. package/src/__tests__/runtime-attachment-metadata.test.ts +1 -1
  164. package/src/__tests__/runtime-events-sse-parity.test.ts +3 -4
  165. package/src/__tests__/runtime-events-sse.test.ts +3 -12
  166. package/src/__tests__/search-skills-unified.test.ts +9 -15
  167. package/src/__tests__/secret-ingress-cli.test.ts +2 -5
  168. package/src/__tests__/secret-ingress-http.test.ts +0 -4
  169. package/src/__tests__/secret-onetime-send.test.ts +4 -2
  170. package/src/__tests__/secret-prompt-log-hygiene.test.ts +24 -7
  171. package/src/__tests__/secret-prompter-channel-fallback.test.ts +42 -47
  172. package/src/__tests__/secret-response-routing.test.ts +29 -15
  173. package/src/__tests__/secret-routes-managed-proxy.test.ts +5 -1
  174. package/src/__tests__/secret-scanner.test.ts +2 -545
  175. package/src/__tests__/send-endpoint-busy.test.ts +9 -24
  176. package/src/__tests__/settings-routes.test.ts +1 -1
  177. package/src/__tests__/shell-credential-ref.test.ts +0 -8
  178. package/src/__tests__/shell-tool-proxy-mode.test.ts +0 -56
  179. package/src/__tests__/skill-script-runner-sandbox.test.ts +0 -11
  180. package/src/__tests__/skill-tool-factory.test.ts +97 -0
  181. package/src/__tests__/skills-file-content-endpoint.test.ts +9 -30
  182. package/src/__tests__/skills-files-catalog-fallback.test.ts +11 -17
  183. package/src/__tests__/slack-inbound-verification.test.ts +1 -62
  184. package/src/__tests__/subagent-fork-notifications.test.ts +57 -47
  185. package/src/__tests__/subagent-manager-notify.test.ts +70 -70
  186. package/src/__tests__/subagent-notify-parent.test.ts +80 -83
  187. package/src/__tests__/system-prompt.test.ts +115 -13
  188. package/src/__tests__/terminal-tools.test.ts +0 -89
  189. package/src/__tests__/thread-backfill.test.ts +945 -31
  190. package/src/__tests__/tool-domain-event-publisher.test.ts +0 -36
  191. package/src/__tests__/tool-execute-pipeline.test.ts +0 -6
  192. package/src/__tests__/tool-execution-abort-cleanup.test.ts +0 -16
  193. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +9 -19
  194. package/src/__tests__/tool-executor-lifecycle-events.test.ts +4 -7
  195. package/src/__tests__/tool-executor.test.ts +12 -19
  196. package/src/__tests__/tool-metrics-listener.test.ts +0 -35
  197. package/src/__tests__/tool-side-effects-slack-dm.test.ts +1 -0
  198. package/src/__tests__/tool-trace-listener.test.ts +0 -17
  199. package/src/__tests__/transfer-progress-screen.test.ts +63 -26
  200. package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +2 -149
  201. package/src/__tests__/trusted-contact-multichannel.test.ts +2 -4
  202. package/src/__tests__/trusted-contact-verification.test.ts +1 -1
  203. package/src/__tests__/tts-catalog-parity.test.ts +16 -5
  204. package/src/__tests__/usage-attribution.test.ts +247 -0
  205. package/src/__tests__/usage-cli.test.ts +143 -0
  206. package/src/__tests__/usage-grouped-buckets.test.ts +155 -0
  207. package/src/__tests__/usage-routes.test.ts +150 -0
  208. package/src/__tests__/validation-results-screen.test.ts +39 -16
  209. package/src/__tests__/vbundle-pax-and-symlink.test.ts +12 -3
  210. package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +49 -137
  211. package/src/__tests__/verification-control-plane-policy.test.ts +4 -7
  212. package/src/__tests__/voice-session-bridge.test.ts +5 -5
  213. package/src/__tests__/workspace-migration-062-drop-memory-v2-edges-json.test.ts +103 -0
  214. package/src/__tests__/workspace-migration-063-release-notes-dynamic-model-context.test.ts +77 -0
  215. package/src/__tests__/workspace-migration-064-unwind-main-agent-opus-seed.test.ts +225 -0
  216. package/src/__tests__/workspace-migration-memory-v2-init.test.ts +8 -30
  217. package/src/acp/index.ts +0 -15
  218. package/src/acp/session-manager.ts +37 -34
  219. package/src/agent/loop.ts +16 -1
  220. package/src/approvals/AGENTS.md +4 -0
  221. package/src/approvals/__tests__/guardian-feed-event.test.ts +10 -3
  222. package/src/approvals/guardian-request-resolvers.ts +10 -2
  223. package/src/backup/__tests__/backup-worker.test.ts +36 -8
  224. package/src/backup/__tests__/paths.test.ts +2 -2
  225. package/src/backup/__tests__/restore.test.ts +45 -28
  226. package/src/backup/backup-worker.ts +36 -2
  227. package/src/backup/paths.ts +9 -6
  228. package/src/browser-session/events.ts +0 -9
  229. package/src/calls/call-store.ts +1 -34
  230. package/src/calls/guardian-question-copy.ts +0 -108
  231. package/src/calls/relay-server.ts +0 -24
  232. package/src/calls/twilio-rest.ts +0 -38
  233. package/src/calls/twilio-routes.ts +1 -1
  234. package/src/calls/voice-session-bridge.ts +7 -38
  235. package/src/channels/types.ts +1 -36
  236. package/src/cli/commands/__tests__/cache.test.ts +152 -5
  237. package/src/cli/commands/__tests__/memory-v2.test.ts +14 -28
  238. package/src/cli/commands/__tests__/trust.test.ts +21 -387
  239. package/src/cli/commands/backup.ts +4 -4
  240. package/src/cli/commands/cache-fs.ts +8 -0
  241. package/src/cli/commands/cache.ts +153 -82
  242. package/src/cli/commands/clients.ts +63 -5
  243. package/src/cli/commands/completions.ts +3 -3
  244. package/src/cli/commands/contacts.ts +231 -76
  245. package/src/cli/commands/keys.ts +4 -1
  246. package/src/cli/commands/memory-v2.ts +24 -52
  247. package/src/cli/commands/oauth/shared.ts +2 -29
  248. package/src/cli/commands/pending.ts +102 -0
  249. package/src/cli/commands/skills.ts +77 -35
  250. package/src/cli/commands/trust.ts +70 -430
  251. package/src/cli/commands/usage.ts +25 -16
  252. package/src/cli/lib/daemon-credential-client.ts +14 -0
  253. package/src/cli/program.ts +2 -0
  254. package/src/cli.ts +0 -21
  255. package/src/config/__tests__/feature-flag-registry-guard.test.ts +2 -2
  256. package/src/config/bundled-skills/messaging/TOOLS.json +14 -4
  257. package/src/config/env-registry.ts +12 -2
  258. package/src/config/env.ts +3 -14
  259. package/src/config/feature-flag-registry.json +30 -30
  260. package/src/config/llm-callsite-catalog.ts +12 -0
  261. package/src/config/llm-context-resolution.ts +80 -0
  262. package/src/config/llm-resolver.ts +58 -22
  263. package/src/config/loader.ts +3 -3
  264. package/src/config/schema.ts +2 -158
  265. package/src/config/schemas/__tests__/memory-v2.test.ts +1 -0
  266. package/src/config/schemas/call-site-catalog.ts +271 -0
  267. package/src/config/schemas/calls.ts +5 -5
  268. package/src/config/schemas/inference.ts +1 -1
  269. package/src/config/schemas/ingress.ts +1 -1
  270. package/src/config/schemas/llm.ts +31 -3
  271. package/src/config/schemas/memory-retrieval.ts +2 -2
  272. package/src/config/schemas/memory-v2.ts +9 -0
  273. package/src/config/schemas/security.ts +1 -42
  274. package/src/config/schemas/services.ts +6 -6
  275. package/src/config/schemas/skills.ts +5 -5
  276. package/src/config/schemas/tts.ts +1 -1
  277. package/src/config/seed-inference-profiles.ts +117 -0
  278. package/src/config/skills.ts +0 -90
  279. package/src/config/types.ts +3 -6
  280. package/src/contacts/contact-store.ts +0 -17
  281. package/src/contacts/contacts-write.ts +1 -105
  282. package/src/context/window-manager.ts +44 -5
  283. package/src/credential-execution/process-manager.ts +34 -10
  284. package/src/credential-health/credential-health-service.ts +21 -16
  285. package/src/daemon/__tests__/conversation-surfaces-launch.test.ts +75 -82
  286. package/src/daemon/__tests__/daemon-skill-host.test.ts +2 -9
  287. package/src/daemon/connection-policy.ts +1 -26
  288. package/src/daemon/conversation-agent-loop-handlers.ts +53 -4
  289. package/src/daemon/conversation-agent-loop.ts +277 -36
  290. package/src/daemon/conversation-history.ts +8 -8
  291. package/src/daemon/conversation-launch.ts +20 -135
  292. package/src/daemon/conversation-lifecycle.ts +1 -1
  293. package/src/daemon/conversation-messaging.ts +1 -0
  294. package/src/daemon/conversation-process.ts +83 -163
  295. package/src/daemon/conversation-runtime-assembly.ts +219 -76
  296. package/src/daemon/conversation-slash.ts +47 -5
  297. package/src/daemon/conversation-store.ts +7 -31
  298. package/src/daemon/conversation-surfaces.ts +22 -28
  299. package/src/daemon/conversation-tool-setup.ts +3 -33
  300. package/src/daemon/conversation-usage.ts +36 -0
  301. package/src/daemon/conversation.ts +117 -233
  302. package/src/daemon/daemon-control.ts +3 -71
  303. package/src/daemon/daemon-skill-host.ts +8 -11
  304. package/src/daemon/dictation-profile-store.ts +2 -26
  305. package/src/daemon/first-greeting.ts +44 -156
  306. package/src/daemon/handlers/config-channels.ts +12 -12
  307. package/src/daemon/handlers/config-ingress.ts +4 -165
  308. package/src/daemon/handlers/config-model.ts +1 -1
  309. package/src/daemon/handlers/config-voice.ts +0 -42
  310. package/src/daemon/handlers/conversations.ts +11 -190
  311. package/src/daemon/handlers/recording.ts +26 -158
  312. package/src/daemon/handlers/shared.ts +23 -71
  313. package/src/daemon/handlers/skills.ts +42 -93
  314. package/src/daemon/host-bash-proxy.ts +67 -45
  315. package/src/daemon/host-browser-proxy.ts +65 -27
  316. package/src/daemon/host-cu-proxy.ts +40 -39
  317. package/src/daemon/host-file-proxy.ts +58 -37
  318. package/src/daemon/host-transfer-proxy.ts +84 -46
  319. package/src/daemon/lifecycle.ts +49 -15
  320. package/src/daemon/message-types/conversations.ts +7 -0
  321. package/src/daemon/message-types/host-bash.ts +1 -0
  322. package/src/daemon/message-types/host-cu.ts +1 -0
  323. package/src/daemon/message-types/host-file.ts +1 -0
  324. package/src/daemon/message-types/host-transfer.ts +1 -0
  325. package/src/daemon/message-types/messages.ts +10 -9
  326. package/src/daemon/message-types/workspace.ts +1 -1
  327. package/src/daemon/process-message.ts +102 -239
  328. package/src/daemon/server.ts +13 -462
  329. package/src/daemon/shutdown-handlers.ts +2 -2
  330. package/src/daemon/tool-side-effects.ts +125 -107
  331. package/src/daemon/trust-context.ts +13 -0
  332. package/src/daemon/wake-target-adapter.ts +4 -9
  333. package/src/events/domain-events.ts +0 -8
  334. package/src/events/tool-audit-listener.ts +3 -1
  335. package/src/events/tool-domain-event-publisher.ts +0 -10
  336. package/src/events/tool-metrics-listener.ts +0 -17
  337. package/src/events/tool-trace-listener.ts +0 -14
  338. package/src/filing/filing-service.ts +13 -1
  339. package/src/heartbeat/__tests__/heartbeat-feed-event.test.ts +6 -2
  340. package/src/heartbeat/heartbeat-service.ts +23 -5
  341. package/src/home/__tests__/feed-writer.test.ts +0 -4
  342. package/src/home/__tests__/relationship-state-writer.test.ts +30 -0
  343. package/src/home/feed-writer.ts +1 -2
  344. package/src/home/relationship-state-writer.ts +16 -3
  345. package/src/ipc/__tests__/browser-ipc.test.ts +2 -12
  346. package/src/ipc/__tests__/skill-server-bidirectional.test.ts +0 -1
  347. package/src/ipc/assistant-server.ts +3 -10
  348. package/src/ipc/routes/__tests__/memory-v2-backfill.test.ts +39 -20
  349. package/src/ipc/routes/route-adapter.ts +1 -1
  350. package/src/ipc/routes/trust-rules.test.ts +0 -95
  351. package/src/ipc/skill-ipc-types.ts +41 -0
  352. package/src/ipc/skill-routes/__tests__/events-ipc.test.ts +13 -27
  353. package/src/ipc/skill-routes/__tests__/identity.test.ts +4 -23
  354. package/src/ipc/skill-routes/events.ts +12 -23
  355. package/src/ipc/skill-routes/identity.ts +4 -17
  356. package/src/ipc/skill-routes/index.ts +1 -1
  357. package/src/ipc/skill-server.ts +6 -39
  358. package/src/live-voice/__tests__/runtime-websocket-shell.test.ts +0 -8
  359. package/src/live-voice/protocol.ts +4 -13
  360. package/src/mcp/manager.ts +0 -5
  361. package/src/memory/__tests__/fixtures/memory-v2-activation-fixtures.ts +55 -0
  362. package/src/memory/__tests__/memory-v2-activation-log-store.test.ts +127 -0
  363. package/src/memory/app-git-service.ts +0 -32
  364. package/src/memory/app-store.ts +154 -0
  365. package/src/memory/attachments-store.ts +6 -0
  366. package/src/memory/context-search/sources/memory-v2.ts +578 -0
  367. package/src/memory/context-search/sources/memory.ts +5 -0
  368. package/src/memory/context-search/sources/pkb.ts +10 -1
  369. package/src/memory/context-search/sources/workspace.ts +3 -2
  370. package/src/memory/conversation-crud.ts +29 -4
  371. package/src/memory/conversation-disk-view.ts +1 -5
  372. package/src/memory/conversation-starter-checkpoints.ts +63 -0
  373. package/src/memory/db-connection.ts +62 -0
  374. package/src/memory/db-init.ts +14 -0
  375. package/src/memory/embedding-backend.ts +3 -21
  376. package/src/memory/embedding-gemini.ts +0 -2
  377. package/src/memory/embedding-local.ts +6 -6
  378. package/src/memory/embedding-ollama.ts +6 -6
  379. package/src/memory/embedding-openai.ts +6 -6
  380. package/src/memory/embedding-types.ts +21 -0
  381. package/src/memory/graph/__tests__/conversation-graph-memory-v2-routing.test.ts +3 -7
  382. package/src/memory/graph/conversation-graph-memory.ts +35 -13
  383. package/src/memory/graph/injection.test.ts +2 -2
  384. package/src/memory/graph/injection.ts +1 -1
  385. package/src/memory/guardian-action-store.ts +0 -83
  386. package/src/memory/guardian-approvals.ts +0 -48
  387. package/src/memory/indexer.ts +1 -15
  388. package/src/memory/job-handlers/conversation-starters.ts +36 -53
  389. package/src/memory/job-utils.ts +0 -6
  390. package/src/memory/jobs-store.ts +0 -1
  391. package/src/memory/jobs-worker.ts +2 -16
  392. package/src/memory/llm-request-log-store.ts +0 -41
  393. package/src/memory/llm-usage-store.ts +129 -43
  394. package/src/memory/memory-v2-activation-log-store.ts +115 -0
  395. package/src/memory/migrations/233-document-conversations.ts +54 -0
  396. package/src/memory/migrations/234-memory-v2-activation-logs.ts +55 -0
  397. package/src/memory/migrations/235-llm-usage-attribution.ts +31 -0
  398. package/src/memory/migrations/235-slack-compaction-watermark.ts +44 -0
  399. package/src/memory/migrations/236-tool-invocations-matched-rule-id.ts +26 -0
  400. package/src/memory/migrations/__tests__/234-memory-v2-activation-logs.test.ts +182 -0
  401. package/src/memory/migrations/index.ts +14 -0
  402. package/src/memory/migrations/registry.ts +24 -0
  403. package/src/memory/raw-query.ts +2 -68
  404. package/src/memory/schema/conversations.ts +7 -0
  405. package/src/memory/schema/infrastructure.ts +25 -0
  406. package/src/memory/search/semantic.ts +5 -16
  407. package/src/memory/tool-usage-store.ts +2 -0
  408. package/src/memory/usage-buckets.ts +40 -1
  409. package/src/memory/usage-grouped-buckets.ts +127 -0
  410. package/src/memory/v2/__tests__/activation.test.ts +289 -90
  411. package/src/memory/v2/__tests__/backfill-jobs.test.ts +2 -129
  412. package/src/memory/v2/__tests__/consolidation-job.test.ts +28 -11
  413. package/src/memory/v2/__tests__/edge-index.test.ts +278 -0
  414. package/src/memory/v2/__tests__/injection.test.ts +384 -15
  415. package/src/memory/v2/__tests__/migration.test.ts +64 -36
  416. package/src/memory/v2/__tests__/page-store.test.ts +191 -8
  417. package/src/memory/v2/__tests__/prompts-consolidation.test.ts +181 -0
  418. package/src/memory/v2/__tests__/skill-store.test.ts +115 -3
  419. package/src/memory/v2/__tests__/static-context.test.ts +153 -0
  420. package/src/memory/v2/activation.ts +168 -97
  421. package/src/memory/v2/backfill-jobs.ts +15 -100
  422. package/src/memory/v2/consolidation-job.ts +14 -12
  423. package/src/memory/v2/edge-index.ts +191 -0
  424. package/src/memory/v2/injection.ts +182 -58
  425. package/src/memory/v2/migration.ts +57 -64
  426. package/src/memory/v2/now-text.ts +2 -3
  427. package/src/memory/v2/page-store.ts +168 -31
  428. package/src/memory/v2/prompts/consolidation.ts +118 -42
  429. package/src/memory/v2/prompts/sweep.ts +3 -3
  430. package/src/memory/v2/skill-store.ts +55 -7
  431. package/src/memory/v2/static-context.ts +62 -0
  432. package/src/memory/v2/types.ts +10 -20
  433. package/src/memory/validation.ts +0 -11
  434. package/src/messaging/draft-store.ts +0 -6
  435. package/src/messaging/provider-types.ts +8 -0
  436. package/src/messaging/provider.ts +7 -0
  437. package/src/messaging/providers/gmail/client.ts +1 -121
  438. package/src/messaging/providers/outlook/client.ts +0 -73
  439. package/src/messaging/providers/slack/__tests__/adapter-mention-rendering.test.ts +226 -0
  440. package/src/messaging/providers/slack/adapter.ts +122 -21
  441. package/src/messaging/providers/slack/backfill.test.ts +95 -6
  442. package/src/messaging/providers/slack/backfill.ts +89 -11
  443. package/src/messaging/providers/slack/client.ts +10 -124
  444. package/src/messaging/providers/slack/message-metadata.ts +12 -2
  445. package/src/messaging/providers/slack/render-transcript.test.ts +56 -0
  446. package/src/messaging/providers/slack/render-transcript.ts +126 -25
  447. package/src/messaging/providers/slack/types.ts +1 -0
  448. package/src/oauth/connection-resolver.test.ts +8 -0
  449. package/src/oauth/connection-resolver.ts +8 -16
  450. package/src/oauth/credential-token-resolver.ts +97 -0
  451. package/src/oauth/manual-token-connection.ts +30 -34
  452. package/src/oauth/oauth-store.ts +6 -4
  453. package/src/outbound-proxy/certs.ts +0 -7
  454. package/src/outbound-proxy/config.ts +0 -74
  455. package/src/outbound-proxy/health.ts +0 -44
  456. package/src/outbound-proxy/index.ts +0 -22
  457. package/src/permissions/approval-provenance.test.ts +184 -0
  458. package/src/permissions/approval-provenance.ts +70 -0
  459. package/src/permissions/checker.ts +4 -1
  460. package/src/permissions/gateway-threshold-reader.ts +4 -1
  461. package/src/permissions/prompter.ts +9 -2
  462. package/src/permissions/secret-prompter.ts +21 -48
  463. package/src/permissions/types.ts +33 -0
  464. package/src/permissions/workspace-policy.ts +0 -5
  465. package/src/platform/sync-identity.ts +0 -8
  466. package/src/plugins/defaults/injectors.ts +69 -2
  467. package/src/plugins/defaults/overflow-reduce.ts +3 -2
  468. package/src/plugins/types.ts +8 -0
  469. package/src/prompts/system-prompt.ts +34 -70
  470. package/src/prompts/templates/BOOTSTRAP.md +52 -6
  471. package/src/prompts/update-bulletin-job.ts +2 -0
  472. package/src/providers/__tests__/retry-callsite.test.ts +138 -1
  473. package/src/providers/anthropic/client.ts +72 -33
  474. package/src/providers/call-site-routing.ts +42 -3
  475. package/src/providers/gemini/client.ts +18 -2
  476. package/src/providers/managed-proxy/context.ts +0 -5
  477. package/src/providers/model-catalog.ts +105 -19
  478. package/src/providers/openai/chat-completions-provider.ts +6 -0
  479. package/src/providers/openai/responses-provider.ts +7 -1
  480. package/src/providers/provider-send-message.ts +45 -2
  481. package/src/providers/ratelimit.ts +7 -2
  482. package/src/providers/registry.ts +14 -9
  483. package/src/providers/retry.ts +96 -8
  484. package/src/providers/types.ts +13 -0
  485. package/src/providers/usage-tracking.ts +96 -0
  486. package/src/runtime/AGENTS.md +10 -6
  487. package/src/runtime/__tests__/agent-wake.test.ts +89 -0
  488. package/src/runtime/agent-wake.ts +39 -2
  489. package/src/runtime/assistant-event-hub.ts +541 -45
  490. package/src/runtime/assistant-event.ts +1 -6
  491. package/src/runtime/auth/context.ts +0 -9
  492. package/src/runtime/auth/middleware.ts +1 -1
  493. package/src/runtime/auth/route-policy.ts +11 -9
  494. package/src/runtime/auth/token-service.ts +0 -11
  495. package/src/runtime/channel-approvals.ts +6 -2
  496. package/src/runtime/channel-verification-service.ts +3 -5
  497. package/src/runtime/http-errors.ts +0 -34
  498. package/src/runtime/http-router.ts +6 -3
  499. package/src/runtime/http-server.ts +22 -82
  500. package/src/runtime/http-types.ts +5 -0
  501. package/src/runtime/interactive-ui.ts +0 -1
  502. package/src/runtime/middleware/auth.ts +0 -20
  503. package/src/runtime/migrations/__tests__/v1-test-helpers.ts +112 -0
  504. package/src/runtime/migrations/__tests__/vbundle-builder-credentials.test.ts +11 -4
  505. package/src/runtime/migrations/__tests__/vbundle-builder-v1-shape.test.ts +253 -0
  506. package/src/runtime/migrations/__tests__/vbundle-import-credentials.test.ts +19 -6
  507. package/src/runtime/migrations/__tests__/vbundle-legacy-user-md.test.ts +71 -27
  508. package/src/runtime/migrations/__tests__/vbundle-metadata-merge-integration.test.ts +41 -2
  509. package/src/runtime/migrations/__tests__/vbundle-streaming-importer.test.ts +143 -79
  510. package/src/runtime/migrations/__tests__/vbundle-streaming-validator.test.ts +143 -23
  511. package/src/runtime/migrations/__tests__/vbundle-tar-stream.test.ts +2 -2
  512. package/src/runtime/migrations/__tests__/vbundle-validator-v1-schema.test.ts +371 -0
  513. package/src/runtime/migrations/migration-transport.ts +46 -13
  514. package/src/runtime/migrations/migration-wizard.ts +2 -2
  515. package/src/runtime/migrations/origin-mode.ts +40 -0
  516. package/src/runtime/migrations/vbundle-builder.ts +133 -79
  517. package/src/runtime/migrations/vbundle-import-analyzer.ts +9 -7
  518. package/src/runtime/migrations/vbundle-importer.ts +7 -7
  519. package/src/runtime/migrations/vbundle-metadata-merge.ts +1 -1
  520. package/src/runtime/migrations/vbundle-streaming-importer.ts +3 -3
  521. package/src/runtime/migrations/vbundle-streaming-validator.ts +48 -26
  522. package/src/runtime/migrations/vbundle-validator.ts +214 -41
  523. package/src/runtime/pending-interactions.ts +13 -4
  524. package/src/runtime/routes/__tests__/acp-routes.test.ts +0 -1
  525. package/src/runtime/routes/__tests__/backup-routes.test.ts +28 -19
  526. package/src/runtime/routes/__tests__/conversation-query-routes.test.ts +235 -0
  527. package/src/runtime/routes/__tests__/llm-call-sites-routes.test.ts +58 -0
  528. package/src/runtime/routes/__tests__/migration-export-secrets-redacted.test.ts +54 -0
  529. package/src/runtime/routes/__tests__/migration-import-credential-filter.test.ts +19 -6
  530. package/src/runtime/routes/__tests__/user-route-dispatcher.test.ts +7 -7
  531. package/src/runtime/routes/acp-routes.test.ts +0 -3
  532. package/src/runtime/routes/acp-routes.ts +3 -7
  533. package/src/runtime/routes/app-management-routes.ts +18 -9
  534. package/src/runtime/routes/approval-routes.ts +55 -14
  535. package/src/runtime/routes/avatar-routes.ts +3 -5
  536. package/src/runtime/routes/browser-routes.ts +1 -15
  537. package/src/runtime/routes/channel-guardian-routes.ts +1 -5
  538. package/src/runtime/routes/channel-readiness-routes.ts +3 -7
  539. package/src/runtime/routes/channel-route-shared.ts +2 -28
  540. package/src/runtime/routes/client-routes.ts +45 -12
  541. package/src/runtime/routes/consolidation-routes.ts +115 -0
  542. package/src/runtime/routes/conversation-list-routes.ts +12 -29
  543. package/src/runtime/routes/conversation-management-routes.ts +14 -51
  544. package/src/runtime/routes/conversation-query-routes.ts +120 -8
  545. package/src/runtime/routes/conversation-routes.ts +44 -528
  546. package/src/runtime/routes/conversation-starter-routes.ts +19 -40
  547. package/src/runtime/routes/documents-routes.ts +53 -18
  548. package/src/runtime/routes/events-routes.ts +59 -91
  549. package/src/runtime/routes/filing-routes.ts +18 -1
  550. package/src/runtime/routes/guardian-action-routes.ts +4 -9
  551. package/src/runtime/routes/host-bash-routes.ts +3 -2
  552. package/src/runtime/routes/host-browser-routes.ts +9 -33
  553. package/src/runtime/routes/host-cu-routes.ts +6 -1
  554. package/src/runtime/routes/host-file-routes.ts +3 -2
  555. package/src/runtime/routes/host-transfer-routes.ts +11 -15
  556. package/src/runtime/routes/identity-routes.ts +78 -6
  557. package/src/runtime/routes/inbound-message-handler.ts +580 -137
  558. package/src/runtime/routes/inbound-stages/acl-enforcement.ts +2 -88
  559. package/src/runtime/routes/inbound-stages/background-dispatch.ts +3 -0
  560. package/src/runtime/routes/index.ts +4 -0
  561. package/src/runtime/routes/integrations/slack/channel.ts +0 -24
  562. package/src/runtime/routes/llm-call-sites-routes.ts +22 -0
  563. package/src/runtime/routes/memory-v2-routes.ts +10 -15
  564. package/src/runtime/routes/migration-routes.ts +188 -31
  565. package/src/runtime/routes/playground/guard.ts +1 -1
  566. package/src/runtime/routes/playground/index.ts +0 -2
  567. package/src/runtime/routes/recording-routes.ts +4 -24
  568. package/src/runtime/routes/rename-conversation-routes.ts +2 -6
  569. package/src/runtime/routes/schedule-routes.ts +3 -6
  570. package/src/runtime/routes/secret-routes.ts +87 -18
  571. package/src/runtime/routes/settings-routes.ts +29 -28
  572. package/src/runtime/routes/skills-routes.ts +12 -31
  573. package/src/runtime/routes/suggest-trust-rule-routes.ts +32 -1
  574. package/src/runtime/routes/task-routes.ts +6 -6
  575. package/src/runtime/routes/trust-rules-routes.ts +3 -94
  576. package/src/runtime/routes/types.ts +4 -4
  577. package/src/runtime/routes/upgrade-broadcast-routes.ts +3 -10
  578. package/src/runtime/routes/usage-routes.ts +87 -10
  579. package/src/runtime/routes/user-routes.ts +17 -31
  580. package/src/runtime/routes/work-items-routes.ts +1 -4
  581. package/src/runtime/services/__tests__/analyze-conversation.test.ts +2 -2
  582. package/src/runtime/services/analyze-conversation.ts +7 -17
  583. package/src/runtime/services/conversation-serializer.ts +2 -4
  584. package/src/runtime/verification-outbound-actions.ts +1 -1
  585. package/src/runtime/verification-rate-limiter.ts +1 -1
  586. package/src/schedule/schedule-store.ts +0 -16
  587. package/src/security/secret-scanner.ts +14 -547
  588. package/src/security/secure-keys.ts +31 -11
  589. package/src/security/token-manager.ts +7 -3
  590. package/src/signals/cancel.ts +16 -25
  591. package/src/signals/conversation-undo.ts +2 -27
  592. package/src/signals/emit-event.ts +1 -2
  593. package/src/signals/user-message.ts +108 -22
  594. package/src/skills/catalog-install.ts +1 -0
  595. package/src/skills/clawhub.ts +2 -2
  596. package/src/skills/inline-command-runner.ts +1 -7
  597. package/src/subagent/manager.ts +67 -84
  598. package/src/tasks/task-store.ts +1 -28
  599. package/src/telemetry/types.ts +6 -0
  600. package/src/telemetry/usage-telemetry-reporter.test.ts +38 -15
  601. package/src/telemetry/usage-telemetry-reporter.ts +3 -5
  602. package/src/tools/acp/spawn.test.ts +1 -2
  603. package/src/tools/acp/steer.test.ts +1 -2
  604. package/src/tools/browser/__tests__/browser-status.test.ts +44 -127
  605. package/src/tools/browser/browser-execution.ts +31 -147
  606. package/src/tools/browser/cdp-client/__tests__/factory.test.ts +92 -68
  607. package/src/tools/browser/cdp-client/factory.ts +48 -76
  608. package/src/tools/browser/cdp-client/index.ts +1 -14
  609. package/src/tools/executor.ts +44 -31
  610. package/src/tools/host-filesystem/edit.ts +3 -2
  611. package/src/tools/host-filesystem/read.ts +3 -2
  612. package/src/tools/host-filesystem/transfer.test.ts +45 -42
  613. package/src/tools/host-filesystem/transfer.ts +4 -3
  614. package/src/tools/host-filesystem/write.ts +3 -2
  615. package/src/tools/host-terminal/host-shell.ts +4 -3
  616. package/src/tools/network/script-proxy/index.ts +1 -10
  617. package/src/tools/permission-checker.ts +66 -1
  618. package/src/tools/skills/sandbox-runner.ts +1 -6
  619. package/src/tools/skills/skill-tool-factory.ts +32 -0
  620. package/src/tools/terminal/safe-env.ts +1 -0
  621. package/src/tools/terminal/shell.ts +2 -78
  622. package/src/tools/types.ts +12 -39
  623. package/src/tts/__tests__/provider-catalog.test.ts +2 -2
  624. package/src/tts/provider-catalog.ts +1 -1
  625. package/src/usage/actors.ts +2 -1
  626. package/src/usage/attribution.ts +185 -0
  627. package/src/usage/pricing.ts +166 -0
  628. package/src/usage/types.ts +14 -0
  629. package/src/util/json.ts +13 -0
  630. package/src/util/logger.ts +3 -3
  631. package/src/util/pricing.ts +50 -3
  632. package/src/work-items/work-item-runner.ts +15 -42
  633. package/src/workspace/migrations/050-seed-main-agent-opus-callsite.ts +4 -3
  634. package/src/workspace/migrations/052-seed-default-inference-profiles.ts +3 -3
  635. package/src/workspace/migrations/060-memory-v2-init.ts +2 -18
  636. package/src/workspace/migrations/061-move-backup-key-to-workspace.ts +59 -0
  637. package/src/workspace/migrations/062-drop-memory-v2-edges-json.ts +27 -0
  638. package/src/workspace/migrations/063-release-notes-dynamic-model-context.ts +70 -0
  639. package/src/workspace/migrations/064-unwind-main-agent-opus-seed.ts +64 -0
  640. package/src/workspace/migrations/registry.ts +8 -0
  641. package/src/workspace/provider-commit-message-generator.ts +3 -3
  642. package/src/__tests__/sandbox-diagnostics.test.ts +0 -138
  643. package/src/__tests__/sandbox-host-parity.test.ts +0 -1024
  644. package/src/__tests__/secret-detection-handler.test.ts +0 -67
  645. package/src/__tests__/secret-scanner-executor.test.ts +0 -450
  646. package/src/__tests__/tcc-sandbox-deny.test.ts +0 -198
  647. package/src/__tests__/terminal-sandbox.test.ts +0 -374
  648. package/src/__tests__/tool-notification-listener.test.ts +0 -65
  649. package/src/context/__tests__/microcompact.test.ts +0 -805
  650. package/src/context/microcompact.ts +0 -443
  651. package/src/daemon/handlers/slack-channel-oauth-install.ts +0 -197
  652. package/src/events/tool-notification-listener.ts +0 -17
  653. package/src/ipc/routes/__tests__/memory-v2-validate.test.ts +0 -219
  654. package/src/memory/v2/__tests__/edges.test.ts +0 -435
  655. package/src/memory/v2/edges.ts +0 -217
  656. package/src/prompts/__tests__/system-prompt-memory-v2.test.ts +0 -197
  657. package/src/runtime/__tests__/chrome-extension-registry.test.ts +0 -518
  658. package/src/runtime/__tests__/client-registry.test.ts +0 -271
  659. package/src/runtime/chrome-extension-registry.ts +0 -368
  660. package/src/runtime/client-registry.ts +0 -254
  661. package/src/runtime/routes/inbound-stages/verification-intercept.ts +0 -329
  662. package/src/tools/secret-detection-handler.ts +0 -269
  663. package/src/tools/terminal/backends/native.ts +0 -327
  664. package/src/tools/terminal/backends/types.ts +0 -37
  665. package/src/tools/terminal/sandbox-diagnostics.ts +0 -87
  666. package/src/tools/terminal/sandbox.ts +0 -40
@@ -23,6 +23,12 @@ const log = getLogger("slack-backfill");
23
23
 
24
24
  const DEFAULT_LIMIT = 50;
25
25
 
26
+ export interface SlackBackfillWindowPage {
27
+ messages: Message[];
28
+ hasMore: boolean;
29
+ nextCursor?: string;
30
+ }
31
+
26
32
  function isChannelNotFound(err: unknown): boolean {
27
33
  const msg = err instanceof Error ? err.message : String(err);
28
34
  return /channel_not_found/i.test(msg);
@@ -41,31 +47,103 @@ export async function backfillThread(
41
47
  threadTs: string,
42
48
  opts?: { limit?: number; account?: string },
43
49
  ): Promise<Message[]> {
50
+ return backfillThreadWindow(channelId, threadTs, opts);
51
+ }
52
+
53
+ /**
54
+ * Fetch a bounded window of messages in a Slack thread.
55
+ *
56
+ * `after` and `before` are passed through to Slack as `oldest` and `latest`;
57
+ * callers can also pass a Slack pagination cursor when continuing a bounded
58
+ * scan. Returns `[]` on transient errors; rethrows `channel_not_found`.
59
+ */
60
+ export async function backfillThreadWindow(
61
+ channelId: string,
62
+ threadTs: string,
63
+ opts?: {
64
+ limit?: number;
65
+ after?: string;
66
+ before?: string;
67
+ cursor?: string;
68
+ account?: string;
69
+ },
70
+ ): Promise<Message[]> {
71
+ const page = await backfillThreadWindowPage(channelId, threadTs, opts);
72
+ return page.messages;
73
+ }
74
+
75
+ /**
76
+ * Fetch a bounded Slack thread page and preserve Slack pagination metadata.
77
+ *
78
+ * This is the preferred helper for callers that need to know whether a
79
+ * bounded window fully covered the requested range. The older
80
+ * `backfillThreadWindow` wrapper intentionally returns only messages for
81
+ * existing consumers.
82
+ */
83
+ export async function backfillThreadWindowPage(
84
+ channelId: string,
85
+ threadTs: string,
86
+ opts?: {
87
+ limit?: number;
88
+ after?: string;
89
+ before?: string;
90
+ cursor?: string;
91
+ account?: string;
92
+ },
93
+ ): Promise<SlackBackfillWindowPage> {
44
94
  const limit = opts?.limit ?? DEFAULT_LIMIT;
45
95
  try {
46
96
  const connection = await slackProvider.resolveConnection?.(opts?.account);
47
- if (!slackProvider.getThreadReplies) {
97
+ if (
98
+ !slackProvider.getThreadRepliesPage &&
99
+ !slackProvider.getThreadReplies
100
+ ) {
48
101
  log.warn(
49
102
  { channelId, threadTs },
50
- "Slack provider does not implement getThreadReplies — returning []",
103
+ "Slack provider does not implement thread reply reads — returning []",
51
104
  );
52
- return [];
105
+ return { messages: [], hasMore: false };
53
106
  }
54
- return await slackProvider.getThreadReplies(
55
- connection,
56
- channelId,
57
- threadTs,
58
- { limit },
59
- );
107
+ const historyOptions = {
108
+ limit,
109
+ ...(opts?.after !== undefined ? { after: opts.after } : {}),
110
+ ...(opts?.before !== undefined ? { before: opts.before } : {}),
111
+ ...(opts?.cursor !== undefined ? { cursor: opts.cursor } : {}),
112
+ };
113
+ if (slackProvider.getThreadRepliesPage) {
114
+ return await slackProvider.getThreadRepliesPage(
115
+ connection,
116
+ channelId,
117
+ threadTs,
118
+ historyOptions,
119
+ );
120
+ }
121
+ return {
122
+ messages: await slackProvider.getThreadReplies!(
123
+ connection,
124
+ channelId,
125
+ threadTs,
126
+ historyOptions,
127
+ ),
128
+ hasMore: false,
129
+ };
60
130
  } catch (err) {
61
131
  if (isChannelNotFound(err)) {
62
132
  throw err;
63
133
  }
64
134
  log.warn(
65
- { channelId, threadTs, account: opts?.account, err },
135
+ {
136
+ channelId,
137
+ threadTs,
138
+ after: opts?.after,
139
+ before: opts?.before,
140
+ cursor: opts?.cursor,
141
+ account: opts?.account,
142
+ err,
143
+ },
66
144
  "Slack thread backfill failed — returning []",
67
145
  );
68
- return [];
146
+ return { messages: [], hasMore: false };
69
147
  }
70
148
  }
71
149
 
@@ -14,19 +14,12 @@ import type { OAuthConnection } from "../../../oauth/connection.js";
14
14
  import type {
15
15
  SlackApiResponse,
16
16
  SlackAuthTestResponse,
17
- SlackChatDeleteResponse,
18
- SlackChatUpdateResponse,
19
17
  SlackConversationHistoryResponse,
20
- SlackConversationInfoResponse,
21
- SlackConversationJoinResponse,
22
- SlackConversationLeaveResponse,
23
18
  SlackConversationMarkResponse,
24
19
  SlackConversationRepliesResponse,
25
20
  SlackConversationsListResponse,
26
21
  SlackConversationsOpenResponse,
27
- SlackPostEphemeralResponse,
28
22
  SlackPostMessageResponse,
29
- SlackReactionAddResponse,
30
23
  SlackSearchMessagesResponse,
31
24
  SlackUserInfoResponse,
32
25
  } from "./types.js";
@@ -310,19 +303,6 @@ export async function listConversations(
310
303
  );
311
304
  }
312
305
 
313
- export async function conversationInfo(
314
- connectionOrToken: OAuthConnection | string,
315
- channel: string,
316
- ): Promise<SlackConversationInfoResponse> {
317
- return request<SlackConversationInfoResponse>(
318
- connectionOrToken,
319
- "conversations.info",
320
- {
321
- channel,
322
- },
323
- );
324
- }
325
-
326
306
  export async function conversationHistory(
327
307
  connectionOrToken: OAuthConnection | string,
328
308
  channel: string,
@@ -330,6 +310,7 @@ export async function conversationHistory(
330
310
  latest?: string,
331
311
  oldest?: string,
332
312
  cursor?: string,
313
+ inclusive?: boolean,
333
314
  ): Promise<SlackConversationHistoryResponse> {
334
315
  return request<SlackConversationHistoryResponse>(
335
316
  connectionOrToken,
@@ -340,6 +321,7 @@ export async function conversationHistory(
340
321
  latest,
341
322
  oldest,
342
323
  cursor,
324
+ inclusive: inclusive === undefined ? undefined : String(inclusive),
343
325
  },
344
326
  );
345
327
  }
@@ -349,6 +331,10 @@ export async function conversationReplies(
349
331
  channel: string,
350
332
  ts: string,
351
333
  limit = 50,
334
+ latest?: string,
335
+ oldest?: string,
336
+ inclusive?: boolean,
337
+ cursor?: string,
352
338
  ): Promise<SlackConversationRepliesResponse> {
353
339
  return request<SlackConversationRepliesResponse>(
354
340
  connectionOrToken,
@@ -357,6 +343,10 @@ export async function conversationReplies(
357
343
  channel,
358
344
  ts,
359
345
  limit: String(limit),
346
+ latest,
347
+ oldest,
348
+ inclusive: inclusive === undefined ? undefined : String(inclusive),
349
+ cursor,
360
350
  },
361
351
  );
362
352
  }
@@ -426,29 +416,6 @@ export async function postMessage(
426
416
  );
427
417
  }
428
418
 
429
- /**
430
- * Post an ephemeral message visible only to the specified user.
431
- *
432
- * Ephemeral messages are fire-and-forget: they cannot be edited or deleted
433
- * after posting, and they disappear when the user reloads the Slack client.
434
- */
435
- export async function postEphemeral(
436
- connectionOrToken: OAuthConnection | string,
437
- channel: string,
438
- user: string,
439
- text: string,
440
- threadTs?: string,
441
- ): Promise<SlackPostEphemeralResponse> {
442
- const body: Record<string, unknown> = { channel, user, text };
443
- if (threadTs) body.thread_ts = threadTs;
444
- return request<SlackPostEphemeralResponse>(
445
- connectionOrToken,
446
- "chat.postEphemeral",
447
- undefined,
448
- body,
449
- );
450
- }
451
-
452
419
  export async function searchMessages(
453
420
  connectionOrToken: OAuthConnection | string,
454
421
  query: string,
@@ -465,84 +432,3 @@ export async function searchMessages(
465
432
  },
466
433
  );
467
434
  }
468
-
469
- export async function addReaction(
470
- connectionOrToken: OAuthConnection | string,
471
- channel: string,
472
- timestamp: string,
473
- name: string,
474
- ): Promise<SlackReactionAddResponse> {
475
- return request<SlackReactionAddResponse>(
476
- connectionOrToken,
477
- "reactions.add",
478
- undefined,
479
- {
480
- channel,
481
- timestamp,
482
- name,
483
- },
484
- );
485
- }
486
-
487
- export async function updateMessage(
488
- connectionOrToken: OAuthConnection | string,
489
- channel: string,
490
- ts: string,
491
- text: string,
492
- ): Promise<SlackChatUpdateResponse> {
493
- return request<SlackChatUpdateResponse>(
494
- connectionOrToken,
495
- "chat.update",
496
- undefined,
497
- {
498
- channel,
499
- ts,
500
- text,
501
- },
502
- );
503
- }
504
-
505
- export async function deleteMessage(
506
- connectionOrToken: OAuthConnection | string,
507
- channel: string,
508
- ts: string,
509
- ): Promise<SlackChatDeleteResponse> {
510
- return request<SlackChatDeleteResponse>(
511
- connectionOrToken,
512
- "chat.delete",
513
- undefined,
514
- {
515
- channel,
516
- ts,
517
- },
518
- );
519
- }
520
-
521
- export async function joinConversation(
522
- connectionOrToken: OAuthConnection | string,
523
- channel: string,
524
- ): Promise<SlackConversationJoinResponse> {
525
- return request<SlackConversationJoinResponse>(
526
- connectionOrToken,
527
- "conversations.join",
528
- undefined,
529
- {
530
- channel,
531
- },
532
- );
533
- }
534
-
535
- export async function leaveConversation(
536
- connectionOrToken: OAuthConnection | string,
537
- channel: string,
538
- ): Promise<SlackConversationLeaveResponse> {
539
- return request<SlackConversationLeaveResponse>(
540
- connectionOrToken,
541
- "conversations.leave",
542
- undefined,
543
- {
544
- channel,
545
- },
546
- );
547
- }
548
-
@@ -11,8 +11,10 @@ import { z } from "zod";
11
11
  * Slack-only blob for fresh writes; `mergeSlackMetadata` patches Slack fields
12
12
  * while preserving unrelated keys on the existing JSON.
13
13
  *
14
- * This file is a pure library addition no consumers wire into it yet; that
15
- * happens in later PRs of the slack-thread-aware-context plan.
14
+ * Slack transcript rendering and backfill paths persist and read this metadata
15
+ * to reconstruct thread order, reactions, edits, deletes, and lightweight
16
+ * Slack file markers. Transient late-join notices are current-turn runtime
17
+ * context only and do not become durable message metadata.
16
18
  */
17
19
 
18
20
  export type SlackEventKind = "message" | "reaction";
@@ -24,6 +26,12 @@ const slackReactionMetadataSchema = z.object({
24
26
  op: z.enum(["added", "removed"]),
25
27
  });
26
28
 
29
+ const slackFileMetadataSchema = z.object({
30
+ id: z.string().optional(),
31
+ name: z.string(),
32
+ mimetype: z.string().optional(),
33
+ });
34
+
27
35
  export const slackMessageMetadataSchema = z.object({
28
36
  source: z.literal("slack"),
29
37
  channelId: z.string(),
@@ -34,9 +42,11 @@ export const slackMessageMetadataSchema = z.object({
34
42
  reaction: slackReactionMetadataSchema.optional(),
35
43
  editedAt: z.number().optional(),
36
44
  deletedAt: z.number().optional(),
45
+ slackFiles: z.array(slackFileMetadataSchema).optional(),
37
46
  });
38
47
 
39
48
  export type SlackReactionMetadata = z.infer<typeof slackReactionMetadataSchema>;
49
+ export type SlackFileMetadata = z.infer<typeof slackFileMetadataSchema>;
40
50
  export type SlackMessageMetadata = z.infer<typeof slackMessageMetadataSchema>;
41
51
 
42
52
  /**
@@ -16,6 +16,7 @@ import {
16
16
  parentAlias,
17
17
  type RenderableSlackMessage,
18
18
  renderSlackTranscript,
19
+ renderSlackTranscriptWithProvenance,
19
20
  } from "./render-transcript.js";
20
21
 
21
22
  // ── helpers ──────────────────────────────────────────────────────────────────
@@ -44,6 +45,7 @@ function userMsg(
44
45
  deletedAt?: number;
45
46
  role?: "user" | "assistant";
46
47
  createdAt?: number;
48
+ slackFiles?: Array<{ id?: string; name: string; mimetype?: string }>;
47
49
  } = {},
48
50
  ): RenderableSlackMessage {
49
51
  return {
@@ -59,6 +61,7 @@ function userMsg(
59
61
  eventKind: "message",
60
62
  editedAt: opts.editedAt,
61
63
  deletedAt: opts.deletedAt,
64
+ slackFiles: opts.slackFiles,
62
65
  },
63
66
  };
64
67
  }
@@ -242,6 +245,59 @@ describe("renderSlackTranscript — basics", () => {
242
245
  expect(out).toEqual([textMsg("assistant", "yo 👋")]);
243
246
  });
244
247
 
248
+ test("backfilled Slack file metadata renders as concise attachment markers", () => {
249
+ const out = renderSlackTranscript([
250
+ userMsg(TS_14_25, "@alice", "shared the draft", {
251
+ slackFiles: [
252
+ { id: "F123", name: "requirements.txt", mimetype: "text/plain" },
253
+ ],
254
+ }),
255
+ userMsg(TS_14_26, "@bob", "", {
256
+ slackFiles: [{ name: "diagram.png", mimetype: "image/png" }],
257
+ }),
258
+ ]);
259
+
260
+ expect(out).toEqual([
261
+ textMsg(
262
+ "user",
263
+ "[11/14/23 14:25 @alice]: shared the draft [attached file: requirements.txt, text/plain]",
264
+ ),
265
+ textMsg(
266
+ "user",
267
+ "[11/14/23 14:26 @bob]: [attached file: diagram.png, image/png]",
268
+ ),
269
+ ]);
270
+ });
271
+
272
+ test("provenance follows the rendered sequence after orphan filtering", () => {
273
+ const out = renderSlackTranscriptWithProvenance([
274
+ userMsg(TS_14_25, "@alice", "kept"),
275
+ {
276
+ ...userMsg(TS_14_26, null, "", { role: "assistant" }),
277
+ contentBlocks: [
278
+ { type: "tool_use", id: "tool-1", name: "lookup", input: {} },
279
+ ],
280
+ },
281
+ userMsg(TS_14_28, "@bob", "also kept"),
282
+ ]);
283
+
284
+ expect(extractTagLineTexts(out.messages)).toEqual([
285
+ "[11/14/23 14:25 @alice]: kept",
286
+ "[11/14/23 14:28 @bob]: also kept",
287
+ ]);
288
+ expect(out.renderedMessages.map((entry) => entry.message)).toEqual(
289
+ out.messages,
290
+ );
291
+ expect(out.renderedMessages.map((entry) => entry.sourceChannelTs)).toEqual([
292
+ TS_14_25,
293
+ TS_14_28,
294
+ ]);
295
+ expect(out.renderedMessages.map((entry) => entry.sourceChannelTs)).toEqual([
296
+ TS_14_25,
297
+ TS_14_28,
298
+ ]);
299
+ });
300
+
245
301
  test("omits sender label for user-role message with null senderLabel (no displayName)", () => {
246
302
  const out = renderSlackTranscript([userMsg(TS_14_25, null, "yo")]);
247
303
  expect(out).toEqual([textMsg("user", "[11/14/23 14:25]: yo")]);
@@ -58,6 +58,18 @@ export interface RenderOptions {
58
58
 
59
59
  const DEFAULT_MAX_REACTIONS = 5;
60
60
 
61
+ export interface RenderedSlackTranscript {
62
+ /** Rendered messages paired with the Slack source timestamp they represent. */
63
+ readonly renderedMessages: readonly RenderedSlackTranscriptMessage[];
64
+ /** Convenience projection of `renderedMessages[].message`. */
65
+ readonly messages: Message[];
66
+ }
67
+
68
+ export interface RenderedSlackTranscriptMessage {
69
+ readonly message: Message;
70
+ readonly sourceChannelTs: string | null;
71
+ }
72
+
61
73
  /**
62
74
  * Replayable Anthropic content-block types that we preserve verbatim from a
63
75
  * persisted row when rendering the Slack chronological transcript.
@@ -146,6 +158,30 @@ function formatEpochMs(ms: number): string {
146
158
  return `${mo}/${da}/${yy} ${hh}:${mm}`;
147
159
  }
148
160
 
161
+ function renderSlackFileMarkers(
162
+ files: SlackMessageMetadata["slackFiles"],
163
+ ): string {
164
+ if (!files || files.length === 0) return "";
165
+ return files
166
+ .map((file) => {
167
+ const name = file.name.replace(/\s+/g, " ").trim();
168
+ const mime = file.mimetype?.replace(/\s+/g, " ").trim();
169
+ return mime
170
+ ? `[attached file: ${name}, ${mime}]`
171
+ : `[attached file: ${name}]`;
172
+ })
173
+ .join(" ");
174
+ }
175
+
176
+ function appendSlackFileMarkers(
177
+ content: string,
178
+ files: SlackMessageMetadata["slackFiles"],
179
+ ): string {
180
+ const markers = renderSlackFileMarkers(files);
181
+ if (!markers) return content;
182
+ return content.length > 0 ? `${content} ${markers}` : markers;
183
+ }
184
+
149
185
  /**
150
186
  * Sort key for chronological ordering.
151
187
  *
@@ -162,6 +198,25 @@ function sortKey(msg: RenderableSlackMessage): number {
162
198
  return msg.createdAt / 1000;
163
199
  }
164
200
 
201
+ export function compareSlackTs(a: string, b: string): number {
202
+ const aNum = Number.parseFloat(a);
203
+ const bNum = Number.parseFloat(b);
204
+ if (Number.isFinite(aNum) && Number.isFinite(bNum) && aNum !== bNum) {
205
+ return aNum - bNum;
206
+ }
207
+ return a.localeCompare(b);
208
+ }
209
+
210
+ export function isSlackTsAfter(ts: string, watermarkTs: string): boolean {
211
+ return compareSlackTs(ts, watermarkTs) > 0;
212
+ }
213
+
214
+ function maxNullableSlackTs(a: string | null, b: string | null): string | null {
215
+ if (a === null) return b;
216
+ if (b === null) return a;
217
+ return compareSlackTs(a, b) >= 0 ? a : b;
218
+ }
219
+
165
220
  /**
166
221
  * Render a single non-reaction message (post-upgrade or legacy) as one
167
222
  * tagged line.
@@ -197,7 +252,7 @@ function sortKey(msg: RenderableSlackMessage): number {
197
252
  function renderMessage(msg: RenderableSlackMessage): string {
198
253
  if (msg.role === "assistant") {
199
254
  if (msg.metadata?.deletedAt !== undefined) return "[deleted]";
200
- return msg.content;
255
+ return appendSlackFileMarkers(msg.content, msg.metadata?.slackFiles);
201
256
  }
202
257
 
203
258
  const meta = msg.metadata;
@@ -222,7 +277,7 @@ function renderMessage(msg: RenderableSlackMessage): string {
222
277
  if (meta.editedAt !== undefined) {
223
278
  head += `, edited ${formatEpochMs(meta.editedAt)}`;
224
279
  }
225
- head += `]: ${msg.content}`;
280
+ head += `]: ${appendSlackFileMarkers(msg.content, meta.slackFiles)}`;
226
281
  return head;
227
282
  }
228
283
 
@@ -342,7 +397,16 @@ export function renderSlackTranscript(
342
397
  messages: RenderableSlackMessage[],
343
398
  opts?: RenderOptions,
344
399
  ): Message[] {
345
- if (messages.length === 0) return [];
400
+ return renderSlackTranscriptWithProvenance(messages, opts).messages;
401
+ }
402
+
403
+ export function renderSlackTranscriptWithProvenance(
404
+ messages: RenderableSlackMessage[],
405
+ opts?: RenderOptions,
406
+ ): RenderedSlackTranscript {
407
+ if (messages.length === 0) {
408
+ return { renderedMessages: [], messages: [] };
409
+ }
346
410
 
347
411
  const maxReactions = Math.max(
348
412
  1,
@@ -364,23 +428,37 @@ export function renderSlackTranscript(
364
428
  // reaches an event that is not an overflowing reaction for that target.
365
429
  const overflowAccumulator = new Map<
366
430
  string,
367
- { excess: number; role: "user" | "assistant" }
431
+ {
432
+ excess: number;
433
+ role: "user" | "assistant";
434
+ sourceChannelTs: string | null;
435
+ }
368
436
  >();
369
437
 
370
438
  const trailerMessage = (
371
439
  target: string,
372
- acc: { excess: number; role: "user" | "assistant" },
373
- ): Message => ({
374
- role: acc.role,
375
- content: [
376
- {
377
- type: "text" as const,
378
- text: `[…and ${acc.excess} more ${acc.excess === 1 ? "reaction" : "reactions"} to ${parentAlias(target)}]`,
379
- },
380
- ],
440
+ acc: {
441
+ excess: number;
442
+ role: "user" | "assistant";
443
+ sourceChannelTs: string | null;
444
+ },
445
+ ): RenderedSlackTranscriptMessage => ({
446
+ message: {
447
+ role: acc.role,
448
+ content: [
449
+ {
450
+ type: "text" as const,
451
+ text: `[…and ${acc.excess} more ${acc.excess === 1 ? "reaction" : "reactions"} to ${parentAlias(target)}]`,
452
+ },
453
+ ],
454
+ },
455
+ sourceChannelTs: acc.sourceChannelTs,
381
456
  });
382
457
 
383
- const flushOverflowExcept = (out: Message[], keepTarget: string | null) => {
458
+ const flushOverflowExcept = (
459
+ out: RenderedSlackTranscriptMessage[],
460
+ keepTarget: string | null,
461
+ ) => {
384
462
  for (const target of Array.from(overflowAccumulator.keys())) {
385
463
  if (target === keepTarget) continue;
386
464
  const acc = overflowAccumulator.get(target)!;
@@ -389,7 +467,7 @@ export function renderSlackTranscript(
389
467
  }
390
468
  };
391
469
 
392
- const out: Message[] = [];
470
+ const out: RenderedSlackTranscriptMessage[] = [];
393
471
  for (const m of sorted) {
394
472
  const meta = m.metadata;
395
473
  if (meta?.eventKind === "reaction" && meta.reaction) {
@@ -403,8 +481,11 @@ export function renderSlackTranscript(
403
481
  const line = renderReaction(m);
404
482
  if (line !== null) {
405
483
  out.push({
406
- role: m.role,
407
- content: [{ type: "text" as const, text: line }],
484
+ message: {
485
+ role: m.role,
486
+ content: [{ type: "text" as const, text: line }],
487
+ },
488
+ sourceChannelTs: meta.channelTs,
408
489
  });
409
490
  }
410
491
  } else {
@@ -414,8 +495,13 @@ export function renderSlackTranscript(
414
495
  const acc = overflowAccumulator.get(target) ?? {
415
496
  excess: 0,
416
497
  role: m.role,
498
+ sourceChannelTs: null,
417
499
  };
418
500
  acc.excess += 1;
501
+ acc.sourceChannelTs = maxNullableSlackTs(
502
+ acc.sourceChannelTs,
503
+ meta.channelTs,
504
+ );
419
505
  overflowAccumulator.set(target, acc);
420
506
  }
421
507
  continue;
@@ -426,15 +512,22 @@ export function renderSlackTranscript(
426
512
  const blocks = buildMessageContentBlocks(m, tagLine);
427
513
  if (blocks.length === 0) continue;
428
514
  out.push({
429
- role: m.role,
430
- content: blocks,
515
+ message: {
516
+ role: m.role,
517
+ content: blocks,
518
+ },
519
+ sourceChannelTs: meta?.channelTs ?? null,
431
520
  });
432
521
  }
433
522
 
434
523
  // End of the walk: flush any still-open overflow windows.
435
524
  flushOverflowExcept(out, null);
436
525
 
437
- return filterOrphanToolPairs(out);
526
+ const filtered = filterOrphanToolPairs(out);
527
+ return {
528
+ renderedMessages: filtered,
529
+ messages: filtered.map((entry) => entry.message),
530
+ };
438
531
  }
439
532
 
440
533
  /**
@@ -459,18 +552,21 @@ export function renderSlackTranscript(
459
552
  * emitted as `{role, content: []}` — empty-content messages are also
460
553
  * rejected by the provider.
461
554
  */
462
- function filterOrphanToolPairs(messages: Message[]): Message[] {
555
+ function filterOrphanToolPairs(
556
+ entries: RenderedSlackTranscriptMessage[],
557
+ ): RenderedSlackTranscriptMessage[] {
463
558
  const produced = new Set<string>();
464
559
  const consumed = new Set<string>();
465
- for (const msg of messages) {
560
+ for (const { message: msg } of entries) {
466
561
  for (const b of msg.content) {
467
562
  if (b.type === "tool_use") produced.add(b.id);
468
563
  else if (b.type === "tool_result" || b.type === "web_search_tool_result")
469
564
  consumed.add(b.tool_use_id);
470
565
  }
471
566
  }
472
- const out: Message[] = [];
473
- for (const msg of messages) {
567
+ const out: RenderedSlackTranscriptMessage[] = [];
568
+ for (const entry of entries) {
569
+ const msg = entry.message;
474
570
  const kept: ContentBlock[] = [];
475
571
  for (const b of msg.content) {
476
572
  if (b.type === "tool_use" && !consumed.has(b.id)) continue;
@@ -481,7 +577,12 @@ function filterOrphanToolPairs(messages: Message[]): Message[] {
481
577
  continue;
482
578
  kept.push(b);
483
579
  }
484
- if (kept.length > 0) out.push({ role: msg.role, content: kept });
580
+ if (kept.length > 0) {
581
+ out.push({
582
+ message: { role: msg.role, content: kept },
583
+ sourceChannelTs: entry.sourceChannelTs,
584
+ });
585
+ }
485
586
  }
486
587
  return out;
487
588
  }
@@ -59,6 +59,7 @@ export interface SlackConversationHistoryResponse extends SlackApiResponse {
59
59
  export interface SlackConversationRepliesResponse extends SlackApiResponse {
60
60
  messages: SlackMessage[];
61
61
  has_more: boolean;
62
+ response_metadata?: { next_cursor?: string };
62
63
  }
63
64
 
64
65
  export interface SlackUser {