@sentry/junior 0.256.0 → 0.258.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 (106) hide show
  1. package/dist/{actor-BTtLaeWy.js → actor-tlxzqaRe.js} +3 -6
  2. package/dist/{admin-BhucwVfy.js → admin-My1SLGVO.js} +2 -3
  3. package/dist/{agent-hooks-DlSK8PQQ.js → agent-hooks-BJ_5mlRH.js} +71 -111
  4. package/dist/{agent-invocations-BY60iNw-.js → agent-invocations-Qfz7dWgU.js} +8 -13
  5. package/dist/{agent-runner-C6_cd61V.js → agent-runner-DGsFQw72.js} +278 -467
  6. package/dist/api/schema.d.ts +454 -448
  7. package/dist/api/schema.js +5 -5
  8. package/dist/api.d.ts +2 -12
  9. package/dist/api.js +189 -165
  10. package/dist/{app-B0gT1Slp.d.ts → app-PX2H1PxU.d.ts} +20 -37
  11. package/dist/app.d.ts +3 -3
  12. package/dist/app.js +565 -305
  13. package/dist/{assistant-reply-yn5G-YEG.js → assistant-reply-H1M-91oF.js} +3 -5
  14. package/dist/{automation-CHdlHVZP.js → automation-DWBFBenG.js} +6 -11
  15. package/dist/{briefs-U6Bi3IYw.js → briefs-vYoK85rJ.js} +8 -11
  16. package/dist/{cadence-D00SCzT1.js → cadence-R7Em4RjE.js} +1 -2
  17. package/dist/{catalog-runtime-DF5OWqCc.js → catalog-runtime-BN4DVxco.js} +3 -4
  18. package/dist/cli/chat.d.ts +2 -4
  19. package/dist/cli/chat.js +22 -24
  20. package/dist/cli/check.d.ts +1 -3
  21. package/dist/cli/check.js +4 -5
  22. package/dist/cli/env.d.ts +1 -3
  23. package/dist/cli/env.js +1 -2
  24. package/dist/cli/init.d.ts +1 -3
  25. package/dist/cli/init.js +3 -3
  26. package/dist/cli/main.d.ts +1 -3
  27. package/dist/cli/main.js +4 -5
  28. package/dist/cli/plugins.d.ts +2 -4
  29. package/dist/cli/plugins.js +7 -8
  30. package/dist/cli/run.d.ts +1 -2
  31. package/dist/cli/run.js +1 -2
  32. package/dist/cli/snapshot-create.d.ts +1 -3
  33. package/dist/cli/snapshot-create.js +4 -5
  34. package/dist/cli/upgrade.d.ts +3 -6
  35. package/dist/cli/upgrade.js +11 -17
  36. package/dist/{client-BVrAp-pq.js → client-DbyHuMFU.js} +9 -16
  37. package/dist/{config-DdBiDanf.js → config-_WO_AjCB.js} +18 -15
  38. package/dist/{connections-CG04HdpC.js → connections-ag_1JOhB.js} +21 -21
  39. package/dist/{conversation-T18Xlkx9.js → conversation-DjN3mlog.js} +11 -17
  40. package/dist/{conversation-privacy-CpSYOWnP.js → conversation-privacy-DHP_xnVj.js} +2 -3
  41. package/dist/{conversation-work-C6y3T5Hx.js → conversation-work-BaT_T6EB.js} +1 -2
  42. package/dist/{credential-sync-DKWNdcgm.js → credential-sync-B-CPX_ag.js} +89 -52
  43. package/dist/{db-Ca9Nt5ci.d.ts → db-BnRqQ7G5.d.ts} +1 -1
  44. package/dist/{executor-BroK9oKy.js → executor-RvG6kVe1.js} +58 -70
  45. package/dist/{experimental-Qn9rKLgx.js → experimental-BNK1l1jv.js} +2 -3
  46. package/dist/{history-9pO1Zd4Y.js → history-AY8rs-FR.js} +5 -9
  47. package/dist/{history-DvqWZlYX.d.ts → history-BgI33Kie.d.ts} +12 -20
  48. package/dist/{images-D0VZ5nv0.js → images-C2J_bj2g.js} +5 -6
  49. package/dist/instrumentation.d.ts +1 -3
  50. package/dist/instrumentation.js +6 -8
  51. package/dist/{job-queue-BbGg3gvu.js → job-queue-DVe37it2.js} +6 -12
  52. package/dist/{logging-tPQeUe2i.js → logging-DsHONhVm.js} +54 -24
  53. package/dist/{message-DdPGRYQP.js → message-DyitL8no.js} +5 -6
  54. package/dist/{model-profile-BwU8mqwD.js → model-profile-Bg8EoCKD.js} +2 -4
  55. package/dist/nitro.d.ts +3 -5
  56. package/dist/nitro.js +12 -17
  57. package/dist/{oauth-authorization-BA4Dt6a7.js → oauth-authorization-djQn5Nhy.js} +2 -4
  58. package/dist/{oauth-callback-server-B-2errCX.js → oauth-callback-server-CDby-pCn.js} +3 -4
  59. package/dist/{oauth-relay-CdCnu80W.js → oauth-relay-CTygMkNx.js} +2 -3
  60. package/dist/{package-discovery-BVvSnQBB.js → package-discovery-DJBompdd.js} +17 -21
  61. package/dist/{pending-auth-DT3MRVW8.js → pending-auth-D8J1uJUS.js} +37 -28
  62. package/dist/{plugin-module-CVvEUSMH.js → plugin-module-Cf5gVPWP.js} +1 -2
  63. package/dist/{plugins-CjfUP5gJ.d.ts → plugins-B11Mfkmv.d.ts} +0 -4
  64. package/dist/{plugins-egKWjgue.js → plugins-DOm9Y6qI.js} +2 -3
  65. package/dist/{private-trace-result-BLvBjy_e.js → private-trace-result-CE7_lEdq.js} +1 -2
  66. package/dist/{profile-Bb1zCVGP.js → profile-DpYjfKke.js} +16 -28
  67. package/dist/{prompt-C04mP1hu.js → prompt-xgpyMtg7.js} +5 -9
  68. package/dist/{queue-B5SnqRln.d.ts → queue-C37RbDVc.d.ts} +0 -2
  69. package/dist/{registry-CsNavQ_Z.js → registry-Du566MtJ.js} +57 -30
  70. package/dist/{resolve-B6ZZ9duG.js → resolve-ClCIgh8E.js} +7 -12
  71. package/dist/{result-j9nS0se-.js → result-BBbKA61B.js} +13 -17
  72. package/dist/{rolldown-runtime-B4FMCO8f.js → rolldown-runtime-nwUcYXjP.js} +1 -2
  73. package/dist/{runner-Y331DoZ5.js → runner-CCuqFSqx.js} +12 -13
  74. package/dist/{sandbox-egress-signals-BUfjEdHY.js → sandbox-egress-signals-DY1mbKF4.js} +2 -3
  75. package/dist/{schema-BBgv0MNf.js → schema-DrMh3NtR.js} +17 -27
  76. package/dist/{sentry-CgWZM_kV.js → sentry-BBUlHih9.js} +2 -3
  77. package/dist/{session-stop-q-6GNHx6.js → session-stop-CIoFiwwe.js} +57 -41
  78. package/dist/{skills-CyvTsR9M.js → skills-DyQBLIrK.js} +9 -9
  79. package/dist/{spawn-Do5mX3d_.js → spawn-Dqfeo7XP.js} +4 -5
  80. package/dist/{store-DoewL5mG.d.ts → store-CG0VJyye.d.ts} +0 -14
  81. package/dist/{store-D2It0ozF.js → store-DJLwq4x8.js} +13 -15
  82. package/dist/{task-queue-ZMk9bLRT.js → task-queue-BzW4MaWU.js} +5 -7
  83. package/dist/{task-runner-cIGU5VwJ.js → task-runner-D3qJh4fK.js} +22 -26
  84. package/dist/{tasks-CODtRzvX.js → tasks-CEXKTASS.js} +78 -79
  85. package/dist/{thread-state-BPkwVmvK.js → thread-state-W3f6kAtz.js} +13 -19
  86. package/dist/{turn-failure-response-ChmMeKar.js → turn-failure-response-CWx7aNIh.js} +16 -22
  87. package/dist/{turn-lifecycle-BUP7ZOVa.js → turn-lifecycle-C9JFst7-.js} +2 -3
  88. package/dist/{turn-session-routing-BcWM3PLm.js → turn-session-routing-CUxtfpr7.js} +2 -3
  89. package/dist/{validation-DCd69-cP.js → validation-BHRxa5G4.js} +3 -4
  90. package/dist/vercel.d.ts +1 -3
  91. package/dist/vercel.js +1 -2
  92. package/dist/{version-DBc4Qt_P.js → version-C0U6rHg0.js} +3 -5
  93. package/dist/{version-CnXZ614E.d.ts → version-Cc2OFd9G.d.ts} +0 -2
  94. package/dist/version.d.ts +1 -1
  95. package/dist/version.js +1 -2
  96. package/dist/{viewer-C-9nFKYr.js → viewer-CGvvRqKp.js} +61 -44
  97. package/dist/{web-input-Cv42P3ni.js → web-input-Keb5GRWj.js} +139 -198
  98. package/dist/{web-message-id-xPI_EFSC.js → web-message-id-CJSUiksE.js} +3 -6
  99. package/dist/{work-6UmVQq1V.js → work-DRcsJ3hV.js} +14 -16
  100. package/dist/{worker-DAoBZuZn.js → worker-Cjo-QqPq.js} +7 -8
  101. package/migrations/0059_automation_run_version.sql +2 -0
  102. package/migrations/0060_identity_signed_in_at.sql +1 -0
  103. package/migrations/meta/0059_snapshot.json +3619 -0
  104. package/migrations/meta/0060_snapshot.json +3465 -0
  105. package/migrations/meta/_journal.json +15 -1
  106. package/package.json +8 -6
@@ -1,14 +1,14 @@
1
- import { _ as getProviderErrorUserMessage, g as getProviderErrorAttributes, h as findProviderError, p as ProviderError } from "./client-BVrAp-pq.js";
2
- import { I as isRecord, t as buildTurnFailureResponse } from "./logging-tPQeUe2i.js";
3
- import { g as parseSlackMessageTs } from "./actor-BTtLaeWy.js";
4
- import { c as getConversationEventStore, d as getDb } from "./viewer-C-9nFKYr.js";
5
- import { Ut as hydrateConversationMessages, rn as markConversationMessage } from "./tasks-CODtRzvX.js";
6
- import { Nt as listConversationAnnotations } from "./agent-hooks-DlSK8PQQ.js";
7
- import { J as removedCardSchema, Y as resolveMessageCards, q as readMessageCardRefs } from "./conversation-T18Xlkx9.js";
8
- import { r as clearPendingAuth, u as buildDeterministicTurnId } from "./pending-auth-DT3MRVW8.js";
9
- import { d as markTurnCompleted, u as markTurnClosed } from "./oauth-authorization-BA4Dt6a7.js";
10
- import { o as persistThreadStateById, r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-BPkwVmvK.js";
11
- //#region src/chat/conversations/pending-cards.ts
1
+ import { _ as getProviderErrorUserMessage, g as getProviderErrorAttributes, h as findProviderError, p as ProviderError } from "./client-DbyHuMFU.js";
2
+ import { t as buildTurnFailureResponse, z as isRecord } from "./logging-DsHONhVm.js";
3
+ import { g as parseSlackMessageTs } from "./actor-tlxzqaRe.js";
4
+ import { c as getConversationEventStore, d as getDb } from "./viewer-CGvvRqKp.js";
5
+ import { Wt as hydrateConversationMessages, in as markConversationMessage } from "./tasks-CEXKTASS.js";
6
+ import { Nt as listConversationAnnotations } from "./agent-hooks-BJ_5mlRH.js";
7
+ import { J as removedCardSchema, Y as resolveMessageCards, q as readMessageCardRefs } from "./conversation-DjN3mlog.js";
8
+ import { d as buildDeterministicTurnId, r as clearPendingAuth } from "./pending-auth-D8J1uJUS.js";
9
+ import { d as markTurnCompleted, u as markTurnClosed } from "./oauth-authorization-djQn5Nhy.js";
10
+ import { o as persistThreadStateById, r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-W3f6kAtz.js";
11
+ // src/chat/conversations/pending-cards.ts
12
12
  /** Select undelivered cards and load their latest saved facts. */
13
13
  async function loadPendingMessageCards(conversationId) {
14
14
  const cards = /* @__PURE__ */ new Map();
@@ -41,15 +41,13 @@ async function loadPendingMessageCards(conversationId) {
41
41
  if (cards.size === 0) return [];
42
42
  return resolveMessageCards([...cards.values()].reverse(), await listConversationAnnotations(getDb(), conversationId));
43
43
  }
44
- //#endregion
45
- //#region src/chat/interruption-marker.ts
44
+ // src/chat/interruption-marker.ts
46
45
  const INTERRUPTED_MARKER = "\n\n[Response interrupted before completion]";
47
46
  /** Return the marker added when a visible reply ended mid-execution. */
48
47
  function getInterruptionMarker() {
49
48
  return INTERRUPTED_MARKER;
50
49
  }
51
- //#endregion
52
- //#region src/chat/runtime/delivered-turn-state.ts
50
+ // src/chat/runtime/delivered-turn-state.ts
53
51
  /** Build state after destination delivery or intentional no-reply completion. */
54
52
  function buildDeliveredTurnStatePatch(args) {
55
53
  const conversation = structuredClone(args.conversation);
@@ -68,8 +66,7 @@ function buildDeliveredTurnStatePatch(args) {
68
66
  sandboxRef: args.reply.sandboxRef
69
67
  };
70
68
  }
71
- //#endregion
72
- //#region src/chat/runtime/turn-user-message.ts
69
+ // src/chat/runtime/turn-user-message.ts
73
70
  /** Return the user message for a persisted turn/session, if one exists. */
74
71
  function getTurnUserMessage(conversation, sessionId) {
75
72
  for (let index = conversation.messages.length - 1; index >= 0; index -= 1) {
@@ -96,8 +93,7 @@ function getTurnUserReplyAttachmentContext(message) {
96
93
  ...!imagesHydrated && imageAttachmentCount > 0 ? { omittedImageAttachmentCount: imageAttachmentCount } : void 0
97
94
  };
98
95
  }
99
- //#endregion
100
- //#region src/chat/runtime/auth-pause-state.ts
96
+ // src/chat/runtime/auth-pause-state.ts
101
97
  /** Mark an auth-paused turn complete after private authorization link delivery. */
102
98
  function completeAuthPauseTurn(args) {
103
99
  markConversationMessage(args.conversation, getTurnUserMessageId(args.conversation, args.sessionId), {
@@ -124,8 +120,7 @@ async function persistAuthPauseTurnState(args) {
124
120
  });
125
121
  await persistThreadStateById(args.threadStateId, { conversation });
126
122
  }
127
- //#endregion
128
- //#region src/chat/services/turn-failure-response.ts
123
+ // src/chat/services/turn-failure-response.ts
129
124
  /** Require captured turn failures to carry a real Sentry event reference. */
130
125
  function requireTurnFailureEventId(eventId, eventName) {
131
126
  if (!eventId) throw new Error(`Sentry did not return an event ID for ${eventName}`);
@@ -202,5 +197,4 @@ function finalizeFailedTurnReplyWithEvent(args) {
202
197
  }
203
198
  };
204
199
  }
205
- //#endregion
206
200
  export { persistAuthPauseTurnState as a, getTurnUserSlackMessageTs as c, loadPendingMessageCards as d, completeAuthPauseTurn as i, buildDeliveredTurnStatePatch as l, getAgentTurnDiagnosticsAttributes as n, getTurnUserMessage as o, requireTurnFailureEventId as r, getTurnUserReplyAttachmentContext as s, finalizeFailedTurnReplyWithEvent as t, getInterruptionMarker as u };
@@ -1,5 +1,5 @@
1
- import { c as getConversationEventStore } from "./viewer-C-9nFKYr.js";
2
- //#region src/chat/conversations/turn-lifecycle.ts
1
+ import { c as getConversationEventStore } from "./viewer-CGvvRqKp.js";
2
+ // src/chat/conversations/turn-lifecycle.ts
3
3
  /** Persist correlated turn lifecycle facts with retry-safe terminal exclusion. */
4
4
  var ConversationTurnLifecycleService = class {
5
5
  events;
@@ -50,5 +50,4 @@ var ConversationTurnLifecycleService = class {
50
50
  function getTurnLifecycle() {
51
51
  return new ConversationTurnLifecycleService(getConversationEventStore());
52
52
  }
53
- //#endregion
54
53
  export { getTurnLifecycle as n, ConversationTurnLifecycleService as t };
@@ -1,4 +1,4 @@
1
- //#region src/chat/services/turn-session-routing.ts
1
+ // src/chat/services/turn-session-routing.ts
2
2
  async function loadConversationChain(conversationId, conversationStore) {
3
3
  const chain = [];
4
4
  const seen = /* @__PURE__ */ new Set();
@@ -34,7 +34,7 @@ function slackSourceForDestination(args) {
34
34
  * Reads parent Conversations when this Conversation has no Destination.
35
35
  */
36
36
  async function resolveConversationRouting(args) {
37
- const conversationStore = args.conversationStore ?? (await import("./viewer-C-9nFKYr.js").then((n) => n.s)).getConversationStore();
37
+ const conversationStore = args.conversationStore ?? (await import("./viewer-CGvvRqKp.js").then((n) => n.s)).getConversationStore();
38
38
  const chain = await loadConversationChain(args.conversationId, conversationStore);
39
39
  let destination;
40
40
  let source;
@@ -73,5 +73,4 @@ async function resolveTurnSessionRouting(args) {
73
73
  source: routing.source
74
74
  };
75
75
  }
76
- //#endregion
77
76
  export { resolveTurnSessionRouting as n, resolveConversationRouting as t };
@@ -1,7 +1,7 @@
1
- import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.js";
2
- import { n as pluginCatalogRuntime } from "./catalog-runtime-DF5OWqCc.js";
1
+ import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
2
+ import { n as pluginCatalogRuntime } from "./catalog-runtime-BN4DVxco.js";
3
3
  import { isDeepStrictEqual } from "node:util";
4
- //#region src/chat/plugins/validation.ts
4
+ // src/chat/plugins/validation.ts
5
5
  var validation_exports = /* @__PURE__ */ __exportAll({
6
6
  validatePluginEgressCredentialHooks: () => validatePluginEgressCredentialHooks,
7
7
  validatePluginRegistrations: () => validatePluginRegistrations
@@ -35,5 +35,4 @@ function validatePluginEgressCredentialHooks(registrations) {
35
35
  if (!hasDomains && !hasGenericCredentials) throw new Error(`Plugin "${provider.manifest.name}" egress credential hooks require manifest.domains to list sandbox egress hosts.`);
36
36
  }
37
37
  }
38
- //#endregion
39
38
  export { validatePluginRegistrations as n, validation_exports as r, validatePluginEgressCredentialHooks as t };
package/dist/vercel.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- //#region src/vercel.d.ts
2
1
  export interface JuniorVercelConfigOptions {
3
2
  /** Override the Vercel build command, or pass null to omit it. */
4
3
  buildCommand?: string | null;
@@ -8,5 +7,4 @@ export interface JuniorVercelConfigOptions {
8
7
  * New apps run `junior upgrade` before `pnpm build`; older installs without
9
8
  * Junior SQL configured can override `buildCommand` to keep their prior build.
10
9
  */
11
- export declare function juniorVercelConfig(options?: JuniorVercelConfigOptions): Record<string, unknown>;
12
- //#endregion
10
+ export declare function juniorVercelConfig(options?: JuniorVercelConfigOptions): Record<string, unknown>;
package/dist/vercel.js CHANGED
@@ -1,4 +1,4 @@
1
- //#region src/vercel.ts
1
+ // src/vercel.ts
2
2
  /** Return the root Vercel project config for scaffolded Junior apps.
3
3
  *
4
4
  * New apps run `junior upgrade` before `pnpm build`; older installs without
@@ -10,5 +10,4 @@ function juniorVercelConfig(options = {}) {
10
10
  if (buildCommand !== null) config.buildCommand = buildCommand;
11
11
  return config;
12
12
  }
13
- //#endregion
14
13
  export { juniorVercelConfig };
@@ -1,8 +1,6 @@
1
- //#region package.json
2
- var version = "0.256.0";
3
- //#endregion
4
- //#region src/version.ts
1
+ // package.json
2
+ var version = "0.258.0";
3
+ // src/version.ts
5
4
  /** Installed Junior package version, or `unknown` when package metadata is unavailable. */
6
5
  const JUNIOR_VERSION = typeof version === "string" && version.trim() ? version : "unknown";
7
- //#endregion
8
6
  export { JUNIOR_VERSION as t };
@@ -1,5 +1,3 @@
1
- //#region src/version.d.ts
2
1
  /** Installed Junior package version, or `unknown` when package metadata is unavailable. */
3
2
  declare const JUNIOR_VERSION: string;
4
- //#endregion
5
3
  export { JUNIOR_VERSION as t };
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { t as JUNIOR_VERSION } from "./version-CnXZ614E.js";
1
+ import { t as JUNIOR_VERSION } from "./version-Cc2OFd9G.js";
2
2
  export { JUNIOR_VERSION };
package/dist/version.js CHANGED
@@ -1,2 +1 @@
1
- import { t as JUNIOR_VERSION } from "./version-DBc4Qt_P.js";
2
- export { JUNIOR_VERSION };
1
+ export { t as JUNIOR_VERSION } from "./version-C0U6rHg0.js";
@@ -1,14 +1,14 @@
1
- import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.js";
2
- import { F as normalizeIdentityEmail } from "./logging-tPQeUe2i.js";
3
- import { i as getChatConfig } from "./config-DdBiDanf.js";
4
- import { d as parseSlackTeamId, o as parseActorUserId, u as parseSlackChannelReferenceId } from "./actor-BTtLaeWy.js";
5
- import { c as juniorIdentities, d as juniorDestinations, l as juniorUsers, o as conversationReadColumns, s as juniorConversations } from "./agent-invocations-BY60iNw-.js";
6
- import { _ as juniorConversationAnnotations, d as juniorConversationBindings, h as juniorConversationEvents, m as juniorConversationMetrics, p as CONVERSATION_METRICS, t as createJuniorSqlExecutor, u as juniorConversationParticipants } from "./executor-BroK9oKy.js";
7
- import { c as newConversationEventSchema, h as usageSchema, l as encodeHistoryPayload, o as decodeStoredConversationEvent, r as conversationEventDataSchema, s as historyReplacementSchema } from "./history-9pO1Zd4Y.js";
1
+ import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
2
+ import { I as GOOGLE_IDENTITY_PROVIDER, R as normalizeIdentityEmail } from "./logging-DsHONhVm.js";
3
+ import { i as getChatConfig } from "./config-_WO_AjCB.js";
4
+ import { d as parseSlackTeamId, o as parseActorUserId, u as parseSlackChannelReferenceId } from "./actor-tlxzqaRe.js";
5
+ import { c as juniorIdentities, d as juniorDestinations, l as juniorUsers, o as conversationReadColumns, s as juniorConversations } from "./agent-invocations-Qfz7dWgU.js";
6
+ import { _ as juniorConversationAnnotations, d as juniorConversationBindings, h as juniorConversationEvents, m as juniorConversationMetrics, p as CONVERSATION_METRICS, t as createJuniorSqlExecutor, u as juniorConversationParticipants } from "./executor-RvG6kVe1.js";
7
+ import { c as newConversationEventSchema, h as usageSchema, l as encodeHistoryPayload, o as decodeStoredConversationEvent, r as conversationEventDataSchema, s as historyReplacementSchema } from "./history-AY8rs-FR.js";
8
8
  import { randomUUID } from "node:crypto";
9
9
  import { and, asc, desc, eq, gt, gte, inArray, isNull, lt, lte, ne, or, sql } from "drizzle-orm";
10
10
  import { destinationSchema, identitySchema, locationSchema, sourceSchema, userSchema } from "@sentry/junior-plugin-api";
11
- //#region src/chat/destination.ts
11
+ // src/chat/destination.ts
12
12
  /** Build Junior's canonical destination from Slack workspace and channel ids. */
13
13
  function createSlackDestination(input) {
14
14
  const channelId = parseSlackChannelReferenceId(input.channelId);
@@ -37,8 +37,7 @@ function sameDestination(left, right) {
37
37
  if (left.platform === "slack" && right.platform === "slack") return left.teamId === right.teamId && left.channelId === right.channelId;
38
38
  return false;
39
39
  }
40
- //#endregion
41
- //#region src/chat/identities/sql.ts
40
+ // src/chat/identities/sql.ts
42
41
  function dateFromMs$1(ms) {
43
42
  return new Date(ms);
44
43
  }
@@ -153,14 +152,47 @@ async function upsertIdentity(executor, identity, nowMs = Date.now()) {
153
152
  async function upsertLinkedIdentity(executor, userId, identity, nowMs = Date.now()) {
154
153
  return await upsertIdentityRecord(executor, identity, userId, nowMs);
155
154
  }
155
+ /**
156
+ * Find the one user whose primary email is in a provider-verified email list.
157
+ * Return undefined when no user or more than one user matches.
158
+ */
159
+ async function findUserByVerifiedEmails(executor, emails) {
160
+ const normalized = new Set(emails.map((email) => normalizeIdentityEmail(email) ?? ""));
161
+ normalized.delete("");
162
+ if (normalized.size === 0) return void 0;
163
+ const rows = await executor.db().select({
164
+ email: juniorUsers.primaryEmail,
165
+ userId: juniorUsers.id
166
+ }).from(juniorUsers).where(inArray(juniorUsers.primaryEmailNormalized, Array.from(normalized))).limit(2);
167
+ return rows.length === 1 ? rows[0] : void 0;
168
+ }
156
169
  /** Remove one exact provider identity owned by a workspace Slack user. */
157
170
  async function deleteProviderIdentityForSlackUser(executor, slackTeamId, slackUserId, provider, providerSubjectId) {
158
171
  const userId = (await executor.db().select({ userId: juniorIdentities.userId }).from(juniorIdentities).where(and(eq(juniorIdentities.kind, "user"), eq(juniorIdentities.provider, "slack"), eq(juniorIdentities.providerTenantId, slackTeamId), eq(juniorIdentities.providerSubjectId, slackUserId))).limit(1))[0]?.userId;
159
172
  if (!userId) return;
173
+ await deleteProviderIdentityForUser(executor, userId, provider, providerSubjectId);
174
+ }
175
+ /** Remove one exact provider identity owned by a user. */
176
+ async function deleteProviderIdentityForUser(executor, userId, provider, providerSubjectId) {
160
177
  await executor.db().delete(juniorIdentities).where(and(eq(juniorIdentities.userId, userId), eq(juniorIdentities.provider, provider), eq(juniorIdentities.providerTenantId, ""), eq(juniorIdentities.providerSubjectId, providerSubjectId)));
161
178
  }
162
- //#endregion
163
- //#region src/chat/conversations/sql/participants.ts
179
+ /**
180
+ * Save one Google sign-in. Link the Google identity to the user of its
181
+ * verified email, and set its sign-in time.
182
+ */
183
+ async function recordGoogleSignIn(executor, account, nowMs = Date.now()) {
184
+ const stored = await upsertIdentity(executor, {
185
+ kind: "user",
186
+ provider: GOOGLE_IDENTITY_PROVIDER,
187
+ providerSubjectId: account.subject,
188
+ email: account.email,
189
+ emailVerified: true,
190
+ displayName: account.displayName
191
+ }, nowMs);
192
+ await executor.db().update(juniorIdentities).set({ signedInAt: dateFromMs$1(nowMs) }).where(eq(juniorIdentities.id, stored.id));
193
+ return stored;
194
+ }
195
+ // src/chat/conversations/sql/participants.ts
164
196
  /** Resolve the root conversation id that owns personal-feed membership. */
165
197
  async function resolveRootConversationId(executor, conversationId) {
166
198
  const [row] = await executor.db().select({ rootConversationId: juniorConversations.rootConversationId }).from(juniorConversations).where(eq(juniorConversations.conversationId, conversationId)).limit(1);
@@ -190,8 +222,7 @@ async function recordConversationParticipant(executor, args) {
190
222
  }
191
223
  });
192
224
  }
193
- //#endregion
194
- //#region src/chat/usage.ts
225
+ // src/chat/usage.ts
195
226
  const agentTurnUsageSchema = usageSchema;
196
227
  const COMPONENT_USAGE_FIELDS = [
197
228
  "inputTokens",
@@ -290,8 +321,7 @@ function addAgentTurnUsage(...usages) {
290
321
  };
291
322
  return hasAgentTurnUsage(result) ? result : void 0;
292
323
  }
293
- //#endregion
294
- //#region src/chat/conversations/metrics.ts
324
+ // src/chat/conversations/metrics.ts
295
325
  function finite(value) {
296
326
  return value !== void 0 && Number.isFinite(value) && value >= 0 ? value : void 0;
297
327
  }
@@ -374,8 +404,7 @@ async function replaceConversationMetrics(executor, args) {
374
404
  end`
375
405
  }).where(eq(juniorConversations.conversationId, args.conversationId));
376
406
  }
377
- //#endregion
378
- //#region src/chat/source.ts
407
+ // src/chat/source.ts
379
408
  /**
380
409
  * Normalize a Turn Source into legacy provider fields stored on a Conversation.
381
410
  * System Sources do not contain a Conversation Location.
@@ -407,8 +436,7 @@ function parseSessionSource(value) {
407
436
  const parsed = sourceSchema.safeParse(value);
408
437
  return parsed.success ? normalizeSessionSource(parsed.data) : void 0;
409
438
  }
410
- //#endregion
411
- //#region src/chat/conversations/sql/bindings.ts
439
+ // src/chat/conversations/sql/bindings.ts
412
440
  /** Resolve the durable conversation bound to provider-owned coordinates. */
413
441
  async function getConversationIdByProviderConversation(executor, args) {
414
442
  return (await executor.db().select({ conversationId: juniorConversationBindings.conversationId }).from(juniorConversationBindings).where(and(eq(juniorConversationBindings.provider, args.provider), eq(juniorConversationBindings.providerTenantId, args.providerTenantId), eq(juniorConversationBindings.providerDestinationId, args.providerDestinationId), eq(juniorConversationBindings.providerConversationId, args.providerConversationId))).limit(1))[0]?.conversationId;
@@ -420,8 +448,7 @@ async function bindProviderConversation(executor, args) {
420
448
  createdAt: /* @__PURE__ */ new Date()
421
449
  }).onConflictDoNothing().returning({ conversationId: juniorConversationBindings.conversationId }))[0]?.conversationId ?? await getConversationIdByProviderConversation(executor, args)) !== args.conversationId) throw new Error("Provider conversation is already bound to another conversation");
422
450
  }
423
- //#endregion
424
- //#region src/chat/conversations/sql/actor-identity.ts
451
+ // src/chat/conversations/sql/actor-identity.ts
425
452
  /** Build a durable identity observation from a stored conversation actor. */
426
453
  function identityFromActor(actor) {
427
454
  if (actor?.slackUserId) return {
@@ -510,8 +537,7 @@ function mergeActor(current, next) {
510
537
  ...current.teamId ?? next.teamId ? { teamId: current.teamId ?? next.teamId } : void 0
511
538
  };
512
539
  }
513
- //#endregion
514
- //#region src/chat/conversations/sql/location.ts
540
+ // src/chat/conversations/sql/location.ts
515
541
  /** Build the complete Location for one Conversation SQL write. */
516
542
  function locationForWrite(args) {
517
543
  const location = args.location ? locationSchema.parse(args.location) : void 0;
@@ -567,8 +593,7 @@ async function startLocationThread(executor, binding) {
567
593
  const location = juniorConversations.location;
568
594
  await executor.db().update(juniorConversations).set({ location: sql`${location} || jsonb_build_object('threadTs', ${binding.providerConversationId}::text)` }).where(and(eq(juniorConversations.conversationId, binding.conversationId), sql`${location}->>'provider' = ${binding.provider}`, sql`${location}->>'teamId' = ${binding.providerTenantId}`, sql`${location}->>'channelId' = ${binding.providerDestinationId}`, isNull(sql`${location}->>'threadTs'`)));
569
595
  }
570
- //#endregion
571
- //#region src/chat/conversations/sql/store.ts
596
+ // src/chat/conversations/sql/store.ts
572
597
  const CONVERSATION_MUTATION_LOCK_PREFIX = "junior_conversation";
573
598
  /** Serialize one conversation's durable mutations inside a SQL transaction. */
574
599
  async function withConversationMutationLock(executor, conversationId, callback) {
@@ -988,8 +1013,7 @@ var SqlStore = class {
988
1013
  function createSqlStore(executor) {
989
1014
  return new SqlStore(executor);
990
1015
  }
991
- //#endregion
992
- //#region src/chat/conversations/sql/conversation-row.ts
1016
+ // src/chat/conversations/sql/conversation-row.ts
993
1017
  /**
994
1018
  * Establish the conversation metadata row on first contact for content writes
995
1019
  * (conversation events, visible transcript) that can land before activity has
@@ -1025,8 +1049,7 @@ async function ensureConversationRow(executor, conversationId, atMs, options = {
1025
1049
  }
1026
1050
  });
1027
1051
  }
1028
- //#endregion
1029
- //#region src/chat/conversations/sql/event-actor.ts
1052
+ // src/chat/conversations/sql/event-actor.ts
1030
1053
  const SLACK_USER_ID_PATTERN = /^[UW][A-Z0-9]{5,}$/;
1031
1054
  function isRecord(value) {
1032
1055
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
@@ -1042,6 +1065,7 @@ function readAuthor(meta) {
1042
1065
  ...typeof author.userName === "string" ? { userName: author.userName } : void 0
1043
1066
  };
1044
1067
  }
1068
+ /** Read the Slack workspace that owns a conversation, when it has one. */
1045
1069
  async function loadConversationSlackTenantId(executor, conversationId) {
1046
1070
  const [row] = await executor.db().select({
1047
1071
  providerTenantId: juniorDestinations.providerTenantId,
@@ -1125,8 +1149,7 @@ function stripPayloadAuthorIdentityId(data) {
1125
1149
  const { authorIdentityId: _authorIdentityId, ...rest } = data;
1126
1150
  return rest;
1127
1151
  }
1128
- //#endregion
1129
- //#region src/db/postgres-json.ts
1152
+ // src/db/postgres-json.ts
1130
1153
  /**
1131
1154
  * Replace actual NUL characters that PostgreSQL cannot store in JSONB.
1132
1155
  * Literal `\\u0000` text is preserved because it contains no NUL character.
@@ -1139,14 +1162,12 @@ function sanitizePostgresJson(value) {
1139
1162
  if (prototype !== Object.prototype && prototype !== null) return value;
1140
1163
  return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, sanitizePostgresJson(item)]));
1141
1164
  }
1142
- //#endregion
1143
- //#region src/chat/conversations/sql/event-lock.ts
1165
+ // src/chat/conversations/sql/event-lock.ts
1144
1166
  /** Serialize event sequence allocation with other conversation writes. */
1145
1167
  async function withConversationEventLock(executor, conversationId, callback) {
1146
1168
  return executor.withLock(`junior_conversation:${conversationId}`, callback);
1147
1169
  }
1148
- //#endregion
1149
- //#region src/chat/conversations/sql/history.ts
1170
+ // src/chat/conversations/sql/history.ts
1150
1171
  const messageHistoryEventTypes = [
1151
1172
  "message",
1152
1173
  "message_updated",
@@ -1375,8 +1396,7 @@ var SqlConversationEventStore = class {
1375
1396
  function createSqlConversationEventStore(executor) {
1376
1397
  return new SqlConversationEventStore(executor);
1377
1398
  }
1378
- //#endregion
1379
- //#region src/chat/conversations/sql/message-search.ts
1399
+ // src/chat/conversations/sql/message-search.ts
1380
1400
  const EXCERPT_WITHOUT_QUERY_CHARS = 240;
1381
1401
  var SqlConversationMessageSearchStore = class {
1382
1402
  executor;
@@ -1448,8 +1468,7 @@ var SqlConversationMessageSearchStore = class {
1448
1468
  function createSqlConversationMessageSearchStore(executor) {
1449
1469
  return new SqlConversationMessageSearchStore(executor);
1450
1470
  }
1451
- //#endregion
1452
- //#region src/chat/db.ts
1471
+ // src/chat/db.ts
1453
1472
  var db_exports = /* @__PURE__ */ __exportAll({
1454
1473
  closeDb: () => closeDb,
1455
1474
  getConversationEventStore: () => getConversationEventStore,
@@ -1517,8 +1536,7 @@ async function closeDb() {
1517
1536
  current = void 0;
1518
1537
  await previous?.db.close();
1519
1538
  }
1520
- //#endregion
1521
- //#region src/chat/plugins/viewer.ts
1539
+ // src/chat/plugins/viewer.ts
1522
1540
  function identityFromRow(row) {
1523
1541
  return identitySchema.parse({
1524
1542
  id: row.id,
@@ -1619,5 +1637,4 @@ async function readActorIdentityFromSql(db, actor) {
1619
1637
  async function readActorIdentity(actor) {
1620
1638
  return await readActorIdentityFromSql(getDb(), actor);
1621
1639
  }
1622
- //#endregion
1623
- export { upsertIdentity as A, agentTurnTotalTokens as C, deleteProviderIdentityForSlackUser as D, resolveRootConversationId as E, sameDestination as F, createSlackDestination as M, parseDestination as N, readUserTimezone as O, requireSlackDestination as P, agentTurnCostUsd as S, hasAgentTurnUsage as T, locationFromRow as _, setUserAdminFromSql as a, parseSessionSource as b, getConversationEventStore as c, getDb as d, getSqlExecutor as f, withConversationMutationLock as g, createSqlStore as h, resolveViewerUser as i, upsertLinkedIdentity as j, saveUserTimezone as k, getConversationMessageSearchStore as l, withConversationEventLock as m, listAdminUsersFromSql as n, updateViewerDisplayName as o, createSqlConversationEventStore as p, readActorIdentity as r, db_exports as s, findUserByEmail as t, getConversationStore as u, startLocationThread as v, agentTurnUsageSchema as w, addAgentTurnUsage as x, bindProviderConversation as y };
1640
+ export { deleteProviderIdentityForUser as A, sameDestination as B, addAgentTurnUsage as C, hasAgentTurnUsage as D, agentTurnUsageSchema as E, upsertIdentity as F, upsertLinkedIdentity as I, createSlackDestination as L, readUserTimezone as M, recordGoogleSignIn as N, resolveRootConversationId as O, saveUserTimezone as P, parseDestination as R, parseSessionSource as S, agentTurnTotalTokens as T, withConversationMutationLock as _, setUserAdminFromSql as a, identityFromActor as b, getConversationEventStore as c, getDb as d, getSqlExecutor as f, createSqlStore as g, loadConversationSlackTenantId as h, resolveViewerUser as i, findUserByVerifiedEmails as j, deleteProviderIdentityForSlackUser as k, getConversationMessageSearchStore as l, withConversationEventLock as m, listAdminUsersFromSql as n, updateViewerDisplayName as o, createSqlConversationEventStore as p, readActorIdentity as r, db_exports as s, findUserByEmail as t, getConversationStore as u, locationFromRow as v, agentTurnCostUsd as w, bindProviderConversation as x, startLocationThread as y, requireSlackDestination as z };