@sentry/junior 0.268.0 → 0.270.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 (83) hide show
  1. package/README.md +2 -9
  2. package/dist/{adapter-04AcD2SO.js → adapter-BQNTKVTF.js} +3 -49
  3. package/dist/{admin-DIU1QyG3.js → admin-CKVEoXa4.js} +1 -1
  4. package/dist/{agent-runner-CAYfFmU7.js → agent-runner-MSQSMFkq.js} +4538 -3251
  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 +190 -301
  9. package/dist/{app-z6Uuyq3j.d.ts → app-Bz8t4P8p.d.ts} +9 -3
  10. package/dist/app.d.ts +1 -1
  11. package/dist/app.js +129 -209
  12. package/dist/{automation-CmeFBSEh.js → automation-Dwh_xcqM.js} +74 -74
  13. package/dist/{briefs-DQbV2jNr.js → briefs-DNFzFFVx.js} +5 -5
  14. package/dist/{catalog-runtime-BD9GSpc6.js → catalog-runtime-Bdym_wKy.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-B2MjENki.js} +31 -16
  23. package/dist/{config-DrTeF80T.js → config-Dm3pWRqY.js} +3 -3
  24. package/dist/{connections-D46f8vvi.js → connections-0BBhiD-p.js} +10 -10
  25. package/dist/{conversation-DSo310Ps.js → conversation-AhOVzN_k.js} +11 -86
  26. package/dist/{conversation-privacy-CxlOCiUo.js → conversation-privacy-C1pJ89rs.js} +1 -1
  27. package/dist/{credential-sync-sm9fegLY.js → credential-sync-BRiWYs6_.js} +15 -14
  28. package/dist/{credentialed-lukuD-cc.js → credentialed-BeBaJMZ_.js} +565 -83
  29. package/dist/{store-xMuuXRE0.d.ts → db-BYOuu6v2.d.ts} +4 -0
  30. package/dist/{executor-4vhvsMZJ.js → executor-BB6eJkD4.js} +6 -6
  31. package/dist/instrumentation.js +2 -2
  32. package/dist/{interruption-marker-CkncDT8d.js → interruption-marker-CdblrIQK.js} +1 -1
  33. package/dist/{job-queue-In9QKz-I.js → job-queue-DiaXoSDg.js} +2 -2
  34. package/dist/{list-BkgnXEEB.js → list-BTDRxkOg.js} +331 -662
  35. package/dist/locks-D-0h111u.js +48 -0
  36. package/dist/{logging-DLSpkSSr.js → logging-C6EdT6PP.js} +1 -1
  37. package/dist/{history-C84mlAwO.js → media-U6Tuz6Mi.js} +84 -2
  38. package/dist/{message-BObyg59s.js → message-DsjiWRVg.js} +4 -4
  39. package/dist/{model-profile-Bg8EoCKD.js → model-profile-B998sjVd.js} +9 -2
  40. package/dist/nitro.d.ts +1 -1
  41. package/dist/nitro.js +5 -3
  42. package/dist/{oauth-callback-server-B-WbSdoH.js → oauth-callback-server-CjFFVGqa.js} +2 -2
  43. package/dist/{prompt-BW9jFsqZ.js → prompt-BPSdXYXV.js} +1 -1
  44. package/dist/{registry-BgecKva0.js → registry-CndmkP2P.js} +1 -1
  45. package/dist/reporting-schema-CZREhYc-.js +104 -0
  46. package/dist/{web-message-id-DlHNANtd.js → reporting-window-DRCi1Ls_.js} +139 -7
  47. package/dist/{resolve-Cpa4Bu1O.js → resolve-BkAA1wH7.js} +3 -3
  48. package/dist/{result-D3TSmZZ8.js → result-9TJTpuYP.js} +30 -11
  49. package/dist/{runner-DS5OKhEp.js → runner-BmKLSyJm.js} +12 -11
  50. package/dist/{sandbox-egress-signals-CnDjY5rx.js → sandbox-egress-signals-CjLaogMo.js} +1 -1
  51. package/dist/{schema-0050HFnB.js → schema-DNLJ_MzW.js} +36 -20
  52. package/dist/{schema-ZngqcOWM.d.ts → schema-WayPSHFu.d.ts} +149 -12
  53. package/dist/{service-account-CKV2WTY7.js → service-account-D6e9cVmH.js} +4 -3
  54. package/dist/{service-account-DGjnDw9y.js → service-account-DlhYl-Mu.js} +3 -3
  55. package/dist/{session-stop-Dam1EI7B.js → session-stop-MZRgYqYH.js} +24 -16
  56. package/dist/{skills-CfAnfImD.js → skills-BggTR_ue.js} +2 -2
  57. package/dist/{spawn-cmq9p4Ly.js → spawn-DmtlcAT_.js} +2 -2
  58. package/dist/{store-zPEoJPBB.js → store-BeWGgaMA.js} +3 -3
  59. package/dist/{store-C5PN02QO.js → store-Byarin7b.js} +4 -4
  60. package/dist/{task-queue-_mf28dSu.js → task-queue-Dt1_ZoI_.js} +3 -3
  61. package/dist/task-runner-DyKqAPpm.js +269 -0
  62. package/dist/{thread-state-BbbPh0Sn.js → thread-state-BHBLMvgb.js} +5 -5
  63. package/dist/{turn-failure-response-BKKmnMB5.js → turn-failure-response-DWXy_0oJ.js} +9 -9
  64. package/dist/{turn-lifecycle-oP0kVeGz.js → turn-lifecycle-AiXkVqCB.js} +1 -1
  65. package/dist/{tasks-SB9z-VTU.js → turn-session-routing-B9KLBhaT.js} +939 -120
  66. package/dist/{validation--JsAGLwc.js → validation-BW60Vtx_.js} +1 -1
  67. package/dist/{version-jHwJp4hC.js → version-CivPYmkH.js} +1 -1
  68. package/dist/version.js +1 -1
  69. package/dist/{viewer-CpXTGlep.js → viewer-BTgAfdUg.js} +216 -27
  70. package/dist/{work-3N-GHY9m.js → work-Bjm52fHo.js} +17 -36
  71. package/dist/{worker-CCdbcItd.js → worker-CMbgtHLu.js} +15 -7
  72. package/migrations/0069_system_identity.sql +25 -0
  73. package/migrations/0070_review_item_foreign_keys.sql +5 -0
  74. package/migrations/AGENTS.md +17 -0
  75. package/migrations/meta/0069_snapshot.json +3979 -0
  76. package/migrations/meta/0070_snapshot.json +3997 -0
  77. package/migrations/meta/_journal.json +15 -1
  78. package/package.json +5 -4
  79. package/dist/db-BU4LQD8s.d.ts +0 -6
  80. package/dist/history-BgI33Kie.d.ts +0 -78
  81. package/dist/reporting-window-DVCD_10C.js +0 -227
  82. package/dist/task-runner-DMI2prDO.js +0 -1073
  83. package/migrations/README.md +0 -30
package/dist/api.js CHANGED
@@ -1,29 +1,28 @@
1
- import { D as AutomationConflictError, E as sameDefinitionValue, N as automationEventCatalog, O as automationRevision, S as automationDefinition, T as readAutomationVersion, a as saveScheduledAutomation, k as requireAutomationRevision, ur as isExperimentalFeatureEnabled, v as saveEventAutomation, y as setEventAutomationStatus } from "./tasks-SB9z-VTU.js";
2
- import { p as escapeXml } from "./client-C1yDYjoS.js";
3
- import { m as logInfo, p as logException } from "./logging-DLSpkSSr.js";
4
- import { I as agentTurnUsageSchema, L as hasAgentTurnUsage, R as resolveRootConversationId, c as updateViewerDisplayName, h as getSqlExecutor, m as getDb, o as resolveViewerUser, p as getConversationStore, t as findUserByEmail } from "./viewer-CpXTGlep.js";
1
+ import { F as conversationRangeColumns, N as conversationActiveDaysColumn, P as conversationAggregateColumns, Wr as isExperimentalFeatureEnabled, ct as AutomationConflictError, ft as automationEventCatalog, j as readAutomationTitlesByConversationId } from "./turn-session-routing-B9KLBhaT.js";
2
+ import { p as escapeXml } from "./client-B2MjENki.js";
3
+ import { m as logInfo, p as logException } from "./logging-C6EdT6PP.js";
4
+ import { C as getSqlExecutor, E as loadConversationSlackTenantIds, J as resolveRootConversationId, K as agentTurnUsageSchema, S as getDb, c as readViewerAvatarUrl, d as updateViewerDisplayName, l as resolveViewerUser, m as readAvatarImage, q as hasAgentTurnUsage, t as findUserByEmail, x as getConversationStore } from "./viewer-BTgAfdUg.js";
5
5
  import { c as juniorIdentities, d as juniorDestinations, l as juniorUsers, s as juniorConversations } from "./agent-invocations-C1RNOCs8.js";
6
- import { C as juniorCodeRepositories, S as juniorCodeChanges, b as juniorApiTokens, m as juniorConversationParticipants, v as juniorConversationMetrics, y as juniorConversationEvents } from "./executor-4vhvsMZJ.js";
7
- import { n as pluginCatalogRuntime } from "./catalog-runtime-BD9GSpc6.js";
8
- import { $ as webUserInputAnswerNote, B as listOwnedWatches, F as editEventAutomation, I as AutomationEditError, Lt as readUserCustomization, M as editScheduledAutomation, Mt as conversationSubtreeColumns, Rt as saveUserCustomization, St as readLiveAttachment, bt as decodeInputImages, ct as searchReviewItems, ft as acceptsWebMessages, ht as createAndEnqueueConversation, it as countReviewItems, jt as conversationSubtree, kt as listChildAgents, m as readStats, ot as listWaitingConversationIds, pt as appendAndEnqueueWebMessage, st as reviewItemReaderForUser, vt as webActorFromEmail, w as persistSlackUserInputReply, z as resolveTaskOutcomes } from "./agent-runner-CAYfFmU7.js";
9
- import { C as listWorkspaces, E as WorkspaceValidationError, Et as SANDBOX_RUNTIME, In as createPluginLogger, Jn as readConversationEventPage, Ln as readConversationAccessFromSql, M as hash, Ot as workspaceRepoCheckoutPath, T as updateWorkspace, Yn as buildSentryConversationUrl, b as deleteWorkspace, cr as createPluginCache, fn as runWithWorkspaceTeamId, j as create, n as createUserTokenStore, p as getPlugins, qn as readLatestConversationBrief, rr as listConversationAnnotations, sr as lookupSlackUser, w as listWorkspacesByRepository, x as getWorkspace, y as createWorkspace } from "./credentialed-lukuD-cc.js";
10
- import { i as getStateAdapter } from "./adapter-04AcD2SO.js";
11
- import { t as getFirstRunAtMs } from "./cadence-R7Em4RjE.js";
12
- import { A as createConversationMessageBodySchema, G as INPUT_IMAGE_TYPES, M as forkConversationResponseSchema, N as steerConversationPendingMessagesBodySchema, P as steerConversationPendingMessagesResponseSchema, W as readMessageAttachments, _ as conversationParamsSchema, a as cancelConversationPendingMessagesBodySchema, c as conversationAttachmentParamsSchema, d as conversationDetailReportSchema, g as conversationFeedSchema, h as conversationFeedQuerySchema, i as archiveConversationResponseSchema, j as forkConversationBodySchema, k as createConversationBodySchema, m as conversationEventsQuerySchema, o as cancelConversationPendingMessagesResponseSchema, p as conversationEventPageSchema, r as archiveConversationBodySchema, t as acceptedConversationMessageSchema, u as conversationDetailQuerySchema, x as conversationPendingMessagesReportSchema } from "./conversation-DSo310Ps.js";
13
- import { h as getChildAgentLabel } from "./store-C5PN02QO.js";
14
- import { d as getEventCatalog } from "./session-stop-Dam1EI7B.js";
15
- import { l as userCustomizationSchema, t as webMessageId } from "./web-message-id-DlHNANtd.js";
16
- import { s as getSandboxResources, t as getCachedSnapshot } from "./resolve-Cpa4Bu1O.js";
17
- import { a as getVercelConversationWorkQueue } from "./job-queue-In9QKz-I.js";
18
- import { E as steerWebPendingMessages, a as cancelHumanFacingPendingMessages, g as getConversationWorkState, h as getConversation } from "./store-zPEoJPBB.js";
19
- import { n as finishServiceAccountSignIn, o as serviceAccountPlugins, r as getServiceAccountStatus, s as startServiceAccountSignIn, t as disconnectServiceAccount } from "./service-account-CKV2WTY7.js";
20
- import { F as weekdaySchema, M as ScheduleIntentError, N as compileScheduleIntent, _ as automationSummarySchema, b as automationVersionListSchema, c as automationLifecycleSchema, d as automationParamsSchema, f as automationRunListSchema, g as automationSchedulePreviewSchema, h as automationScheduleIntentSchema, i as automationExecutionListSchema, l as automationListQuerySchema, n as automationEditSchema, r as automationEventCatalogSchema, t as automationEditErrorSchema, u as automationListSchema, v as automationUpdateSchema, x as automationVersionParamsSchema, y as automationVersionActivateSchema } from "./automation-CmeFBSEh.js";
21
- import { S as skillReportsSchema, a as fillUtcSixHours, b as runtimeInfoReportSchema, c as trailingUtcDayWindow, d as utcDayKey, f as utcHourKey, i as fillUtcHours, l as trailingUtcHourWindow, m as pluginOperationalReportFeedSchema, n as HOUR_MS$1, o as startOfUtcHour, p as healthReportSchema, r as fillUtcDays, s as sumUtcHoursIntoSixHours, t as DAY_MS$1, u as trailingUtcSixHourWindow, y as pluginsSchema } from "./reporting-window-DVCD_10C.js";
22
- import { C as readConversationSourceTask, D as readViewerAutomationVersions, E as readViewerAutomationSummary, H as stopConversationTurn, J as canActOnReviewItem, K as ReviewItemActionError, L as clearSlackPendingReactions, M as isAllowedSignInEmail, O as readViewerAutomations, Q as getAttachmentStorage, S as deleteViewerTask, T as readViewerAutomationRuns, X as readReviewItemForUser, Y as isOnlyAssignee, a as resolveMentions, c as readConversationAuxiliaryCostsFromSql, d as notCopiedByFork, f as childAgentTotalsReport, g as resolveSlackTeamDomains, h as conversationSummaryFromStoredConversation, i as attachConversationMentions, k as resolveViewerTaskCandidate, l as ConversationForkError, m as conversationEventHistory, n as readConversationRecordFromSql, nt as readHealthReport, o as readFirstHumanMessageTexts, p as readConversationTreeMetricsFromSql, q as actOnReviewItem, r as readConversationParticipants, s as listConversationSidebarAnnotations, t as readConversationFeed, u as forkConversation, w as readViewerAutomationExecutions, x as ViewerTaskNotFoundError, y as getProductionSlackAdapter } from "./list-BkgnXEEB.js";
23
- import { F as conversationAggregateColumns, I as conversationRangeColumns, M as readAutomationTitlesByConversationId, P as conversationActiveDaysColumn } from "./task-runner-DMI2prDO.js";
24
- import { d as legacyWebMailboxMetadataSchema } from "./result-D3TSmZZ8.js";
25
- import { a as startConnection, l as getWebAuthorization, n as isConnectableProvider, r as listConnections, t as disconnectConnection, u as htmlCallbackResponse } from "./connections-D46f8vvi.js";
26
- import { A as personParamsSchema, B as connectionListSchema, C as createdPersonalTokenSchema, D as revokePersonalTokenResponseSchema, E as personalTokenParamsSchema, F as locationParamsSchema, I as activityDays$1, J as codeOverviewReportSchema, L as activityHours$1, N as locationDetailReportSchema, O as actorDirectoryReportSchema, P as locationDirectoryReportSchema, R as activitySixHours$1, S as createPersonalTokenBodySchema, U as disconnectConnectionResponseSchema, V as connectionParamsSchema, W as startConnectionResponseSchema, X as codeRepositoryParamsSchema, Y as codePersonReportSchema, Z as codeRepositoryReportSchema, _ as disconnectServiceAccountResponseSchema, a as workspaceBodySchema, at as apiErrorSchema, d as reviewItemCountSchema, et as conversationWatchesReportSchema, f as reviewItemListQuerySchema, g as reviewItemWaitingConversationsSchema, h as reviewItemSchema, i as deleteWorkspaceResponseSchema, it as conversationStatsReportSchema, j as personalSpendReportSchema, k as actorProfileReportSchema, l as workspaceSchema, m as reviewItemParamsSchema, n as statsReportSchema, nt as conversationChildAgentsReportSchema, o as workspaceListSchema, p as reviewItemListSchema, rt as stopConversationTurnResponseSchema, s as workspaceParamsSchema, u as reviewItemActionSchema, v as serviceAccountListSchema, w as personalTokenListSchema, x as startServiceAccountSignInResponseSchema, y as serviceAccountParamsSchema } from "./schema-0050HFnB.js";
6
+ import { C as juniorCodeRepositories, S as juniorCodeChanges, b as juniorApiTokens, m as juniorConversationParticipants, v as juniorConversationMetrics, y as juniorConversationEvents } from "./executor-BB6eJkD4.js";
7
+ import { t as INPUT_IMAGE_TYPES } from "./media-U6Tuz6Mi.js";
8
+ import { n as pluginCatalogRuntime } from "./catalog-runtime-Bdym_wKy.js";
9
+ import { $ as listOwnedWatches, B as changeViewerAutomationLifecycle, Dt as readUserCustomization, G as readConversationSourceTask, H as readViewerAutomationEdit, J as readViewerAutomationSummary, K as readViewerAutomationExecutions, Ot as saveUserCustomization, St as conversationSubtreeColumns, U as updateViewerAutomation, V as deleteViewerTask, W as ViewerTaskNotFoundError, X as readViewerAutomations, Y as readViewerAutomationVersions, Z as AutomationEditError, at as createAndEnqueueConversation, ct as webActorFromEmail, ft as readLiveAttachment, m as readStats, nt as acceptsWebMessages, q as readViewerAutomationRuns, rt as appendAndEnqueueWebMessage, ut as decodeInputImages, x as createSlackReviewItemShow, xt as conversationSubtree, yt as listChildAgents, z as activateViewerAutomationVersion } from "./agent-runner-MSQSMFkq.js";
10
+ import { $t as workspaceRepoCheckoutPath, Ar as lookupSlackUser, D as listWaitingConversationIds, Er as listConversationAnnotations, F as isOnlyAssignee, G as deleteWorkspace, J as listWorkspaces, K as getWorkspace, M as canActOnReviewItem, O as searchReviewItems, W as createWorkspace, X as updateWorkspace, Y as listWorkspacesByRepository, Z as WorkspaceValidationError, Zt as SANDBOX_RUNTIME, _r as readConversationEventPage, ar as createPluginLogger, gr as readLatestConversationBrief, jr as createPluginCache, n as createUserTokenStore, nt as create, or as readConversationAccessFromSql, p as getPlugins, rt as hash, vr as buildSentryConversationUrl, x as countReviewItemsNeedingUser, z as reviewItemReaderForUser } from "./credentialed-BeBaJMZ_.js";
11
+ import { r as getStateAdapter } from "./adapter-BQNTKVTF.js";
12
+ import { A as createConversationMessageBodySchema, M as forkConversationResponseSchema, N as steerConversationPendingMessagesBodySchema, P as steerConversationPendingMessagesResponseSchema, W as readMessageAttachments, _ as conversationParamsSchema, a as cancelConversationPendingMessagesBodySchema, c as conversationAttachmentParamsSchema, d as conversationDetailReportSchema, g as conversationFeedSchema, h as conversationFeedQuerySchema, i as archiveConversationResponseSchema, j as forkConversationBodySchema, k as createConversationBodySchema, m as conversationEventsQuerySchema, o as cancelConversationPendingMessagesResponseSchema, p as conversationEventPageSchema, r as archiveConversationBodySchema, t as acceptedConversationMessageSchema, u as conversationDetailQuerySchema, x as conversationPendingMessagesReportSchema } from "./conversation-AhOVzN_k.js";
13
+ import { h as getChildAgentLabel } from "./store-Byarin7b.js";
14
+ import { d as getEventCatalog } from "./session-stop-MZRgYqYH.js";
15
+ import { S as userCustomizationSchema, a as fillUtcSixHours, b as webMessageId, c as trailingUtcDayWindow, d as utcDayKey, f as utcHourKey, i as fillUtcHours, l as trailingUtcHourWindow, n as HOUR_MS$1, o as startOfUtcHour, r as fillUtcDays, s as sumUtcHoursIntoSixHours, t as DAY_MS$1, u as trailingUtcSixHourWindow } from "./reporting-window-DRCi1Ls_.js";
16
+ import { s as getSandboxResources, t as getCachedSnapshot } from "./resolve-BkAA1wH7.js";
17
+ import { a as getVercelConversationWorkQueue } from "./job-queue-DiaXoSDg.js";
18
+ import { E as steerWebPendingMessages, a as cancelHumanFacingPendingMessages, g as getConversationWorkState, h as getConversation } from "./store-BeWGgaMA.js";
19
+ import { n as finishServiceAccountSignIn, o as serviceAccountPlugins, r as getServiceAccountStatus, s as startServiceAccountSignIn, t as disconnectServiceAccount } from "./service-account-D6e9cVmH.js";
20
+ import { N as ScheduleIntentError, P as compileScheduleIntent, _ as automationSummarySchema, b as automationVersionListSchema, c as automationLifecycleSchema, d as automationParamsSchema, f as automationRunListSchema, g as automationSchedulePreviewSchema, h as automationScheduleIntentSchema, i as automationExecutionListSchema, l as automationListQuerySchema, n as automationEditSchema, r as automationEventCatalogSchema, t as automationEditErrorSchema, u as automationListSchema, v as automationUpdateSchema, x as automationVersionParamsSchema, y as automationVersionActivateSchema } from "./automation-Dwh_xcqM.js";
21
+ import { c as runtimeInfoReportSchema, n as pluginOperationalReportFeedSchema, s as pluginsSchema, t as healthReportSchema, u as skillReportsSchema } from "./reporting-schema-CZREhYc-.js";
22
+ import { B as actOnReviewItem, C as isAllowedSignInEmail, H as readReviewItemForUser, J as readHealthReport, N as stopConversationTurn, O as clearSlackPendingReactions, R as parseContent, V as closeReviewItemsAnsweredByReply, W as getAttachmentStorage, a as resolveMentions, c as readConversationAuxiliaryCostsFromSql, d as notCopiedByFork, f as childAgentTotalsReport, g as resolveSlackTeamDomains, h as conversationSummaryFromStoredConversation, i as attachConversationMentions, l as ConversationForkError, m as conversationEventHistory, n as readConversationRecordFromSql, o as readFirstHumanMessageTexts, p as readConversationTreeMetricsFromSql, r as readConversationParticipants, s as listConversationSidebarAnnotations, t as readConversationFeed, u as forkConversation, y as getProductionSlackAdapter, z as ReviewItemActionError } from "./list-BTDRxkOg.js";
23
+ import { d as legacyWebMailboxMetadataSchema } from "./result-9TJTpuYP.js";
24
+ import { a as startConnection, l as getWebAuthorization, n as isConnectableProvider, r as listConnections, t as disconnectConnection, u as htmlCallbackResponse } from "./connections-0BBhiD-p.js";
25
+ import { A as avatarParamsSchema, C as createdPersonalTokenSchema, D as revokePersonalTokenResponseSchema, E as personalTokenParamsSchema, F as locationDirectoryReportSchema, G as startConnectionResponseSchema, H as connectionParamsSchema, I as locationParamsSchema, L as activityDays$1, M as personalSpendReportSchema, O as actorDirectoryReportSchema, P as locationDetailReportSchema, Q as codeRepositoryReportSchema, R as activityHours$1, S as createPersonalTokenBodySchema, V as connectionListSchema, W as disconnectConnectionResponseSchema, X as codePersonReportSchema, Y as codeOverviewReportSchema, Z as codeRepositoryParamsSchema, _ as disconnectServiceAccountResponseSchema, a as workspaceBodySchema, at as conversationStatsReportSchema, d as reviewItemCountSchema, f as reviewItemListQuerySchema, g as reviewItemWaitingConversationsSchema, h as reviewItemSchema, i as deleteWorkspaceResponseSchema, it as stopConversationTurnResponseSchema, j as personParamsSchema, k as actorProfileReportSchema, l as workspaceSchema, m as reviewItemParamsSchema, n as statsReportSchema, o as workspaceListSchema, ot as apiErrorSchema, p as reviewItemListSchema, rt as conversationChildAgentsReportSchema, s as workspaceParamsSchema, tt as conversationWatchesReportSchema, u as reviewItemActionSchema, v as serviceAccountListSchema, w as personalTokenListSchema, x as startServiceAccountSignInResponseSchema, y as serviceAccountParamsSchema, z as activitySixHours$1 } from "./schema-DNLJ_MzW.js";
27
26
  import { Hono } from "hono";
28
27
  import path from "node:path";
29
28
  import { z } from "zod";
@@ -272,31 +271,34 @@ async function appendConversationMessageForViewer(viewer, conversationId, body,
272
271
  attachmentStorage: services.attachmentStorage,
273
272
  queue: services.queue
274
273
  });
275
- const destination = conversation.destination;
274
+ const closeAnswered = () => closeReviewItemsAnsweredByReply({
275
+ conversationId,
276
+ delivery: {
277
+ queue: services.queue,
278
+ show: createSlackReviewItemShow(getProductionSlackAdapter)
279
+ },
280
+ resolveUser: async () => viewer,
281
+ text: body.message
282
+ });
276
283
  try {
277
- if (destination?.platform !== "slack") return await append();
278
- return await runWithWorkspaceTeamId(destination.teamId, async () => {
284
+ let accepted;
285
+ try {
286
+ accepted = await append();
287
+ } catch (error) {
279
288
  const state = getStateAdapter();
280
289
  await state.connect();
281
- return persistSlackUserInputReply({
282
- channelId: destination.channelId,
283
- claimedBy: viewer.email,
284
- isSaved: async () => {
285
- const [messageId, work] = await Promise.all([webMessageId({
286
- conversationId,
287
- idempotencyKey: body.idempotencyKey
288
- }), getConversationWorkState({
289
- conversationId,
290
- state
291
- })]);
292
- return work?.execution.inboundMessageIds.includes(messageId) === true;
293
- },
294
- note: () => webUserInputAnswerNote(viewer.displayName ?? viewer.email),
295
- persist: append,
296
- state,
297
- threadTs: conversation.location?.threadTs ?? (conversation.sessionSource?.kind === "slack" ? conversation.sessionSource.threadTs : void 0)
298
- });
299
- });
290
+ const [messageId, work] = await Promise.all([webMessageId({
291
+ conversationId,
292
+ idempotencyKey: body.idempotencyKey
293
+ }), getConversationWorkState({
294
+ conversationId,
295
+ state
296
+ })]);
297
+ if (work?.execution.inboundMessageIds.includes(messageId)) await closeAnswered();
298
+ throw error;
299
+ }
300
+ await closeAnswered();
301
+ return accepted;
300
302
  } catch (error) {
301
303
  throwApiError(500, "Unable to append message.", error);
302
304
  }
@@ -749,12 +751,29 @@ const slackMailboxAuthorSchema = z.object({
749
751
  }).passthrough();
750
752
  const slackMailboxMessageSchema = z.object({
751
753
  author: slackMailboxAuthorSchema,
752
- id: z.string().min(1)
754
+ id: z.string().min(1),
755
+ raw: z.unknown().optional()
753
756
  }).passthrough();
754
757
  const slackMailboxMetadataSchema = z.object({
755
758
  message: slackMailboxMessageSchema,
756
759
  platform: z.literal("slack")
757
760
  }).passthrough();
761
+ /**
762
+ * Project Slack text the way the Turn stores it in history. The SDK text
763
+ * turns `<@U123>` into a bare `@U123` or `@name`, which the dashboard
764
+ * cannot render as a mention.
765
+ */
766
+ function slackDisplayText(message, sdkText) {
767
+ return parseContent({
768
+ attachments: [],
769
+ formatted: {
770
+ type: "root",
771
+ children: []
772
+ },
773
+ raw: message.raw,
774
+ text: sdkText
775
+ }).text;
776
+ }
758
777
  function isoFromMs(value) {
759
778
  return new Date(value).toISOString();
760
779
  }
@@ -805,7 +824,7 @@ async function projectPendingMessage(message, canExposePayload) {
805
824
  const metadata = slackMailboxMetadataSchema.safeParse(message.input.metadata);
806
825
  if (!metadata.success) return void 0;
807
826
  if (metadata.data.message.author.isMe === true) return void 0;
808
- const text = message.input.text.trim();
827
+ const text = slackDisplayText(metadata.data.message, message.input.text).trim();
809
828
  if (!text) return void 0;
810
829
  if (!canExposePayload) return {
811
830
  createdAt: isoFromMs(message.createdAtMs),
@@ -831,6 +850,19 @@ async function projectPendingMessage(message, canExposePayload) {
831
850
  };
832
851
  }
833
852
  }
853
+ async function attachPendingMentions(conversationId, messages) {
854
+ if (!messages.some((message) => message.text?.includes("<@"))) return messages;
855
+ const executor = getSqlExecutor();
856
+ const tenantId = (await loadConversationSlackTenantIds(executor, [conversationId])).get(conversationId);
857
+ const mentions = await resolveMentions(executor, messages.map((message) => ({
858
+ tenantId,
859
+ texts: [message.text]
860
+ })));
861
+ return messages.map((message, index) => mentions[index].length > 0 ? {
862
+ ...message,
863
+ mentions: mentions[index]
864
+ } : message);
865
+ }
834
866
  /**
835
867
  * Read accepted mailbox messages that have not reached durable history yet.
836
868
  *
@@ -848,7 +880,7 @@ async function readConversationPendingMessages(conversationId, options = {}) {
848
880
  conversationId
849
881
  }) : void 0;
850
882
  const work = await getConversation({ conversationId });
851
- const messages = (await Promise.all((work?.execution.pendingMessages ?? []).map((message) => projectPendingMessage(message, canExposePayload)))).filter((message) => Boolean(message));
883
+ const messages = await attachPendingMentions(conversationId, (await Promise.all((work?.execution.pendingMessages ?? []).map((message) => projectPendingMessage(message, canExposePayload)))).filter((message) => Boolean(message)));
852
884
  return conversationPendingMessagesReportSchema.parse({
853
885
  ...authorization ? { authorization: {
854
886
  authorizationUrl: authorization.authorizationUrl,
@@ -2694,7 +2726,7 @@ async function readPeoplePluginReports(args) {
2694
2726
  reports: [],
2695
2727
  source: "plugins"
2696
2728
  });
2697
- const { getPluginProfileReports } = await import("./credentialed-lukuD-cc.js").then((n) => n.a);
2729
+ const { getPluginProfileReports } = await import("./credentialed-BeBaJMZ_.js").then((n) => n.a);
2698
2730
  return pluginOperationalReportFeedSchema.parse({
2699
2731
  generatedAt: new Date(nowMs).toISOString(),
2700
2732
  reports: await getPluginProfileReports({
@@ -2903,6 +2935,23 @@ function spendWindow(nowMs) {
2903
2935
  thirtyDayStart
2904
2936
  };
2905
2937
  }
2938
+ /**
2939
+ * Read a cheap change marker for one viewer's spend window.
2940
+ *
2941
+ * Writes that record Conversation metrics also move `updated_at` forward, so
2942
+ * the marker changes when spend can change. The spend cache TTL bounds changes
2943
+ * that the marker misses, such as a day that leaves the window.
2944
+ */
2945
+ async function readPersonalSpendVersion(email, nowMs = Date.now()) {
2946
+ const normalizedEmail = normalizeEmail$1(email);
2947
+ if (!normalizedEmail) return "";
2948
+ const { end, thirtyDayStart } = spendWindow(nowMs);
2949
+ const [row] = await getDb().select({
2950
+ conversations: sql`count(*)::int`,
2951
+ updatedAt: sql`max(${juniorConversations.updatedAt})::text`
2952
+ }).from(juniorConversations).innerJoin(juniorIdentities, eq(juniorIdentities.id, juniorConversations.actorIdentityId)).innerJoin(juniorUsers, eq(juniorUsers.id, juniorIdentities.userId)).where(and(verifiedActorWhere(normalizedEmail), gte(juniorConversations.lastActivityAt, thirtyDayStart), lte(juniorConversations.lastActivityAt, end)));
2953
+ return `${row?.conversations ?? 0}:${row?.updatedAt ?? ""}`;
2954
+ }
2906
2955
  /** Read one viewer's rolling model spend with one bounded aggregate query. */
2907
2956
  async function readPersonalSpendFromSql(email, nowMs = Date.now()) {
2908
2957
  const normalizedEmail = normalizeEmail$1(email);
@@ -2935,19 +2984,27 @@ async function readPersonalSpendFromSql(email, nowMs = Date.now()) {
2935
2984
  }
2936
2985
  // src/api/people/spend.ts
2937
2986
  const PERSONAL_SPEND_CACHE_TTL_MS = 3e5;
2938
- /** Create an app-scoped personal-spend reader with a five-minute cache. */
2987
+ /**
2988
+ * Create an app-scoped personal-spend reader.
2989
+ *
2990
+ * A cached report stays valid for five minutes, or until the viewer's spend
2991
+ * version changes. The dashboard can poll often and still see a finished Turn
2992
+ * without a full aggregate query on every poll.
2993
+ */
2939
2994
  function createPersonalSpendReader() {
2940
2995
  const cache = /* @__PURE__ */ new Map();
2941
2996
  return async function readPersonalSpend(email) {
2942
2997
  const normalizedEmail = email.trim().toLowerCase();
2943
2998
  const nowMs = Date.now();
2999
+ const version = await readPersonalSpendVersion(normalizedEmail, nowMs);
2944
3000
  const cached = cache.get(normalizedEmail);
2945
- if (cached && cached.expiresAtMs > nowMs) return cached.report;
3001
+ if (cached && cached.expiresAtMs > nowMs && cached.version === version) return cached.report;
2946
3002
  cache.delete(normalizedEmail);
2947
3003
  const report = readPersonalSpendFromSql(normalizedEmail, nowMs);
2948
3004
  const entry = {
2949
3005
  expiresAtMs: nowMs + PERSONAL_SPEND_CACHE_TTL_MS,
2950
- report
3006
+ report,
3007
+ version
2951
3008
  };
2952
3009
  cache.set(normalizedEmail, entry);
2953
3010
  try {
@@ -2963,6 +3020,17 @@ function createPersonalSpendReader() {
2963
3020
  function createPeopleRoutes() {
2964
3021
  const app = new Hono();
2965
3022
  const readPersonalSpend = createPersonalSpendReader();
3023
+ app.get("/avatars/:identityId", requireViewer, validateRequest("param", avatarParamsSchema, "Invalid route parameters."), async (context) => {
3024
+ const { identityId } = context.req.valid("param");
3025
+ const image = await readAvatarImage(getDb(), getStateAdapter(), identityId);
3026
+ if (!image) throwApiError(404, "Avatar not found.");
3027
+ return new Response(Buffer.from(image.data, "base64"), { headers: {
3028
+ "cache-control": "private, max-age=86400",
3029
+ "content-security-policy": "default-src 'none'; sandbox",
3030
+ "content-type": image.contentType,
3031
+ "x-content-type-options": "nosniff"
3032
+ } });
3033
+ });
2966
3034
  app.get("/me/spend", requireViewer, async (context) => {
2967
3035
  const viewer = context.get("viewer");
2968
3036
  return jsonResponse(personalSpendReportSchema, await readPersonalSpend(viewer.email));
@@ -3206,233 +3274,6 @@ function createUserPageRoutes() {
3206
3274
  });
3207
3275
  return app;
3208
3276
  }
3209
- // src/chat/automations/edit.ts
3210
- /**
3211
- * Web edits. Owners and public Destination readers can edit. Creator-only
3212
- * rules still apply, and lifecycle actions stay creator-only.
3213
- */
3214
- /** Owners and public Destination readers can edit. Others get not found. */
3215
- async function requireEditableAutomation(user, id) {
3216
- const candidate = await resolveViewerTaskCandidate(user, id);
3217
- if (!candidate) throw new ViewerTaskNotFoundError();
3218
- return candidate;
3219
- }
3220
- /** Lifecycle actions are creator-only. Others get not found. */
3221
- async function requireOwnedAutomation(user, id) {
3222
- const candidate = await requireEditableAutomation(user, id);
3223
- if (!candidate.ownedByViewer) throw new ViewerTaskNotFoundError();
3224
- return candidate;
3225
- }
3226
- /** Record the viewer's Slack identity in the Automation workspace as the editor. */
3227
- function viewerEditor(user, automation) {
3228
- if (automation.ownedByViewer) return automation.task.createdBy;
3229
- const identity = user.identities.find((candidate) => candidate.provider === "slack" && candidate.providerTenantId === automation.task.destination.teamId);
3230
- if (!identity) return void 0;
3231
- const editor = { slackUserId: identity.providerSubjectId };
3232
- if (identity.displayName) editor.fullName = identity.displayName;
3233
- if (identity.handle) editor.userName = identity.handle;
3234
- return editor;
3235
- }
3236
- function editView(automation, ownedByViewer) {
3237
- const { task } = automation;
3238
- const common = {
3239
- ownedByViewer,
3240
- id: task.id,
3241
- revision: automationRevision(task),
3242
- title: task.title ?? null,
3243
- instruction: task.task.text,
3244
- credentialMode: task.credentialMode,
3245
- outcomes: task.outcomes,
3246
- destination: task.destination,
3247
- createdBy: task.createdBy
3248
- };
3249
- if (automation.kind === "scheduled") {
3250
- const status = automation.task.status;
3251
- if (status === "deleted") throw new ViewerTaskNotFoundError();
3252
- return {
3253
- ...common,
3254
- kind: "scheduled",
3255
- status,
3256
- schedule: automation.task.schedule,
3257
- nextRunAtMs: automation.task.nextRunAtMs
3258
- };
3259
- }
3260
- return {
3261
- ...common,
3262
- kind: "event",
3263
- status: automation.task.status === "deleted" ? "active" : automation.task.status,
3264
- trigger: automation.task.trigger
3265
- };
3266
- }
3267
- /** Load exact editable values by ID, independent of list filters. */
3268
- async function readViewerAutomationEdit(user, id) {
3269
- const automation = await requireEditableAutomation(user, id);
3270
- return editView(automation, automation.ownedByViewer);
3271
- }
3272
- /** Save a partial edit against the read revision, without dispatching work. */
3273
- async function updateViewerAutomation(user, id, input) {
3274
- const current = await requireEditableAutomation(user, id);
3275
- if (input.kind !== current.kind) throw new AutomationEditError("The trigger type cannot change.", "kind");
3276
- requireAutomationRevision(current.task, input.revision);
3277
- return saveViewerEdit(user, current, input);
3278
- }
3279
- /** `restored` carries version values that edit input cannot express, such as a cleared title. */
3280
- async function saveViewerEdit(user, current, input, restored) {
3281
- const isCreator = current.ownedByViewer;
3282
- const editedBy = viewerEditor(user, current);
3283
- if (input.kind === "scheduled" && current.kind === "scheduled") {
3284
- const next = await editScheduledAutomation(current.task, input, isCreator, Date.now());
3285
- return editView({
3286
- kind: "scheduled",
3287
- task: await saveScheduledAutomation(getDb(), restored ? {
3288
- ...next,
3289
- ...restored
3290
- } : next, input.revision, editedBy)
3291
- }, isCreator);
3292
- }
3293
- if (input.kind === "event" && current.kind === "event") {
3294
- const next = await editEventAutomation(current.task, input, isCreator, getEventCatalog());
3295
- const task = await saveEventAutomation(getDb(), restored ? {
3296
- ...next,
3297
- title: restored.title
3298
- } : next, input.revision, editedBy);
3299
- if (!task) throw new ViewerTaskNotFoundError();
3300
- return editView({
3301
- kind: "event",
3302
- task
3303
- }, isCreator);
3304
- }
3305
- throw new ViewerTaskNotFoundError();
3306
- }
3307
- function scheduleIntent(schedule) {
3308
- const recurrence = schedule.recurrence;
3309
- if (schedule.kind !== "recurring" || !recurrence) throw new AutomationEditError("A one-time Schedule cannot be restored. Set a new time in the editor.", "schedule");
3310
- return {
3311
- kind: "recurring",
3312
- frequency: recurrence.frequency,
3313
- interval: recurrence.interval,
3314
- time: `${String(recurrence.time.hour).padStart(2, "0")}:${String(recurrence.time.minute).padStart(2, "0")}`,
3315
- weekdays: recurrence.weekdays?.map((day) => weekdaySchema.options[day]),
3316
- dayOfMonth: recurrence.dayOfMonth,
3317
- month: recurrence.month,
3318
- startDate: recurrence.startDate,
3319
- timezone: schedule.timezone
3320
- };
3321
- }
3322
- /**
3323
- * Turn saved outcomes back into edit input. Messages to the Automation
3324
- * Destination or the creator DM are always allowed again. Other stored
3325
- * Destinations must still be on the Automation.
3326
- */
3327
- async function restorableOutcomes(current, outcomes) {
3328
- const { task } = current;
3329
- let creatorDm;
3330
- const restored = [];
3331
- for (const outcome of outcomes) {
3332
- if (sameDefinitionValue(outcome.destination, task.destination)) {
3333
- restored.push({
3334
- action: outcome.action,
3335
- destination: "current_conversation"
3336
- });
3337
- continue;
3338
- }
3339
- if (current.ownedByViewer && !task.outcomes.some((stored) => sameDefinitionValue(stored, outcome))) {
3340
- creatorDm ??= (await resolveTaskOutcomes([{
3341
- action: "send_message",
3342
- destination: "task_creator"
3343
- }], task.destination, task.createdBy.slackUserId))[0].destination;
3344
- if (sameDefinitionValue(outcome.destination, creatorDm)) {
3345
- restored.push({
3346
- action: outcome.action,
3347
- destination: "task_creator"
3348
- });
3349
- continue;
3350
- }
3351
- }
3352
- restored.push(outcome);
3353
- }
3354
- return restored;
3355
- }
3356
- /**
3357
- * Make a saved version active. This saves its definition as a new version
3358
- * through the same edit rules, so history is never rewritten.
3359
- */
3360
- async function activateViewerAutomationVersion(user, id, input) {
3361
- const current = await requireEditableAutomation(user, id);
3362
- requireAutomationRevision(current.task, input.revision);
3363
- const saved = await readAutomationVersion(getDb(), id, input.version);
3364
- if (!saved) throw new AutomationEditError("This version does not exist.", "version");
3365
- const { definition } = saved;
3366
- if (sameDefinitionValue(definition, automationDefinition(current.task))) return editView(current, current.ownedByViewer);
3367
- if (!sameDefinitionValue(definition.destination, current.task.destination)) throw new AutomationEditError("This version delivers to another Destination. Move the automation from Slack instead.", "destination");
3368
- const fields = {};
3369
- if (definition.instruction !== current.task.task.text) fields.instruction = definition.instruction;
3370
- if (definition.credentialMode !== current.task.credentialMode) fields.credentialMode = definition.credentialMode;
3371
- if (!sameDefinitionValue(definition.outcomes, current.task.outcomes)) fields.outcomes = await restorableOutcomes(current, definition.outcomes);
3372
- const title = definition.title ?? void 0;
3373
- if (saved.kind === "scheduled" && current.kind === "scheduled") {
3374
- const update = {
3375
- kind: "scheduled",
3376
- revision: input.revision,
3377
- ...fields
3378
- };
3379
- const restored = { title };
3380
- const { schedule } = saved.definition;
3381
- if (!sameDefinitionValue(schedule, current.task.schedule)) {
3382
- update.schedule = scheduleIntent(schedule);
3383
- restored.schedule = schedule;
3384
- }
3385
- return saveViewerEdit(user, current, update, restored);
3386
- }
3387
- if (saved.kind === "event" && current.kind === "event") {
3388
- const update = {
3389
- kind: "event",
3390
- revision: input.revision,
3391
- ...fields
3392
- };
3393
- if (!sameDefinitionValue(saved.definition.trigger, current.task.trigger)) update.trigger = saved.definition.trigger;
3394
- return saveViewerEdit(user, current, update, { title });
3395
- }
3396
- throw new ViewerTaskNotFoundError();
3397
- }
3398
- /** Pause or resume future triggers. Already-claimed work can finish. */
3399
- async function changeViewerAutomationLifecycle(user, id, input) {
3400
- const current = await requireOwnedAutomation(user, id);
3401
- requireAutomationRevision(current.task, input.revision);
3402
- const status = current.task.status;
3403
- if (status === "completed") throw new AutomationEditError("Completed Automations cannot be restarted.");
3404
- if (input.action === "pause" && status === "paused") return editView(current, true);
3405
- if (input.action === "resume" && status !== "paused" && status !== "blocked") throw new AutomationEditError("Only paused or blocked Automations can be resumed.");
3406
- if (current.kind === "event") return editView({
3407
- kind: "event",
3408
- task: await setEventAutomationStatus(getDb(), id, input.action === "pause" ? "paused" : "active", input.revision)
3409
- }, true);
3410
- const nowMs = Date.now();
3411
- const next = {
3412
- ...current.task,
3413
- updatedAtMs: nowMs,
3414
- runNowAtMs: void 0
3415
- };
3416
- if (input.action === "pause") {
3417
- next.status = "paused";
3418
- if (status === "blocked") next.statusReason ??= "A requirement blocked this Automation. Inspect its executions before resuming.";
3419
- } else {
3420
- next.status = status === "paused" && next.statusReason ? "blocked" : "active";
3421
- if (next.status === "active") {
3422
- next.nextRunAtMs = next.schedule.recurrence ? getFirstRunAtMs({
3423
- afterMs: nowMs,
3424
- recurrence: next.schedule.recurrence,
3425
- timezone: next.schedule.timezone
3426
- }) : next.nextRunAtMs;
3427
- if (!next.nextRunAtMs || next.nextRunAtMs <= nowMs) throw new AutomationEditError("This Schedule has no future occurrence. Set a future Schedule before resuming.", "schedule");
3428
- next.statusReason = void 0;
3429
- }
3430
- }
3431
- return editView({
3432
- kind: "scheduled",
3433
- task: await saveScheduledAutomation(getDb(), next, input.revision)
3434
- }, true);
3435
- }
3436
3277
  // src/chat/automations/editor.ts
3437
3278
  /** Read-only editor support. Core owns schedules; plugins own Event choices. */
3438
3279
  /**
@@ -3634,7 +3475,39 @@ function createUserCustomizationRoutes() {
3634
3475
  return app;
3635
3476
  }
3636
3477
  // src/api/review-items/routes.ts
3637
- const LIST_LIMIT = 100;
3478
+ const ARCHIVED_LIMIT = 50;
3479
+ const cursorSchema = z.object({
3480
+ conversationId: z.string().min(1).optional(),
3481
+ id: z.string().min(1),
3482
+ query: z.string().min(1).optional(),
3483
+ updatedAtMs: z.number().int(),
3484
+ version: z.literal(1)
3485
+ }).strict();
3486
+ /**
3487
+ * Encode the last open item of a page as the cursor of the next page. The
3488
+ * cursor names its list, so it cannot page through a different list.
3489
+ */
3490
+ function encodeCursor(item, filters) {
3491
+ return Buffer.from(JSON.stringify({
3492
+ ...filters,
3493
+ id: item.id,
3494
+ updatedAtMs: item.updatedAt.getTime(),
3495
+ version: 1
3496
+ }), "utf8").toString("base64url");
3497
+ }
3498
+ /** Decode a cursor of the same list, or return undefined. */
3499
+ function decodeCursor(cursor, filters) {
3500
+ try {
3501
+ const parsed = cursorSchema.parse(JSON.parse(Buffer.from(cursor, "base64url").toString("utf8")));
3502
+ if (parsed.conversationId !== filters.conversationId || parsed.query !== filters.query) return;
3503
+ return {
3504
+ id: parsed.id,
3505
+ updatedAt: new Date(parsed.updatedAtMs)
3506
+ };
3507
+ } catch {
3508
+ return;
3509
+ }
3510
+ }
3638
3511
  const ERROR_STATUS = {
3639
3512
  conflict: 409,
3640
3513
  forbidden: 403,
@@ -3677,26 +3550,40 @@ function createReviewItemRoutes(services) {
3677
3550
  app.get("/", requireViewer, validateRequest("query", reviewItemListQuerySchema, "Invalid review item query."), async (context) => {
3678
3551
  const viewer = context.get("viewer");
3679
3552
  const query = context.req.valid("query");
3680
- const view = query.view ?? "all";
3681
- const items = await searchReviewItems(getDb(), reviewItemReaderForUser(viewer), {
3682
- limit: LIST_LIMIT,
3683
- statuses: query.archived === "true" ? ["done", "dismissed"] : ["open"],
3684
- ...view === "mine" ? { assignee: { userId: viewer.id } } : view === "everyone" ? { assignee: { everyone: true } } : void 0,
3553
+ const filters = {
3685
3554
  ...query.conversationId ? { conversationId: query.conversationId } : void 0,
3686
3555
  ...query.q ? { query: query.q } : void 0
3556
+ };
3557
+ const after = query.cursor ? decodeCursor(query.cursor, filters) : void 0;
3558
+ if (query.cursor && !after) return jsonResponse(apiErrorSchema, { error: "Invalid review item cursor." }, { status: 400 });
3559
+ const db = getDb();
3560
+ const reader = reviewItemReaderForUser(viewer);
3561
+ const open = await searchReviewItems(db, reader, {
3562
+ ...filters,
3563
+ limit: query.limit + 1,
3564
+ statuses: ["open"],
3565
+ ...after ? { after } : void 0
3566
+ });
3567
+ const page = open.slice(0, query.limit);
3568
+ const last = page.at(-1);
3569
+ const archived = filters.query && !after ? await searchReviewItems(db, reader, {
3570
+ ...filters,
3571
+ limit: 51,
3572
+ statuses: ["done", "dismissed"]
3573
+ }) : [];
3574
+ return jsonResponse(reviewItemListSchema, {
3575
+ items: [...page, ...archived.slice(0, ARCHIVED_LIMIT)].map((item) => reviewItemPayload(item, viewer)),
3576
+ ...archived.length > ARCHIVED_LIMIT ? { moreArchived: true } : void 0,
3577
+ ...open.length > query.limit && last ? { nextCursor: encodeCursor(last, filters) } : void 0
3687
3578
  });
3688
- return jsonResponse(reviewItemListSchema, { items: items.map((item) => reviewItemPayload(item, viewer)) });
3689
3579
  });
3690
3580
  app.get("/count", requireViewer, async (context) => {
3691
3581
  const viewer = context.get("viewer");
3692
- return jsonResponse(reviewItemCountSchema, { mine: await countReviewItems(getDb(), reviewItemReaderForUser(viewer), {
3693
- assignee: { userId: viewer.id },
3694
- statuses: ["open"]
3695
- }) });
3582
+ return jsonResponse(reviewItemCountSchema, { needsViewer: await countReviewItemsNeedingUser(getDb(), viewer.id) });
3696
3583
  });
3697
3584
  app.get("/waiting-conversations", requireViewer, async (context) => {
3698
3585
  const viewer = context.get("viewer");
3699
- return jsonResponse(reviewItemWaitingConversationsSchema, { conversationIds: await listWaitingConversationIds(getDb(), viewer) });
3586
+ return jsonResponse(reviewItemWaitingConversationsSchema, { conversationIds: await listWaitingConversationIds(getDb(), viewer.id) });
3700
3587
  });
3701
3588
  app.get("/:id", requireViewer, validateRequest("param", reviewItemParamsSchema, "Invalid review item."), async (context) => {
3702
3589
  const viewer = context.get("viewer");
@@ -3714,9 +3601,8 @@ function createReviewItemRoutes(services) {
3714
3601
  try {
3715
3602
  const item = await actOnReviewItem({
3716
3603
  action: body.action,
3717
- getSlackAdapter: getProductionSlackAdapter,
3604
+ delivery: services.delivery,
3718
3605
  id,
3719
- queue: services.queue,
3720
3606
  user: viewer,
3721
3607
  ...body.action === "submit" ? { answer: {
3722
3608
  ...body.answer,
@@ -3854,7 +3740,7 @@ function readDescriptionText(home) {
3854
3740
  }
3855
3741
  /** Read discovered skill names for authenticated runtime diagnostics. */
3856
3742
  async function readSkillReports() {
3857
- const { discoverSkills } = await import("./skills-CfAnfImD.js").then((n) => n.o);
3743
+ const { discoverSkills } = await import("./skills-BggTR_ue.js").then((n) => n.o);
3858
3744
  const skills = await discoverSkills();
3859
3745
  return skillReportsSchema.parse(skills.map((skill) => ({
3860
3746
  name: skill.name,
@@ -3863,7 +3749,7 @@ async function readSkillReports() {
3863
3749
  }
3864
3750
  /** Read safe configured plugin metadata for authenticated runtime diagnostics. */
3865
3751
  async function readPlugins() {
3866
- const { pluginCatalogRuntime } = await import("./catalog-runtime-BD9GSpc6.js").then((n) => n.t);
3752
+ const { pluginCatalogRuntime } = await import("./catalog-runtime-Bdym_wKy.js").then((n) => n.t);
3867
3753
  return pluginsSchema.parse(pluginCatalogRuntime.getProviders().map((plugin) => ({
3868
3754
  configKeys: plugin.manifest.configKeys ?? [],
3869
3755
  description: plugin.manifest.description,
@@ -3875,7 +3761,7 @@ async function readPlugins() {
3875
3761
  async function readRuntimeInfoReport() {
3876
3762
  const [{ homeDir }, { pluginCatalogRuntime }, plugins, skills] = await Promise.all([
3877
3763
  import("./package-discovery-DJBompdd.js").then((n) => n.r),
3878
- import("./catalog-runtime-BD9GSpc6.js").then((n) => n.t),
3764
+ import("./catalog-runtime-Bdym_wKy.js").then((n) => n.t),
3879
3765
  readPlugins(),
3880
3766
  readSkillReports()
3881
3767
  ]);
@@ -3892,7 +3778,7 @@ async function readRuntimeInfoReport() {
3892
3778
  /** Read sanitized operational summaries contributed by plugins. */
3893
3779
  async function readPluginOperationalReportFeed() {
3894
3780
  const nowMs = Date.now();
3895
- const { getPluginOperationalReports } = await import("./credentialed-lukuD-cc.js").then((n) => n.a);
3781
+ const { getPluginOperationalReports } = await import("./credentialed-BeBaJMZ_.js").then((n) => n.a);
3896
3782
  return pluginOperationalReportFeedSchema.parse({
3897
3783
  source: "plugins",
3898
3784
  generatedAt: new Date(nowMs).toISOString(),
@@ -3914,7 +3800,10 @@ function createJuniorApi(options = {}) {
3914
3800
  attachmentStorage: getAttachmentStorage(),
3915
3801
  queue
3916
3802
  }));
3917
- app.route("/api/review-items", createReviewItemRoutes({ queue }));
3803
+ app.route("/api/review-items", createReviewItemRoutes({ delivery: {
3804
+ queue,
3805
+ show: createSlackReviewItemShow(getProductionSlackAdapter)
3806
+ } }));
3918
3807
  app.route("/api/code", createCodeRoutes());
3919
3808
  app.route("/api/connections", createConnectionRoutes());
3920
3809
  app.route("/api/personal-tokens", createPersonalTokenRoutes());
@@ -3936,4 +3825,4 @@ function createJuniorApi(options = {}) {
3936
3825
  });
3937
3826
  return app;
3938
3827
  }
3939
- export { authenticatePersonalToken, createJuniorApi, isAllowedSignInEmail, jsonResponse, resolveViewerUser, updateViewerDisplayName };
3828
+ export { authenticatePersonalToken, createJuniorApi, isAllowedSignInEmail, jsonResponse, readViewerAvatarUrl, resolveViewerUser, updateViewerDisplayName };