@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/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, Ur as isExperimentalFeatureEnabled, ct as AutomationConflictError, ft as automationEventCatalog, j as readAutomationTitlesByConversationId } from "./turn-session-routing-BqO0qXLk.js";
2
+ import { p as escapeXml } from "./client-Cqf4TboL.js";
3
+ import { m as logInfo, p as logException } from "./logging-n7knse-O.js";
4
+ import { C as getSqlExecutor, 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-DSbD6DF6.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-CNS7ONt-.js";
7
+ import { t as INPUT_IMAGE_TYPES } from "./media-85PDJxO_.js";
8
+ import { n as pluginCatalogRuntime } from "./catalog-runtime-BsoSmTM0.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-CrDrPUtY.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-BU-OW7HP.js";
11
+ import { r as getStateAdapter } from "./adapter-2-CG25be.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-CTpD_PGk.js";
13
+ import { h as getChildAgentLabel } from "./store-1DVhoKOL.js";
14
+ import { d as getEventCatalog } from "./session-stop-BQW_iFcd.js";
15
+ import { a as fillUtcSixHours, 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, x as userCustomizationSchema, y as webMessageId } from "./reporting-window-CVarfId9.js";
16
+ import { s as getSandboxResources, t as getCachedSnapshot } from "./resolve-CUIBcdPd.js";
17
+ import { a as getVercelConversationWorkQueue } from "./job-queue-DI-k-Bbk.js";
18
+ import { E as steerWebPendingMessages, a as cancelHumanFacingPendingMessages, g as getConversationWorkState, h as getConversation } from "./store-DCo2n5iJ.js";
19
+ import { n as finishServiceAccountSignIn, o as serviceAccountPlugins, r as getServiceAccountStatus, s as startServiceAccountSignIn, t as disconnectServiceAccount } from "./service-account-DHvlLnZw.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-p87hg_AV.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, 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-CGoQdXTp.js";
23
+ import { d as legacyWebMailboxMetadataSchema } from "./result-BemsOMOO.js";
24
+ import { a as startConnection, l as getWebAuthorization, n as isConnectableProvider, r as listConnections, t as disconnectConnection, u as htmlCallbackResponse } from "./connections-upFXLmhG.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-ChnFo5f2.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
  }
@@ -2694,7 +2696,7 @@ async function readPeoplePluginReports(args) {
2694
2696
  reports: [],
2695
2697
  source: "plugins"
2696
2698
  });
2697
- const { getPluginProfileReports } = await import("./credentialed-lukuD-cc.js").then((n) => n.a);
2699
+ const { getPluginProfileReports } = await import("./credentialed-BU-OW7HP.js").then((n) => n.a);
2698
2700
  return pluginOperationalReportFeedSchema.parse({
2699
2701
  generatedAt: new Date(nowMs).toISOString(),
2700
2702
  reports: await getPluginProfileReports({
@@ -2903,6 +2905,23 @@ function spendWindow(nowMs) {
2903
2905
  thirtyDayStart
2904
2906
  };
2905
2907
  }
2908
+ /**
2909
+ * Read a cheap change marker for one viewer's spend window.
2910
+ *
2911
+ * Writes that record Conversation metrics also move `updated_at` forward, so
2912
+ * the marker changes when spend can change. The spend cache TTL bounds changes
2913
+ * that the marker misses, such as a day that leaves the window.
2914
+ */
2915
+ async function readPersonalSpendVersion(email, nowMs = Date.now()) {
2916
+ const normalizedEmail = normalizeEmail$1(email);
2917
+ if (!normalizedEmail) return "";
2918
+ const { end, thirtyDayStart } = spendWindow(nowMs);
2919
+ const [row] = await getDb().select({
2920
+ conversations: sql`count(*)::int`,
2921
+ updatedAt: sql`max(${juniorConversations.updatedAt})::text`
2922
+ }).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)));
2923
+ return `${row?.conversations ?? 0}:${row?.updatedAt ?? ""}`;
2924
+ }
2906
2925
  /** Read one viewer's rolling model spend with one bounded aggregate query. */
2907
2926
  async function readPersonalSpendFromSql(email, nowMs = Date.now()) {
2908
2927
  const normalizedEmail = normalizeEmail$1(email);
@@ -2935,19 +2954,27 @@ async function readPersonalSpendFromSql(email, nowMs = Date.now()) {
2935
2954
  }
2936
2955
  // src/api/people/spend.ts
2937
2956
  const PERSONAL_SPEND_CACHE_TTL_MS = 3e5;
2938
- /** Create an app-scoped personal-spend reader with a five-minute cache. */
2957
+ /**
2958
+ * Create an app-scoped personal-spend reader.
2959
+ *
2960
+ * A cached report stays valid for five minutes, or until the viewer's spend
2961
+ * version changes. The dashboard can poll often and still see a finished Turn
2962
+ * without a full aggregate query on every poll.
2963
+ */
2939
2964
  function createPersonalSpendReader() {
2940
2965
  const cache = /* @__PURE__ */ new Map();
2941
2966
  return async function readPersonalSpend(email) {
2942
2967
  const normalizedEmail = email.trim().toLowerCase();
2943
2968
  const nowMs = Date.now();
2969
+ const version = await readPersonalSpendVersion(normalizedEmail, nowMs);
2944
2970
  const cached = cache.get(normalizedEmail);
2945
- if (cached && cached.expiresAtMs > nowMs) return cached.report;
2971
+ if (cached && cached.expiresAtMs > nowMs && cached.version === version) return cached.report;
2946
2972
  cache.delete(normalizedEmail);
2947
2973
  const report = readPersonalSpendFromSql(normalizedEmail, nowMs);
2948
2974
  const entry = {
2949
2975
  expiresAtMs: nowMs + PERSONAL_SPEND_CACHE_TTL_MS,
2950
- report
2976
+ report,
2977
+ version
2951
2978
  };
2952
2979
  cache.set(normalizedEmail, entry);
2953
2980
  try {
@@ -2963,6 +2990,17 @@ function createPersonalSpendReader() {
2963
2990
  function createPeopleRoutes() {
2964
2991
  const app = new Hono();
2965
2992
  const readPersonalSpend = createPersonalSpendReader();
2993
+ app.get("/avatars/:identityId", requireViewer, validateRequest("param", avatarParamsSchema, "Invalid route parameters."), async (context) => {
2994
+ const { identityId } = context.req.valid("param");
2995
+ const image = await readAvatarImage(getDb(), getStateAdapter(), identityId);
2996
+ if (!image) throwApiError(404, "Avatar not found.");
2997
+ return new Response(Buffer.from(image.data, "base64"), { headers: {
2998
+ "cache-control": "private, max-age=86400",
2999
+ "content-security-policy": "default-src 'none'; sandbox",
3000
+ "content-type": image.contentType,
3001
+ "x-content-type-options": "nosniff"
3002
+ } });
3003
+ });
2966
3004
  app.get("/me/spend", requireViewer, async (context) => {
2967
3005
  const viewer = context.get("viewer");
2968
3006
  return jsonResponse(personalSpendReportSchema, await readPersonalSpend(viewer.email));
@@ -3206,233 +3244,6 @@ function createUserPageRoutes() {
3206
3244
  });
3207
3245
  return app;
3208
3246
  }
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
3247
  // src/chat/automations/editor.ts
3437
3248
  /** Read-only editor support. Core owns schedules; plugins own Event choices. */
3438
3249
  /**
@@ -3634,7 +3445,39 @@ function createUserCustomizationRoutes() {
3634
3445
  return app;
3635
3446
  }
3636
3447
  // src/api/review-items/routes.ts
3637
- const LIST_LIMIT = 100;
3448
+ const ARCHIVED_LIMIT = 50;
3449
+ const cursorSchema = z.object({
3450
+ conversationId: z.string().min(1).optional(),
3451
+ id: z.string().min(1),
3452
+ query: z.string().min(1).optional(),
3453
+ updatedAtMs: z.number().int(),
3454
+ version: z.literal(1)
3455
+ }).strict();
3456
+ /**
3457
+ * Encode the last open item of a page as the cursor of the next page. The
3458
+ * cursor names its list, so it cannot page through a different list.
3459
+ */
3460
+ function encodeCursor(item, filters) {
3461
+ return Buffer.from(JSON.stringify({
3462
+ ...filters,
3463
+ id: item.id,
3464
+ updatedAtMs: item.updatedAt.getTime(),
3465
+ version: 1
3466
+ }), "utf8").toString("base64url");
3467
+ }
3468
+ /** Decode a cursor of the same list, or return undefined. */
3469
+ function decodeCursor(cursor, filters) {
3470
+ try {
3471
+ const parsed = cursorSchema.parse(JSON.parse(Buffer.from(cursor, "base64url").toString("utf8")));
3472
+ if (parsed.conversationId !== filters.conversationId || parsed.query !== filters.query) return;
3473
+ return {
3474
+ id: parsed.id,
3475
+ updatedAt: new Date(parsed.updatedAtMs)
3476
+ };
3477
+ } catch {
3478
+ return;
3479
+ }
3480
+ }
3638
3481
  const ERROR_STATUS = {
3639
3482
  conflict: 409,
3640
3483
  forbidden: 403,
@@ -3677,26 +3520,40 @@ function createReviewItemRoutes(services) {
3677
3520
  app.get("/", requireViewer, validateRequest("query", reviewItemListQuerySchema, "Invalid review item query."), async (context) => {
3678
3521
  const viewer = context.get("viewer");
3679
3522
  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,
3523
+ const filters = {
3685
3524
  ...query.conversationId ? { conversationId: query.conversationId } : void 0,
3686
3525
  ...query.q ? { query: query.q } : void 0
3526
+ };
3527
+ const after = query.cursor ? decodeCursor(query.cursor, filters) : void 0;
3528
+ if (query.cursor && !after) return jsonResponse(apiErrorSchema, { error: "Invalid review item cursor." }, { status: 400 });
3529
+ const db = getDb();
3530
+ const reader = reviewItemReaderForUser(viewer);
3531
+ const open = await searchReviewItems(db, reader, {
3532
+ ...filters,
3533
+ limit: query.limit + 1,
3534
+ statuses: ["open"],
3535
+ ...after ? { after } : void 0
3536
+ });
3537
+ const page = open.slice(0, query.limit);
3538
+ const last = page.at(-1);
3539
+ const archived = filters.query && !after ? await searchReviewItems(db, reader, {
3540
+ ...filters,
3541
+ limit: 51,
3542
+ statuses: ["done", "dismissed"]
3543
+ }) : [];
3544
+ return jsonResponse(reviewItemListSchema, {
3545
+ items: [...page, ...archived.slice(0, ARCHIVED_LIMIT)].map((item) => reviewItemPayload(item, viewer)),
3546
+ ...archived.length > ARCHIVED_LIMIT ? { moreArchived: true } : void 0,
3547
+ ...open.length > query.limit && last ? { nextCursor: encodeCursor(last, filters) } : void 0
3687
3548
  });
3688
- return jsonResponse(reviewItemListSchema, { items: items.map((item) => reviewItemPayload(item, viewer)) });
3689
3549
  });
3690
3550
  app.get("/count", requireViewer, async (context) => {
3691
3551
  const viewer = context.get("viewer");
3692
- return jsonResponse(reviewItemCountSchema, { mine: await countReviewItems(getDb(), reviewItemReaderForUser(viewer), {
3693
- assignee: { userId: viewer.id },
3694
- statuses: ["open"]
3695
- }) });
3552
+ return jsonResponse(reviewItemCountSchema, { needsViewer: await countReviewItemsNeedingUser(getDb(), viewer.id) });
3696
3553
  });
3697
3554
  app.get("/waiting-conversations", requireViewer, async (context) => {
3698
3555
  const viewer = context.get("viewer");
3699
- return jsonResponse(reviewItemWaitingConversationsSchema, { conversationIds: await listWaitingConversationIds(getDb(), viewer) });
3556
+ return jsonResponse(reviewItemWaitingConversationsSchema, { conversationIds: await listWaitingConversationIds(getDb(), viewer.id) });
3700
3557
  });
3701
3558
  app.get("/:id", requireViewer, validateRequest("param", reviewItemParamsSchema, "Invalid review item."), async (context) => {
3702
3559
  const viewer = context.get("viewer");
@@ -3714,9 +3571,8 @@ function createReviewItemRoutes(services) {
3714
3571
  try {
3715
3572
  const item = await actOnReviewItem({
3716
3573
  action: body.action,
3717
- getSlackAdapter: getProductionSlackAdapter,
3574
+ delivery: services.delivery,
3718
3575
  id,
3719
- queue: services.queue,
3720
3576
  user: viewer,
3721
3577
  ...body.action === "submit" ? { answer: {
3722
3578
  ...body.answer,
@@ -3854,7 +3710,7 @@ function readDescriptionText(home) {
3854
3710
  }
3855
3711
  /** Read discovered skill names for authenticated runtime diagnostics. */
3856
3712
  async function readSkillReports() {
3857
- const { discoverSkills } = await import("./skills-CfAnfImD.js").then((n) => n.o);
3713
+ const { discoverSkills } = await import("./skills-DmJJIuLF.js").then((n) => n.o);
3858
3714
  const skills = await discoverSkills();
3859
3715
  return skillReportsSchema.parse(skills.map((skill) => ({
3860
3716
  name: skill.name,
@@ -3863,7 +3719,7 @@ async function readSkillReports() {
3863
3719
  }
3864
3720
  /** Read safe configured plugin metadata for authenticated runtime diagnostics. */
3865
3721
  async function readPlugins() {
3866
- const { pluginCatalogRuntime } = await import("./catalog-runtime-BD9GSpc6.js").then((n) => n.t);
3722
+ const { pluginCatalogRuntime } = await import("./catalog-runtime-BsoSmTM0.js").then((n) => n.t);
3867
3723
  return pluginsSchema.parse(pluginCatalogRuntime.getProviders().map((plugin) => ({
3868
3724
  configKeys: plugin.manifest.configKeys ?? [],
3869
3725
  description: plugin.manifest.description,
@@ -3875,7 +3731,7 @@ async function readPlugins() {
3875
3731
  async function readRuntimeInfoReport() {
3876
3732
  const [{ homeDir }, { pluginCatalogRuntime }, plugins, skills] = await Promise.all([
3877
3733
  import("./package-discovery-DJBompdd.js").then((n) => n.r),
3878
- import("./catalog-runtime-BD9GSpc6.js").then((n) => n.t),
3734
+ import("./catalog-runtime-BsoSmTM0.js").then((n) => n.t),
3879
3735
  readPlugins(),
3880
3736
  readSkillReports()
3881
3737
  ]);
@@ -3892,7 +3748,7 @@ async function readRuntimeInfoReport() {
3892
3748
  /** Read sanitized operational summaries contributed by plugins. */
3893
3749
  async function readPluginOperationalReportFeed() {
3894
3750
  const nowMs = Date.now();
3895
- const { getPluginOperationalReports } = await import("./credentialed-lukuD-cc.js").then((n) => n.a);
3751
+ const { getPluginOperationalReports } = await import("./credentialed-BU-OW7HP.js").then((n) => n.a);
3896
3752
  return pluginOperationalReportFeedSchema.parse({
3897
3753
  source: "plugins",
3898
3754
  generatedAt: new Date(nowMs).toISOString(),
@@ -3914,7 +3770,10 @@ function createJuniorApi(options = {}) {
3914
3770
  attachmentStorage: getAttachmentStorage(),
3915
3771
  queue
3916
3772
  }));
3917
- app.route("/api/review-items", createReviewItemRoutes({ queue }));
3773
+ app.route("/api/review-items", createReviewItemRoutes({ delivery: {
3774
+ queue,
3775
+ show: createSlackReviewItemShow(getProductionSlackAdapter)
3776
+ } }));
3918
3777
  app.route("/api/code", createCodeRoutes());
3919
3778
  app.route("/api/connections", createConnectionRoutes());
3920
3779
  app.route("/api/personal-tokens", createPersonalTokenRoutes());
@@ -3936,4 +3795,4 @@ function createJuniorApi(options = {}) {
3936
3795
  });
3937
3796
  return app;
3938
3797
  }
3939
- export { authenticatePersonalToken, createJuniorApi, isAllowedSignInEmail, jsonResponse, resolveViewerUser, updateViewerDisplayName };
3798
+ export { authenticatePersonalToken, createJuniorApi, isAllowedSignInEmail, jsonResponse, readViewerAvatarUrl, resolveViewerUser, updateViewerDisplayName };
@@ -1,6 +1,6 @@
1
1
  import { n as ConversationWorkQueue, t as ConversationQueueMessage } from "./queue-C37RbDVc.js";
2
- import { t as ConversationStore } from "./store-xMuuXRE0.js";
3
- import "./history-BgI33Kie.js";
2
+ import { t as ConversationStore } from "./db-BzOCzVb1.js";
3
+ import "./schema-jK4-1u_H.js";
4
4
  import { n as JuniorPluginSet } from "./plugins-B_0Cr0MO.js";
5
5
  import { Hono } from "hono";
6
6
  import "@earendil-works/pi-ai/compat";
@@ -8,6 +8,7 @@ import "@earendil-works/pi-ai/api/anthropic-messages";
8
8
  import "ai";
9
9
  import "@sentry/node";
10
10
  import { z } from "zod";
11
+ import "drizzle-orm";
11
12
  import { Destination, OwnedObjectAnnotation, PluginRegistration, Source, User } from "@sentry/junior-plugin-api";
12
13
  import "@earendil-works/pi-agent-core";
13
14
  import "@earendil-works/pi-ai";
@@ -168,6 +169,11 @@ interface InboxAttempt {
168
169
  drain(handle: (messages: InboundMessage[]) => Promise<readonly string[] | void>, options?: {
169
170
  deferred?: boolean;
170
171
  }): Promise<InboundMessage[]>;
172
+ /**
173
+ * True when a failure of this attempt can end the work: the worker gives up
174
+ * and drops the mailbox. The adapter must record its own failure first.
175
+ * Resume attempts, which have no messages, can also be final.
176
+ */
171
177
  isFinalAttempt: boolean;
172
178
  messages: InboundMessage[];
173
179
  }
package/dist/app.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as ModelProfileInput, i as JuniorDashboardOptions, n as JuniorAppOptions, r as createApp, t as JuniorApp } from "./app-z6Uuyq3j.js";
1
+ import { a as ModelProfileInput, i as JuniorDashboardOptions, n as JuniorAppOptions, r as createApp, t as JuniorApp } from "./app-BrMMzjYm.js";
2
2
  import { i as defineJuniorPlugins, n as JuniorPluginSet, r as JuniorPluginSetOptions, t as JuniorPluginInput } from "./plugins-B_0Cr0MO.js";
3
3
  import { t as JUNIOR_VERSION } from "./version-Cc2OFd9G.js";
4
4
  export { JUNIOR_VERSION, JuniorApp, JuniorAppOptions, type JuniorDashboardOptions, type JuniorPluginInput, type JuniorPluginSet, type JuniorPluginSetOptions, type ModelProfileInput, createApp, defineJuniorPlugins };