@sentry/junior 0.235.0 → 0.237.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 (73) hide show
  1. package/dist/{agent-hooks-DS7k0ZWY.js → agent-hooks-otHGbhBx.js} +20 -9
  2. package/dist/{agent-runner-BlDI1zV2.js → agent-runner-DMAsnPb9.js} +456 -120
  3. package/dist/api/schema.d.ts +223 -2
  4. package/dist/api/schema.js +5 -4
  5. package/dist/api.d.ts +8 -2
  6. package/dist/api.js +404 -47
  7. package/dist/{app-pGsR__aT.d.ts → app-MEd7wbF0.d.ts} +82 -48
  8. package/dist/app.d.ts +3 -3
  9. package/dist/app.js +162 -119
  10. package/dist/{types-Du-HbEun.js → automation-CrQGQ2MT.js} +306 -34
  11. package/dist/{briefs-C3jhszOz.js → briefs-DDA1ugXk.js} +4 -4
  12. package/dist/{catalog-runtime-B9u_3-GW.js → catalog-runtime-DlXuhrmk.js} +1 -1
  13. package/dist/{checkpoint-DLcJ5mKL.js → checkpoint-BlIIiHG5.js} +16 -9
  14. package/dist/cli/chat.d.ts +1 -1
  15. package/dist/cli/chat.js +14 -14
  16. package/dist/cli/check.js +4 -4
  17. package/dist/cli/main.js +1 -1
  18. package/dist/cli/plugins.d.ts +1 -1
  19. package/dist/cli/plugins.js +4 -4
  20. package/dist/cli/snapshot-create.js +3 -3
  21. package/dist/cli/upgrade.d.ts +1 -1
  22. package/dist/cli/upgrade.js +5 -5
  23. package/dist/{client-BSnNHO0R.js → client-CPMbTmJU.js} +2 -2
  24. package/dist/{config-Bmw4xTPK.js → config-CxpPG6nR.js} +57 -17
  25. package/dist/{conversation-C_aYrISI.js → conversation-9Fxa1Zbq.js} +13 -1
  26. package/dist/{conversation-privacy-BV2dtba2.js → conversation-privacy-Dbkdvozu.js} +1 -1
  27. package/dist/{credential-sync-CukzQJ1x.js → credential-sync-D9yGg3q5.js} +14 -14
  28. package/dist/{executor-B9ksWZCv.js → executor-BNxfDS1V.js} +39 -6
  29. package/dist/{images-CEXcQ0Id.js → images-D6Y3FJDQ.js} +3 -3
  30. package/dist/instrumentation.js +2 -2
  31. package/dist/{job-queue-CY1L2YRn.js → job-queue-Dq5_zt_l.js} +1 -1
  32. package/dist/{logging-F--48Q7Q.js → logging-rB_ngE_R.js} +1 -1
  33. package/dist/nitro.d.ts +2 -2
  34. package/dist/nitro.js +5 -5
  35. package/dist/{oauth-authorization-LasSG3Qc.js → oauth-authorization-5T1S1v_1.js} +1 -1
  36. package/dist/{oauth-callback-server-D07ZzVMs.js → oauth-callback-server-Csw7RssK.js} +2 -2
  37. package/dist/{pending-auth-DrG9Mkje.js → pending-auth-moCA2mTc.js} +1 -1
  38. package/dist/{plugins-BT2l4We3.d.ts → plugins-CjfUP5gJ.d.ts} +1 -0
  39. package/dist/{profile-DZ2DUdd1.js → profile-D6apIG2N.js} +4 -4
  40. package/dist/{prompt-BM_5mAU3.js → prompt-Ctwy6hSI.js} +1 -1
  41. package/dist/queue-B5SnqRln.d.ts +25 -0
  42. package/dist/{registry-_JLY0x7b.js → registry-zfTzTHe6.js} +38 -2
  43. package/dist/{resolve-Cuoj3MML.js → resolve-sJtTzuBO.js} +2 -2
  44. package/dist/{runner-BfelmbMv.js → runner-DkCk8cbc.js} +9 -9
  45. package/dist/{sandbox-egress-signals-D5QUIO7Z.js → sandbox-egress-signals-tSQ8OEcw.js} +1 -1
  46. package/dist/{schema-CrdDxGbx.js → schema-C5bgOpRg.js} +3 -2
  47. package/dist/{skills-DAegjk5Y.js → skills-BVpr_Gnv.js} +3 -3
  48. package/dist/{spawn-DCfV7zGK.js → spawn-CJhmyE4E.js} +2 -2
  49. package/dist/{task-queue-GcuFtzor.js → task-queue-BAiZ7_CF.js} +16 -10
  50. package/dist/{task-runner-B0-P_3aq.js → task-runner-Bh8XONXT.js} +9 -9
  51. package/dist/{thread-state-TezcEhuH.js → thread-state-BnQln4jO.js} +5 -5
  52. package/dist/{turn-failure-response-Drhj_-t4.js → turn-failure-response-Ba7_kItn.js} +8 -8
  53. package/dist/{turn-lifecycle-BpIW3zOx.js → turn-lifecycle-D6CTbkb9.js} +1 -1
  54. package/dist/{turn-session-routing-Dg8GDgyc.js → turn-session-routing-DNevs9H7.js} +1 -1
  55. package/dist/{validation-DAkYeKDT.js → validation-BNPhuAvt.js} +2 -3
  56. package/dist/{version-9CB4Z-J4.js → version-EQ4MWuUJ.js} +1 -1
  57. package/dist/version.js +1 -1
  58. package/dist/{web-authorization-Cu33voNg.js → web-authorization-DDt4FZld.js} +6 -6
  59. package/dist/{web-input-B3k0J7WB.js → web-input-C56ivZuH.js} +86 -102
  60. package/dist/web-message-id-xPI_EFSC.js +239 -0
  61. package/dist/{work-PmkvcY9l.js → work-DJ7hb9Ul.js} +7 -7
  62. package/dist/{worker-COcaq2J6.js → worker-DiiV8Lba.js} +5 -5
  63. package/migrations/0045_conversation_forks.sql +3 -0
  64. package/migrations/0046_automation_versions.sql +71 -0
  65. package/migrations/0047_user_timezone.sql +1 -0
  66. package/migrations/meta/0045_snapshot.json +3503 -0
  67. package/migrations/meta/0046_snapshot.json +3707 -0
  68. package/migrations/meta/0047_snapshot.json +3713 -0
  69. package/migrations/meta/_journal.json +22 -1
  70. package/package.json +4 -4
  71. package/dist/web-message-id-CVVCTWUb.js +0 -464
  72. package/dist/{package-discovery-7a9YqLhE.js → package-discovery-BVvSnQBB.js} +1 -1
  73. package/dist/{plugin-module-BKGOXca2.js → plugin-module-CVvEUSMH.js} +1 -1
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.js";
2
- import { S as toOptionalTrimmed, o as resolveGatewayModel } from "./client-BSnNHO0R.js";
3
- import { p as logWarn } from "./logging-F--48Q7Q.js";
2
+ import { S as toOptionalTrimmed, o as resolveGatewayModel } from "./client-CPMbTmJU.js";
3
+ import { p as logWarn } from "./logging-rB_ngE_R.js";
4
4
  import { l as TURN_REASONING_LEVELS, s as modelProfileSchema, t as DEFAULT_MODEL_PROFILES, u as parseTurnReasoningLevel } from "./model-profile-BwU8mqwD.js";
5
5
  //#region src/chat/slack/emoji.ts
6
6
  const SLACK_EMOJI_NAME_RE = /^(?:[a-z0-9_+-]+)(?:::(?:skin-tone-[2-6]))?$/;
@@ -17,18 +17,21 @@ var config_exports = /* @__PURE__ */ __exportAll({
17
17
  DEFAULT_SQL_STATEMENT_TIMEOUT_MS: () => DEFAULT_SQL_STATEMENT_TIMEOUT_MS,
18
18
  FUNCTION_TIMEOUT_BUFFER_SECONDS: () => 20,
19
19
  botConfig: () => botConfig,
20
- configureFunctionMaxDurationSeconds: () => configureFunctionMaxDurationSeconds,
21
20
  getChatConfig: () => getChatConfig,
22
21
  getRuntimeMetadata: () => getRuntimeMetadata,
23
22
  getSlackBotToken: () => getSlackBotToken,
24
23
  getSlackClientId: () => getSlackClientId,
25
24
  getSlackClientSecret: () => getSlackClientSecret,
26
- getSlackReactionConfig: () => getSlackReactionConfig,
27
25
  getSlackSigningSecret: () => getSlackSigningSecret,
28
26
  readChatConfig: () => readChatConfig,
27
+ resetRuntimeConfig: () => resetRuntimeConfig,
28
+ restoreRuntimeConfig: () => restoreRuntimeConfig,
29
29
  setBotModelConfig: () => setBotModelConfig,
30
+ setCrossActorMidRunMode: () => setCrossActorMidRunMode,
30
31
  setProfiles: () => setProfiles,
31
- setSlackReactionConfig: () => setSlackReactionConfig
32
+ setRuntimeLimits: () => setRuntimeLimits,
33
+ setSlackReactionConfig: () => setSlackReactionConfig,
34
+ snapshotRuntimeConfig: () => snapshotRuntimeConfig
32
35
  });
33
36
  const MIN_AGENT_TURN_TIMEOUT_MS = 1e4;
34
37
  const DEFAULT_AGENT_TURN_TIMEOUT_MS = 72e4;
@@ -231,7 +234,6 @@ function warnDeprecatedProfileEnv(env) {
231
234
  });
232
235
  }
233
236
  function readBotConfig(env, functionMaxDurationSeconds) {
234
- warnDeprecatedProfileEnv(env);
235
237
  const maxTurnTimeoutMs = resolveMaxTurnTimeoutMs(functionMaxDurationSeconds);
236
238
  const modelId = validateGatewayModelId(env.AI_MODEL) ?? DEFAULT_MODEL_ID;
237
239
  const reasoningLevel = toOptionalTrimmed(env.AI_REASONING_LEVEL);
@@ -290,6 +292,7 @@ function readSqlStatementTimeoutMs(env) {
290
292
  /** Parse all chat configuration from environment variables. */
291
293
  function readChatConfig(env = process.env, functionMaxDurationSeconds = DEFAULT_FUNCTION_MAX_DURATION_SECONDS) {
292
294
  const databaseUrl = readDatabaseUrl(env);
295
+ warnDeprecatedProfileEnv(env);
293
296
  const resolvedFunctionMaxDurationSeconds = resolveFunctionMaxDurationSeconds(functionMaxDurationSeconds);
294
297
  return {
295
298
  bot: readBotConfig(env, resolvedFunctionMaxDurationSeconds),
@@ -319,12 +322,56 @@ function readChatConfig(env = process.env, functionMaxDurationSeconds = DEFAULT_
319
322
  }
320
323
  /** Chat configuration parsed once at module load from the process environment. */
321
324
  const chatConfig = readChatConfig(process.env);
322
- /** Apply the host execution budget injected by juniorNitro(). */
323
- function configureFunctionMaxDurationSeconds(functionMaxDurationSeconds) {
325
+ /** Copy the runtime config so a failed app setup can restore it. */
326
+ function snapshotRuntimeConfig() {
327
+ return {
328
+ bot: { ...chatConfig.bot },
329
+ completedReactionEmoji: chatConfig.slack.completedReactionEmoji,
330
+ conversationWorkSoftYieldAfterMs: chatConfig.conversationWorkSoftYieldAfterMs,
331
+ functionMaxDurationSeconds: chatConfig.functionMaxDurationSeconds,
332
+ processingReactionEmoji: chatConfig.slack.processingReactionEmoji
333
+ };
334
+ }
335
+ /** Replace the runtime config with a snapshot. */
336
+ function restoreRuntimeConfig(snapshot) {
337
+ replaceBotConfig(snapshot.bot);
338
+ chatConfig.functionMaxDurationSeconds = snapshot.functionMaxDurationSeconds;
339
+ chatConfig.conversationWorkSoftYieldAfterMs = snapshot.conversationWorkSoftYieldAfterMs;
340
+ chatConfig.slack.completedReactionEmoji = snapshot.completedReactionEmoji;
341
+ chatConfig.slack.processingReactionEmoji = snapshot.processingReactionEmoji;
342
+ }
343
+ /**
344
+ * Reset bot, limit, and Slack settings to the environment defaults and apply
345
+ * the host execution budget. Each app calls this before it applies options.
346
+ */
347
+ function resetRuntimeConfig(functionMaxDurationSeconds) {
324
348
  const resolved = resolveFunctionMaxDurationSeconds(functionMaxDurationSeconds);
325
349
  chatConfig.functionMaxDurationSeconds = resolved;
326
350
  chatConfig.conversationWorkSoftYieldAfterMs = resolveConversationWorkSoftYieldAfterMs(resolved);
327
- chatConfig.bot.turnTimeoutMs = parseAgentTurnTimeoutMs(process.env.AGENT_TURN_TIMEOUT_MS, resolveMaxTurnTimeoutMs(resolved));
351
+ replaceBotConfig(readBotConfig(process.env, resolved));
352
+ chatConfig.slack.completedReactionEmoji = DEFAULT_COMPLETED_REACTION_EMOJI;
353
+ chatConfig.slack.processingReactionEmoji = DEFAULT_PROCESSING_REACTION_EMOJI;
354
+ }
355
+ function replaceBotConfig(next) {
356
+ for (const key of Object.keys(chatConfig.bot)) delete chatConfig.bot[key];
357
+ Object.assign(chatConfig.bot, next);
358
+ }
359
+ function requirePositiveLimit(name, value) {
360
+ if (!Number.isSafeInteger(value) || value <= 0) throw new Error(`limits.${name} must be a positive integer`);
361
+ return value;
362
+ }
363
+ /** Apply limits from createApp(). Unset limits keep their defaults. */
364
+ function setRuntimeLimits(limits) {
365
+ const bot = chatConfig.bot;
366
+ if (limits?.contextWindowTokens !== void 0) bot.contextWindowTokens = requirePositiveLimit("contextWindowTokens", limits.contextWindowTokens);
367
+ if (limits?.maxConsecutiveAutomatedTurns !== void 0) bot.maxConsecutiveAutomatedTurns = requirePositiveLimit("maxConsecutiveAutomatedTurns", limits.maxConsecutiveAutomatedTurns);
368
+ if (limits?.maxSlicesPerTurn !== void 0) bot.maxSlicesPerTurn = requirePositiveLimit("maxSlicesPerTurn", limits.maxSlicesPerTurn);
369
+ if (limits?.maxToolCallsPerTurn !== void 0) bot.maxToolCallsPerTurn = requirePositiveLimit("maxToolCallsPerTurn", limits.maxToolCallsPerTurn);
370
+ if (limits?.turnTimeoutMs !== void 0) bot.turnTimeoutMs = Math.min(requirePositiveLimit("turnTimeoutMs", limits.turnTimeoutMs), resolveMaxTurnTimeoutMs(chatConfig.functionMaxDurationSeconds));
371
+ }
372
+ /** Apply the Slack cross-actor steering mode from createApp(). */
373
+ function setCrossActorMidRunMode(mode) {
374
+ chatConfig.bot.crossActorMidRunMode = parseCrossActorMidRunMode(mode);
328
375
  }
329
376
  /** Return the chat configuration (parsed once at startup). */
330
377
  function getChatConfig() {
@@ -367,17 +414,10 @@ function setProfiles(profiles, defaultProfile) {
367
414
  botConfig.profiles = configuredProfiles;
368
415
  botConfig.defaultProfile = selectedDefault;
369
416
  }
370
- /** Return the current Slack reaction emoji config. */
371
- function getSlackReactionConfig() {
372
- return {
373
- completedReactionEmoji: chatConfig.slack.completedReactionEmoji,
374
- processingReactionEmoji: chatConfig.slack.processingReactionEmoji
375
- };
376
- }
377
417
  /** Apply Slack reaction emoji overrides from createApp() options, validating names. */
378
418
  function setSlackReactionConfig(overrides) {
379
419
  if (overrides.processingReactionEmoji !== void 0) chatConfig.slack.processingReactionEmoji = parseReactionEmoji("processingReactionEmoji", overrides.processingReactionEmoji, chatConfig.slack.processingReactionEmoji);
380
420
  if (overrides.completedReactionEmoji !== void 0) chatConfig.slack.completedReactionEmoji = parseReactionEmoji("completedReactionEmoji", overrides.completedReactionEmoji, chatConfig.slack.completedReactionEmoji);
381
421
  }
382
422
  //#endregion
383
- export { getChatConfig as a, getSlackClientId as c, getSlackSigningSecret as d, setBotModelConfig as f, normalizeSlackEmojiName as h, configureFunctionMaxDurationSeconds as i, getSlackClientSecret as l, setSlackReactionConfig as m, botConfig as n, getRuntimeMetadata as o, setProfiles as p, config_exports as r, getSlackBotToken as s, DEFAULT_SQL_STATEMENT_TIMEOUT_MS as t, getSlackReactionConfig as u };
423
+ export { snapshotRuntimeConfig as _, getRuntimeMetadata as a, getSlackClientSecret as c, restoreRuntimeConfig as d, setBotModelConfig as f, setSlackReactionConfig as g, setRuntimeLimits as h, getChatConfig as i, getSlackSigningSecret as l, setProfiles as m, botConfig as n, getSlackBotToken as o, setCrossActorMidRunMode as p, config_exports as r, getSlackClientId as s, DEFAULT_SQL_STATEMENT_TIMEOUT_MS as t, resetRuntimeConfig as u, normalizeSlackEmojiName as v };
@@ -1270,7 +1270,19 @@ function validateConversationEvents(report, context) {
1270
1270
  });
1271
1271
  }
1272
1272
  }
1273
+ const forkConversationBodySchema = z.object({
1274
+ /** Assistant reply that ends the copied history. */
1275
+ messageId: z.string().min(1).max(500),
1276
+ idempotencyKey: z.string().trim().min(1).max(200)
1277
+ }).strict();
1278
+ const forkConversationResponseSchema = z.object({ conversationId: z.string() }).strict();
1273
1279
  const conversationDetailReportSchema = conversationSummaryReportSchema.extend({
1280
+ /** The viewer can fork this conversation from an assistant reply. */
1281
+ canFork: z.boolean().optional(),
1282
+ forkedFromConversationId: z.string().optional(),
1283
+ /** Title of the fork source, when the viewer can open it. */
1284
+ forkedFromTitle: z.string().optional(),
1285
+ forks: z.array(z.string()).optional(),
1274
1286
  brief: z.object({
1275
1287
  content: conversationBriefSchema,
1276
1288
  updatedAt: z.string().datetime(),
@@ -1356,4 +1368,4 @@ const conversationStatsReportSchema = z.object({
1356
1368
  windowStart: z.string()
1357
1369
  }).strict();
1358
1370
  //#endregion
1359
- export { encodeHistoryPayload as $, MAX_INPUT_IMAGE_BYTES as A, messageCardRef as B, conversationReportEventSchema as C, createConversationBodySchema as D, conversationSummaryReportSchema as E, briefLinkSchema as F, KNOWN_CONVERSATION_EVENT_TYPES as G, readMessageCardRefs as H, briefOutcomeStatusSchema as I, conversationTurnFailureCodeSchema as J, agentHistoryItemSchema as K, conversationBriefSchema as L, INPUT_IMAGE_TYPES as M, isVisionImageMediaType as N, createConversationMessageBodySchema as O, briefCodeChangeSchema as P, newConversationEventSchema as Q, parseBriefInput as R, conversationReportEventDataSchema as S, conversationStatsReportSchema as T, removedCardSchema as U, messageCardText as V, resolveMessageCards as W, decodeStoredConversationEvent as X, conversationTurnFailureReasonSchema as Y, historyReplacementSchema as Z, conversationParamsSchema as _, cancelConversationPendingMessagesBodySchema as a, conversationPendingMessageSchema as b, conversationAttachmentParamsSchema as c, conversationDetailReportSchema as d, contextProvenance as et, conversationEventHistorySchema as f, conversationFeedSchema as g, conversationFeedQuerySchema as h, archiveConversationResponseSchema as i, usageSchema as it, readMessageAttachments as j, MAX_INPUT_IMAGES as k, conversationAuxiliaryCostsSchema as l, conversationEventsQuerySchema as m, actorIdentitySchema as n, instructionProvenanceFor as nt, cancelConversationPendingMessagesResponseSchema as o, conversationEventPageSchema as p, conversationEventDataSchema as q, archiveConversationBodySchema as r, sameActorIdentity as rt, conversationActivityPreviewSchema as s, acceptedConversationMessageSchema as t, instructionActors as tt, conversationDetailQuerySchema as u, conversationPendingAuthorizationSchema as v, conversationStatsItemSchema as w, conversationPendingMessagesReportSchema as x, conversationPendingMessageDeliverySchema as y, annotationCard as z };
1371
+ export { historyReplacementSchema as $, forkConversationResponseSchema as A, parseBriefInput as B, conversationReportEventSchema as C, createConversationBodySchema as D, conversationSummaryReportSchema as E, isVisionImageMediaType as F, removedCardSchema as G, messageCardRef as H, briefCodeChangeSchema as I, agentHistoryItemSchema as J, resolveMessageCards as K, briefLinkSchema as L, MAX_INPUT_IMAGE_BYTES as M, readMessageAttachments as N, createConversationMessageBodySchema as O, INPUT_IMAGE_TYPES as P, decodeStoredConversationEvent as Q, briefOutcomeStatusSchema as R, conversationReportEventDataSchema as S, conversationStatsReportSchema as T, messageCardText as U, annotationCard as V, readMessageCardRefs as W, conversationTurnFailureCodeSchema as X, conversationEventDataSchema as Y, conversationTurnFailureReasonSchema as Z, conversationParamsSchema as _, cancelConversationPendingMessagesBodySchema as a, sameActorIdentity as at, conversationPendingMessageSchema as b, conversationAttachmentParamsSchema as c, conversationDetailReportSchema as d, newConversationEventSchema as et, conversationEventHistorySchema as f, conversationFeedSchema as g, conversationFeedQuerySchema as h, archiveConversationResponseSchema as i, instructionProvenanceFor as it, MAX_INPUT_IMAGES as j, forkConversationBodySchema as k, conversationAuxiliaryCostsSchema as l, conversationEventsQuerySchema as m, actorIdentitySchema as n, contextProvenance as nt, cancelConversationPendingMessagesResponseSchema as o, usageSchema as ot, conversationEventPageSchema as p, KNOWN_CONVERSATION_EVENT_TYPES as q, archiveConversationBodySchema as r, instructionActors as rt, conversationActivityPreviewSchema as s, acceptedConversationMessageSchema as t, encodeHistoryPayload as tt, conversationDetailQuerySchema as u, conversationPendingAuthorizationSchema as v, conversationStatsItemSchema as w, conversationPendingMessagesReportSchema as x, conversationPendingMessageDeliverySchema as y, conversationBriefSchema as z };
@@ -1,4 +1,4 @@
1
- import { p as logWarn } from "./logging-F--48Q7Q.js";
1
+ import { p as logWarn } from "./logging-rB_ngE_R.js";
2
2
  import { AsyncLocalStorage } from "node:async_hooks";
3
3
  //#region src/chat/conversation-privacy.ts
4
4
  const SAFE_METADATA_KEY_LIMIT = 20;
@@ -1,18 +1,18 @@
1
- import { Cn as postSlackMessage, Dn as createUserTokenStore, T as lookupSlackUserProfile, _ as resolvePluginOAuthAccount, d as getMcpAuthSession, f as getMcpStoredOAuthCredentials, hn as resolveBaseUrl, ht as getMcpProviderErrorAttributes, mn as parseOAuthStatePayload, o as finalizeMcpAuthorization, p as putMcpStoredOAuthCredentials, pn as formatProviderLabel, s as deleteMcpAuthSession } from "./agent-runner-BlDI1zV2.js";
2
- import { f as escapeXml } from "./client-BSnNHO0R.js";
3
- import { d as logException, h as runBestEffort, p as logWarn } from "./logging-F--48Q7Q.js";
4
- import { n as botConfig, o as getRuntimeMetadata } from "./config-Bmw4xTPK.js";
1
+ import { Fn as createUserTokenStore, Sn as resolveBaseUrl, St as getMcpProviderErrorAttributes, T as lookupSlackUserProfile, _ as resolvePluginOAuthAccount, bn as formatProviderLabel, d as getMcpAuthSession, f as getMcpStoredOAuthCredentials, jn as postSlackMessage, o as finalizeMcpAuthorization, p as putMcpStoredOAuthCredentials, s as deleteMcpAuthSession, xn as parseOAuthStatePayload } from "./agent-runner-DMAsnPb9.js";
2
+ import { f as escapeXml } from "./client-CPMbTmJU.js";
3
+ import { d as logException, h as runBestEffort, p as logWarn } from "./logging-rB_ngE_R.js";
4
+ import { a as getRuntimeMetadata, n as botConfig } from "./config-CxpPG6nR.js";
5
5
  import { g as parseSlackUserId } from "./context-0Et9iVSB.js";
6
- import { W as getSlackClient, _n as upsertLinkedIdentity, gn as upsertIdentity, nn as getSqlExecutor } from "./agent-hooks-DS7k0ZWY.js";
7
- import { i as homeDir } from "./package-discovery-7a9YqLhE.js";
8
- import { n as buildOAuthTokenRequest, r as parseOAuthTokenResponse, u as hasRequiredOAuthScope } from "./registry-_JLY0x7b.js";
9
- import { n as pluginCatalogRuntime } from "./catalog-runtime-B9u_3-GW.js";
10
- import { t as discoverSkills } from "./skills-DAegjk5Y.js";
11
- import { B as recordAuthorizationCompleted, s as getTurnRecord, z as recordAuthenticationLinked } from "./checkpoint-DLcJ5mKL.js";
12
- import { E as acquireActiveLock, w as getStateAdapter } from "./profile-DZ2DUdd1.js";
13
- import { i as getConversationPendingAuth } from "./pending-auth-DrG9Mkje.js";
14
- import { r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-TezcEhuH.js";
15
- import { n as deleteWebAuthorization, o as wakeAuthorizedTurn, s as wakePausedTurn } from "./web-authorization-Cu33voNg.js";
6
+ import { W as getSlackClient, nn as getSqlExecutor, vn as upsertIdentity, yn as upsertLinkedIdentity } from "./agent-hooks-otHGbhBx.js";
7
+ import { i as homeDir } from "./package-discovery-BVvSnQBB.js";
8
+ import { n as buildOAuthTokenRequest, r as parseOAuthTokenResponse, u as hasRequiredOAuthScope } from "./registry-zfTzTHe6.js";
9
+ import { n as pluginCatalogRuntime } from "./catalog-runtime-DlXuhrmk.js";
10
+ import { t as discoverSkills } from "./skills-BVpr_Gnv.js";
11
+ import { B as recordAuthenticationLinked, V as recordAuthorizationCompleted, s as getTurnRecord } from "./checkpoint-BlIIiHG5.js";
12
+ import { E as acquireActiveLock, w as getStateAdapter } from "./profile-D6apIG2N.js";
13
+ import { i as getConversationPendingAuth } from "./pending-auth-moCA2mTc.js";
14
+ import { r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-BnQln4jO.js";
15
+ import { n as deleteWebAuthorization, o as wakeAuthorizedTurn, s as wakePausedTurn } from "./web-authorization-DDt4FZld.js";
16
16
  import { n as relayLocalOAuthCallback } from "./oauth-relay-CdCnu80W.js";
17
17
  import path from "node:path";
18
18
  import { z } from "zod";
@@ -1,5 +1,6 @@
1
+ import { d as logException } from "./logging-rB_ngE_R.js";
1
2
  import { g as startSpanManual } from "./sentry-CgWZM_kV.js";
2
- import "./config-Bmw4xTPK.js";
3
+ import "./config-CxpPG6nR.js";
3
4
  import { n as juniorDestinations, r as timestamptz } from "./destinations-BeBiJeEM.js";
4
5
  import { AsyncLocalStorage } from "node:async_hooks";
5
6
  import { getTableColumns, sql } from "drizzle-orm";
@@ -38,6 +39,7 @@ const juniorUsers = pgTable("junior_users", {
38
39
  primaryEmail: text("primary_email").notNull(),
39
40
  primaryEmailNormalized: text("primary_email_normalized").notNull(),
40
41
  displayName: text("display_name"),
42
+ timezone: text("timezone"),
41
43
  createdAt: timestamptz("created_at").notNull(),
42
44
  updatedAt: timestamptz("updated_at").notNull()
43
45
  }, (table) => [uniqueIndex("junior_users_primary_email_normalized_uidx").on(table.primaryEmailNormalized)]);
@@ -95,6 +97,7 @@ const juniorConversations = pgTable("junior_conversations", {
95
97
  lastCheckpointAt: timestamptz("last_checkpoint_at"),
96
98
  lastEnqueuedAt: timestamptz("last_enqueued_at"),
97
99
  parentConversationId: text("parent_conversation_id").references(() => juniorConversations.conversationId),
100
+ forkedFromConversationId: text("forked_from_conversation_id").references(() => juniorConversations.conversationId, { onDelete: "set null" }),
98
101
  rootConversationId: text("root_conversation_id").references(() => juniorConversations.conversationId),
99
102
  transcriptPurgedAt: timestamptz("transcript_purged_at"),
100
103
  durationMs: integer("duration_ms").notNull().default(0),
@@ -110,6 +113,7 @@ const juniorConversations = pgTable("junior_conversations", {
110
113
  index("junior_conversations_actor_activity_idx").on(table.actorIdentityId, table.lastActivityAt.desc()),
111
114
  index("junior_conversations_origin_idx").on(table.originType, table.originId, table.lastActivityAt.desc()),
112
115
  index("junior_conversations_parent_idx").on(table.parentConversationId),
116
+ index("junior_conversations_forked_from_idx").on(table.forkedFromConversationId),
113
117
  index("junior_conversations_root_idx").on(table.rootConversationId)
114
118
  ]);
115
119
  /** Select runtime conversation fields without reading the legacy archive column. */
@@ -458,6 +462,26 @@ const juniorAutomationExecutions = pgTable("junior_task_executions", {
458
462
  index("junior_task_executions_conversation_time_idx").on(table.conversationId, table.executedAtMs)
459
463
  ]);
460
464
  //#endregion
465
+ //#region src/db/schema/automation-versions.ts
466
+ /** One saved Automation definition. Lifecycle and scheduler state are not versioned. */
467
+ const juniorAutomationVersions = pgTable("junior_automation_versions", {
468
+ kind: text("kind").$type().notNull(),
469
+ automationId: text("automation_id").notNull(),
470
+ /** Starts at 1 and increases by 1 for each saved definition change. */
471
+ version: integer("version").notNull(),
472
+ createdAtMs: bigint("created_at_ms", { mode: "number" }).notNull(),
473
+ /** Slack principal that saved this definition. Null when unknown. */
474
+ editedBy: jsonb("edited_by"),
475
+ definition: jsonb("definition").notNull()
476
+ }, (table) => [check("junior_automation_versions_kind_check", sql`${table.kind} in ('scheduled', 'event')`), primaryKey({
477
+ name: "junior_automation_versions_pk",
478
+ columns: [
479
+ table.kind,
480
+ table.automationId,
481
+ table.version
482
+ ]
483
+ })]);
484
+ //#endregion
461
485
  //#region src/db/schema/scheduled-automations.ts
462
486
  const juniorSchedulerTasks = pgTable("junior_scheduler_tasks", {
463
487
  id: text("id").primaryKey(),
@@ -564,6 +588,7 @@ const juniorSqlSchema = {
564
588
  juniorSnapshots,
565
589
  juniorStats,
566
590
  juniorAutomationExecutions,
591
+ juniorAutomationVersions,
567
592
  juniorSchedulerRuns,
568
593
  juniorSchedulerTasks,
569
594
  juniorUsers,
@@ -957,11 +982,15 @@ var NeonExecutor = class {
957
982
  };
958
983
  /** Create the shared Neon-backed Junior SQL executor. */
959
984
  function createNeonJuniorSqlExecutor(args) {
960
- return new NeonExecutor(new Pool({
985
+ const pool = new Pool({
961
986
  connectionString: args.connectionString,
962
987
  max: 3,
963
988
  statement_timeout: args.statementTimeoutMs
964
- }), args.connectionString);
989
+ });
990
+ pool.on("error", (error) => {
991
+ logException(error, "db.pool.client.failed", { "app.db.driver": "neon" });
992
+ });
993
+ return new NeonExecutor(pool, args.connectionString);
965
994
  }
966
995
  //#endregion
967
996
  //#region src/db/postgres.ts
@@ -1078,12 +1107,16 @@ var PostgresExecutor = class {
1078
1107
  };
1079
1108
  /** Create the shared Node Postgres-backed Junior SQL executor. */
1080
1109
  function createPostgresJuniorSqlExecutor(args) {
1081
- return new PostgresExecutor(new Pool$1({
1110
+ const pool = new Pool$1({
1082
1111
  application_name: args.applicationName,
1083
1112
  connectionString: args.connectionString,
1084
1113
  max: 3,
1085
1114
  statement_timeout: args.statementTimeoutMs
1086
- }), args.connectionString);
1115
+ });
1116
+ pool.on("error", (error) => {
1117
+ logException(error, "db.pool.client.failed", { "app.db.driver": "postgres" });
1118
+ });
1119
+ return new PostgresExecutor(pool, args.connectionString);
1087
1120
  }
1088
1121
  //#endregion
1089
1122
  //#region src/db/executor.ts
@@ -1100,4 +1133,4 @@ function createJuniorSqlExecutor(args) {
1100
1133
  });
1101
1134
  }
1102
1135
  //#endregion
1103
- export { juniorCodeRepositories as C, juniorIdentities as D, juniorConversations as E, juniorUsers as O, juniorCodeChanges as S, conversationReadColumns as T, CONVERSATION_METRICS as _, juniorSchedulerRuns as a, juniorApiTokens as b, juniorStats as c, AGENT_INVOCATION_MAILBOX_STATUSES as d, juniorAgentBindings as f, juniorConversationBriefs as g, juniorConversationBindings as h, juniorWorkspaces as i, juniorArtifacts as k, juniorEventAutomations as l, juniorConversationParticipants as m, juniorSnapshots as n, juniorSchedulerTasks as o, juniorAgentInvocations as p, juniorWorkspaceRepos as r, juniorAutomationExecutions as s, createJuniorSqlExecutor as t, juniorLocationConfigurations as u, juniorConversationMetrics as v, juniorAttachments as w, juniorConversationAnnotations as x, juniorConversationEvents as y };
1136
+ export { juniorArtifacts as A, juniorCodeChanges as C, juniorConversations as D, conversationReadColumns as E, juniorIdentities as O, juniorConversationAnnotations as S, juniorAttachments as T, juniorConversationBriefs as _, juniorSchedulerRuns as a, juniorConversationEvents as b, juniorAutomationExecutions as c, juniorLocationConfigurations as d, AGENT_INVOCATION_MAILBOX_STATUSES as f, juniorConversationBindings as g, juniorConversationParticipants as h, juniorWorkspaces as i, juniorUsers as k, juniorStats as l, juniorAgentInvocations as m, juniorSnapshots as n, juniorSchedulerTasks as o, juniorAgentBindings as p, juniorWorkspaceRepos as r, juniorAutomationVersions as s, createJuniorSqlExecutor as t, juniorEventAutomations as u, CONVERSATION_METRICS as v, juniorCodeRepositories as w, juniorApiTokens as x, juniorConversationMetrics as y };
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.js";
2
- import { j as storeAttachment, k as readLiveAttachment } from "./agent-runner-BlDI1zV2.js";
3
- import { nn as getSqlExecutor } from "./agent-hooks-DS7k0ZWY.js";
4
- import "./conversation-C_aYrISI.js";
2
+ import { j as storeAttachment, k as readLiveAttachment } from "./agent-runner-DMAsnPb9.js";
3
+ import { nn as getSqlExecutor } from "./agent-hooks-otHGbhBx.js";
4
+ import "./conversation-9Fxa1Zbq.js";
5
5
  //#region src/chat/attachments/images.ts
6
6
  var images_exports = /* @__PURE__ */ __exportAll({
7
7
  decodeInputImages: () => decodeInputImages,
@@ -1,6 +1,6 @@
1
- import { N as getDeploymentServiceVersion, P as getDeploymentTelemetryAttributes } from "./logging-F--48Q7Q.js";
1
+ import { N as getDeploymentServiceVersion, P as getDeploymentTelemetryAttributes } from "./logging-rB_ngE_R.js";
2
2
  import { _ as vercelAIIntegration, a as getClient, b as withStreamedSpan, c as init, o as getGlobalScope } from "./sentry-CgWZM_kV.js";
3
- import { n as getCurrentConversationPrivacy } from "./conversation-privacy-BV2dtba2.js";
3
+ import { n as getCurrentConversationPrivacy } from "./conversation-privacy-Dbkdvozu.js";
4
4
  import { t as consumePrivateTraceResultMarker } from "./private-trace-result-BLvBjy_e.js";
5
5
  //#region src/chat/sentry-payload-filter.ts
6
6
  const PAYLOAD_ATTRIBUTE_KEYS = /* @__PURE__ */ new Set([
@@ -1,4 +1,4 @@
1
- import { a as getChatConfig } from "./config-Bmw4xTPK.js";
1
+ import { i as getChatConfig } from "./config-CxpPG6nR.js";
2
2
  import { AsyncLocalStorage } from "node:async_hooks";
3
3
  import { z } from "zod";
4
4
  import { createHash, createHmac, timingSafeEqual } from "node:crypto";
@@ -1,5 +1,5 @@
1
1
  import { d as setTag, f as setUser, h as startSpan, i as getActiveSpan, l as logger, n as captureMessage, p as spanToJSON, s as getTraceData, t as captureException, y as withScope } from "./sentry-CgWZM_kV.js";
2
- import { t as JUNIOR_VERSION } from "./version-9CB4Z-J4.js";
2
+ import { t as JUNIOR_VERSION } from "./version-EQ4MWuUJ.js";
3
3
  import path from "node:path";
4
4
  import { styleText } from "node:util";
5
5
  import { ConfigError, configureSync, getConfig, getLogger } from "@logtape/logtape";
package/dist/nitro.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { n as JuniorDashboardOptions } from "./app-pGsR__aT.js";
2
- import { n as JuniorPluginSet } from "./plugins-BT2l4We3.js";
1
+ import { r as JuniorDashboardOptions } from "./app-MEd7wbF0.js";
2
+ import { n as JuniorPluginSet } from "./plugins-CjfUP5gJ.js";
3
3
  //#region src/nitro.d.ts
4
4
  export type JuniorNitroDashboardOptions = JuniorDashboardOptions;
5
5
  export interface JuniorPluginModuleReference {
package/dist/nitro.js CHANGED
@@ -1,9 +1,9 @@
1
- import { A as JUNIOR_RETENTION_ROUTE, D as JUNIOR_HEARTBEAT_ROUTE, E as JUNIOR_HEARTBEAT_CRON_SCHEDULE, O as JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE, T as JUNIOR_CONVERSATION_WORK_CALLBACK_ROUTE, j as JUNIOR_WORKSPACE_SNAPSHOT_JOB_CALLBACK_ROUTE, k as JUNIOR_RETENTION_CRON_SCHEDULE } from "./logging-F--48Q7Q.js";
2
- import { d as resolvePackageDir, t as discoverInstalledPluginPackageContent, u as isValidPackageName } from "./package-discovery-7a9YqLhE.js";
3
- import { o as resolveConversationWorkQueueTopic, t as WORKSPACE_SNAPSHOT_JOB_QUEUE_TOPIC } from "./job-queue-CY1L2YRn.js";
1
+ import { A as JUNIOR_RETENTION_ROUTE, D as JUNIOR_HEARTBEAT_ROUTE, E as JUNIOR_HEARTBEAT_CRON_SCHEDULE, O as JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE, T as JUNIOR_CONVERSATION_WORK_CALLBACK_ROUTE, j as JUNIOR_WORKSPACE_SNAPSHOT_JOB_CALLBACK_ROUTE, k as JUNIOR_RETENTION_CRON_SCHEDULE } from "./logging-rB_ngE_R.js";
2
+ import { d as resolvePackageDir, t as discoverInstalledPluginPackageContent, u as isValidPackageName } from "./package-discovery-BVvSnQBB.js";
3
+ import { o as resolveConversationWorkQueueTopic, t as WORKSPACE_SNAPSHOT_JOB_QUEUE_TOPIC } from "./job-queue-Dq5_zt_l.js";
4
4
  import { a as pluginRuntimeRegistrationsFromPluginSet, r as pluginCatalogConfigFromPluginSet } from "./plugins-egKWjgue.js";
5
- import { t as PLUGIN_TASK_QUEUE_TOPIC } from "./task-queue-GcuFtzor.js";
6
- import { n as loadPluginSetFromModule, r as resolvePluginModule } from "./plugin-module-BKGOXca2.js";
5
+ import { t as PLUGIN_TASK_QUEUE_TOPIC } from "./task-queue-BAiZ7_CF.js";
6
+ import { n as loadPluginSetFromModule, r as resolvePluginModule } from "./plugin-module-CVvEUSMH.js";
7
7
  import path from "node:path";
8
8
  import { cpSync, existsSync, mkdirSync, readdirSync, statSync } from "node:fs";
9
9
  //#region src/build/rolldown-workarounds.ts
@@ -1,4 +1,4 @@
1
- import { h as extractAssistantText } from "./checkpoint-DLcJ5mKL.js";
1
+ import { h as extractAssistantText } from "./checkpoint-BlIIiHG5.js";
2
2
  //#region src/chat/runtime/turn.ts
3
3
  /** Classified Slack turn failure carrying the owning Sentry capture outward. */
4
4
  var ConversationTurnBoundaryError = class extends Error {
@@ -1,5 +1,5 @@
1
- import { Dn as createUserTokenStore } from "./agent-runner-BlDI1zV2.js";
2
- import { a as GET, n as syncLocalOAuthCredential, r as GET$1 } from "./credential-sync-CukzQJ1x.js";
1
+ import { Fn as createUserTokenStore } from "./agent-runner-DMAsnPb9.js";
2
+ import { a as GET, n as syncLocalOAuthCredential, r as GET$1 } from "./credential-sync-D9yGg3q5.js";
3
3
  import { createServer } from "node:http";
4
4
  //#region src/chat/local/oauth-callback-server.ts
5
5
  const LOCAL_OAUTH_TIMEOUT_MS = 6e5;
@@ -1,4 +1,4 @@
1
- import { i as abandonTurnRecord } from "./checkpoint-DLcJ5mKL.js";
1
+ import { i as abandonTurnRecord } from "./checkpoint-BlIIiHG5.js";
2
2
  //#region src/chat/state/turn-id.ts
3
3
  /** Build a stable turn identifier from a message ID. */
4
4
  function buildDeterministicTurnId(messageId) {
@@ -64,6 +64,7 @@ interface PluginManifestConfig {
64
64
  url?: string;
65
65
  headers?: Record<string, string | null> | null;
66
66
  auth?: PluginMcpConfig["auth"];
67
+ oauthClient?: PluginMcpConfig["oauthClient"];
67
68
  allowedTools?: string[] | null;
68
69
  wrappedTools?: string[] | null;
69
70
  } | null;
@@ -1,7 +1,7 @@
1
- import { S as toOptionalTrimmed } from "./client-BSnNHO0R.js";
2
- import { v as setSpanAttributes, y as setSpanStatus } from "./logging-F--48Q7Q.js";
3
- import { a as getChatConfig } from "./config-Bmw4xTPK.js";
4
- import { n as pluginCatalogRuntime } from "./catalog-runtime-B9u_3-GW.js";
1
+ import { S as toOptionalTrimmed } from "./client-CPMbTmJU.js";
2
+ import { v as setSpanAttributes, y as setSpanStatus } from "./logging-rB_ngE_R.js";
3
+ import { i as getChatConfig } from "./config-CxpPG6nR.js";
4
+ import { n as pluginCatalogRuntime } from "./catalog-runtime-DlXuhrmk.js";
5
5
  import { createHash } from "node:crypto";
6
6
  import { createMemoryState } from "@chat-adapter/state-memory";
7
7
  import { createRedisState } from "@chat-adapter/state-redis";
@@ -1,4 +1,4 @@
1
- import { I as briefOutcomeStatusSchema, L as conversationBriefSchema, R as parseBriefInput } from "./conversation-C_aYrISI.js";
1
+ import { B as parseBriefInput, R as briefOutcomeStatusSchema, z as conversationBriefSchema } from "./conversation-9Fxa1Zbq.js";
2
2
  import { z } from "zod";
3
3
  //#region src/chat/briefs/generate.ts
4
4
  const MAX_INPUT_CHARS = 6e4;
@@ -0,0 +1,25 @@
1
+ import { z } from "zod";
2
+ //#region src/chat/task-execution/queue.d.ts
3
+ /** Validate the v2 conversation work hint sent through Vercel Queue. */
4
+ declare const conversationQueueMessageSchema: z.ZodObject<{
5
+ schemaVersion: z.ZodLiteral<2>;
6
+ conversationId: z.ZodString;
7
+ }, z.core.$strict>;
8
+ /** Conversation work hint accepted by the queue callback and worker. */
9
+ type ConversationQueueMessage = z.output<typeof conversationQueueMessageSchema>;
10
+ interface ConversationQueueSendOptions {
11
+ delayMs?: number;
12
+ idempotencyKey?: string;
13
+ }
14
+ interface ConversationQueueSendResult {
15
+ messageId?: string;
16
+ }
17
+ /**
18
+ * External transport for wake-up hints. Durable work stays in the mailbox;
19
+ * transports only need to accept one hint and may return a provider message id.
20
+ */
21
+ interface ConversationWorkQueue {
22
+ send(message: ConversationQueueMessage, options?: ConversationQueueSendOptions): Promise<ConversationQueueSendResult | void>;
23
+ }
24
+ //#endregion
25
+ export { ConversationWorkQueue as n, ConversationQueueMessage as t };
@@ -1,6 +1,6 @@
1
- import { f as logInfo, p as logWarn, v as setSpanAttributes } from "./logging-F--48Q7Q.js";
1
+ import { f as logInfo, p as logWarn, v as setSpanAttributes } from "./logging-rB_ngE_R.js";
2
2
  import { i as credentialUserSubjectId } from "./context-0Et9iVSB.js";
3
- import { n as normalizePluginPackageNames, o as pluginRoots, t as discoverInstalledPluginPackageContent } from "./package-discovery-7a9YqLhE.js";
3
+ import { n as normalizePluginPackageNames, o as pluginRoots, t as discoverInstalledPluginPackageContent } from "./package-discovery-BVvSnQBB.js";
4
4
  import path from "node:path";
5
5
  import { z } from "zod";
6
6
  import { randomUUID } from "node:crypto";
@@ -39,6 +39,16 @@ function mcpAuthSource(auth) {
39
39
  "private-key-env": auth.privateKeyEnv
40
40
  };
41
41
  }
42
+ /** Convert a camelCase `mcp.oauthClient` block to its plugin.yaml source keys. */
43
+ function mcpOauthClientSource(oauthClient) {
44
+ const result = {
45
+ "client-id-env": oauthClient.clientIdEnv,
46
+ "client-secret-env": oauthClient.clientSecretEnv
47
+ };
48
+ setDefined$1(result, "scope", oauthClient.scope);
49
+ setDefined$1(result, "authorize-params", oauthClient.authorizeParams);
50
+ return result;
51
+ }
42
52
  function inlineMcpSource(mcp) {
43
53
  if (mcp === void 0 || !isRecord(mcp)) return mcp;
44
54
  const result = {};
@@ -46,6 +56,7 @@ function inlineMcpSource(mcp) {
46
56
  setDefined$1(result, "url", mcp.url);
47
57
  setDefined$1(result, "headers", mcp.headers);
48
58
  setDefined$1(result, "auth", mcp.auth && mcpAuthSource(mcp.auth));
59
+ setDefined$1(result, "oauth-client", mcp.oauthClient && mcpOauthClientSource(mcp.oauthClient));
49
60
  setDefined$1(result, "allowed-tools", mcp.allowedTools);
50
61
  setDefined$1(result, "wrapped-tools", mcp.wrappedTools);
51
62
  return result;
@@ -233,11 +244,18 @@ const mcpAuthSourceSchema = z.object({
233
244
  "key-id": nonEmptyTrimmedString,
234
245
  "private-key-env": envVarString
235
246
  }).passthrough();
247
+ const mcpOauthClientSourceSchema = z.object({
248
+ "client-id-env": envVarString,
249
+ "client-secret-env": envVarString,
250
+ scope: nonEmptyTrimmedString.optional(),
251
+ "authorize-params": stringMapSchema.optional()
252
+ }).passthrough();
236
253
  const mcpSourceSchema = z.object({
237
254
  transport: nonEmptyTrimmedString.refine((value) => value === "http", { error: "must be \"http\"" }).optional(),
238
255
  url: httpsUrlString,
239
256
  auth: mcpAuthSourceSchema.optional(),
240
257
  headers: stringMapSchema.optional(),
258
+ "oauth-client": mcpOauthClientSourceSchema.optional(),
241
259
  "allowed-tools": nonEmptyStringArraySchema("allowed-tools").optional(),
242
260
  "wrapped-tools": nonEmptyStringArraySchema("wrapped-tools").optional()
243
261
  }).passthrough();
@@ -296,6 +314,7 @@ function manifestConfigPatch(config) {
296
314
  setDefined(mcp, "url", config.mcp.url);
297
315
  setDefined(mcp, "headers", config.mcp.headers);
298
316
  setDefined(mcp, "auth", config.mcp.auth && mcpAuthSource(config.mcp.auth));
317
+ setDefined(mcp, "oauth-client", config.mcp.oauthClient && mcpOauthClientSource(config.mcp.oauthClient));
299
318
  setDefined(mcp, "allowed-tools", config.mcp.allowedTools);
300
319
  setDefined(mcp, "wrapped-tools", config.mcp.wrappedTools);
301
320
  result.mcp = mcp;
@@ -422,6 +441,10 @@ function normalizeCommandEnv(value, prefix, envVars) {
422
441
  function hostOnlyEnvNames(manifest) {
423
442
  const names = /* @__PURE__ */ new Set();
424
443
  if (manifest.mcp?.auth) names.add(manifest.mcp.auth.privateKeyEnv);
444
+ if (manifest.mcp?.oauthClient) {
445
+ names.add(manifest.mcp.oauthClient.clientIdEnv);
446
+ names.add(manifest.mcp.oauthClient.clientSecretEnv);
447
+ }
425
448
  for (const value of [...Object.values(manifest.apiHeaders ?? {}), ...Object.values(manifest.mcp?.headers ?? {})]) for (const name of envReferences(value)) names.add(name);
426
449
  if (manifest.credentials?.authTokenEnv) names.add(manifest.credentials.authTokenEnv);
427
450
  if (manifest.oauth) {
@@ -572,6 +595,13 @@ function normalizeMcp(data, envVars, name) {
572
595
  const headers = result.data.headers ? normalizeStringMap(result.data.headers, `Plugin ${name} mcp.headers`, { forbiddenKeys: FORBIDDEN_API_HEADER_NAMES }) : void 0;
573
596
  assertDeclaredHeaderEnvReferences(headers, envVars, `Plugin ${name} mcp.headers`);
574
597
  if (result.data.auth) assertDeclaredHostSecretEnv(result.data.auth["private-key-env"], envVars, `Plugin ${name} mcp.auth.private-key-env`);
598
+ const oauthClient = result.data["oauth-client"];
599
+ if (oauthClient) {
600
+ if (result.data.auth) throw new Error(`Plugin ${name} mcp must not declare both auth and oauth-client`);
601
+ assertDeclaredHostSecretEnv(oauthClient["client-id-env"], envVars, `Plugin ${name} mcp.oauth-client.client-id-env`);
602
+ assertDeclaredHostSecretEnv(oauthClient["client-secret-env"], envVars, `Plugin ${name} mcp.oauth-client.client-secret-env`);
603
+ }
604
+ const oauthClientAuthorizeParams = oauthClient?.["authorize-params"] ? normalizeStringMap(oauthClient["authorize-params"], `Plugin ${name} mcp.oauth-client.authorize-params`, { reservedKeys: RESERVED_AUTHORIZE_PARAM_KEYS }) : void 0;
575
605
  return {
576
606
  transport: "http",
577
607
  url: result.data.url,
@@ -581,6 +611,12 @@ function normalizeMcp(data, envVars, name) {
581
611
  privateKeyEnv: result.data.auth["private-key-env"]
582
612
  } } : void 0,
583
613
  ...headers ? { headers } : void 0,
614
+ ...oauthClient ? { oauthClient: {
615
+ clientIdEnv: oauthClient["client-id-env"],
616
+ clientSecretEnv: oauthClient["client-secret-env"],
617
+ ...oauthClient.scope ? { scope: oauthClient.scope } : void 0,
618
+ ...oauthClientAuthorizeParams ? { authorizeParams: oauthClientAuthorizeParams } : void 0
619
+ } } : void 0,
584
620
  ...result.data["allowed-tools"] ? { allowedTools: result.data["allowed-tools"] } : void 0,
585
621
  ...result.data["wrapped-tools"] ? { wrappedTools: result.data["wrapped-tools"] } : void 0
586
622
  };
@@ -1,5 +1,5 @@
1
- import { v as setSpanAttributes, w as withSpan } from "./logging-F--48Q7Q.js";
2
- import { N as SANDBOX_WORKSPACE_ROOT, k as sleep, r as isStale, t as create, u as isSandboxUnavailableError, v as getVercelSandboxCredentials, w as getStateAdapter, x as runNonInteractiveCommand } from "./profile-DZ2DUdd1.js";
1
+ import { v as setSpanAttributes, w as withSpan } from "./logging-rB_ngE_R.js";
2
+ import { N as SANDBOX_WORKSPACE_ROOT, k as sleep, r as isStale, t as create, u as isSandboxUnavailableError, v as getVercelSandboxCredentials, w as getStateAdapter, x as runNonInteractiveCommand } from "./profile-D6apIG2N.js";
3
3
  import { z } from "zod";
4
4
  import { FileSystem, Sandbox } from "@vercel/sandbox";
5
5
  //#region src/chat/sandbox/resources.ts
@@ -1,13 +1,13 @@
1
- import { C as withLogContext, b as setTags, d as logException } from "./logging-F--48Q7Q.js";
1
+ import { C as withLogContext, b as setTags, d as logException } from "./logging-rB_ngE_R.js";
2
2
  import { t as credentialContextForActor } from "./context-0Et9iVSB.js";
3
- import { Qt as getConversationEventStore, en as getConversationStore } from "./agent-hooks-DS7k0ZWY.js";
4
- import { V as messageCardText } from "./conversation-C_aYrISI.js";
5
- import { A as commitAcceptedReply, B as recordAuthorizationCompleted, J as hydrateConversationMessages, P as loadProjection, Y as persistConversationMessages, ct as normalizeConversationText, dt as upsertConversationMessage, lt as recordDeliveredAssistantMessage, nt as buildConversationContext, r as saveTurnCheckpoint, st as markConversationMessage, u as persistWithRetry } from "./checkpoint-DLcJ5mKL.js";
6
- import { _ as markTurnFailed, r as getAssistantReplyText, t as authorizationId, v as startActiveTurn } from "./oauth-authorization-LasSG3Qc.js";
7
- import { n as scheduleSessionCompletedPluginTasks, t as processPluginTask } from "./task-runner-B0-P_3aq.js";
8
- import { t as ConversationTurnLifecycleService } from "./turn-lifecycle-BpIW3zOx.js";
9
- import { n as getPersistedSandboxState, o as persistThreadStateById, r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-TezcEhuH.js";
10
- import { d as loadPendingMessageCards, i as completeAuthPauseTurn, l as buildDeliveredTurnStatePatch, t as finalizeFailedTurnReplyWithEvent } from "./turn-failure-response-Drhj_-t4.js";
3
+ import { Qt as getConversationEventStore, en as getConversationStore } from "./agent-hooks-otHGbhBx.js";
4
+ import { U as messageCardText } from "./conversation-9Fxa1Zbq.js";
5
+ import { A as commitAcceptedReply, P as loadProjection, V as recordAuthorizationCompleted, X as persistConversationMessages, Y as hydrateConversationMessages, dt as recordDeliveredAssistantMessage, it as buildConversationContext, lt as markConversationMessage, pt as upsertConversationMessage, r as saveTurnCheckpoint, u as persistWithRetry, ut as normalizeConversationText } from "./checkpoint-BlIIiHG5.js";
6
+ import { _ as markTurnFailed, r as getAssistantReplyText, t as authorizationId, v as startActiveTurn } from "./oauth-authorization-5T1S1v_1.js";
7
+ import { n as scheduleSessionCompletedPluginTasks, t as processPluginTask } from "./task-runner-Bh8XONXT.js";
8
+ import { t as ConversationTurnLifecycleService } from "./turn-lifecycle-D6CTbkb9.js";
9
+ import { n as getPersistedSandboxState, o as persistThreadStateById, r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-BnQln4jO.js";
10
+ import { d as loadPendingMessageCards, i as completeAuthPauseTurn, l as buildDeliveredTurnStatePatch, t as finalizeFailedTurnReplyWithEvent } from "./turn-failure-response-Ba7_kItn.js";
11
11
  import { randomUUID } from "node:crypto";
12
12
  import { createLocalSource, localDestinationSchema } from "@sentry/junior-plugin-api";
13
13
  //#region src/chat/local/runner.ts
@@ -1,4 +1,4 @@
1
- import { fn as sandboxEgressSignalsResponseSchema } from "./agent-runner-BlDI1zV2.js";
1
+ import { yn as sandboxEgressSignalsResponseSchema } from "./agent-runner-DMAsnPb9.js";
2
2
  //#region src/chat/local/sandbox-egress-signals.ts
3
3
  const SANDBOX_EGRESS_SIGNALS_PATH = "/api/internal/sandbox-egress/signals";
4
4
  const LOCAL_DEV_SERVER_TIMEOUT_MS = 1e3;
@@ -1,6 +1,7 @@
1
1
  import { t as juniorDestinationKindSchema } from "./destinations-BeBiJeEM.js";
2
- import { E as conversationSummaryReportSchema, n as actorIdentitySchema, w as conversationStatsItemSchema } from "./conversation-C_aYrISI.js";
3
- import { a as fillUtcHours, c as sumUtcHoursIntoSixHours, i as fillUtcDays } from "./web-message-id-CVVCTWUb.js";
2
+ import { E as conversationSummaryReportSchema, n as actorIdentitySchema, w as conversationStatsItemSchema } from "./conversation-9Fxa1Zbq.js";
3
+ import "./automation-CrQGQ2MT.js";
4
+ import { a as fillUtcHours, c as sumUtcHoursIntoSixHours, i as fillUtcDays } from "./web-message-id-xPI_EFSC.js";
4
5
  import { z } from "zod";
5
6
  import { codeChangeStateSchema } from "@sentry/junior-plugin-api";
6
7
  //#region src/api/schema/common.ts