@sentry/junior 0.185.0 → 0.186.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/dist/{agent-hooks-NGZQLL5O.js → agent-hooks-4B3Z4WRK.js} +11 -11
  2. package/dist/api/schema/conversation.d.ts +8 -0
  3. package/dist/api/schema.js +1 -1
  4. package/dist/api.js +43 -35
  5. package/dist/app.js +1061 -216
  6. package/dist/{catalog-runtime-AAEAO2RL.js → catalog-runtime-AFJCAOHC.js} +4 -4
  7. package/dist/chat/api-turns/mailbox-input.d.ts +7 -0
  8. package/dist/chat/api-turns/routing.d.ts +18 -3
  9. package/dist/chat/conversations/turn-lifecycle.d.ts +2 -0
  10. package/dist/chat/providers/slack/runtime.d.ts +0 -2
  11. package/dist/chat/providers/slack/turn.d.ts +0 -2
  12. package/dist/chat/resource-events/actor.d.ts +7 -2
  13. package/dist/chat/resource-events/app-publisher.d.ts +18 -0
  14. package/dist/chat/resource-events/catalog.d.ts +19 -0
  15. package/dist/chat/resource-events/ingest.d.ts +0 -1
  16. package/dist/chat/resource-events/notification.d.ts +28 -3
  17. package/dist/chat/resource-events/runtime-catalog.d.ts +7 -2
  18. package/dist/chat/resource-events/store.d.ts +1 -13
  19. package/dist/chat/resource-events/workspace.d.ts +7 -3
  20. package/dist/chat/sandbox/egress/credentials.d.ts +5 -4
  21. package/dist/chat/sandbox/egress/session.d.ts +9 -9
  22. package/dist/chat/sandbox/errors.d.ts +1 -1
  23. package/dist/chat/sandbox/ref.d.ts +1 -1
  24. package/dist/chat/sandbox/snapshot/events.d.ts +8 -1
  25. package/dist/chat/sandbox/snapshot/not-ready-error.d.ts +6 -1
  26. package/dist/chat/sentry-links.d.ts +2 -0
  27. package/dist/chat/services/turn-session-routing.d.ts +20 -5
  28. package/dist/chat/task-execution/slack-resource-event.d.ts +47 -0
  29. package/dist/chat/task-execution/slack-work.d.ts +0 -21
  30. package/dist/chat/tools/event-tasks.d.ts +1 -1
  31. package/dist/chat/tools/resource-events.d.ts +1 -1
  32. package/dist/{chunk-D63IUQQE.js → chunk-2IBDVE62.js} +12 -9
  33. package/dist/{chunk-C6TS47CQ.js → chunk-2U7EPTRZ.js} +11 -5
  34. package/dist/{chunk-OMQ2J6F6.js → chunk-3CVEE6LA.js} +1 -1
  35. package/dist/{chunk-ABAX75GG.js → chunk-43LODHJM.js} +17 -3
  36. package/dist/{chunk-7MHNIGHP.js → chunk-64WF2GQ3.js} +1 -1
  37. package/dist/{chunk-X7NCJQAA.js → chunk-7EOWT62G.js} +1 -1
  38. package/dist/{chunk-MWOH6CIK.js → chunk-7EU4YSZ4.js} +201 -57
  39. package/dist/{chunk-4S47VHJR.js → chunk-ACGWTJ74.js} +3 -3
  40. package/dist/{chunk-LRI5IRGY.js → chunk-AD64YMEC.js} +2 -2
  41. package/dist/{chunk-FTVMXDNN.js → chunk-BRKB5R7P.js} +1 -1
  42. package/dist/{chunk-Y5G23T2D.js → chunk-CM6RTYSO.js} +5 -5
  43. package/dist/{chunk-QCT4226Q.js → chunk-CV5CPRVG.js} +3 -3
  44. package/dist/{chunk-QZKHHG3B.js → chunk-DHYZ4VKG.js} +382 -279
  45. package/dist/{chunk-PNYJOEVV.js → chunk-DOP3FIQC.js} +1 -1
  46. package/dist/{chunk-HJPC32TQ.js → chunk-EWRPUXE3.js} +9 -9
  47. package/dist/{chunk-EIJCPJOY.js → chunk-FFYDRLXW.js} +1 -1
  48. package/dist/{chunk-W7GCLNIV.js → chunk-GQMQCY7H.js} +2 -2
  49. package/dist/{chunk-6DOAUXLD.js → chunk-GSB3NTNS.js} +744 -1707
  50. package/dist/{chunk-WLKWN4CD.js → chunk-H7X2G2KS.js} +8 -5
  51. package/dist/{chunk-ATUWN6Z3.js → chunk-HKFLRIBD.js} +2 -2
  52. package/dist/{chunk-EJYP3NQ4.js → chunk-HWXP6RHG.js} +37 -3
  53. package/dist/{chunk-VH4IU3UC.js → chunk-JFPY6XFF.js} +19 -45
  54. package/dist/{chunk-FFHXG2FX.js → chunk-MCLWOBPN.js} +76 -16
  55. package/dist/{chunk-GJTIZQGJ.js → chunk-NRMAOGRS.js} +1 -1
  56. package/dist/{chunk-X2SS6BF7.js → chunk-O6GQO7VP.js} +27 -33
  57. package/dist/{chunk-DAPC2HTM.js → chunk-OZG7E22Y.js} +5 -5
  58. package/dist/{chunk-4K25ODAO.js → chunk-PFAZSRGR.js} +3 -1
  59. package/dist/{chunk-UUULGCKK.js → chunk-PZZOGHVR.js} +14 -4
  60. package/dist/{chunk-TVVAMOLS.js → chunk-QBL2AVFF.js} +1 -1
  61. package/dist/{chunk-4HA36IWS.js → chunk-QU3URVWG.js} +8 -8
  62. package/dist/{chunk-6Q7YZLCL.js → chunk-STOCCPWH.js} +9 -1
  63. package/dist/{chunk-EWEH2PJW.js → chunk-TXLBLGNQ.js} +5 -5
  64. package/dist/{chunk-U4CTAVWN.js → chunk-VOGOTEW7.js} +1 -1
  65. package/dist/{chunk-ZIF2S464.js → chunk-VQIWBJOP.js} +1 -1
  66. package/dist/{chunk-ZKKGFUWM.js → chunk-VQZYIVYN.js} +6 -6
  67. package/dist/{chunk-LVK4WJKM.js → chunk-VXL2LBPK.js} +1 -1
  68. package/dist/{chunk-7GAP2XG4.js → chunk-YXSBZRP7.js} +1 -1
  69. package/dist/cli/chat.js +32 -32
  70. package/dist/cli/check.js +5 -5
  71. package/dist/cli/plugins.js +12 -12
  72. package/dist/cli/snapshot-create.js +9 -9
  73. package/dist/cli/upgrade.js +6 -6
  74. package/dist/{db-TRJ77FAU.js → db-7XL4UPAE.js} +6 -6
  75. package/dist/instrumentation.js +3 -3
  76. package/dist/nitro.js +6 -6
  77. package/dist/{oauth-callback-server-XD5SV3MS.js → oauth-callback-server-RAOYHWDI.js} +27 -27
  78. package/dist/{runner-KFX7NG6D.js → runner-KMPBWRPM.js} +19 -19
  79. package/dist/{skills-J2AH26CW.js → skills-IPCALGLQ.js} +5 -5
  80. package/dist/spawn-OSOWTMBG.js +41 -0
  81. package/dist/task-runner-IQNBA3RY.js +34 -0
  82. package/dist/{validation-O5J4VOPF.js → validation-BSRCCX6N.js} +5 -5
  83. package/dist/version.js +1 -1
  84. package/dist/{work-ECPQTG3U.js → work-T6UFTOJY.js} +20 -20
  85. package/dist/{worker-RS3DXUDO.js → worker-L35OG7VA.js} +10 -10
  86. package/package.json +5 -5
  87. package/dist/spawn-VU3CSRI6.js +0 -41
  88. package/dist/task-runner-5JG3VIIY.js +0 -34
package/dist/app.js CHANGED
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  processConversationWork
3
- } from "./chunk-C6TS47CQ.js";
3
+ } from "./chunk-2U7EPTRZ.js";
4
4
  import {
5
5
  bindSpawnAgent
6
- } from "./chunk-TVVAMOLS.js";
6
+ } from "./chunk-QBL2AVFF.js";
7
7
  import {
8
8
  createAgentInvocationWorker,
9
9
  enqueueAgentInvocation,
10
10
  listPendingAgentInvocationMailboxAppends,
11
11
  routeAgentInvocationWork
12
- } from "./chunk-HJPC32TQ.js";
12
+ } from "./chunk-EWRPUXE3.js";
13
13
  import {
14
14
  GET as GET2,
15
15
  GET2 as GET3,
@@ -37,7 +37,7 @@ import {
37
37
  startProcessingReaction,
38
38
  stripLeadingBotMention,
39
39
  wakePausedTurn
40
- } from "./chunk-X2SS6BF7.js";
40
+ } from "./chunk-O6GQO7VP.js";
41
41
  import "./chunk-FA6POGLH.js";
42
42
  import {
43
43
  GET,
@@ -48,18 +48,19 @@ import {
48
48
  createApiTurnWorker,
49
49
  createVercelAttachmentStorage,
50
50
  getAuthPausedApiTurnId,
51
+ lookupSlackUser,
51
52
  readConversationAccessFromSql,
52
53
  recordApiConversationActivity,
53
54
  resolveSlackChannelTypeFromMessage,
54
55
  resolveSlackConversationContext,
55
56
  routeApiTurnWork,
56
57
  webActorFromEmail
57
- } from "./chunk-MWOH6CIK.js";
58
- import "./chunk-UUULGCKK.js";
58
+ } from "./chunk-7EU4YSZ4.js";
59
+ import "./chunk-PZZOGHVR.js";
59
60
  import {
60
61
  AgentRunError,
61
62
  executeTurn
62
- } from "./chunk-W7GCLNIV.js";
63
+ } from "./chunk-GQMQCY7H.js";
63
64
  import {
64
65
  buildDeliveredTurnStatePatch,
65
66
  completeAuthPauseTurn,
@@ -70,7 +71,7 @@ import {
70
71
  getTurnUserSlackMessageTs,
71
72
  persistAuthPauseTurnState,
72
73
  requireTurnFailureEventId
73
- } from "./chunk-DAPC2HTM.js";
74
+ } from "./chunk-OZG7E22Y.js";
74
75
  import {
75
76
  claimDispatchMailboxAppend,
76
77
  confirmDispatchMailboxAppend,
@@ -88,12 +89,13 @@ import {
88
89
  markDispatchFailed,
89
90
  markDispatchRunning,
90
91
  recordTaskExecution,
92
+ resolveConversationRouting,
91
93
  resolveTurnSessionRouting,
92
94
  scheduleSessionCompletedPluginTasks
93
- } from "./chunk-FFHXG2FX.js";
95
+ } from "./chunk-MCLWOBPN.js";
94
96
  import {
95
- ConversationTurnLifecycleService
96
- } from "./chunk-6Q7YZLCL.js";
97
+ getTurnLifecycle
98
+ } from "./chunk-STOCCPWH.js";
97
99
  import {
98
100
  coerceThreadConversationState,
99
101
  getLocationConfigurationService,
@@ -102,17 +104,17 @@ import {
102
104
  persistThreadRuntimeState,
103
105
  persistThreadState,
104
106
  persistThreadStateById
105
- } from "./chunk-Y5G23T2D.js";
107
+ } from "./chunk-CM6RTYSO.js";
106
108
  import "./chunk-UTL3MHPC.js";
107
109
  import {
108
110
  createVercelPluginTaskCallback,
109
111
  queueCallback,
110
112
  registerVercelPluginTaskDevConsumer
111
- } from "./chunk-4S47VHJR.js";
113
+ } from "./chunk-ACGWTJ74.js";
112
114
  import {
113
115
  validatePluginEgressCredentialHooks,
114
116
  validatePluginRegistrations
115
- } from "./chunk-ZIF2S464.js";
117
+ } from "./chunk-VQIWBJOP.js";
116
118
  import {
117
119
  defineJuniorPlugins,
118
120
  pluginCatalogConfigFromEnv,
@@ -120,28 +122,20 @@ import {
120
122
  pluginRuntimeRegistrationsFromPluginSet
121
123
  } from "./chunk-CM5HNV2W.js";
122
124
  import {
123
- RESOURCE_EVENT_SYSTEM_ACTOR,
124
125
  SANDBOX_EGRESS_PROXY_PATH,
125
- buildSlackInboundMessage,
126
126
  buildSteeringPiMessage,
127
127
  clearSandboxEgressSignals,
128
128
  consumeSandboxEgressAuthRequiredSignal,
129
129
  consumeSandboxEgressPermissionDeniedSignal,
130
130
  createContextCompactor,
131
- createSlackConversationWorker,
132
- ensureSlackMessageActorIdentity,
133
131
  executeAgentRun,
134
132
  executeCredentialedEgressRequest,
135
133
  getConfigDefaults,
136
- getMessageActorIdentity,
137
134
  getNextRunAtMs,
138
135
  ingestResourceEvent,
139
- isResourceEventConversationMessage,
140
- isResourceEventSlackMessage,
141
136
  latestReportedProgress,
142
137
  listThreadReplies,
143
138
  logScheduledTaskRunSkipped,
144
- normalizeIncomingSlackThreadId,
145
139
  normalizeSandboxEgressTracePropagationDomains,
146
140
  parseSandboxEgressCredentialToken,
147
141
  processWorkspaceSnapshotJob,
@@ -151,20 +145,16 @@ import {
151
145
  renderBlockText,
152
146
  resolveDestinationVisibility,
153
147
  resolveSandboxEgressProviderForHost,
154
- runWithSlackInstallation,
155
148
  scheduledTaskRunAttributes,
156
149
  setConfigDefaults,
157
150
  shouldEmitDevAgentTrace,
158
151
  shouldPropagateSandboxEgressTrace,
159
- stripLeadingSteeringOverride,
160
- unpublishedArtifactHeaders,
161
- verifySlackSignature,
162
- withNormalizedThreadId
163
- } from "./chunk-6DOAUXLD.js";
152
+ unpublishedArtifactHeaders
153
+ } from "./chunk-GSB3NTNS.js";
164
154
  import {
165
155
  AuthorizationFlowDisabledError,
166
156
  PluginCredentialFailureError
167
- } from "./chunk-EWEH2PJW.js";
157
+ } from "./chunk-TXLBLGNQ.js";
168
158
  import "./chunk-6Y5B5PEX.js";
169
159
  import "./chunk-DIB4GX3G.js";
170
160
  import {
@@ -172,21 +162,24 @@ import {
172
162
  deleteMcpAuthSessionsForUserProvider,
173
163
  deleteMcpServerSessionId,
174
164
  deleteMcpStoredOAuthCredentials
175
- } from "./chunk-4HA36IWS.js";
165
+ } from "./chunk-QU3URVWG.js";
176
166
  import {
177
167
  formatProviderLabel,
178
168
  postSlackMessage,
179
169
  startOAuthFlow
180
- } from "./chunk-ZKKGFUWM.js";
170
+ } from "./chunk-VQZYIVYN.js";
181
171
  import {
172
+ RESOURCE_EVENT_AUTHOR_ID,
173
+ RESOURCE_EVENT_SYSTEM_ACTOR,
182
174
  collectAttachmentGarbage,
183
175
  collectEventTaskMatchKeys,
184
- createResourceEventTeamIdResolver,
185
176
  findMatchingEventTasks,
186
177
  getResourceEventCatalog,
178
+ isResourceEventConversationMessage,
179
+ isResourceEventMailboxMetadata,
180
+ isResourceEventSlackMessage,
187
181
  listScheduledTasks,
188
182
  listScheduledTasksForTeam,
189
- lookupSlackUser,
190
183
  readScheduledTask,
191
184
  requestAttachmentDeletion,
192
185
  resourceEventGuidance,
@@ -194,10 +187,10 @@ import {
194
187
  scheduledRunId,
195
188
  scheduledRunSchema,
196
189
  withScheduledTaskLock
197
- } from "./chunk-QZKHHG3B.js";
190
+ } from "./chunk-DHYZ4VKG.js";
198
191
  import {
199
192
  parseSlackThreadId
200
- } from "./chunk-X7NCJQAA.js";
193
+ } from "./chunk-7EOWT62G.js";
201
194
  import {
202
195
  RetryableDeliveryError,
203
196
  createAgentRunner
@@ -216,7 +209,7 @@ import {
216
209
  removeActiveConversation,
217
210
  requestConversationWork,
218
211
  stopConversationWork
219
- } from "./chunk-D63IUQQE.js";
212
+ } from "./chunk-2IBDVE62.js";
220
213
  import {
221
214
  ConversationTurnBoundaryError,
222
215
  CooperativeTurnYieldError,
@@ -234,7 +227,7 @@ import {
234
227
  markTurnCompleted,
235
228
  markTurnFailed,
236
229
  startActiveTurn
237
- } from "./chunk-U4CTAVWN.js";
230
+ } from "./chunk-VOGOTEW7.js";
238
231
  import {
239
232
  abandonTurnRecord,
240
233
  appendThreadContextMessages,
@@ -270,7 +263,7 @@ import {
270
263
  trimTrailingAssistantMessages,
271
264
  turnHasReply,
272
265
  upsertConversationMessage
273
- } from "./chunk-WLKWN4CD.js";
266
+ } from "./chunk-H7X2G2KS.js";
274
267
  import {
275
268
  getExperimentalFeatures,
276
269
  isExperimentalFeatureEnabled,
@@ -279,7 +272,7 @@ import {
279
272
  import {
280
273
  getSandboxResourceConfig,
281
274
  setSandboxResourceConfig
282
- } from "./chunk-QCT4226Q.js";
275
+ } from "./chunk-CV5CPRVG.js";
283
276
  import "./chunk-PDO5BLNM.js";
284
277
  import "./chunk-UIE3R5XU.js";
285
278
  import {
@@ -298,7 +291,7 @@ import {
298
291
  import "./chunk-7H2VZTWN.js";
299
292
  import {
300
293
  getTurnRequestDeadline
301
- } from "./chunk-FTVMXDNN.js";
294
+ } from "./chunk-BRKB5R7P.js";
302
295
  import {
303
296
  SlackActionError,
304
297
  bindEventTaskCredentialSubject,
@@ -316,6 +309,7 @@ import {
316
309
  getWorkspaceTeamId,
317
310
  isDmChannel,
318
311
  normalizeSlackConversationId,
312
+ runWithSlackInstallationToken,
319
313
  runWithWorkspaceTeamId,
320
314
  setDashboardConversationLinkOptions,
321
315
  setPlugins,
@@ -323,9 +317,10 @@ import {
323
317
  verifyEventTaskCredentialSubject,
324
318
  verifyScheduledTaskCredentialSubject,
325
319
  verifySlackDirectCredentialSubject
326
- } from "./chunk-VH4IU3UC.js";
320
+ } from "./chunk-JFPY6XFF.js";
327
321
  import "./chunk-3Y47VMHV.js";
328
322
  import {
323
+ createSlackDestination,
329
324
  deleteProviderIdentityForSlackUser,
330
325
  getConversationEventStore,
331
326
  getConversationStore,
@@ -334,7 +329,7 @@ import {
334
329
  requireSlackDestination,
335
330
  withConversationEventLock,
336
331
  withConversationMutationLock
337
- } from "./chunk-ABAX75GG.js";
332
+ } from "./chunk-43LODHJM.js";
338
333
  import {
339
334
  juniorAgentBindings,
340
335
  juniorAgentInvocations,
@@ -342,13 +337,13 @@ import {
342
337
  juniorConversations,
343
338
  juniorSchedulerRuns,
344
339
  juniorSchedulerTasks
345
- } from "./chunk-LVK4WJKM.js";
346
- import "./chunk-EJYP3NQ4.js";
340
+ } from "./chunk-VXL2LBPK.js";
341
+ import "./chunk-HWXP6RHG.js";
347
342
  import {
348
343
  acquireActiveLock,
349
344
  getStateAdapter,
350
345
  withActiveLock
351
- } from "./chunk-PNYJOEVV.js";
346
+ } from "./chunk-DOP3FIQC.js";
352
347
  import {
353
348
  contextProvenance,
354
349
  instructionProvenanceFor
@@ -371,17 +366,17 @@ import {
371
366
  isProviderRetryError,
372
367
  setProfiles,
373
368
  setSlackReactionConfig
374
- } from "./chunk-LRI5IRGY.js";
369
+ } from "./chunk-AD64YMEC.js";
375
370
  import {
376
371
  defaultModelId,
377
372
  modelIdForProfile
378
373
  } from "./chunk-D4YV5TDV.js";
379
- import "./chunk-EIJCPJOY.js";
380
- import "./chunk-ATUWN6Z3.js";
374
+ import "./chunk-FFYDRLXW.js";
375
+ import "./chunk-HKFLRIBD.js";
381
376
  import {
382
377
  pluginCatalogRuntime
383
- } from "./chunk-GJTIZQGJ.js";
384
- import "./chunk-7MHNIGHP.js";
378
+ } from "./chunk-NRMAOGRS.js";
379
+ import "./chunk-64WF2GQ3.js";
385
380
  import {
386
381
  credentialContextForActor
387
382
  } from "./chunk-CEMMLV5L.js";
@@ -389,6 +384,7 @@ import {
389
384
  createActor,
390
385
  createSlackActor,
391
386
  createSlackResumeActor,
387
+ isActorUserId,
392
388
  parseActorUserId,
393
389
  parseSlackChannelId,
394
390
  parseSlackMessageTs
@@ -416,13 +412,13 @@ import {
416
412
  withContext,
417
413
  withLogContext,
418
414
  withSpan
419
- } from "./chunk-OMQ2J6F6.js";
415
+ } from "./chunk-3CVEE6LA.js";
420
416
  import {
421
417
  continueTrace
422
418
  } from "./chunk-PEQXYSSE.js";
423
419
  import {
424
420
  JUNIOR_VERSION
425
- } from "./chunk-7GAP2XG4.js";
421
+ } from "./chunk-YXSBZRP7.js";
426
422
 
427
423
  // src/app.ts
428
424
  import { createRequire } from "module";
@@ -2750,8 +2746,830 @@ async function GET6(request) {
2750
2746
  // src/chat/ingress/slack-webhook.ts
2751
2747
  import {
2752
2748
  ChannelImpl,
2753
- ThreadImpl
2749
+ ThreadImpl as ThreadImpl3
2750
+ } from "chat";
2751
+
2752
+ // src/chat/task-execution/slack-work.ts
2753
+ import {
2754
+ Message as Message3,
2755
+ ThreadImpl as ThreadImpl2
2754
2756
  } from "chat";
2757
+ import { z as z3 } from "zod";
2758
+
2759
+ // src/chat/ingress/message-router.ts
2760
+ import { Message } from "chat";
2761
+ function withNormalizedThreadId(message, threadId) {
2762
+ if (message.threadId === threadId) {
2763
+ return message;
2764
+ }
2765
+ return new Message({
2766
+ attachments: message.attachments,
2767
+ author: message.author,
2768
+ formatted: message.formatted,
2769
+ id: message.id,
2770
+ isMention: message.isMention,
2771
+ links: message.links,
2772
+ metadata: message.metadata,
2773
+ raw: message.raw,
2774
+ text: message.text,
2775
+ threadId
2776
+ });
2777
+ }
2778
+ function normalizeIncomingSlackThreadId(threadId, message) {
2779
+ if (!threadId.startsWith("slack:")) {
2780
+ return threadId;
2781
+ }
2782
+ if (!message || typeof message !== "object") {
2783
+ return threadId;
2784
+ }
2785
+ const raw = message.raw;
2786
+ if (!raw || typeof raw !== "object") {
2787
+ return threadId;
2788
+ }
2789
+ const channelId = nonEmptyString(raw.channel);
2790
+ const threadTs = nonEmptyString(raw.thread_ts) ?? nonEmptyString(raw.ts);
2791
+ if (!channelId || !threadTs) {
2792
+ return threadId;
2793
+ }
2794
+ return `slack:${channelId}:${threadTs}`;
2795
+ }
2796
+ function nonEmptyString(value) {
2797
+ if (typeof value !== "string") return void 0;
2798
+ const trimmed = value.trim();
2799
+ return trimmed || void 0;
2800
+ }
2801
+
2802
+ // src/chat/slack/attachment-fetchers.ts
2803
+ function rehydrateAttachmentFetchers(message, downloadPrivateSlackFile2 = downloadPrivateSlackFile) {
2804
+ for (const attachment of message.attachments) {
2805
+ if (!attachment.fetchData && attachment.url) {
2806
+ attachment.fetchData = () => downloadPrivateSlackFile2(attachment.url);
2807
+ }
2808
+ }
2809
+ }
2810
+
2811
+ // src/chat/slack/adapter-context.ts
2812
+ var initializedAdapters = /* @__PURE__ */ new WeakSet();
2813
+ async function getConnectedState(stateAdapter) {
2814
+ const state = stateAdapter ?? getStateAdapter();
2815
+ await state.connect();
2816
+ return state;
2817
+ }
2818
+ async function ensureSlackAdapterInitialized(args) {
2819
+ if (initializedAdapters.has(args.adapter)) {
2820
+ return;
2821
+ }
2822
+ const state = await getConnectedState(args.state);
2823
+ await args.adapter.initialize({
2824
+ getState: () => state
2825
+ });
2826
+ const internals = args.adapter;
2827
+ if (internals.defaultBotTokenProvider && !args.adapter.botUserId) {
2828
+ throw new Error("Slack adapter initialized without a resolved bot user id");
2829
+ }
2830
+ initializedAdapters.add(args.adapter);
2831
+ }
2832
+ function verifySlackSignature(args) {
2833
+ const internals = args.adapter;
2834
+ const verifySignature = internals.verifySignature;
2835
+ if (!verifySignature) {
2836
+ throw new Error("Slack adapter does not expose signature verification");
2837
+ }
2838
+ return verifySignature.call(
2839
+ args.adapter,
2840
+ args.body,
2841
+ args.request.headers.get("x-slack-request-timestamp"),
2842
+ args.request.headers.get("x-slack-signature")
2843
+ );
2844
+ }
2845
+ async function runWithSlackInstallation(args) {
2846
+ await ensureSlackAdapterInitialized({
2847
+ adapter: args.adapter,
2848
+ state: args.state
2849
+ });
2850
+ const internals = args.adapter;
2851
+ if (internals.defaultBotTokenProvider) {
2852
+ return await args.task();
2853
+ }
2854
+ const installationId = args.installation.isEnterpriseInstall ? args.installation.enterpriseId : args.installation.teamId;
2855
+ if (!installationId) {
2856
+ throw new Error("Slack installation context is missing team id");
2857
+ }
2858
+ if (!internals.resolveTokenForTeam || !internals.requestContext) {
2859
+ throw new Error("Slack adapter cannot resolve workspace installations");
2860
+ }
2861
+ const tokenContext = await internals.resolveTokenForTeam.call(
2862
+ args.adapter,
2863
+ installationId,
2864
+ args.installation.isEnterpriseInstall
2865
+ );
2866
+ if (!tokenContext) {
2867
+ throw new Error(
2868
+ `Slack installation token was not found for ${installationId}`
2869
+ );
2870
+ }
2871
+ return await internals.requestContext.run(
2872
+ {
2873
+ ...tokenContext,
2874
+ enterpriseId: args.installation.enterpriseId,
2875
+ isEnterpriseInstall: args.installation.isEnterpriseInstall
2876
+ },
2877
+ () => runWithSlackInstallationToken(tokenContext.token, args.task)
2878
+ );
2879
+ }
2880
+
2881
+ // src/chat/services/message-actor-identity.ts
2882
+ var messageActors = /* @__PURE__ */ new WeakMap();
2883
+ function canonicalUserId(author, actor) {
2884
+ const authorUserId = parseActorUserId(author.userId);
2885
+ if (authorUserId && authorUserId !== actor.userId) {
2886
+ throw new Error("Message actor user id mismatch");
2887
+ }
2888
+ const userId = authorUserId ?? actor.userId;
2889
+ if (!userId) {
2890
+ throw new Error("Message actor requires a user id");
2891
+ }
2892
+ return userId;
2893
+ }
2894
+ function actorFromAuthor(author) {
2895
+ const userId = parseActorUserId(author.userId);
2896
+ return userId ? { userId } : void 0;
2897
+ }
2898
+ function applyActorToAuthor(author, actor) {
2899
+ if (!isActorUserId(actor.userId)) {
2900
+ throw new Error("Message actor requires a user id");
2901
+ }
2902
+ author.userId = actor.userId;
2903
+ author.userName = actor.userName ?? "";
2904
+ author.fullName = actor.fullName ?? "";
2905
+ }
2906
+ function bindMessageActorIdentity(message, actor) {
2907
+ const userId = canonicalUserId(message.author, actor);
2908
+ const currentActor = createActor(actor, {
2909
+ platform: actor.platform,
2910
+ ...actor.platform === "slack" ? { teamId: actor.teamId } : void 0,
2911
+ userId
2912
+ });
2913
+ if (!currentActor) {
2914
+ throw new Error("Message actor requires a user id");
2915
+ }
2916
+ messageActors.set(message, currentActor);
2917
+ applyActorToAuthor(message.author, currentActor);
2918
+ return currentActor;
2919
+ }
2920
+ function getMessageActorIdentity(message) {
2921
+ return messageActors.get(message) ?? actorFromAuthor(message.author);
2922
+ }
2923
+ async function ensureSlackMessageActorIdentity(message, teamId, lookupSlackUser2) {
2924
+ const existing = messageActors.get(message);
2925
+ if (existing) {
2926
+ if (existing.platform !== "slack") {
2927
+ throw new Error("Slack message actor identity requires a Slack actor");
2928
+ }
2929
+ return existing;
2930
+ }
2931
+ const userId = parseActorUserId(message.author.userId);
2932
+ if (!userId) {
2933
+ throw new Error("Slack message actor identity requires a user id");
2934
+ }
2935
+ const actor = bindMessageActorIdentity(
2936
+ message,
2937
+ createSlackActor(teamId, userId, await lookupSlackUser2(teamId, userId))
2938
+ );
2939
+ if (actor.platform !== "slack") {
2940
+ throw new Error("Slack message actor identity requires a Slack actor");
2941
+ }
2942
+ return actor;
2943
+ }
2944
+
2945
+ // src/chat/task-execution/slack-resource-event.ts
2946
+ import { Message as Message2, ThreadImpl } from "chat";
2947
+ async function resolveSlackResourceEventThread(args) {
2948
+ const routing = await resolveConversationRouting({
2949
+ conversationId: args.conversationId,
2950
+ conversationStore: args.conversationStore
2951
+ });
2952
+ const destination = requireSlackDestination(
2953
+ routing?.destination ?? args.destination,
2954
+ "Slack resource-event turn"
2955
+ );
2956
+ const threadTs = routing?.source?.platform === "slack" ? routing.source.threadTs?.trim() : void 0;
2957
+ if (!threadTs) {
2958
+ throw new Error(
2959
+ `Conversation ${args.conversationId} is missing a Slack thread for resource-event delivery`
2960
+ );
2961
+ }
2962
+ return { destination, threadTs };
2963
+ }
2964
+ function isPlainResourceEventRecord(record) {
2965
+ return record.source === "resource_event" && isResourceEventMailboxMetadata(record.input.metadata) && !hasSlackConversationMetadata(record.input.metadata);
2966
+ }
2967
+ function hasSlackConversationMetadata(value) {
2968
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
2969
+ return false;
2970
+ }
2971
+ const record = value;
2972
+ return record.platform === "slack" && typeof record.thread === "object" && record.thread !== null && typeof record.message === "object" && record.message !== null;
2973
+ }
2974
+ function buildResourceEventSlackMessage(args) {
2975
+ if (!isResourceEventMailboxMetadata(args.record.input.metadata)) {
2976
+ throw new Error(
2977
+ "Resource-event Slack turn requires resource-event metadata"
2978
+ );
2979
+ }
2980
+ const event = args.record.input.metadata.resourceEvent;
2981
+ const messageId = `resource-event-${event.subscriptionId}-${event.eventKey}`;
2982
+ const threadId = `slack:${args.channelId}:${args.threadTs}`;
2983
+ return new Message2({
2984
+ id: messageId,
2985
+ threadId,
2986
+ text: args.record.input.text,
2987
+ author: {
2988
+ userId: RESOURCE_EVENT_AUTHOR_ID,
2989
+ userName: "junior-event",
2990
+ fullName: "Junior event",
2991
+ isBot: true,
2992
+ isMe: false
2993
+ },
2994
+ isMention: false,
2995
+ attachments: [],
2996
+ metadata: {
2997
+ dateSent: new Date(args.record.createdAtMs),
2998
+ edited: false
2999
+ },
3000
+ formatted: { type: "root", children: [] },
3001
+ raw: {
3002
+ channel: args.channelId,
3003
+ event_type: "resource_event",
3004
+ resource_event_type: event.eventType,
3005
+ thread_ts: args.threadTs,
3006
+ type: "message",
3007
+ user: RESOURCE_EVENT_AUTHOR_ID
3008
+ }
3009
+ });
3010
+ }
3011
+ function buildResourceEventSlackThread(args) {
3012
+ const threadId = normalizeIncomingSlackThreadId(
3013
+ `slack:${args.channelId}:${args.threadTs}`,
3014
+ args.message
3015
+ );
3016
+ const message = withNormalizedThreadId(args.message, threadId);
3017
+ return new ThreadImpl({
3018
+ adapter: args.adapter,
3019
+ stateAdapter: args.state,
3020
+ id: threadId,
3021
+ channelId: args.channelId,
3022
+ currentMessage: message,
3023
+ initialMessage: message,
3024
+ isDM: args.channelId.startsWith("D"),
3025
+ isSubscribedContext: true
3026
+ });
3027
+ }
3028
+
3029
+ // src/chat/slack/message-control.ts
3030
+ var LEADING_MENTION_BEFORE_STEERING_RE = /^(\s*(?:<@[^>]+>|@[A-Za-z0-9._-]+\b)[\s,:-]*)!!\s*/;
3031
+ function stripLeadingSteeringOverride(text) {
3032
+ return text.replace(LEADING_MENTION_BEFORE_STEERING_RE, "$1").replace(/^\s*!!\s*/, "");
3033
+ }
3034
+
3035
+ // src/chat/task-execution/slack-work.ts
3036
+ var slackConversationRouteSchema = z3.enum(["mention", "subscribed"]);
3037
+ function hasSteeringOverride(text) {
3038
+ return stripLeadingSteeringOverride(text) !== text;
3039
+ }
3040
+ var serializedDateSchema = z3.iso.datetime();
3041
+ var mdastPointSchema = z3.object({
3042
+ column: z3.number().int().positive(),
3043
+ line: z3.number().int().positive(),
3044
+ offset: z3.number().int().nonnegative().optional()
3045
+ }).strict();
3046
+ var mdastPositionSchema = z3.object({
3047
+ end: mdastPointSchema,
3048
+ start: mdastPointSchema
3049
+ }).strict();
3050
+ function isOptionalNullableString(value) {
3051
+ return value === void 0 || value === null || typeof value === "string";
3052
+ }
3053
+ function isOptionalNullableBoolean(value) {
3054
+ return value === void 0 || value === null || typeof value === "boolean";
3055
+ }
3056
+ function hasValidMdastBase(node, fields) {
3057
+ const allowed = /* @__PURE__ */ new Set(["data", "position", "type", ...fields]);
3058
+ return Object.keys(node).every((key) => allowed.has(key)) && (node.data === void 0 || typeof node.data === "object" && node.data !== null && !Array.isArray(node.data)) && (node.position === void 0 || mdastPositionSchema.safeParse(node.position).success);
3059
+ }
3060
+ var mdastPhrasingTypes = /* @__PURE__ */ new Set([
3061
+ "break",
3062
+ "delete",
3063
+ "emphasis",
3064
+ "footnoteReference",
3065
+ "html",
3066
+ "image",
3067
+ "imageReference",
3068
+ "inlineCode",
3069
+ "link",
3070
+ "linkReference",
3071
+ "strong",
3072
+ "text"
3073
+ ]);
3074
+ var mdastBlockOrDefinitionTypes = /* @__PURE__ */ new Set([
3075
+ "blockquote",
3076
+ "code",
3077
+ "definition",
3078
+ "footnoteDefinition",
3079
+ "heading",
3080
+ "html",
3081
+ "list",
3082
+ "paragraph",
3083
+ "table",
3084
+ "thematicBreak"
3085
+ ]);
3086
+ var mdastListItemTypes = /* @__PURE__ */ new Set(["listItem"]);
3087
+ var mdastTableCellTypes = /* @__PURE__ */ new Set(["tableCell"]);
3088
+ var mdastTableRowTypes = /* @__PURE__ */ new Set(["tableRow"]);
3089
+ function hasMdastChildren(node, allowedTypes) {
3090
+ return Array.isArray(node.children) && node.children.every(
3091
+ (child) => isFormattedContentNode(child) && (!allowedTypes || typeof child === "object" && child !== null && !Array.isArray(child) && allowedTypes.has(String(child.type)))
3092
+ );
3093
+ }
3094
+ function isFormattedContentNode(value) {
3095
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
3096
+ return false;
3097
+ }
3098
+ const node = value;
3099
+ switch (node.type) {
3100
+ case "break":
3101
+ case "thematicBreak":
3102
+ return hasValidMdastBase(node, []);
3103
+ case "html":
3104
+ case "inlineCode":
3105
+ case "text":
3106
+ case "yaml":
3107
+ return hasValidMdastBase(node, ["value"]) && typeof node.value === "string";
3108
+ case "code":
3109
+ return hasValidMdastBase(node, ["lang", "meta", "value"]) && typeof node.value === "string" && isOptionalNullableString(node.lang) && isOptionalNullableString(node.meta);
3110
+ case "delete":
3111
+ case "emphasis":
3112
+ case "paragraph":
3113
+ case "strong":
3114
+ case "tableCell":
3115
+ return hasValidMdastBase(node, ["children"]) && hasMdastChildren(node, mdastPhrasingTypes);
3116
+ case "blockquote":
3117
+ return hasValidMdastBase(node, ["children"]) && hasMdastChildren(node, mdastBlockOrDefinitionTypes);
3118
+ case "tableRow":
3119
+ return hasValidMdastBase(node, ["children"]) && hasMdastChildren(node, mdastTableCellTypes);
3120
+ case "heading":
3121
+ return hasValidMdastBase(node, ["children", "depth"]) && hasMdastChildren(node, mdastPhrasingTypes) && Number.isInteger(node.depth) && Number(node.depth) >= 1 && Number(node.depth) <= 6;
3122
+ case "list":
3123
+ return hasValidMdastBase(node, ["children", "ordered", "spread", "start"]) && hasMdastChildren(node, mdastListItemTypes) && isOptionalNullableBoolean(node.ordered) && isOptionalNullableBoolean(node.spread) && (node.start === void 0 || node.start === null || typeof node.start === "number" && Number.isFinite(node.start));
3124
+ case "listItem":
3125
+ return hasValidMdastBase(node, ["checked", "children", "spread"]) && hasMdastChildren(node, mdastBlockOrDefinitionTypes) && isOptionalNullableBoolean(node.checked) && isOptionalNullableBoolean(node.spread);
3126
+ case "table":
3127
+ return hasValidMdastBase(node, ["align", "children"]) && hasMdastChildren(node, mdastTableRowTypes) && (node.align === void 0 || node.align === null || Array.isArray(node.align) && node.align.every(
3128
+ (align) => align === null || align === "center" || align === "left" || align === "right"
3129
+ ));
3130
+ case "definition":
3131
+ return hasValidMdastBase(node, ["identifier", "label", "title", "url"]) && typeof node.identifier === "string" && typeof node.url === "string" && isOptionalNullableString(node.label) && isOptionalNullableString(node.title);
3132
+ case "footnoteDefinition":
3133
+ return hasValidMdastBase(node, ["children", "identifier", "label"]) && hasMdastChildren(node, mdastBlockOrDefinitionTypes) && typeof node.identifier === "string" && isOptionalNullableString(node.label);
3134
+ case "footnoteReference":
3135
+ return hasValidMdastBase(node, ["identifier", "label"]) && typeof node.identifier === "string" && isOptionalNullableString(node.label);
3136
+ case "image":
3137
+ return hasValidMdastBase(node, ["alt", "title", "url"]) && typeof node.url === "string" && isOptionalNullableString(node.alt) && isOptionalNullableString(node.title);
3138
+ case "imageReference":
3139
+ return hasValidMdastBase(node, [
3140
+ "alt",
3141
+ "identifier",
3142
+ "label",
3143
+ "referenceType"
3144
+ ]) && typeof node.identifier === "string" && isOptionalNullableString(node.alt) && isOptionalNullableString(node.label) && (node.referenceType === "collapsed" || node.referenceType === "full" || node.referenceType === "shortcut");
3145
+ case "link":
3146
+ return hasValidMdastBase(node, ["children", "title", "url"]) && hasMdastChildren(node, mdastPhrasingTypes) && typeof node.url === "string" && isOptionalNullableString(node.title);
3147
+ case "linkReference":
3148
+ return hasValidMdastBase(node, [
3149
+ "children",
3150
+ "identifier",
3151
+ "label",
3152
+ "referenceType"
3153
+ ]) && hasMdastChildren(node, mdastPhrasingTypes) && typeof node.identifier === "string" && isOptionalNullableString(node.label) && (node.referenceType === "collapsed" || node.referenceType === "full" || node.referenceType === "shortcut");
3154
+ default:
3155
+ return false;
3156
+ }
3157
+ }
3158
+ var formattedContentSchema = z3.custom(
3159
+ (value) => {
3160
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
3161
+ return false;
3162
+ }
3163
+ const root = value;
3164
+ return root.type === "root" && hasValidMdastBase(root, ["children"]) && hasMdastChildren(root);
3165
+ },
3166
+ "must be a valid formatted-content root"
3167
+ );
3168
+ var serializedMessageSchema = z3.object({
3169
+ _type: z3.literal("chat:Message"),
3170
+ attachments: z3.array(
3171
+ z3.object({
3172
+ type: z3.enum(["image", "file", "video", "audio"]),
3173
+ url: z3.string().optional(),
3174
+ name: z3.string().optional(),
3175
+ mimeType: z3.string().optional(),
3176
+ size: z3.number().finite().optional(),
3177
+ width: z3.number().finite().optional(),
3178
+ height: z3.number().finite().optional(),
3179
+ fetchMetadata: z3.record(z3.string(), z3.string()).optional()
3180
+ }).strict()
3181
+ ),
3182
+ author: z3.object({
3183
+ userId: z3.string(),
3184
+ userName: z3.string(),
3185
+ fullName: z3.string(),
3186
+ isBot: z3.union([z3.boolean(), z3.literal("unknown")]),
3187
+ isMe: z3.boolean()
3188
+ }).strict(),
3189
+ formatted: formattedContentSchema,
3190
+ id: z3.string().min(1),
3191
+ isMention: z3.boolean().optional(),
3192
+ links: z3.array(
3193
+ z3.object({
3194
+ url: z3.string(),
3195
+ title: z3.string().optional(),
3196
+ description: z3.string().optional(),
3197
+ imageUrl: z3.string().optional(),
3198
+ siteName: z3.string().optional()
3199
+ }).strict()
3200
+ ).optional(),
3201
+ metadata: z3.object({
3202
+ dateSent: serializedDateSchema,
3203
+ edited: z3.boolean(),
3204
+ editedAt: serializedDateSchema.optional()
3205
+ }).strict(),
3206
+ raw: z3.unknown(),
3207
+ text: z3.string(),
3208
+ threadId: z3.string().min(1)
3209
+ }).strict();
3210
+ var serializedThreadSchema = z3.object({
3211
+ _type: z3.literal("chat:Thread"),
3212
+ adapterName: z3.literal("slack"),
3213
+ channelId: z3.string().min(1),
3214
+ channelVisibility: z3.enum(["private", "workspace", "external", "unknown"]).optional(),
3215
+ currentMessage: serializedMessageSchema.optional(),
3216
+ id: z3.string().min(1),
3217
+ isDM: z3.boolean()
3218
+ }).strict();
3219
+ var slackInstallationSchema = z3.object({
3220
+ enterpriseId: z3.string().optional(),
3221
+ isEnterpriseInstall: z3.boolean().optional(),
3222
+ teamId: z3.string().optional()
3223
+ }).strict();
3224
+ var slackConversationMessageMetadataBaseSchema = z3.object({
3225
+ installation: slackInstallationSchema.optional(),
3226
+ message: serializedMessageSchema,
3227
+ platform: z3.literal("slack"),
3228
+ route: slackConversationRouteSchema,
3229
+ thread: serializedThreadSchema
3230
+ });
3231
+ var slackConversationMessageMetadataSchema = z3.union([
3232
+ slackConversationMessageMetadataBaseSchema.strict(),
3233
+ slackConversationMessageMetadataBaseSchema.extend({
3234
+ kind: z3.literal("resource_event"),
3235
+ resourceEvent: z3.object({
3236
+ eventKey: z3.string(),
3237
+ eventType: z3.string(),
3238
+ namespace: z3.string(),
3239
+ identifier: z3.string(),
3240
+ subscriptionId: z3.string()
3241
+ }).strict()
3242
+ }).strict()
3243
+ ]);
3244
+ function requireSlackAuthorId(message) {
3245
+ const authorId = parseActorUserId(message.author.userId);
3246
+ if (!authorId) {
3247
+ throw new Error("Slack message requires an actor user id");
3248
+ }
3249
+ return authorId;
3250
+ }
3251
+ function getConnectedState2(stateAdapter) {
3252
+ return stateAdapter ?? getStateAdapter();
3253
+ }
3254
+ function parseSlackMetadata(value) {
3255
+ const parsed = slackConversationMessageMetadataSchema.safeParse(value);
3256
+ return parsed.success ? parsed.data : void 0;
3257
+ }
3258
+ function compareInboundMessages(left, right) {
3259
+ return left.createdAtMs - right.createdAtMs || left.receivedAtMs - right.receivedAtMs || left.inboundMessageId.localeCompare(right.inboundMessageId);
3260
+ }
3261
+ function routeForRecords(records) {
3262
+ return records.some((record) => {
3263
+ if (isPlainResourceEventRecord(record)) {
3264
+ return false;
3265
+ }
3266
+ const metadata = parseSlackMetadata(record.input.metadata);
3267
+ if (!metadata) {
3268
+ throw new Error("Conversation mailbox record is not Slack metadata");
3269
+ }
3270
+ return metadata.route === "mention";
3271
+ }) ? "mention" : "subscribed";
3272
+ }
3273
+ function restoreMessage(args) {
3274
+ if (isPlainResourceEventRecord(args.record)) {
3275
+ if (!args.threadTs) {
3276
+ throw new Error(
3277
+ "Resource-event Slack turn requires a thread timestamp"
3278
+ );
3279
+ }
3280
+ return buildResourceEventSlackMessage({
3281
+ channelId: args.channelId,
3282
+ record: args.record,
3283
+ threadTs: args.threadTs
3284
+ });
3285
+ }
3286
+ const metadata = parseSlackMetadata(args.record.input.metadata);
3287
+ if (!metadata) {
3288
+ throw new Error("Conversation mailbox record is not a Slack message");
3289
+ }
3290
+ const message = Message3.fromJSON(metadata.message);
3291
+ message.attachments = message.attachments.map(
3292
+ (attachment) => args.adapter.rehydrateAttachment(attachment)
3293
+ );
3294
+ rehydrateAttachmentFetchers(message);
3295
+ return message;
3296
+ }
3297
+ async function bindSlackActorIdentities(args) {
3298
+ const byAuthorId = /* @__PURE__ */ new Map();
3299
+ for (const message of args.messages) {
3300
+ if (isResourceEventSlackMessage(message)) {
3301
+ continue;
3302
+ }
3303
+ const authorId = requireSlackAuthorId(message);
3304
+ byAuthorId.set(authorId, [...byAuthorId.get(authorId) ?? [], message]);
3305
+ }
3306
+ await Promise.all(
3307
+ [...byAuthorId].map(async ([authorId, messages]) => {
3308
+ const profile = await args.lookupSlackUser(args.teamId, authorId);
3309
+ await Promise.all(
3310
+ messages.map(
3311
+ (message) => ensureSlackMessageActorIdentity(
3312
+ message,
3313
+ args.teamId,
3314
+ async () => profile
3315
+ )
3316
+ )
3317
+ );
3318
+ })
3319
+ );
3320
+ }
3321
+ function restoreThread(args) {
3322
+ const threadId = normalizeIncomingSlackThreadId(
3323
+ args.threadJson.id,
3324
+ args.message
3325
+ );
3326
+ const message = withNormalizedThreadId(args.message, threadId);
3327
+ return new ThreadImpl2({
3328
+ adapter: args.adapter,
3329
+ stateAdapter: args.state,
3330
+ id: threadId,
3331
+ channelId: args.threadJson.channelId,
3332
+ channelVisibility: args.threadJson.channelVisibility,
3333
+ currentMessage: message,
3334
+ initialMessage: message,
3335
+ isDM: args.threadJson.isDM,
3336
+ isSubscribedContext: args.isSubscribedContext
3337
+ });
3338
+ }
3339
+ function getInstallation(records) {
3340
+ for (let index = records.length - 1; index >= 0; index -= 1) {
3341
+ const metadata = parseSlackMetadata(records[index]?.input.metadata);
3342
+ if (metadata?.installation) {
3343
+ return metadata.installation;
3344
+ }
3345
+ }
3346
+ return {};
3347
+ }
3348
+ function getPendingRecords(work) {
3349
+ if (!work) {
3350
+ return [];
3351
+ }
3352
+ return work.execution.pendingMessages.sort(compareInboundMessages);
3353
+ }
3354
+ function createSlackConversationWorker(options) {
3355
+ const crossActorMidRunMode = options.crossActorMidRunMode ?? botConfig.crossActorMidRunMode;
3356
+ return async (context) => {
3357
+ const adapter = options.getSlackAdapter();
3358
+ const actorLookup = options.lookupSlackUser ?? lookupSlackUser;
3359
+ const state = getConnectedState2(options.state);
3360
+ await state.connect();
3361
+ const records = getPendingRecords({
3362
+ execution: { pendingMessages: [...context.attempt.messages] }
3363
+ });
3364
+ if (records.length === 0) {
3365
+ const destination = requireSlackDestination(
3366
+ context.destination,
3367
+ "Slack paused-turn recovery"
3368
+ );
3369
+ try {
3370
+ await runWithSlackInstallation({
3371
+ adapter,
3372
+ installation: { teamId: destination.teamId },
3373
+ state,
3374
+ task: async () => {
3375
+ await options.runNextPausedTurn(context.conversationId, {
3376
+ shouldYield: context.shouldYield
3377
+ });
3378
+ }
3379
+ });
3380
+ } catch (error) {
3381
+ if (isCooperativeTurnYieldError(error)) {
3382
+ return { status: "yielded" };
3383
+ }
3384
+ throw error;
3385
+ }
3386
+ return { status: "completed" };
3387
+ }
3388
+ const latestRecord = records[records.length - 1];
3389
+ if (!latestRecord) {
3390
+ return { status: "completed" };
3391
+ }
3392
+ const hasPlainResourceEvent = records.some(isPlainResourceEventRecord);
3393
+ const publishExternally = hasPlainResourceEvent ? true : latestRecord.publishExternally ?? context.publishExternally;
3394
+ const latestMetadata = isPlainResourceEventRecord(latestRecord) ? void 0 : parseSlackMetadata(latestRecord.input.metadata);
3395
+ if (!isPlainResourceEventRecord(latestRecord) && !latestMetadata) {
3396
+ throw new Error(
3397
+ "Latest conversation mailbox record is not Slack metadata"
3398
+ );
3399
+ }
3400
+ if (!await context.checkIn()) {
3401
+ return { status: "lost_lease" };
3402
+ }
3403
+ const resourceEventThread = hasPlainResourceEvent ? await resolveSlackResourceEventThread({
3404
+ conversationId: context.conversationId,
3405
+ conversationStore: options.conversationStore,
3406
+ destination: context.destination
3407
+ }) : void 0;
3408
+ const turnResult = await runWithSlackInstallation({
3409
+ adapter,
3410
+ installation: resourceEventThread ? { teamId: resourceEventThread.destination.teamId } : getInstallation(records),
3411
+ state,
3412
+ task: async () => {
3413
+ const destination = resourceEventThread?.destination ?? requireSlackDestination(
3414
+ context.destination,
3415
+ "Slack conversation work"
3416
+ );
3417
+ const threadTs = resourceEventThread?.threadTs;
3418
+ const messages = records.map(
3419
+ (record) => restoreMessage({
3420
+ adapter,
3421
+ channelId: destination.channelId,
3422
+ record,
3423
+ ...threadTs ? { threadTs } : void 0
3424
+ })
3425
+ );
3426
+ await bindSlackActorIdentities({
3427
+ lookupSlackUser: actorLookup,
3428
+ messages,
3429
+ teamId: destination.teamId
3430
+ });
3431
+ const latestMessage = messages[messages.length - 1];
3432
+ if (!latestMessage) {
3433
+ return;
3434
+ }
3435
+ const route = routeForRecords(records);
3436
+ const thread = isPlainResourceEventRecord(latestRecord) && threadTs ? buildResourceEventSlackThread({
3437
+ adapter,
3438
+ channelId: destination.channelId,
3439
+ message: latestMessage,
3440
+ state,
3441
+ threadTs
3442
+ }) : restoreThread({
3443
+ adapter,
3444
+ isSubscribedContext: route === "subscribed",
3445
+ message: latestMessage,
3446
+ state,
3447
+ threadJson: latestMetadata.thread
3448
+ });
3449
+ const skipped = messages.slice(0, -1);
3450
+ const messageContext = {
3451
+ skipped,
3452
+ totalSinceLastHandler: messages.length
3453
+ };
3454
+ const activeAuthorId = isResourceEventSlackMessage(latestMessage) ? RESOURCE_EVENT_AUTHOR_ID : requireSlackAuthorId(latestMessage);
3455
+ let initialMessagesAcked = false;
3456
+ const ack = async () => {
3457
+ if (initialMessagesAcked) {
3458
+ return;
3459
+ }
3460
+ try {
3461
+ await context.attempt.ack();
3462
+ initialMessagesAcked = true;
3463
+ } catch {
3464
+ throw new TurnInputCommitLostError(
3465
+ `Conversation work lease lost before Slack inbox ack for ${context.conversationId}`
3466
+ );
3467
+ }
3468
+ };
3469
+ const drainSteeringMessages = async (accept) => {
3470
+ await context.attempt.drain(async (pendingRecords) => {
3471
+ const candidates = pendingRecords.filter(
3472
+ (record) => isPlainResourceEventRecord(record) ? publishExternally : record.publishExternally === publishExternally
3473
+ ).map((record) => ({
3474
+ inboundMessageId: record.inboundMessageId,
3475
+ message: restoreMessage({
3476
+ adapter,
3477
+ channelId: destination.channelId,
3478
+ record,
3479
+ ...threadTs ? { threadTs } : void 0
3480
+ })
3481
+ })).filter(
3482
+ (candidate) => crossActorMidRunMode === "steer" || isResourceEventSlackMessage(candidate.message) || requireSlackAuthorId(candidate.message) === activeAuthorId || hasSteeringOverride(candidate.message.text)
3483
+ );
3484
+ return candidates.length > 0 ? await accept(candidates) : [];
3485
+ });
3486
+ };
3487
+ try {
3488
+ if (route === "mention") {
3489
+ await options.runtime.handleNewMention(thread, latestMessage, {
3490
+ conversationId: context.conversationId,
3491
+ destination,
3492
+ publishExternally,
3493
+ messageContext,
3494
+ drainSteeringMessages,
3495
+ ack,
3496
+ isFinalAttempt: context.attempt.isFinalAttempt,
3497
+ shouldYield: context.shouldYield
3498
+ });
3499
+ } else {
3500
+ await options.runtime.handleSubscribedMessage(
3501
+ thread,
3502
+ latestMessage,
3503
+ {
3504
+ conversationId: context.conversationId,
3505
+ destination,
3506
+ publishExternally,
3507
+ messageContext,
3508
+ drainSteeringMessages,
3509
+ ack,
3510
+ isFinalAttempt: context.attempt.isFinalAttempt,
3511
+ shouldYield: context.shouldYield
3512
+ }
3513
+ );
3514
+ }
3515
+ } catch (error) {
3516
+ if (isTurnInputDeferredError(error)) {
3517
+ return { status: "deferred" };
3518
+ }
3519
+ if (isCooperativeTurnYieldError(error)) {
3520
+ return { status: "yielded" };
3521
+ }
3522
+ if (isTurnInputCommitLostError(error)) {
3523
+ return { status: "lost_lease" };
3524
+ }
3525
+ throw error;
3526
+ }
3527
+ }
3528
+ });
3529
+ if (turnResult?.status === "deferred" || turnResult?.status === "yielded" || turnResult?.status === "lost_lease") {
3530
+ return turnResult;
3531
+ }
3532
+ return { status: "completed" };
3533
+ };
3534
+ }
3535
+ function buildSlackInboundMessage(args) {
3536
+ const authorId = requireSlackAuthorId(args.message);
3537
+ const destination = createSlackDestination({
3538
+ channelId: args.thread.channelId,
3539
+ teamId: args.installation?.teamId
3540
+ });
3541
+ if (!destination) {
3542
+ throw new Error("Slack inbound message requires destination context");
3543
+ }
3544
+ const hasInterruptOverride = hasSteeringOverride(args.message.text);
3545
+ return {
3546
+ conversationId: args.conversationId,
3547
+ destination,
3548
+ inboundMessageId: [
3549
+ "slack",
3550
+ args.installation?.teamId ?? args.installation?.enterpriseId ?? "unknown",
3551
+ args.conversationId,
3552
+ args.message.id
3553
+ ].join(":"),
3554
+ delivery: args.message.isMention || hasInterruptOverride ? "interrupt" : "defer",
3555
+ source: "slack",
3556
+ createdAtMs: args.message.metadata.dateSent.getTime(),
3557
+ receivedAtMs: args.receivedAtMs,
3558
+ publishExternally: true,
3559
+ input: {
3560
+ text: args.message.text || " ",
3561
+ authorId,
3562
+ attachments: args.message.attachments,
3563
+ metadata: {
3564
+ platform: "slack",
3565
+ route: args.route,
3566
+ installation: args.installation,
3567
+ thread: serializedThreadSchema.parse(args.thread.toJSON()),
3568
+ message: args.message.toJSON()
3569
+ }
3570
+ }
3571
+ };
3572
+ }
2755
3573
 
2756
3574
  // src/chat/ingress/bot-mention.ts
2757
3575
  function escapeRegExp(value) {
@@ -2819,7 +3637,7 @@ function textMentionsBot(text, botUserId) {
2819
3637
  }
2820
3638
 
2821
3639
  // src/chat/ingress/message-changed.ts
2822
- import { Message } from "chat";
3640
+ import { Message as Message4 } from "chat";
2823
3641
  function getEditedMentionMessageId(messageTs) {
2824
3642
  return `${messageTs}:message_changed_mention`;
2825
3643
  }
@@ -2886,7 +3704,7 @@ function extractMessageChangedMention(body, botUserId, adapter) {
2886
3704
  ...sourceTeam ? { source_team: sourceTeam } : void 0,
2887
3705
  ...botId ? { bot_id: botId } : void 0
2888
3706
  };
2889
- const message = new Message({
3707
+ const message = new Message4({
2890
3708
  id: getEditedMentionMessageId(messageTs),
2891
3709
  threadId,
2892
3710
  text: newText,
@@ -3125,7 +3943,7 @@ function normalizeMessageThreadId(message) {
3125
3943
  }
3126
3944
  async function buildThread(args) {
3127
3945
  const normalized = normalizeMessageThreadId(args.message);
3128
- return new ThreadImpl({
3946
+ return new ThreadImpl3({
3129
3947
  adapter: args.adapter,
3130
3948
  stateAdapter: args.state,
3131
3949
  id: normalized.threadId,
@@ -3754,7 +4572,7 @@ function registerVercelWorkspaceSnapshotJobDevConsumer() {
3754
4572
  }
3755
4573
 
3756
4574
  // src/chat/services/subscribed-decision.ts
3757
- import { z as z3 } from "zod";
4575
+ import { z as z4 } from "zod";
3758
4576
 
3759
4577
  // src/chat/services/subscribed-reply-router-policy.ts
3760
4578
  function buildSubscribedReplyRouterPolicy(assistantName) {
@@ -3799,13 +4617,13 @@ Assess conversation floor ownership and whether the latest message continues wor
3799
4617
  }
3800
4618
 
3801
4619
  // src/chat/services/subscribed-decision.ts
3802
- var replyDecisionSchema = z3.object({
3803
- should_reply: z3.boolean().describe("Whether Junior should respond to this thread message."),
3804
- should_unsubscribe: z3.boolean().describe(
4620
+ var replyDecisionSchema = z4.object({
4621
+ should_reply: z4.boolean().describe("Whether Junior should respond to this thread message."),
4622
+ should_unsubscribe: z4.boolean().describe(
3805
4623
  "Whether Junior should unsubscribe from this thread because the user clearly asked it to stop participating."
3806
4624
  ),
3807
- confidence: z3.number().min(0).max(1).describe("Classifier confidence from 0 to 1."),
3808
- reason: z3.string().describe("Short reason for the decision; use an empty string if none.")
4625
+ confidence: z4.number().min(0).max(1).describe("Classifier confidence from 0 to 1."),
4626
+ reason: z4.string().describe("Short reason for the decision; use an empty string if none.")
3809
4627
  }).strict();
3810
4628
  var ROUTER_CONFIDENCE_THRESHOLD = 0.7;
3811
4629
  var ROUTER_CLASSIFIER_MAX_TOKENS = 400;
@@ -4293,6 +5111,7 @@ function shouldPublishExternally(publishExternally) {
4293
5111
  return publishExternally !== false;
4294
5112
  }
4295
5113
  function createSlackTurnRuntime(deps) {
5114
+ const turnLifecycle = getTurnLifecycle();
4296
5115
  const logContext = (args) => buildLogContext(deps, args);
4297
5116
  const maybeHandleThreadOptOutDecision = async (args) => {
4298
5117
  if (!args.decision?.shouldUnsubscribe) {
@@ -4309,7 +5128,7 @@ function createSlackTurnRuntime(deps) {
4309
5128
  if (!conversationId) {
4310
5129
  return;
4311
5130
  }
4312
- await deps.failConversationTurn({
5131
+ await turnLifecycle.fail({
4313
5132
  conversationId,
4314
5133
  createdAtMs: deps.now(),
4315
5134
  eventId: args.eventId,
@@ -5532,11 +6351,11 @@ function getMessageTimestamp(message) {
5532
6351
  }
5533
6352
 
5534
6353
  // src/chat/slack/action-token.ts
5535
- import { z as z4 } from "zod";
5536
- var slackActionTokenSchema = z4.string().trim().min(1).brand();
5537
- var slackMessageEnvelopeSchema = z4.object({
5538
- raw: z4.object({
5539
- action_token: z4.unknown().optional()
6354
+ import { z as z5 } from "zod";
6355
+ var slackActionTokenSchema = z5.string().trim().min(1).brand();
6356
+ var slackMessageEnvelopeSchema = z5.object({
6357
+ raw: z5.object({
6358
+ action_token: z5.unknown().optional()
5540
6359
  }).optional()
5541
6360
  });
5542
6361
  function readSlackActionToken(message) {
@@ -5781,6 +6600,7 @@ function shouldPublishExternally2(publishExternally) {
5781
6600
  return publishExternally !== false;
5782
6601
  }
5783
6602
  function createSlackTurn(deps) {
6603
+ const turnLifecycle = getTurnLifecycle();
5784
6604
  return async function executeSlackTurn(thread, message, options) {
5785
6605
  if (message.author.isMe) {
5786
6606
  return;
@@ -6111,7 +6931,7 @@ function createSlackTurn(deps) {
6111
6931
  nextTurnId: turnId
6112
6932
  });
6113
6933
  if (conversationId && preparedState.userMessageId) {
6114
- await deps.turnLifecycle.start({
6934
+ await turnLifecycle.start({
6115
6935
  conversationId,
6116
6936
  createdAtMs: Date.now(),
6117
6937
  inputMessageIds: [
@@ -6648,7 +7468,7 @@ function createSlackTurn(deps) {
6648
7468
  conversation: preparedState.conversation
6649
7469
  });
6650
7470
  if (conversationId) {
6651
- await deps.turnLifecycle.fail({
7471
+ await turnLifecycle.fail({
6652
7472
  conversationId,
6653
7473
  createdAtMs: Date.now(),
6654
7474
  ...authFailureEventId ? { eventId: authFailureEventId } : void 0,
@@ -7115,14 +7935,14 @@ function createPrepareTurnState(deps) {
7115
7935
  }
7116
7936
 
7117
7937
  // src/chat/slack/dispatch-turn.ts
7118
- import { Message as Message2, ThreadImpl as ThreadImpl2 } from "chat";
7938
+ import { Message as Message5, ThreadImpl as ThreadImpl4 } from "chat";
7119
7939
  function createSlackDispatchTurnRunner(options) {
7120
7940
  return async function runSlackDispatchTurn(dispatch2, hooks) {
7121
7941
  const state = getStateAdapter();
7122
7942
  await state.connect();
7123
7943
  const conversationId = getDispatchConversationId(dispatch2);
7124
7944
  const adapter = options.getSlackAdapter();
7125
- const message = new Message2({
7945
+ const message = new Message5({
7126
7946
  id: getDispatchInputMessageId(dispatch2.id),
7127
7947
  threadId: conversationId,
7128
7948
  text: dispatch2.input,
@@ -7145,7 +7965,7 @@ function createSlackDispatchTurnRunner(options) {
7145
7965
  }
7146
7966
  });
7147
7967
  message.isMention = true;
7148
- const thread = new ThreadImpl2({
7968
+ const thread = new ThreadImpl4({
7149
7969
  adapter,
7150
7970
  stateAdapter: state,
7151
7971
  id: conversationId,
@@ -7219,9 +8039,6 @@ function upsertSkippedConversationMessage(conversation, args) {
7219
8039
  }
7220
8040
  function createSlackRuntime(options) {
7221
8041
  const services = createJuniorRuntimeServices(options.services);
7222
- const turnLifecycle = new ConversationTurnLifecycleService(
7223
- getConversationEventStore()
7224
- );
7225
8042
  const prepareTurnState = createPrepareTurnState({
7226
8043
  compactConversationIfNeeded: services.conversationMemory.compactConversationIfNeeded,
7227
8044
  hydrateConversationVisionContext: services.visionContext.hydrateConversationVisionContext,
@@ -7250,8 +8067,7 @@ function createSlackRuntime(options) {
7250
8067
  pausedTurns: options.pausedTurns ?? createPausedTurns(),
7251
8068
  prepareTurnState,
7252
8069
  resolveUserAttachments: services.visionContext.resolveUserAttachments,
7253
- sendPluginTask: options.sendPluginTask,
7254
- turnLifecycle
8070
+ sendPluginTask: options.sendPluginTask
7255
8071
  });
7256
8072
  const runtime = createSlackTurnRuntime({
7257
8073
  assistantUserName: botConfig.userName,
@@ -7259,7 +8075,6 @@ function createSlackRuntime(options) {
7259
8075
  getBotUserId: () => options.getSlackAdapter().botUserId,
7260
8076
  modelId: defaultModelId(botConfig),
7261
8077
  now: options.now ?? (() => Date.now()),
7262
- failConversationTurn: (input) => turnLifecycle.fail(input),
7263
8078
  prepareTurnState,
7264
8079
  persistPreparedState: async ({ thread, preparedState }) => {
7265
8080
  await persistThreadState(thread, {
@@ -7937,9 +8752,23 @@ function createConversationWork(options) {
7937
8752
  },
7938
8753
  runTurn: runtime.runDispatchTurn
7939
8754
  });
8755
+ const destinationWorker = async (context) => {
8756
+ const destination = context.destination;
8757
+ if (!destination) {
8758
+ throw new Error(
8759
+ `Conversation ${context.conversationId} is missing a destination`
8760
+ );
8761
+ }
8762
+ if (destination.platform === "slack") {
8763
+ return await slackWorker(context);
8764
+ }
8765
+ throw new Error(
8766
+ `Conversation ${context.conversationId} has a ${destination.platform} destination but no matching conversation worker`
8767
+ );
8768
+ };
7940
8769
  const providerWorker = createAgentDispatchWorkRouter({
7941
8770
  dispatchWorker,
7942
- fallbackWorker: slackWorker
8771
+ fallbackWorker: destinationWorker
7943
8772
  });
7944
8773
  return {
7945
8774
  apiTurnCancellation,
@@ -8149,6 +8978,66 @@ async function ingestEventTasks(input, options) {
8149
8978
  return { dispatched };
8150
8979
  }
8151
8980
 
8981
+ // src/chat/resource-events/workspace.ts
8982
+ function createResourceEventTeamIdResolver() {
8983
+ let pending;
8984
+ return async () => {
8985
+ if (!getSlackBotToken()) return void 0;
8986
+ pending ??= getSlackClient().auth.test().then((result) => {
8987
+ const teamId = result.team_id?.trim();
8988
+ if (!teamId) {
8989
+ throw new Error("Slack auth.test did not return a team id");
8990
+ }
8991
+ return teamId;
8992
+ }).catch((error) => {
8993
+ pending = void 0;
8994
+ throw error;
8995
+ });
8996
+ return await pending;
8997
+ };
8998
+ }
8999
+
9000
+ // src/chat/resource-events/app-publisher.ts
9001
+ function createResourceEventAppPublisher(args) {
9002
+ const resolveEventTaskTeamId = createResourceEventTeamIdResolver();
9003
+ return {
9004
+ async neededMatchKeys(input) {
9005
+ const work = args.conversationWork();
9006
+ const eventTaskTeamId = await resolveEventTaskTeamId();
9007
+ const [watchKeys, taskKeys] = await Promise.all([
9008
+ collectResourceEventMatchKeys({
9009
+ eventTypes: input.eventTypes,
9010
+ identifiers: input.identifiers,
9011
+ namespace: input.namespace,
9012
+ state: work.state
9013
+ }),
9014
+ eventTaskTeamId ? collectEventTaskMatchKeys(getDb(), {
9015
+ eventTypes: input.eventTypes,
9016
+ identifiers: input.identifiers,
9017
+ namespace: input.namespace,
9018
+ teamId: eventTaskTeamId
9019
+ }) : Promise.resolve([])
9020
+ ]);
9021
+ return [.../* @__PURE__ */ new Set([...watchKeys, ...taskKeys])].sort();
9022
+ },
9023
+ async publish(event) {
9024
+ const work = args.conversationWork();
9025
+ const queue = work.queue ?? getVercelConversationWorkQueue();
9026
+ const eventTaskTeamId = await resolveEventTaskTeamId();
9027
+ await Promise.all([
9028
+ ingestResourceEvent(event, {
9029
+ queue,
9030
+ state: work.state
9031
+ }),
9032
+ eventTaskTeamId ? ingestEventTasks(event, {
9033
+ queue,
9034
+ teamId: eventTaskTeamId
9035
+ }) : Promise.resolve()
9036
+ ]);
9037
+ }
9038
+ };
9039
+ }
9040
+
8152
9041
  // src/chat/api-turns/stop.ts
8153
9042
  async function stopApiConversationTurn(args) {
8154
9043
  const nowMs = args.nowMs ?? Date.now();
@@ -8351,7 +9240,7 @@ import {
8351
9240
  } from "crypto";
8352
9241
  import * as acp3 from "@agentclientprotocol/sdk";
8353
9242
  import { userSchema as userSchema2 } from "@sentry/junior-plugin-api";
8354
- import { z as z7 } from "zod";
9243
+ import { z as z8 } from "zod";
8355
9244
 
8356
9245
  // src/api/acp/state.ts
8357
9246
  import { setTimeout as wait } from "timers/promises";
@@ -8392,14 +9281,14 @@ async function fenceLock(state, lock, ttlMs = MUTATION_LOCK_TTL_MS) {
8392
9281
  import { createHash as createHash2, randomUUID } from "crypto";
8393
9282
  import * as acp2 from "@agentclientprotocol/sdk";
8394
9283
  import { userSchema } from "@sentry/junior-plugin-api";
8395
- import { z as z6 } from "zod";
9284
+ import { z as z7 } from "zod";
8396
9285
 
8397
9286
  // src/api/acp/schema.ts
8398
9287
  import * as acp from "@agentclientprotocol/sdk";
8399
- import { z as z5 } from "zod";
9288
+ import { z as z6 } from "zod";
8400
9289
  var ACP_SESSION_ID_PATTERN = /^local:acp:[a-f0-9]{32}$/;
8401
- var metaSchema = z5.record(z5.string(), z5.unknown()).nullable();
8402
- var jsonRpcIdSchema = z5.union([z5.string(), z5.number().finite(), z5.null()]);
9290
+ var metaSchema = z6.record(z6.string(), z6.unknown()).nullable();
9291
+ var jsonRpcIdSchema = z6.union([z6.string(), z6.number().finite(), z6.null()]);
8403
9292
  var SESSION_HEADER_METHODS = /* @__PURE__ */ new Set([
8404
9293
  acp.methods.agent.session.cancel,
8405
9294
  acp.methods.agent.session.close,
@@ -8409,94 +9298,94 @@ var SESSION_HEADER_METHODS = /* @__PURE__ */ new Set([
8409
9298
  acp.methods.agent.session.setConfigOption,
8410
9299
  acp.methods.agent.session.setMode
8411
9300
  ]);
8412
- var acpConnectionIdSchema = z5.string().uuid();
8413
- var acpSessionIdSchema = z5.string().regex(ACP_SESSION_ID_PATTERN);
8414
- var acpCallSchema = z5.object({
9301
+ var acpConnectionIdSchema = z6.string().uuid();
9302
+ var acpSessionIdSchema = z6.string().regex(ACP_SESSION_ID_PATTERN);
9303
+ var acpCallSchema = z6.object({
8415
9304
  id: jsonRpcIdSchema.optional(),
8416
- jsonrpc: z5.literal("2.0"),
8417
- method: z5.string().min(1),
8418
- params: z5.unknown().optional()
9305
+ jsonrpc: z6.literal("2.0"),
9306
+ method: z6.string().min(1),
9307
+ params: z6.unknown().optional()
8419
9308
  }).strict();
8420
- var jsonRpcErrorSchema = z5.object({
8421
- code: z5.number().int(),
8422
- data: z5.unknown().optional(),
8423
- message: z5.string()
9309
+ var jsonRpcErrorSchema = z6.object({
9310
+ code: z6.number().int(),
9311
+ data: z6.unknown().optional(),
9312
+ message: z6.string()
8424
9313
  }).strict();
8425
- var acpResponseSchema = z5.union([
8426
- z5.object({
9314
+ var acpResponseSchema = z6.union([
9315
+ z6.object({
8427
9316
  id: jsonRpcIdSchema,
8428
- jsonrpc: z5.literal("2.0"),
8429
- result: z5.unknown()
9317
+ jsonrpc: z6.literal("2.0"),
9318
+ result: z6.unknown()
8430
9319
  }).strict(),
8431
- z5.object({
9320
+ z6.object({
8432
9321
  error: jsonRpcErrorSchema,
8433
9322
  id: jsonRpcIdSchema,
8434
- jsonrpc: z5.literal("2.0")
9323
+ jsonrpc: z6.literal("2.0")
8435
9324
  }).strict()
8436
9325
  ]);
8437
- var acpInboundMessageSchema = z5.union([
9326
+ var acpInboundMessageSchema = z6.union([
8438
9327
  acpCallSchema,
8439
9328
  acpResponseSchema
8440
9329
  ]);
8441
- var implementationSchema = z5.object({
9330
+ var implementationSchema = z6.object({
8442
9331
  _meta: metaSchema.optional(),
8443
- name: z5.string().min(1),
8444
- title: z5.string().nullable().optional(),
8445
- version: z5.string()
9332
+ name: z6.string().min(1),
9333
+ title: z6.string().nullable().optional(),
9334
+ version: z6.string()
8446
9335
  }).strict();
8447
- var initializeParamsSchema = z5.object({
9336
+ var initializeParamsSchema = z6.object({
8448
9337
  _meta: metaSchema.optional(),
8449
- clientCapabilities: z5.record(z5.string(), z5.unknown()).optional(),
9338
+ clientCapabilities: z6.record(z6.string(), z6.unknown()).optional(),
8450
9339
  clientInfo: implementationSchema.nullable().optional(),
8451
- protocolVersion: z5.number().int().min(0).max(65535)
9340
+ protocolVersion: z6.number().int().min(0).max(65535)
8452
9341
  }).strict();
8453
- var authenticateParamsSchema = z5.object({
9342
+ var authenticateParamsSchema = z6.object({
8454
9343
  _meta: metaSchema.optional(),
8455
- methodId: z5.string().min(1)
9344
+ methodId: z6.string().min(1)
8456
9345
  }).strict();
8457
- var newSessionParamsSchema = z5.object({
9346
+ var newSessionParamsSchema = z6.object({
8458
9347
  _meta: metaSchema.optional(),
8459
- additionalDirectories: z5.array(z5.string()).optional(),
8460
- cwd: z5.string().min(1),
8461
- mcpServers: z5.array(z5.unknown())
9348
+ additionalDirectories: z6.array(z6.string()).optional(),
9349
+ cwd: z6.string().min(1),
9350
+ mcpServers: z6.array(z6.unknown())
8462
9351
  }).strict();
8463
9352
  var loadSessionParamsSchema = newSessionParamsSchema.extend({
8464
9353
  sessionId: acpSessionIdSchema
8465
9354
  });
8466
- var annotationsSchema = z5.object({
9355
+ var annotationsSchema = z6.object({
8467
9356
  _meta: metaSchema.optional(),
8468
- audience: z5.array(z5.enum(["assistant", "user"])).nullable().optional(),
8469
- lastModified: z5.string().nullable().optional(),
8470
- priority: z5.number().finite().nullable().optional()
9357
+ audience: z6.array(z6.enum(["assistant", "user"])).nullable().optional(),
9358
+ lastModified: z6.string().nullable().optional(),
9359
+ priority: z6.number().finite().nullable().optional()
8471
9360
  }).strict();
8472
- var textContentBlockSchema = z5.object({
9361
+ var textContentBlockSchema = z6.object({
8473
9362
  _meta: metaSchema.optional(),
8474
9363
  annotations: annotationsSchema.nullable().optional(),
8475
- text: z5.string(),
8476
- type: z5.literal("text")
9364
+ text: z6.string(),
9365
+ type: z6.literal("text")
8477
9366
  }).strict();
8478
- var resourceLinkContentBlockSchema = z5.object({
9367
+ var resourceLinkContentBlockSchema = z6.object({
8479
9368
  _meta: metaSchema.optional(),
8480
9369
  annotations: annotationsSchema.nullable().optional(),
8481
- description: z5.string().nullable().optional(),
8482
- mimeType: z5.string().nullable().optional(),
8483
- name: z5.string(),
8484
- size: z5.number().finite().nullable().optional(),
8485
- title: z5.string().nullable().optional(),
8486
- type: z5.literal("resource_link"),
8487
- uri: z5.string()
9370
+ description: z6.string().nullable().optional(),
9371
+ mimeType: z6.string().nullable().optional(),
9372
+ name: z6.string(),
9373
+ size: z6.number().finite().nullable().optional(),
9374
+ title: z6.string().nullable().optional(),
9375
+ type: z6.literal("resource_link"),
9376
+ uri: z6.string()
8488
9377
  }).strict();
8489
- var promptParamsSchema = z5.object({
9378
+ var promptParamsSchema = z6.object({
8490
9379
  _meta: metaSchema.optional(),
8491
- prompt: z5.array(
8492
- z5.discriminatedUnion("type", [
9380
+ prompt: z6.array(
9381
+ z6.discriminatedUnion("type", [
8493
9382
  textContentBlockSchema,
8494
9383
  resourceLinkContentBlockSchema
8495
9384
  ])
8496
9385
  ),
8497
9386
  sessionId: acpSessionIdSchema
8498
9387
  }).strict();
8499
- var cancelParamsSchema = z5.object({
9388
+ var cancelParamsSchema = z6.object({
8500
9389
  _meta: metaSchema.optional(),
8501
9390
  sessionId: acpSessionIdSchema
8502
9391
  }).strict();
@@ -8534,41 +9423,41 @@ var MUTATION_LOCK_OPTIONS = {
8534
9423
  };
8535
9424
  var SSE_KEEP_ALIVE_MS = 15e3;
8536
9425
  var SSE_MAINTENANCE_INTERVAL_MS = 1e3;
8537
- var jsonRpcIdSchema2 = z6.union([z6.string(), z6.number().finite(), z6.null()]);
8538
- var acpConnectionSchema = z6.object({
8539
- credentialHash: z6.string().length(64),
8540
- nonce: z6.string().min(1),
9426
+ var jsonRpcIdSchema2 = z7.union([z7.string(), z7.number().finite(), z7.null()]);
9427
+ var acpConnectionSchema = z7.object({
9428
+ credentialHash: z7.string().length(64),
9429
+ nonce: z7.string().min(1),
8541
9430
  user: userSchema.optional()
8542
9431
  }).strict();
8543
- var acpStreamRouteSchema = z6.object({
8544
- connectionId: z6.string().min(1),
8545
- sessionId: z6.string().min(1).optional()
9432
+ var acpStreamRouteSchema = z7.object({
9433
+ connectionId: z7.string().min(1),
9434
+ sessionId: z7.string().min(1).optional()
8546
9435
  }).strict();
8547
- var acpPromptStreamOutputSchema = z6.object({
8548
- afterSeq: z6.number().int().nonnegative(),
8549
- kind: z6.literal("prompt"),
8550
- messageId: z6.string().min(1),
9436
+ var acpPromptStreamOutputSchema = z7.object({
9437
+ afterSeq: z7.number().int().nonnegative(),
9438
+ kind: z7.literal("prompt"),
9439
+ messageId: z7.string().min(1),
8551
9440
  requestId: jsonRpcIdSchema2,
8552
- turnId: z6.string().min(1)
9441
+ turnId: z7.string().min(1)
8553
9442
  }).strict();
8554
- var acpStreamOutputSchema = z6.discriminatedUnion("kind", [
8555
- z6.object({
8556
- kind: z6.literal("message"),
9443
+ var acpStreamOutputSchema = z7.discriminatedUnion("kind", [
9444
+ z7.object({
9445
+ kind: z7.literal("message"),
8557
9446
  message: acpInboundMessageSchema
8558
9447
  }).strict(),
8559
- z6.object({ kind: z6.literal("replay") }).strict(),
9448
+ z7.object({ kind: z7.literal("replay") }).strict(),
8560
9449
  acpPromptStreamOutputSchema
8561
9450
  ]);
8562
- var storedAcpStreamItemSchema = z6.object({
8563
- id: z6.string().min(1),
9451
+ var storedAcpStreamItemSchema = z7.object({
9452
+ id: z7.string().min(1),
8564
9453
  output: acpStreamOutputSchema
8565
9454
  }).strict();
8566
- var acpRequestReceiptSchema = z6.object({
8567
- deliveryKey: z6.string().min(1).optional(),
8568
- outputs: z6.array(acpStreamOutputSchema),
8569
- sessionId: z6.string().min(1).optional()
9455
+ var acpRequestReceiptSchema = z7.object({
9456
+ deliveryKey: z7.string().min(1).optional(),
9457
+ outputs: z7.array(acpStreamOutputSchema),
9458
+ sessionId: z7.string().min(1).optional()
8570
9459
  }).strict();
8571
- var acpStreamCursorSchema = z6.object({ itemId: z6.string().min(1) }).strict();
9460
+ var acpStreamCursorSchema = z7.object({ itemId: z7.string().min(1) }).strict();
8572
9461
  function stableHex(value) {
8573
9462
  return createHash2("sha256").update(value).digest("hex").slice(0, 32);
8574
9463
  }
@@ -9177,19 +10066,19 @@ function createSseBody(args) {
9177
10066
  var ACP_AUTHORIZATION_TTL_MS = 10 * 60 * 1e3;
9178
10067
  var ACP_CONNECTION_COOKIE = "junior_acp_connection";
9179
10068
  var LOCK_WAIT_MS2 = 5e3;
9180
- var jsonRpcIdSchema3 = z7.union([z7.string(), z7.number().finite(), z7.null()]);
9181
- var acpAuthorizationSchema = z7.object({
9182
- connectionId: z7.string().uuid(),
9183
- credentialHash: z7.string().length(64),
9184
- elicitationId: z7.string().uuid(),
9185
- expiresAtMs: z7.number().int().positive(),
10069
+ var jsonRpcIdSchema3 = z8.union([z8.string(), z8.number().finite(), z8.null()]);
10070
+ var acpAuthorizationSchema = z8.object({
10071
+ connectionId: z8.string().uuid(),
10072
+ credentialHash: z8.string().length(64),
10073
+ elicitationId: z8.string().uuid(),
10074
+ expiresAtMs: z8.number().int().positive(),
9186
10075
  requestId: jsonRpcIdSchema3,
9187
- requestKey: z7.string().min(1),
9188
- userCodeHash: z7.string().length(64)
10076
+ requestKey: z8.string().min(1),
10077
+ userCodeHash: z8.string().length(64)
9189
10078
  }).strict();
9190
- var acpAuthorizationPointerSchema = z7.object({
9191
- expiresAtMs: z7.number().int().positive(),
9192
- transactionId: z7.string().uuid()
10079
+ var acpAuthorizationPointerSchema = z8.object({
10080
+ expiresAtMs: z8.number().int().positive(),
10081
+ transactionId: z8.string().uuid()
9193
10082
  }).strict();
9194
10083
  var ACP_AUTH_METHOD_ID = "junior";
9195
10084
  var ACP_AUTH_METHOD = {
@@ -9516,7 +10405,7 @@ async function completeAcpAuthorization(args) {
9516
10405
  }
9517
10406
  async function handleAcpAuthorizationResponse(args) {
9518
10407
  if (typeof args.response.id !== "string") return "ignored";
9519
- const parsedId = z7.string().uuid().safeParse(args.response.id);
10408
+ const parsedId = z8.string().uuid().safeParse(args.response.id);
9520
10409
  if (!parsedId.success) return "ignored";
9521
10410
  const authorization = await readAuthorization(args.state, parsedId.data);
9522
10411
  if (!authorization || authorization.connectionId !== args.connectionId) {
@@ -10652,53 +11541,9 @@ async function createApp(options) {
10652
11541
  };
10653
11542
  let pluginRoutes = [];
10654
11543
  let pluginApiRoutes = [];
10655
- const resolveResourceEventTeamId = createResourceEventTeamIdResolver();
10656
- const resourceEvents = {
10657
- async neededMatchKeys(input) {
10658
- const teamId = await resolveResourceEventTeamId();
10659
- if (!teamId) return [];
10660
- const conversationWork = getConversationWorkOptions();
10661
- const [watchKeys, taskKeys] = await Promise.all([
10662
- collectResourceEventMatchKeys({
10663
- eventTypes: input.eventTypes,
10664
- identifiers: input.identifiers,
10665
- namespace: input.namespace,
10666
- state: conversationWork.state,
10667
- teamId
10668
- }),
10669
- collectEventTaskMatchKeys(getDb(), {
10670
- eventTypes: input.eventTypes,
10671
- identifiers: input.identifiers,
10672
- namespace: input.namespace,
10673
- teamId
10674
- })
10675
- ]);
10676
- return [.../* @__PURE__ */ new Set([...watchKeys, ...taskKeys])].sort();
10677
- },
10678
- async publish(event) {
10679
- const teamId = await resolveResourceEventTeamId();
10680
- if (!teamId) {
10681
- logWarn("resource_event.delivery.unavailable", {
10682
- "app.resource_event.namespace": event.namespace,
10683
- "app.resource_event.reason": "multi_workspace"
10684
- });
10685
- return;
10686
- }
10687
- const conversationWork = getConversationWorkOptions();
10688
- const queue = conversationWork.queue ?? getVercelConversationWorkQueue();
10689
- await Promise.all([
10690
- ingestResourceEvent(event, {
10691
- queue,
10692
- state: conversationWork.state,
10693
- teamId
10694
- }),
10695
- ingestEventTasks(event, {
10696
- queue,
10697
- teamId
10698
- })
10699
- ]);
10700
- }
10701
- };
11544
+ const resourceEvents = createResourceEventAppPublisher({
11545
+ conversationWork: () => getConversationWorkOptions()
11546
+ });
10702
11547
  let sandboxEgressTracePropagationDomains = [];
10703
11548
  try {
10704
11549
  sandboxEgressTracePropagationDomains = normalizeSandboxEgressTracePropagationDomains(