@sentry/junior 0.268.0 → 0.269.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 (82) hide show
  1. package/README.md +2 -9
  2. package/dist/{adapter-04AcD2SO.js → adapter-2-CG25be.js} +3 -49
  3. package/dist/{admin-DIU1QyG3.js → admin-DSs8S5Uy.js} +1 -1
  4. package/dist/{agent-runner-CAYfFmU7.js → agent-runner-CrDrPUtY.js} +3208 -2826
  5. package/dist/api/schema.d.ts +2 -3
  6. package/dist/api/schema.js +7 -7
  7. package/dist/api.d.ts +3 -1
  8. package/dist/api.js +157 -298
  9. package/dist/{app-z6Uuyq3j.d.ts → app-BrMMzjYm.d.ts} +8 -2
  10. package/dist/app.d.ts +1 -1
  11. package/dist/app.js +121 -207
  12. package/dist/{automation-CmeFBSEh.js → automation-p87hg_AV.js} +74 -74
  13. package/dist/{briefs-DQbV2jNr.js → briefs-PtODdLNu.js} +4 -4
  14. package/dist/{catalog-runtime-BD9GSpc6.js → catalog-runtime-BsoSmTM0.js} +1 -1
  15. package/dist/cli/chat.js +16 -26
  16. package/dist/cli/check.js +3 -3
  17. package/dist/cli/main.js +5 -3
  18. package/dist/cli/plugins.js +4 -4
  19. package/dist/cli/snapshot-create.js +4 -4
  20. package/dist/cli/upgrade.d.ts +1 -1
  21. package/dist/cli/upgrade.js +3 -3
  22. package/dist/{client-C1yDYjoS.js → client-Cqf4TboL.js} +20 -15
  23. package/dist/{config-DrTeF80T.js → config-CPsE4T5L.js} +2 -2
  24. package/dist/{connections-D46f8vvi.js → connections-upFXLmhG.js} +10 -10
  25. package/dist/{conversation-DSo310Ps.js → conversation-CTpD_PGk.js} +7 -84
  26. package/dist/{conversation-privacy-CxlOCiUo.js → conversation-privacy-D6zJc8ff.js} +1 -1
  27. package/dist/{credential-sync-sm9fegLY.js → credential-sync-CS_6IC-f.js} +15 -14
  28. package/dist/{credentialed-lukuD-cc.js → credentialed-BU-OW7HP.js} +548 -71
  29. package/dist/{store-xMuuXRE0.d.ts → db-BzOCzVb1.d.ts} +4 -0
  30. package/dist/{executor-4vhvsMZJ.js → executor-CNS7ONt-.js} +6 -6
  31. package/dist/instrumentation.js +2 -2
  32. package/dist/{interruption-marker-CkncDT8d.js → interruption-marker-g6Xup3Fk.js} +1 -1
  33. package/dist/{job-queue-In9QKz-I.js → job-queue-DI-k-Bbk.js} +2 -2
  34. package/dist/{list-BkgnXEEB.js → list-CGoQdXTp.js} +193 -656
  35. package/dist/locks-D-0h111u.js +48 -0
  36. package/dist/{logging-DLSpkSSr.js → logging-n7knse-O.js} +1 -1
  37. package/dist/{history-C84mlAwO.js → media-85PDJxO_.js} +83 -1
  38. package/dist/{message-BObyg59s.js → message-BpaWd8TT.js} +4 -4
  39. package/dist/nitro.d.ts +1 -1
  40. package/dist/nitro.js +3 -3
  41. package/dist/{oauth-callback-server-B-WbSdoH.js → oauth-callback-server-CpGmEw_i.js} +2 -2
  42. package/dist/{prompt-BW9jFsqZ.js → prompt-BlQB0QQt.js} +1 -1
  43. package/dist/{registry-BgecKva0.js → registry-By36_xsm.js} +1 -1
  44. package/dist/reporting-schema-CZREhYc-.js +104 -0
  45. package/dist/{web-message-id-DlHNANtd.js → reporting-window-CVarfId9.js} +130 -7
  46. package/dist/{resolve-Cpa4Bu1O.js → resolve-CUIBcdPd.js} +3 -3
  47. package/dist/{result-D3TSmZZ8.js → result-BemsOMOO.js} +30 -11
  48. package/dist/{runner-DS5OKhEp.js → runner-BVok7PAA.js} +12 -11
  49. package/dist/{sandbox-egress-signals-CnDjY5rx.js → sandbox-egress-signals-BSUWQI95.js} +1 -1
  50. package/dist/{schema-0050HFnB.js → schema-ChnFo5f2.js} +36 -20
  51. package/dist/{schema-ZngqcOWM.d.ts → schema-jK4-1u_H.d.ts} +126 -12
  52. package/dist/{service-account-CKV2WTY7.js → service-account-DHvlLnZw.js} +4 -3
  53. package/dist/{service-account-DGjnDw9y.js → service-account-hMmESDcr.js} +3 -3
  54. package/dist/{session-stop-Dam1EI7B.js → session-stop-BQW_iFcd.js} +15 -15
  55. package/dist/{skills-CfAnfImD.js → skills-DmJJIuLF.js} +2 -2
  56. package/dist/{spawn-cmq9p4Ly.js → spawn-ChCm46i-.js} +2 -2
  57. package/dist/{store-C5PN02QO.js → store-1DVhoKOL.js} +3 -3
  58. package/dist/{store-zPEoJPBB.js → store-DCo2n5iJ.js} +3 -3
  59. package/dist/{task-queue-_mf28dSu.js → task-queue-HMC4QjFm.js} +3 -3
  60. package/dist/task-runner-cA6yjn_E.js +269 -0
  61. package/dist/{thread-state-BbbPh0Sn.js → thread-state-CHy8LS0C.js} +5 -5
  62. package/dist/{turn-failure-response-BKKmnMB5.js → turn-failure-response-Dr7erLWs.js} +9 -9
  63. package/dist/{turn-lifecycle-oP0kVeGz.js → turn-lifecycle-bf2fIYi_.js} +1 -1
  64. package/dist/{tasks-SB9z-VTU.js → turn-session-routing-BqO0qXLk.js} +928 -116
  65. package/dist/{validation--JsAGLwc.js → validation-DHR1ivfh.js} +1 -1
  66. package/dist/{version-jHwJp4hC.js → version-CXCHLgWm.js} +1 -1
  67. package/dist/version.js +1 -1
  68. package/dist/{viewer-CpXTGlep.js → viewer-DSbD6DF6.js} +201 -27
  69. package/dist/{work-3N-GHY9m.js → work-BE_qTYGi.js} +17 -36
  70. package/dist/{worker-CCdbcItd.js → worker-Cm9_sWXg.js} +15 -7
  71. package/migrations/0069_system_identity.sql +25 -0
  72. package/migrations/0070_review_item_foreign_keys.sql +5 -0
  73. package/migrations/AGENTS.md +17 -0
  74. package/migrations/meta/0069_snapshot.json +3979 -0
  75. package/migrations/meta/0070_snapshot.json +3997 -0
  76. package/migrations/meta/_journal.json +15 -1
  77. package/package.json +4 -4
  78. package/dist/db-BU4LQD8s.d.ts +0 -6
  79. package/dist/history-BgI33Kie.d.ts +0 -78
  80. package/dist/reporting-window-DVCD_10C.js +0 -227
  81. package/dist/task-runner-DMI2prDO.js +0 -1073
  82. package/migrations/README.md +0 -30
package/dist/app.js CHANGED
@@ -1,43 +1,44 @@
1
- import { $t as CONVERSATION_WORK_STALE_ENQUEUE_MS, C as automationVersionOf, I as eventGuidance, _n as isInvalidConversationRecordError, _r as setConfigDefaults, _t as settleConversationTitleWork, ar as getThreadStopDecision, b as admitEventAutomationRun, c as withScheduledAutomationLock, dr as setExperimentalFeatures, dt as appendConversationMessages, gr as getConfigDefaults, hn as hasRunnableConversationWork, i as readScheduledAutomation, l as blockEventAutomation, lr as getExperimentalFeatures, mt as projectConversationMessages, n as listScheduledAutomationsForTeam, nr as SubscribedReplyReason, o as saveScheduledAutomationInLock, p as findMatchingEventAutomations, s as scheduledRunId, u as collectEventAutomationMatchKeys, ur as isExperimentalFeatureEnabled, x as eventAutomationRunLimitReason } from "./tasks-SB9z-VTU.js";
2
- import { _ as snapshotRuntimeConfig, d as restoreRuntimeConfig, f as setBotModelConfig, g as setSlackReactionConfig, h as setRuntimeLimits, i as getChatConfig, m as setProfiles, n as botConfig, o as getSlackBotToken, p as setCrossActorMidRunMode, u as resetRuntimeConfig } from "./config-DrTeF80T.js";
3
- import { A as JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE, E as withSpan, N as JUNIOR_WORKSPACE_SNAPSHOT_JOB_CALLBACK_ROUTE, T as withLogContext, b as setSpanAttributes, h as logWarn, m as logInfo, p as logException, r as createRequestContext, w as withContext, z as normalizeIdentityEmail } from "./logging-DLSpkSSr.js";
1
+ import { B as readScheduledAutomation, Fr as SubscribedReplyReason, G as blockEventAutomation, H as saveScheduledAutomationInLock, Hr as getExperimentalFeatures, Jn as hasRunnableConversationWork, K as collectEventAutomationMatchKeys, M as recordAutomationExecution, Mn as CONVERSATION_WORK_STALE_ENQUEUE_MS, R as listScheduledAutomationsForTeam, Rr as getThreadStopDecision, S as existingConversationId, U as scheduledRunId, Ur as isExperimentalFeatureEnabled, W as withScheduledAutomationLock, Wr as setExperimentalFeatures, Wt as appendConversationMessages, Xn as isInvalidConversationRecordError, Xr as setConfigDefaults, Xt as settleConversationTitleWork, Y as findMatchingEventAutomations, Yr as getConfigDefaults, a as confirmDispatchMailboxAppend, b as notifyAutomationBlocked, f as getPluginDispatchProjection, ht as eventGuidance, it as automationVersionOf, m as listPendingDispatchMailboxAppends, nt as eventAutomationRunLimitReason, o as createOrGetDispatch, p as isTerminalDispatchStatus, qt as projectConversationMessages, r as buildDispatchId, s as getDispatchConversationId, tt as admitEventAutomationRun, u as getDispatchRecord, v as markDispatchFailed } from "./turn-session-routing-BqO0qXLk.js";
2
+ import { _ as snapshotRuntimeConfig, d as restoreRuntimeConfig, f as setBotModelConfig, g as setSlackReactionConfig, h as setRuntimeLimits, i as getChatConfig, m as setProfiles, n as botConfig, o as getSlackBotToken, p as setCrossActorMidRunMode, u as resetRuntimeConfig } from "./config-CPsE4T5L.js";
3
+ import { A as JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE, E as withSpan, L as GOOGLE_IDENTITY_PROVIDER, N as JUNIOR_WORKSPACE_SNAPSHOT_JOB_CALLBACK_ROUTE, T as withLogContext, b as setSpanAttributes, h as logWarn, m as logInfo, p as logException, r as createRequestContext, w as withContext, z as normalizeIdentityEmail } from "./logging-n7knse-O.js";
4
4
  import { n as captureMessage } from "./sentry-MDkYAVPV.js";
5
- import { t as JUNIOR_VERSION } from "./version-jHwJp4hC.js";
5
+ import { t as JUNIOR_VERSION } from "./version-CXCHLgWm.js";
6
6
  import { f as parseSlackTeamId, g as slackMessageTsSchema, h as slackMessageTsFromMs, m as parseSlackMessageTs, n as createSlackActor, p as parseSlackUserId, s as parseActorUserId, u as parseSlackChannelId } from "./actor-CP9K2Idu.js";
7
- import { O as recordGoogleSignIn, _ as withConversationEventLock, b as withConversationMutationLock, d as getConversationEventStore, h as getSqlExecutor, i as readActorIdentity, l as closeDb, m as getDb, o as resolveViewerUser, p as getConversationStore } from "./viewer-CpXTGlep.js";
7
+ import { C as getSqlExecutor, M as resolveActorIdentityId, O as withConversationMutationLock, R as recordGoogleSignIn, S as getDb, T as withConversationEventLock, _ as closeDb, g as createCache, i as readActorIdentity, l as resolveViewerUser, p as parseAvatarUrl, x as getConversationStore, y as getConversationEventStore } from "./viewer-DSbD6DF6.js";
8
8
  import { a as juniorAgentInvocations, d as juniorDestinations, i as juniorAgentBindings, s as juniorConversations } from "./agent-invocations-C1RNOCs8.js";
9
- import { d as juniorAutomations, g as juniorConversationBriefs, l as juniorAutomationRuns, y as juniorConversationEvents } from "./executor-4vhvsMZJ.js";
10
- import { n as pluginCatalogRuntime } from "./catalog-runtime-BD9GSpc6.js";
11
- import { C as getOpenSlackUserInput, Ct as requestAttachmentDeletion, Dt as recordSubagentEnded, E as parseSlackThreadId, Et as stopConversationSession, G as parseSlackReviewItemClick, H as syncReviewItemSlackCards, J as buildSlackUserInputModal, K as parseSlackReviewItemFormTarget, N as logScheduledAutomationRunSkipped, Nt as processWorkspaceSnapshotJob, P as scheduledAutomationRunAttributes, Pt as ingestEvent, Q as slackUserInputAnswerNote, R as effectiveTaskOutcomes, S as closeSlackUserInput, T as releaseSlackUserInput, V as readSlackReviewItemCardConversationId, W as buildSlackReviewItemModal, X as parseSlackUserInputSubmission, Y as parseSlackUserInputFormTarget, Z as slackUserInputAction, _ as unpublishedArtifactHeaders, _t as recordWebConversationActivity, dt as sendReviewItemMessages, et as runWithSlackInstallation, g as readPublicArtifact, h as publicArtifactHeaders, mt as conversationTurnIdForMessage, n as executeAgentRun, pt as appendAndEnqueueWebMessage, t as createAgentRunner, tt as verifySlackSignature, ut as renderReviewItemMessage, v as lookupSlackUserProfile, vt as webActorFromEmail, w as persistSlackUserInputReply, x as claimSlackUserInput, xt as collectAttachmentGarbage } from "./agent-runner-CAYfFmU7.js";
12
- import { $ as openSlackModal, I as isVercelSandboxEgressRequest, In as createPluginLogger, Jt as bindScheduledAutomationCredentialSubject, Kt as takeDueTimerWatches, L as proxyVercelSandboxEgressRequest, Ln as readConversationAccessFromSql, Nn as createPluginState, Qt as verifySlackDirectCredentialSubject, Tt as normalizeSandboxEgressTracePropagationDomains, Ut as findMatchingWatches, V as resolveBaseUrl, Xt as verifyEventAutomationCredentialSubject, Yt as bindSlackDirectCredentialSubject, Zt as verifyScheduledAutomationCredentialSubject, _n as getDashboardTaskLink, _t as consumeSandboxEgressPermissionDeniedSignal, at as slackEntitySchema, c as getPluginRoutes, cr as createPluginCache, dn as getWorkspaceTeamId, er as resolveRootVisibility, et as postSlackEphemeralMessage, fn as runWithWorkspaceTeamId, gt as consumeSandboxEgressAuthRequiredSignal, h as validatePlugins, ht as clearSandboxEgressSignals, in as getSlackClient, lr as createCache, m as setPlugins, mn as getDashboardConversationLink, n as createUserTokenStore, on as isDmChannel, ot as slackExternalRefIdSchema, p as getPlugins, q as slackMention, qt as bindEventAutomationCredentialSubject, rr as listConversationAnnotations, s as getPluginApiRoutes, v as setBriefsConfig, vn as setDashboardConversationLinkOptions, yt as parseSandboxEgressCredentialToken, zt as collectEventMatchKeys } from "./credentialed-lukuD-cc.js";
13
- import { a as MUTATION_LOCK_TTL_MS, c as withLock, i as getStateAdapter, s as fenceLock, t as disconnectStateAdapter } from "./adapter-04AcD2SO.js";
9
+ import { c as juniorReviewItems, d as juniorAutomations, g as juniorConversationBriefs, l as juniorAutomationRuns, y as juniorConversationEvents } from "./executor-CNS7ONt-.js";
10
+ import { n as pluginCatalogRuntime } from "./catalog-runtime-BsoSmTM0.js";
11
+ import { A as verifySlackSignature, C as syncReviewItemSlackCards, Ct as processWorkspaceSnapshotJob, D as parseSlackReviewItemFormTarget, E as parseSlackReviewItemClick, J as readViewerAutomationSummary, L as logScheduledAutomationRunSkipped, O as parseSlackUserInputSubmission, Q as effectiveTaskOutcomes, R as scheduledAutomationRunAttributes, S as readSlackReviewItemCardConversationId, T as buildSlackReviewItemModal, _ as unpublishedArtifactHeaders, _t as recordSubagentEnded, ct as webActorFromEmail, dt as collectAttachmentGarbage, et as deliverReviewItemChange, g as readPublicArtifact, gt as stopConversationSession, h as publicArtifactHeaders, it as conversationTurnIdForMessage, j as parseSlackThreadId, k as runWithSlackInstallation, n as executeAgentRun, pt as requestAttachmentDeletion, rt as appendAndEnqueueWebMessage, st as recordWebConversationActivity, t as createAgentRunner, tt as renderReviewItemMessage, v as lookupSlackUserProfile, wt as ingestEvent, x as createSlackReviewItemShow } from "./agent-runner-CrDrPUtY.js";
12
+ import { At as slackEntitySchema, Bn as getDashboardTaskLink, Bt as clearSandboxEgressSignals, Cr as resolveRootVisibility, Dn as getSlackClient, Er as listConversationAnnotations, Fn as runWithWorkspaceTeamId, Ht as consumeSandboxEgressPermissionDeniedSignal, Ln as getDashboardConversationLink, M as canActOnReviewItem, Pn as getWorkspaceTeamId, S as dismissOpenReviewItems, Tt as postSlackEphemeralMessage, Vn as setDashboardConversationLinkOptions, Vt as consumeSandboxEgressAuthRequiredSignal, Wt as parseSandboxEgressCredentialToken, Xt as normalizeSandboxEgressTracePropagationDomains, _n as bindScheduledAutomationCredentialSubject, ar as createPluginLogger, bn as verifyScheduledAutomationCredentialSubject, c as getPluginRoutes, cn as collectEventMatchKeys, ct as proxyVercelSandboxEgressRequest, fn as findMatchingWatches, ft as resolveBaseUrl, gn as bindEventAutomationCredentialSubject, h as validatePlugins, hn as takeDueTimerWatches, jr as createPluginCache, jt as slackExternalRefIdSchema, kn as isDmChannel, m as setPlugins, n as createUserTokenStore, nr as createPluginState, or as readConversationAccessFromSql, p as getPlugins, s as getPluginApiRoutes, st as isVercelSandboxEgressRequest, v as setBriefsConfig, vn as bindSlackDirectCredentialSubject, vt as slackMention, wt as openSlackModal, xn as verifySlackDirectCredentialSubject, yn as verifyEventAutomationCredentialSubject } from "./credentialed-BU-OW7HP.js";
13
+ import { a as withLock, i as fenceLock, n as MUTATION_LOCK_TTL_MS } from "./locks-D-0h111u.js";
14
+ import { r as getStateAdapter, t as disconnectStateAdapter } from "./adapter-2-CG25be.js";
14
15
  import { n as getNextRunAtMs } from "./cadence-R7Em4RjE.js";
15
- import { D as conversationSurfaceSchema, I as annotationCard, T as conversationReportStatusSchema, h as conversationFeedQuerySchema } from "./conversation-DSo310Ps.js";
16
- import { b as listPendingAgentInvocationMailboxAppends, x as listPendingAgentInvocationResults } from "./store-C5PN02QO.js";
17
- import { E as renderSlackObjectCard, S as renderTaskInput, d as getEventCatalog, f as SLACK_EVENT_NAMESPACE, g as slackChannelMessageRunsAutomation, h as slackChannelMessageReplyThreadTs, m as slackChannelMessageEvent } from "./session-stop-Dam1EI7B.js";
18
- import { a as isEmptyUserInputAnswer, i as formatUserInputAnswer, o as normalizeUserInputAnswer, r as buttonUserInputField } from "./web-message-id-DlHNANtd.js";
19
- import { c as setSandboxResourceConfig, o as getSandboxResourceConfig } from "./resolve-Cpa4Bu1O.js";
20
- import { a as getVercelConversationWorkQueue, d as getQueueProvider, g as isConversationQueueMessageRejectedError, h as conversationQueueMessageSchema, i as verifyWorkspaceSnapshotJobMessage, o as resolveConversationWorkQueueTopic, s as verifyConversationQueueMessage, t as WORKSPACE_SNAPSHOT_JOB_QUEUE_TOPIC } from "./job-queue-In9QKz-I.js";
21
- import { S as removeActiveConversation, _ as hasRunnableConversationWork$1, c as clearExpiredConversationLease, g as getConversationWorkState, h as getConversation, m as ensureConversationWake, r as appendAndEnqueueInboundMessage, v as listActiveConversationIds } from "./store-zPEoJPBB.js";
22
- import { D as scheduledRunSchema } from "./automation-CmeFBSEh.js";
23
- import { n as validatePluginRegistrations, t as validatePluginEgressCredentialHooks } from "./validation--JsAGLwc.js";
16
+ import { D as conversationSurfaceSchema, I as annotationCard, T as conversationReportStatusSchema, h as conversationFeedQuerySchema } from "./conversation-CTpD_PGk.js";
17
+ import { b as listPendingAgentInvocationMailboxAppends, x as listPendingAgentInvocationResults } from "./store-1DVhoKOL.js";
18
+ import { E as renderSlackObjectCard, S as renderTaskInput, d as getEventCatalog, f as SLACK_EVENT_NAMESPACE, g as slackChannelMessageRunsAutomation, h as slackChannelMessageReplyThreadTs, m as slackChannelMessageEvent } from "./session-stop-BQW_iFcd.js";
19
+ import { m as buttonUserInputField } from "./reporting-window-CVarfId9.js";
20
+ import { c as setSandboxResourceConfig, o as getSandboxResourceConfig } from "./resolve-CUIBcdPd.js";
21
+ import { a as getVercelConversationWorkQueue, d as getQueueProvider, g as isConversationQueueMessageRejectedError, h as conversationQueueMessageSchema, i as verifyWorkspaceSnapshotJobMessage, o as resolveConversationWorkQueueTopic, s as verifyConversationQueueMessage, t as WORKSPACE_SNAPSHOT_JOB_QUEUE_TOPIC } from "./job-queue-DI-k-Bbk.js";
22
+ import { S as removeActiveConversation, _ as hasRunnableConversationWork$1, c as clearExpiredConversationLease, g as getConversationWorkState, h as getConversation, m as ensureConversationWake, r as appendAndEnqueueInboundMessage, v as listActiveConversationIds } from "./store-DCo2n5iJ.js";
23
+ import { M as scheduledRunSchema } from "./automation-p87hg_AV.js";
24
+ import { n as validatePluginRegistrations, t as validatePluginEgressCredentialHooks } from "./validation-DHR1ivfh.js";
24
25
  import { a as pluginRuntimeRegistrationsFromPluginSet, n as pluginCatalogConfigFromEnv, r as pluginCatalogConfigFromPluginSet, t as defineJuniorPlugins } from "./plugins-DOm9Y6qI.js";
25
- import { A as assertNoLegacyAllowedDomains, B as normalizeIncomingSlackThreadId, E as readViewerAutomationSummary, F as recordSkippedConversationMessage, G as parseContent, H as stopConversationTurn, I as buildSlackInboundMessage, J as canActOnReviewItem, K as ReviewItemActionError, L as clearSlackPendingReactions, M as isAllowedSignInEmail, N as readEnvList, P as resolveAllowedDomains, Q as getAttachmentStorage, R as isSlackMessageStopped, U as THREAD_OPTOUT_ACK, V as withNormalizedThreadId, W as startProcessingReaction, X as readReviewItemForUser, Z as reviewItemChange, _ as createProductionConversationWorkOptions, b as createSlackWebApiStatusSender, et as enqueueAgentDispatch, j as isAllowedDomain, q as actOnReviewItem, t as readConversationFeed, tt as GET$3, v as createProductionSlackWebhookServices, y as getProductionSlackAdapter, z as stopSlackThread } from "./list-BkgnXEEB.js";
26
- import { C as existingConversationId, N as recordAutomationExecution, c as getDispatchConversationId, d as getDispatchRecord, h as listPendingDispatchMailboxAppends, i as buildDispatchId, m as isTerminalDispatchStatus, o as confirmDispatchMailboxAppend, p as getPluginDispatchProjection, s as createOrGetDispatch, t as processPluginTask, x as notifyAutomationBlocked, y as markDispatchFailed } from "./task-runner-DMI2prDO.js";
27
- import { o as getAuthPausedConversationTurnId, t as enqueueAgentInvocationResult } from "./result-D3TSmZZ8.js";
28
- import { r as enqueueAgentInvocation } from "./work-3N-GHY9m.js";
29
- import { o as coerceThreadConversationState } from "./thread-state-BbbPh0Sn.js";
30
- import { o as unlinkProvider } from "./connections-D46f8vvi.js";
31
- import { a as GET$4, i as publishAppHomeView, r as GET$5, t as receiveLocalOAuthCredential } from "./credential-sync-sm9fegLY.js";
32
- import { a as pluginTaskQueueConsumer, c as queueCallback, n as createVercelPluginTaskCallback, o as registerVercelPluginTaskDevConsumer } from "./task-queue-_mf28dSu.js";
33
- import { t as processConversationWork } from "./worker-CCdbcItd.js";
34
- import { t as bindMessageAgent } from "./message-BObyg59s.js";
35
- import { t as bindSpawnAgent } from "./spawn-cmq9p4Ly.js";
26
+ import { A as stopSlackThread, B as actOnReviewItem, C as isAllowedSignInEmail, D as buildSlackInboundMessage, E as recordSkippedConversationMessage, F as bindMessageAuthorIdentityId, H as readReviewItemForUser, I as startProcessingReaction, K as enqueueAgentDispatch, L as stripLeadingBotMention, M as withNormalizedThreadId, N as stopConversationTurn, O as clearSlackPendingReactions, P as THREAD_OPTOUT_ACK, R as parseContent, S as isAllowedDomain, T as resolveAllowedDomains, U as reviewItemChange, V as closeReviewItemsAnsweredByReply, W as getAttachmentStorage, _ as createProductionConversationWorkOptions, b as createSlackWebApiStatusSender, j as normalizeIncomingSlackThreadId, k as isSlackMessageStopped, q as GET$3, t as readConversationFeed, v as createProductionSlackWebhookServices, w as readEnvList, x as assertNoLegacyAllowedDomains, y as getProductionSlackAdapter, z as ReviewItemActionError } from "./list-CGoQdXTp.js";
27
+ import { n as enqueueAgentInvocationResult, o as getAuthPausedConversationTurnId } from "./result-BemsOMOO.js";
28
+ import { r as enqueueAgentInvocation } from "./work-BE_qTYGi.js";
29
+ import { o as coerceThreadConversationState } from "./thread-state-CHy8LS0C.js";
30
+ import { o as unlinkProvider } from "./connections-upFXLmhG.js";
31
+ import { a as GET$4, i as publishAppHomeView, r as GET$5, t as receiveLocalOAuthCredential } from "./credential-sync-CS_6IC-f.js";
32
+ import { a as pluginTaskQueueConsumer, c as queueCallback, n as createVercelPluginTaskCallback, o as registerVercelPluginTaskDevConsumer } from "./task-queue-HMC4QjFm.js";
33
+ import { t as processConversationWork } from "./worker-Cm9_sWXg.js";
34
+ import { t as bindMessageAgent } from "./message-BpaWd8TT.js";
35
+ import { t as bindSpawnAgent } from "./spawn-ChCm46i-.js";
36
+ import { t as processPluginTask } from "./task-runner-cA6yjn_E.js";
36
37
  import { createRequire } from "node:module";
37
38
  import { Hono } from "hono";
38
39
  import { z } from "zod";
39
40
  import { createHash, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
40
- import { and, asc, eq, inArray, isNotNull, isNull, lte, or, sql } from "drizzle-orm";
41
+ import { and, asc, eq, inArray, isNotNull, isNull, lte, ne, or, sql } from "drizzle-orm";
41
42
  import { EVENT_SUMMARY_MAX_LENGTH, EVENT_TEXT_MAX_LENGTH, dispatchOptionsSchema, eventSchema, eventTriggerFiltersText, isSlackDestination, userSchema } from "@sentry/junior-plugin-api";
42
43
  import { pathToFileURL } from "node:url";
43
44
  import net from "node:net";
@@ -1226,6 +1227,12 @@ async function selectExpiredRoots(executor, args) {
1226
1227
  where bindings.parent_conversation_id = tree.conversation_id
1227
1228
  or bindings.child_conversation_id = tree.conversation_id
1228
1229
  )
1230
+ or exists (
1231
+ select 1 from junior_review_items review_items
1232
+ where review_items.added_by_conversation_id = tree.conversation_id
1233
+ and review_items.status = 'open'
1234
+ and review_items.automation_id is null
1235
+ )
1229
1236
  or (
1230
1237
  ${juniorDestinations.visibility} is distinct from 'public'
1231
1238
  and (
@@ -1233,6 +1240,15 @@ async function selectExpiredRoots(executor, args) {
1233
1240
  select 1 from junior_conversation_briefs briefs
1234
1241
  where briefs.conversation_id = tree.conversation_id
1235
1242
  )
1243
+ or exists (
1244
+ select 1 from junior_review_items review_items
1245
+ where review_items.added_by_conversation_id = tree.conversation_id
1246
+ and review_items.visibility = 'private'
1247
+ and (
1248
+ review_items.status <> 'open'
1249
+ or review_items.automation_id is null
1250
+ )
1251
+ )
1236
1252
  or exists (
1237
1253
  select 1 from junior_conversations metadata
1238
1254
  where metadata.conversation_id = tree.conversation_id
@@ -1258,7 +1274,9 @@ async function selectExpiredRoots(executor, args) {
1258
1274
  * event rows for the given conversation and every descendant, stamp
1259
1275
  * `transcript_purged_at`, and — for non-public content — null the raw-payload
1260
1276
  * metadata (`title`, `channel_name`, legacy actor JSON) so purged private
1261
- * conversations keep only safe metadata. The metadata rows themselves survive.
1277
+ * conversations keep only safe metadata. Non-public content also loses its
1278
+ * Briefs and the Review items that it added. The metadata rows themselves
1279
+ * survive.
1262
1280
  */
1263
1281
  async function purgeConversationTree(executor, args) {
1264
1282
  return await withConversationMutationLock(executor, args.rootConversationId, async () => {
@@ -1303,9 +1321,17 @@ async function purgeConversationTree(executor, args) {
1303
1321
  await executor.db().delete(juniorConversationEvents).where(inArray(juniorConversationEvents.conversationId, ids));
1304
1322
  await executor.db().delete(juniorAgentInvocations).where(or(inArray(juniorAgentInvocations.parentConversationId, ids), inArray(juniorAgentInvocations.childConversationId, ids)));
1305
1323
  await executor.db().delete(juniorAgentBindings).where(or(inArray(juniorAgentBindings.parentConversationId, ids), inArray(juniorAgentBindings.childConversationId, ids)));
1324
+ await dismissOpenReviewItems(executor.db(), {
1325
+ addedByConversationIds: ids,
1326
+ nowMs: args.nowMs,
1327
+ reason: "Conversation purged"
1328
+ });
1306
1329
  await requestAttachmentDeletion(executor, ids, args.nowMs);
1307
1330
  const scrubMetadata = args.retention ? !isPublic : resolvedScrubMetadata;
1308
- if (scrubMetadata) await executor.db().delete(juniorConversationBriefs).where(inArray(juniorConversationBriefs.conversationId, ids));
1331
+ if (scrubMetadata) {
1332
+ await executor.db().delete(juniorConversationBriefs).where(inArray(juniorConversationBriefs.conversationId, ids));
1333
+ await executor.db().delete(juniorReviewItems).where(and(inArray(juniorReviewItems.addedByConversationId, ids), eq(juniorReviewItems.visibility, "private"), or(ne(juniorReviewItems.status, "open"), isNull(juniorReviewItems.automationId))));
1334
+ }
1309
1335
  await executor.db().update(juniorConversations).set({
1310
1336
  transcriptPurgedAt: new Date(args.nowMs),
1311
1337
  ...scrubMetadata ? {
@@ -1776,8 +1802,8 @@ async function refreshCards(services, user, itemId) {
1776
1802
  }
1777
1803
  /**
1778
1804
  * Do one person action from a Slack card. The thread of the card gets the
1779
- * action as Slack input from the person, like an answer to
1780
- * `requestUserInput`. The other linked Conversations get messages from
1805
+ * action as Slack input from the person, like a typed reply. The other
1806
+ * linked Conversations get messages from
1781
1807
  * `actOnReviewItem`. An expected failure, such as an item that is already
1782
1808
  * closed, goes to the person as an ephemeral message.
1783
1809
  */
@@ -1789,6 +1815,10 @@ async function act(args) {
1789
1815
  ...target,
1790
1816
  itemId: args.itemId
1791
1817
  }) ?? `slack:${target.channelId}:${target.threadTs}`;
1818
+ const delivery = {
1819
+ queue: services.queue,
1820
+ show: createSlackReviewItemShow(() => services.adapter)
1821
+ };
1792
1822
  let item;
1793
1823
  try {
1794
1824
  const current = await readReviewItemForUser(actor.user, args.itemId);
@@ -1796,9 +1826,8 @@ async function act(args) {
1796
1826
  action: args.action,
1797
1827
  exceptConversationId: conversationId,
1798
1828
  firstCloseOnly: true,
1799
- getSlackAdapter: () => services.adapter,
1829
+ delivery,
1800
1830
  id: current.id,
1801
- queue: services.queue,
1802
1831
  user: actor.user,
1803
1832
  ...args.answer ? { answer: args.answer(current) } : void 0
1804
1833
  });
@@ -1824,11 +1853,11 @@ async function act(args) {
1824
1853
  }));
1825
1854
  } catch (error) {
1826
1855
  logException(error, "review_item.slack_input.persist.failed", { "app.review_item.id": item.id });
1827
- await sendReviewItemMessages({
1856
+ await deliverReviewItemChange({
1828
1857
  change,
1858
+ delivery,
1829
1859
  item,
1830
- nowMs: Date.now(),
1831
- queue: services.queue
1860
+ nowMs: Date.now()
1832
1861
  });
1833
1862
  }
1834
1863
  }
@@ -1972,139 +2001,8 @@ async function handleAppHomeDisconnect(args) {
1972
2001
  });
1973
2002
  }
1974
2003
  /**
1975
- * Save the first answer to the open request of a Slack thread as Slack input
1976
- * from the person who answered. The input text is the formatted answer, so
1977
- * the model reads one format on every surface. Later answers to the same
1978
- * request do nothing. A stale request, such as one that a newer request
1979
- * replaced, also does nothing.
1980
- */
1981
- async function answerSlackUserInput(args) {
1982
- const userId = requireSlackPayloadUserId(args.payload.user?.id, "Slack user input payload");
1983
- const { channelId, messageTs } = args;
1984
- const open = await getOpenSlackUserInput(args.state, {
1985
- channelId,
1986
- threadTs: args.threadTs
1987
- });
1988
- if (!open || open.messageTs !== messageTs) return;
1989
- const answer = args.answer(open);
1990
- if (isEmptyUserInputAnswer(answer)) return;
1991
- const userTeam = args.payload.user?.team_id;
1992
- if (!await isSlackWorkspaceMember({
1993
- user: userId,
1994
- user_team: userTeam
1995
- }, args.state)) return;
1996
- if (!await args.isAuthorAllowed(userId)) return;
1997
- if (!await claimSlackUserInput(args.state, {
1998
- channelId,
1999
- claimedBy: userId,
2000
- messageTs
2001
- })) return;
2002
- const message = buildSlackInteractionInput({
2003
- adapter: args.adapter,
2004
- channelId,
2005
- inputTs: args.inputTs,
2006
- messageId: args.messageId,
2007
- messageTs,
2008
- payload: args.payload,
2009
- text: formatUserInputAnswer(open.request, answer),
2010
- threadTs: args.threadTs,
2011
- userId
2012
- });
2013
- try {
2014
- await args.persistMessage(message);
2015
- } catch (error) {
2016
- await releaseSlackUserInput(args.state, {
2017
- channelId,
2018
- messageTs
2019
- });
2020
- throw error;
2021
- }
2022
- await closeSlackUserInput({
2023
- note: slackUserInputAnswerNote({
2024
- answer,
2025
- request: open.request,
2026
- who: slackMention(userId)
2027
- }),
2028
- open
2029
- });
2030
- }
2031
- /** Read the request message and thread of a block action. */
2032
- function blockActionTarget(payload) {
2033
- const channelId = parseSlackChannelId(payload.channel?.id);
2034
- const messageTs = parseSlackMessageTs(payload.message?.ts);
2035
- if (!channelId || !messageTs) throw new Error("Slack user input payload is incomplete");
2036
- return {
2037
- channelId,
2038
- messageTs,
2039
- threadTs: parseSlackMessageTs(payload.message?.thread_ts) ?? messageTs
2040
- };
2041
- }
2042
- /** Answer a one-click request with the clicked choice. */
2043
- async function handleUserInputChoice(args) {
2044
- const target = blockActionTarget(args.payload);
2045
- const actionTs = parseSlackMessageTs(args.action.action_ts);
2046
- const choice = args.action.value?.trim();
2047
- if (!actionTs || !choice) throw new Error("Slack user input click payload is incomplete");
2048
- await answerSlackUserInput({
2049
- ...target,
2050
- adapter: args.adapter,
2051
- answer: (open) => {
2052
- const field = buttonUserInputField(open.request);
2053
- return normalizeUserInputAnswer(open.request, {
2054
- requestId: open.requestId,
2055
- values: field ? { [field.id]: [choice] } : {}
2056
- });
2057
- },
2058
- inputTs: actionTs,
2059
- messageId: `slack-user-input-answer:${actionTs}`,
2060
- payload: args.payload,
2061
- isAuthorAllowed: args.isAuthorAllowed,
2062
- persistMessage: args.persistMessage,
2063
- state: args.state
2064
- });
2065
- }
2066
- /** Open the answer form of the open request for the person who clicked. */
2067
- async function handleUserInputOpenForm(args) {
2068
- const target = blockActionTarget(args.payload);
2069
- const triggerId = args.payload.trigger_id;
2070
- if (!triggerId) throw new Error("Slack user input form payload is missing a trigger id");
2071
- const open = await getOpenSlackUserInput(args.state, target);
2072
- if (!open || open.messageTs !== target.messageTs) return;
2073
- await openSlackModal({
2074
- triggerId,
2075
- view: buildSlackUserInputModal(open.request, target)
2076
- });
2077
- }
2078
- /** Answer a request with the values of its submitted form. */
2079
- async function handleUserInputSubmission(args) {
2080
- const view = args.payload.view;
2081
- const formTarget = parseSlackUserInputFormTarget(view?.private_metadata);
2082
- const channelId = parseSlackChannelId(formTarget?.channelId);
2083
- const messageTs = parseSlackMessageTs(formTarget?.messageTs);
2084
- const threadTs = parseSlackMessageTs(formTarget?.threadTs);
2085
- if (!view?.id || !channelId || !messageTs || !threadTs) throw new Error("Slack user input form submission is incomplete");
2086
- const inputTs = slackMessageTsFromMs(Date.now());
2087
- await answerSlackUserInput({
2088
- adapter: args.adapter,
2089
- answer: (open) => parseSlackUserInputSubmission({
2090
- request: open.request,
2091
- requestId: open.requestId,
2092
- values: view.state?.values ?? {}
2093
- }),
2094
- channelId,
2095
- inputTs,
2096
- messageId: `slack-user-input-answer:${view.id}`,
2097
- messageTs,
2098
- payload: args.payload,
2099
- isAuthorAllowed: args.isAuthorAllowed,
2100
- persistMessage: args.persistMessage,
2101
- state: args.state,
2102
- threadTs
2103
- });
2104
- }
2105
- /**
2106
- * Handle Slack interactions from App Home, user input requests, and Review
2107
- * item cards: block actions and submitted forms.
2004
+ * Handle Slack interactions from App Home and Review item cards: block
2005
+ * actions and submitted forms.
2108
2006
  */
2109
2007
  async function handleSlackInteractivePayload(args) {
2110
2008
  const spanAttributes = { userId: args.payload.user?.id?.trim() || void 0 };
@@ -2115,10 +2013,6 @@ async function handleSlackInteractivePayload(args) {
2115
2013
  }));
2116
2014
  return;
2117
2015
  }
2118
- if (args.payload.type === "view_submission" && args.payload.view?.callback_id === "junior_user_input") {
2119
- await withSpan("chat.slack_user_input_submit", "chat.slack_user_input_submit", spanAttributes, () => handleUserInputSubmission(args));
2120
- return;
2121
- }
2122
2016
  if (args.payload.type !== "block_actions") return;
2123
2017
  for (const action of args.payload.actions ?? []) {
2124
2018
  const click = parseSlackReviewItemClick(action);
@@ -2131,18 +2025,6 @@ async function handleSlackInteractivePayload(args) {
2131
2025
  }));
2132
2026
  return;
2133
2027
  }
2134
- const kind = slackUserInputAction(action.action_id);
2135
- if (kind === "choice") {
2136
- await withSpan("chat.slack_user_input_click", "chat.slack_user_input_click", spanAttributes, () => handleUserInputChoice({
2137
- ...args,
2138
- action
2139
- }));
2140
- return;
2141
- }
2142
- if (kind === "open_form") {
2143
- await withSpan("chat.slack_user_input_open_form", "chat.slack_user_input_open_form", spanAttributes, () => handleUserInputOpenForm(args));
2144
- return;
2145
- }
2146
2028
  }
2147
2029
  const disconnect = args.payload.actions?.find((candidate) => candidate.action_id === "app_home_disconnect");
2148
2030
  const provider = disconnect?.selected_option?.value ?? disconnect?.value;
@@ -2644,6 +2526,17 @@ async function buildThread(args) {
2644
2526
  function shouldIgnoreMessage(message) {
2645
2527
  return message.author.isMe === true || !parseActorUserId(message.author.userId);
2646
2528
  }
2529
+ /**
2530
+ * Resolve the Slack author Identity at ingress and bind its id to the message.
2531
+ * Ingress does no profile lookup. The worker adds the profile names later.
2532
+ * Bot authors wait for their own bot Identity, so they get no id here.
2533
+ */
2534
+ async function bindSlackAuthorIdentity(message, installation) {
2535
+ const teamId = installation.teamId;
2536
+ const userId = parseActorUserId(message.author.userId);
2537
+ if (!teamId || !userId || message.author.isBot === true) return;
2538
+ bindMessageAuthorIdentityId(message, await resolveActorIdentityId(getSqlExecutor(), createSlackActor(teamId, userId, null)));
2539
+ }
2647
2540
  function shouldPersistBeforeAck(body) {
2648
2541
  return body.event?.type === "app_mention" || body.event?.type === "message";
2649
2542
  }
@@ -2742,6 +2635,7 @@ async function handleSlackThreadStop(args) {
2742
2635
  conversationId,
2743
2636
  state: args.state
2744
2637
  });
2638
+ await bindSlackAuthorIdentity(args.message, args.installation);
2745
2639
  const content = parseContent(args.message);
2746
2640
  const conversation = coerceThreadConversationState(void 0);
2747
2641
  recordSkippedConversationMessage({
@@ -2848,13 +2742,15 @@ async function routeParsedMessage(args) {
2848
2742
  });
2849
2743
  return;
2850
2744
  }
2851
- if (route === "mention" && !await isSlackAuthorDomainAllowed({
2745
+ const isAuthorDomainAllowed = () => isSlackAuthorDomainAllowed({
2852
2746
  allowedBotUserIds: args.allowedBotUserIds,
2853
2747
  allowedDomains: args.allowedDomains,
2854
2748
  state: args.state,
2855
2749
  teamId: args.installation.teamId,
2856
2750
  user: args.event.user
2857
- })) return;
2751
+ });
2752
+ if (route === "mention" && !await isAuthorDomainAllowed()) return;
2753
+ await bindSlackAuthorIdentity(message, args.installation);
2858
2754
  const conversationId = await resolveSlackConversationId({
2859
2755
  canonicalThreadId,
2860
2756
  conversationStore: args.conversationStore,
@@ -2886,22 +2782,34 @@ async function routeParsedMessage(args) {
2886
2782
  route,
2887
2783
  state: args.state
2888
2784
  });
2889
- if (route !== "mention") {
2785
+ const closeAnswered = async () => {
2786
+ if (message.author.isBot === true) return;
2787
+ await closeReviewItemsAnsweredByReply({
2788
+ ...route === "subscribed" ? { canAnswer: isAuthorDomainAllowed } : void 0,
2789
+ conversationId,
2790
+ delivery: {
2791
+ queue: args.queue,
2792
+ show: createSlackReviewItemShow(() => args.adapter)
2793
+ },
2794
+ resolveUser: async () => {
2795
+ const teamId = args.installation.teamId;
2796
+ const userId = parseActorUserId(message.author.userId);
2797
+ if (!teamId || !userId) return void 0;
2798
+ return (await readActorIdentity(createSlackActor(teamId, userId, null)))?.user;
2799
+ },
2800
+ text: stripLeadingBotMention(parseContent(message).topLevelText, {
2801
+ botUserId: args.adapter.botUserId,
2802
+ stripLeadingSlackMentionToken: true
2803
+ })
2804
+ });
2805
+ };
2806
+ try {
2890
2807
  await persist();
2891
- return;
2808
+ } catch (error) {
2809
+ if (error instanceof SlackEventPersistenceError && error.saved) await closeAnswered();
2810
+ throw error;
2892
2811
  }
2893
- await persistSlackUserInputReply({
2894
- channelId: args.event.channel,
2895
- claimedBy: message.author.userId,
2896
- isSaved: (error) => error instanceof SlackEventPersistenceError && error.saved,
2897
- note: (request) => slackUserInputAnswerNote({
2898
- request,
2899
- who: slackMention(message.author.userId)
2900
- }),
2901
- persist,
2902
- state: args.state,
2903
- threadTs: args.event.thread_ts
2904
- });
2812
+ await closeAnswered();
2905
2813
  }
2906
2814
  async function handleSlackEvent(args) {
2907
2815
  const event = args.body.event;
@@ -3005,6 +2913,7 @@ async function handleSlackEvent(args) {
3005
2913
  */
3006
2914
  async function persistSlackMentionWithLock(args) {
3007
2915
  const { message, threadId } = normalizeMessageThreadId(args.message);
2916
+ await bindSlackAuthorIdentity(message, args.installation);
3008
2917
  try {
3009
2918
  if (!(await withLock(args.state, `slack:ingress:${threadId}`, () => persistSlackMessage({
3010
2919
  adapter: args.adapter,
@@ -6264,7 +6173,8 @@ function createBetterAuth(config) {
6264
6173
  await recordGoogleSignIn(getSqlExecutor(), {
6265
6174
  email,
6266
6175
  subject: google.accountId,
6267
- displayName: created.user.name || void 0
6176
+ displayName: created.user.name || void 0,
6177
+ avatarUrl: parseAvatarUrl(created.user.image, GOOGLE_IDENTITY_PROVIDER)
6268
6178
  });
6269
6179
  }) }
6270
6180
  });
@@ -6663,7 +6573,10 @@ async function createApp(options) {
6663
6573
  validatePluginRegistrations(configuredPlugins?.registrations ?? []);
6664
6574
  validatePluginEgressCredentialHooks(configuredPlugins?.registrations ?? []);
6665
6575
  }
6666
- pluginRoutes = getPluginRoutes({ events });
6576
+ pluginRoutes = getPluginRoutes({
6577
+ events,
6578
+ showReviewItem: createSlackReviewItemShow(getProductionSlackAdapter)
6579
+ });
6667
6580
  if (dashboard && !dashboard.disabled) pluginApiRoutes = getPluginApiRoutes();
6668
6581
  } catch (error) {
6669
6582
  restoreRuntimeConfig$1();
@@ -6681,6 +6594,7 @@ async function createApp(options) {
6681
6594
  attachmentStorage,
6682
6595
  bindMessageAgent: (request) => bindMessageAgent(request, { queue: conversationWorkQueue }),
6683
6596
  bindSpawnAgent: (request) => bindSpawnAgent(request, { queue: conversationWorkQueue }),
6597
+ conversationWorkQueue,
6684
6598
  tracePropagation
6685
6599
  });
6686
6600
  const runtimeServiceOverrides = {