@sentry/junior 0.234.0 → 0.236.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 (71) hide show
  1. package/dist/{agent-hooks-BcH6E48y.js → agent-hooks-Da_H0jHv.js} +17 -10
  2. package/dist/{agent-runner-DUkGlK89.js → agent-runner-uP7QRc4c.js} +484 -162
  3. package/dist/api/schema.d.ts +288 -2
  4. package/dist/api/schema.js +5 -4
  5. package/dist/api.d.ts +8 -2
  6. package/dist/api.js +524 -83
  7. package/dist/{app-xk2-Id1T.d.ts → app-MEd7wbF0.d.ts} +83 -49
  8. package/dist/app.d.ts +3 -3
  9. package/dist/app.js +164 -119
  10. package/dist/{types-Du-HbEun.js → automation-B9Kc1gcf.js} +304 -33
  11. package/dist/{briefs-lyAQbDxJ.js → briefs-DrjBPQFy.js} +4 -4
  12. package/dist/{catalog-runtime-BSgsPVnr.js → catalog-runtime-C7339Cfm.js} +1 -1
  13. package/dist/{checkpoint-BNfXlq_1.js → checkpoint-DaD7_Gsb.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-BX5lJRqW.js → client-Ch9Hg9NU.js} +2 -2
  24. package/dist/{config-DuCzUoCo.js → config-JR9wke1W.js} +57 -17
  25. package/dist/{conversation-CPjHYOV5.js → conversation-9Fxa1Zbq.js} +14 -1
  26. package/dist/{conversation-privacy-CSxvdSoV.js → conversation-privacy-au02dyZK.js} +1 -1
  27. package/dist/{credential-sync-BO4DfH9a.js → credential-sync-BWTA3LnL.js} +14 -14
  28. package/dist/{executor--jWf-Nnm.js → executor-BW9XWgUQ.js} +70 -6
  29. package/dist/{images-BaL19wFC.js → images-BdG7zcNf.js} +3 -3
  30. package/dist/instrumentation.js +2 -2
  31. package/dist/{job-queue-cwHVOwVZ.js → job-queue-BqXd0ZPV.js} +1 -1
  32. package/dist/{logging-Cox1Mgcv.js → logging-B4sKwmCG.js} +1 -1
  33. package/dist/nitro.d.ts +2 -2
  34. package/dist/nitro.js +5 -5
  35. package/dist/{oauth-authorization-CC8a1JKP.js → oauth-authorization-BjRN99dc.js} +1 -1
  36. package/dist/{oauth-callback-server-Z7QSt416.js → oauth-callback-server-B_1p98Mb.js} +2 -2
  37. package/dist/{pending-auth-DQhC3eSR.js → pending-auth-WqF4Gh8Z.js} +1 -1
  38. package/dist/{plugins-BT2l4We3.d.ts → plugins-CjfUP5gJ.d.ts} +1 -0
  39. package/dist/{profile-BdApelHS.js → profile-BamYnmhO.js} +4 -4
  40. package/dist/{prompt-3D0sSbTC.js → prompt-Ctwy6hSI.js} +1 -1
  41. package/dist/queue-B5SnqRln.d.ts +25 -0
  42. package/dist/{registry-DiY6B8CN.js → registry-CXNv9fDX.js} +38 -2
  43. package/dist/{resolve-VpJoiDpc.js → resolve-C9ETkt4T.js} +2 -2
  44. package/dist/{runner-BIMegnPE.js → runner-DnBGVRnW.js} +9 -9
  45. package/dist/{sandbox-egress-signals-Cbtxe492.js → sandbox-egress-signals-DwJ7Boi_.js} +1 -1
  46. package/dist/{schema-CxwnlTDN.js → schema-CJiqDc5r.js} +26 -3
  47. package/dist/{skills-WttpPJUy.js → skills-Dd8O9Aav.js} +3 -3
  48. package/dist/{spawn-DhfMKt4y.js → spawn-DFdRspSD.js} +2 -2
  49. package/dist/{task-queue-CZqUNJD0.js → task-queue-DGQEOk1A.js} +16 -10
  50. package/dist/{task-runner-BZaqoUCT.js → task-runner-C5XCIDSF.js} +9 -9
  51. package/dist/{thread-state-8tXZhu0y.js → thread-state-D3E29wZk.js} +5 -5
  52. package/dist/{turn-failure-response-DFJ9L9NQ.js → turn-failure-response-TDoj0aZz.js} +8 -8
  53. package/dist/{turn-lifecycle-WbpTUQ_r.js → turn-lifecycle-DOnU45p7.js} +1 -1
  54. package/dist/{turn-session-routing--EhI76rH.js → turn-session-routing-DbpZZoin.js} +1 -1
  55. package/dist/{validation-0F9IgG3b.js → validation-B9lMbisx.js} +1 -1
  56. package/dist/{version-A7-RRBOE.js → version-CWkIGcLU.js} +1 -1
  57. package/dist/version.js +1 -1
  58. package/dist/{web-authorization-BJggXofy.js → web-authorization-PPaoj2ns.js} +6 -6
  59. package/dist/{web-input-B-siN5Dr.js → web-input-CfNxXtHm.js} +86 -34
  60. package/dist/web-message-id-xPI_EFSC.js +239 -0
  61. package/dist/{work-CNc0ejGG.js → work-DNaoFrEe.js} +7 -7
  62. package/dist/{worker-BHbqpUAu.js → worker-xeJLxYwm.js} +5 -5
  63. package/migrations/0045_conversation_forks.sql +3 -0
  64. package/migrations/0046_automation_versions.sql +71 -0
  65. package/migrations/meta/0045_snapshot.json +3503 -0
  66. package/migrations/meta/0046_snapshot.json +3707 -0
  67. package/migrations/meta/_journal.json +15 -1
  68. package/package.json +5 -5
  69. package/dist/web-message-id-CVVCTWUb.js +0 -464
  70. package/dist/{package-discovery-7a9YqLhE.js → package-discovery-BVvSnQBB.js} +1 -1
  71. 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-BX5lJRqW.js";
3
- import { p as logWarn } from "./logging-Cox1Mgcv.js";
2
+ import { S as toOptionalTrimmed, o as resolveGatewayModel } from "./client-Ch9Hg9NU.js";
3
+ import { p as logWarn } from "./logging-B4sKwmCG.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 };
@@ -786,6 +786,7 @@ const conversationEventsQuerySchema = z.object({
786
786
  }).strict();
787
787
  const conversationFeedQuerySchema = z.object({
788
788
  actorEmail: z.string().trim().email().transform((value) => value.toLowerCase()).optional(),
789
+ codeRepositoryId: z.string().uuid().optional(),
789
790
  q: z.string().trim().max(200).optional(),
790
791
  status: z.enum(["active", "archived"]).default("active")
791
792
  }).strict();
@@ -1269,7 +1270,19 @@ function validateConversationEvents(report, context) {
1269
1270
  });
1270
1271
  }
1271
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();
1272
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(),
1273
1286
  brief: z.object({
1274
1287
  content: conversationBriefSchema,
1275
1288
  updatedAt: z.string().datetime(),
@@ -1355,4 +1368,4 @@ const conversationStatsReportSchema = z.object({
1355
1368
  windowStart: z.string()
1356
1369
  }).strict();
1357
1370
  //#endregion
1358
- 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-Cox1Mgcv.js";
1
+ import { p as logWarn } from "./logging-B4sKwmCG.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 putMcpStoredOAuthCredentials, d as deleteMcpAuthSession, g as getMcpStoredOAuthCredentials, h as getMcpAuthSession, hn as resolveBaseUrl, ht as getMcpProviderErrorAttributes, mn as parseOAuthStatePayload, pn as formatProviderLabel, u as finalizeMcpAuthorization, x as resolvePluginOAuthAccount } from "./agent-runner-DUkGlK89.js";
2
- import { f as escapeXml } from "./client-BX5lJRqW.js";
3
- import { d as logException, h as runBestEffort, p as logWarn } from "./logging-Cox1Mgcv.js";
4
- import { n as botConfig, o as getRuntimeMetadata } from "./config-DuCzUoCo.js";
1
+ import { An as postSlackMessage, Pn as createUserTokenStore, T as lookupSlackUserProfile, _ as resolvePluginOAuthAccount, bn as parseOAuthStatePayload, d as getMcpAuthSession, f as getMcpStoredOAuthCredentials, o as finalizeMcpAuthorization, p as putMcpStoredOAuthCredentials, s as deleteMcpAuthSession, xn as resolveBaseUrl, xt as getMcpProviderErrorAttributes, yn as formatProviderLabel } from "./agent-runner-uP7QRc4c.js";
2
+ import { f as escapeXml } from "./client-Ch9Hg9NU.js";
3
+ import { d as logException, h as runBestEffort, p as logWarn } from "./logging-B4sKwmCG.js";
4
+ import { a as getRuntimeMetadata, n as botConfig } from "./config-JR9wke1W.js";
5
5
  import { g as parseSlackUserId } from "./context-0Et9iVSB.js";
6
- import { U as getSlackClient, gn as upsertLinkedIdentity, hn as upsertIdentity, tn as getSqlExecutor } from "./agent-hooks-BcH6E48y.js";
7
- import { i as homeDir } from "./package-discovery-7a9YqLhE.js";
8
- import { n as buildOAuthTokenRequest, r as parseOAuthTokenResponse, u as hasRequiredOAuthScope } from "./registry-DiY6B8CN.js";
9
- import { n as pluginCatalogRuntime } from "./catalog-runtime-BSgsPVnr.js";
10
- import { t as discoverSkills } from "./skills-WttpPJUy.js";
11
- import { B as recordAuthorizationCompleted, s as getTurnRecord, z as recordAuthenticationLinked } from "./checkpoint-BNfXlq_1.js";
12
- import { E as acquireActiveLock, w as getStateAdapter } from "./profile-BdApelHS.js";
13
- import { i as getConversationPendingAuth } from "./pending-auth-DQhC3eSR.js";
14
- import { r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-8tXZhu0y.js";
15
- import { n as deleteWebAuthorization, o as wakeAuthorizedTurn, s as wakePausedTurn } from "./web-authorization-BJggXofy.js";
6
+ import { W as getSlackClient, _n as upsertLinkedIdentity, gn as upsertIdentity, nn as getSqlExecutor } from "./agent-hooks-Da_H0jHv.js";
7
+ import { i as homeDir } from "./package-discovery-BVvSnQBB.js";
8
+ import { n as buildOAuthTokenRequest, r as parseOAuthTokenResponse, u as hasRequiredOAuthScope } from "./registry-CXNv9fDX.js";
9
+ import { n as pluginCatalogRuntime } from "./catalog-runtime-C7339Cfm.js";
10
+ import { t as discoverSkills } from "./skills-Dd8O9Aav.js";
11
+ import { B as recordAuthenticationLinked, V as recordAuthorizationCompleted, s as getTurnRecord } from "./checkpoint-DaD7_Gsb.js";
12
+ import { E as acquireActiveLock, w as getStateAdapter } from "./profile-BamYnmhO.js";
13
+ import { i as getConversationPendingAuth } from "./pending-auth-WqF4Gh8Z.js";
14
+ import { r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-D3E29wZk.js";
15
+ import { n as deleteWebAuthorization, o as wakeAuthorizedTurn, s as wakePausedTurn } from "./web-authorization-PPaoj2ns.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-B4sKwmCG.js";
1
2
  import { g as startSpanManual } from "./sentry-CgWZM_kV.js";
2
- import "./config-DuCzUoCo.js";
3
+ import "./config-JR9wke1W.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";
@@ -95,6 +96,7 @@ const juniorConversations = pgTable("junior_conversations", {
95
96
  lastCheckpointAt: timestamptz("last_checkpoint_at"),
96
97
  lastEnqueuedAt: timestamptz("last_enqueued_at"),
97
98
  parentConversationId: text("parent_conversation_id").references(() => juniorConversations.conversationId),
99
+ forkedFromConversationId: text("forked_from_conversation_id").references(() => juniorConversations.conversationId, { onDelete: "set null" }),
98
100
  rootConversationId: text("root_conversation_id").references(() => juniorConversations.conversationId),
99
101
  transcriptPurgedAt: timestamptz("transcript_purged_at"),
100
102
  durationMs: integer("duration_ms").notNull().default(0),
@@ -110,6 +112,7 @@ const juniorConversations = pgTable("junior_conversations", {
110
112
  index("junior_conversations_actor_activity_idx").on(table.actorIdentityId, table.lastActivityAt.desc()),
111
113
  index("junior_conversations_origin_idx").on(table.originType, table.originId, table.lastActivityAt.desc()),
112
114
  index("junior_conversations_parent_idx").on(table.parentConversationId),
115
+ index("junior_conversations_forked_from_idx").on(table.forkedFromConversationId),
113
116
  index("junior_conversations_root_idx").on(table.rootConversationId)
114
117
  ]);
115
118
  /** Select runtime conversation fields without reading the legacy archive column. */
@@ -458,6 +461,26 @@ const juniorAutomationExecutions = pgTable("junior_task_executions", {
458
461
  index("junior_task_executions_conversation_time_idx").on(table.conversationId, table.executedAtMs)
459
462
  ]);
460
463
  //#endregion
464
+ //#region src/db/schema/automation-versions.ts
465
+ /** One saved Automation definition. Lifecycle and scheduler state are not versioned. */
466
+ const juniorAutomationVersions = pgTable("junior_automation_versions", {
467
+ kind: text("kind").$type().notNull(),
468
+ automationId: text("automation_id").notNull(),
469
+ /** Starts at 1 and increases by 1 for each saved definition change. */
470
+ version: integer("version").notNull(),
471
+ createdAtMs: bigint("created_at_ms", { mode: "number" }).notNull(),
472
+ /** Slack principal that saved this definition. Null when unknown. */
473
+ editedBy: jsonb("edited_by"),
474
+ definition: jsonb("definition").notNull()
475
+ }, (table) => [check("junior_automation_versions_kind_check", sql`${table.kind} in ('scheduled', 'event')`), primaryKey({
476
+ name: "junior_automation_versions_pk",
477
+ columns: [
478
+ table.kind,
479
+ table.automationId,
480
+ table.version
481
+ ]
482
+ })]);
483
+ //#endregion
461
484
  //#region src/db/schema/scheduled-automations.ts
462
485
  const juniorSchedulerTasks = pgTable("junior_scheduler_tasks", {
463
486
  id: text("id").primaryKey(),
@@ -564,6 +587,7 @@ const juniorSqlSchema = {
564
587
  juniorSnapshots,
565
588
  juniorStats,
566
589
  juniorAutomationExecutions,
590
+ juniorAutomationVersions,
567
591
  juniorSchedulerRuns,
568
592
  juniorSchedulerTasks,
569
593
  juniorUsers,
@@ -850,6 +874,7 @@ var NeonExecutor = class {
850
874
  connectionString;
851
875
  transactionClient = new AsyncLocalStorage();
852
876
  savepointId = 0;
877
+ isolatedQueryId = 0;
853
878
  constructor(pool, connectionString) {
854
879
  this.pool = pool;
855
880
  this.connectionString = connectionString;
@@ -863,6 +888,21 @@ var NeonExecutor = class {
863
888
  async query(statement, params = []) {
864
889
  return (await this.queryClient().query(statement, [...params])).rows;
865
890
  }
891
+ async queryIsolated(statement, params = []) {
892
+ const client = traceQueries(await this.pool.connect(), {
893
+ connectionString: this.connectionString,
894
+ driver: "neon"
895
+ });
896
+ try {
897
+ return (await client.query({
898
+ name: `junior_isolated_${++this.isolatedQueryId}`,
899
+ text: statement,
900
+ values: [...params]
901
+ })).rows;
902
+ } finally {
903
+ client.release(true);
904
+ }
905
+ }
866
906
  async migrate(config) {
867
907
  await migrate(drizzle(this.queryClient(), { schema: juniorSqlSchema }), config);
868
908
  }
@@ -941,11 +981,15 @@ var NeonExecutor = class {
941
981
  };
942
982
  /** Create the shared Neon-backed Junior SQL executor. */
943
983
  function createNeonJuniorSqlExecutor(args) {
944
- return new NeonExecutor(new Pool({
984
+ const pool = new Pool({
945
985
  connectionString: args.connectionString,
946
986
  max: 3,
947
987
  statement_timeout: args.statementTimeoutMs
948
- }), args.connectionString);
988
+ });
989
+ pool.on("error", (error) => {
990
+ logException(error, "db.pool.client.failed", { "app.db.driver": "neon" });
991
+ });
992
+ return new NeonExecutor(pool, args.connectionString);
949
993
  }
950
994
  //#endregion
951
995
  //#region src/db/postgres.ts
@@ -955,6 +999,7 @@ var PostgresExecutor = class {
955
999
  connectionString;
956
1000
  transactionClient = new AsyncLocalStorage();
957
1001
  savepointId = 0;
1002
+ isolatedQueryId = 0;
958
1003
  constructor(pool, connectionString) {
959
1004
  this.pool = pool;
960
1005
  this.connectionString = connectionString;
@@ -968,6 +1013,21 @@ var PostgresExecutor = class {
968
1013
  async query(statement, params = []) {
969
1014
  return (await this.queryClient().query(statement, [...params])).rows;
970
1015
  }
1016
+ async queryIsolated(statement, params = []) {
1017
+ const client = traceQueries(await this.pool.connect(), {
1018
+ connectionString: this.connectionString,
1019
+ driver: "postgres"
1020
+ });
1021
+ try {
1022
+ return (await client.query({
1023
+ name: `junior_isolated_${++this.isolatedQueryId}`,
1024
+ text: statement,
1025
+ values: [...params]
1026
+ })).rows;
1027
+ } finally {
1028
+ client.release(true);
1029
+ }
1030
+ }
971
1031
  async migrate(config) {
972
1032
  await migrate$1(drizzle$1(this.queryClient(), { schema: juniorSqlSchema }), config);
973
1033
  }
@@ -1046,12 +1106,16 @@ var PostgresExecutor = class {
1046
1106
  };
1047
1107
  /** Create the shared Node Postgres-backed Junior SQL executor. */
1048
1108
  function createPostgresJuniorSqlExecutor(args) {
1049
- return new PostgresExecutor(new Pool$1({
1109
+ const pool = new Pool$1({
1050
1110
  application_name: args.applicationName,
1051
1111
  connectionString: args.connectionString,
1052
1112
  max: 3,
1053
1113
  statement_timeout: args.statementTimeoutMs
1054
- }), args.connectionString);
1114
+ });
1115
+ pool.on("error", (error) => {
1116
+ logException(error, "db.pool.client.failed", { "app.db.driver": "postgres" });
1117
+ });
1118
+ return new PostgresExecutor(pool, args.connectionString);
1055
1119
  }
1056
1120
  //#endregion
1057
1121
  //#region src/db/executor.ts
@@ -1068,4 +1132,4 @@ function createJuniorSqlExecutor(args) {
1068
1132
  });
1069
1133
  }
1070
1134
  //#endregion
1071
- 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 };
1135
+ 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-DUkGlK89.js";
3
- import { tn as getSqlExecutor } from "./agent-hooks-BcH6E48y.js";
4
- import "./conversation-CPjHYOV5.js";
2
+ import { j as storeAttachment, k as readLiveAttachment } from "./agent-runner-uP7QRc4c.js";
3
+ import { nn as getSqlExecutor } from "./agent-hooks-Da_H0jHv.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-Cox1Mgcv.js";
1
+ import { N as getDeploymentServiceVersion, P as getDeploymentTelemetryAttributes } from "./logging-B4sKwmCG.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-CSxvdSoV.js";
3
+ import { n as getCurrentConversationPrivacy } from "./conversation-privacy-au02dyZK.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-DuCzUoCo.js";
1
+ import { i as getChatConfig } from "./config-JR9wke1W.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-A7-RRBOE.js";
2
+ import { t as JUNIOR_VERSION } from "./version-CWkIGcLU.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-xk2-Id1T.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-Cox1Mgcv.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-cwHVOwVZ.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-B4sKwmCG.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-BqXd0ZPV.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-CZqUNJD0.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-DGQEOk1A.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-BNfXlq_1.js";
1
+ import { h as extractAssistantText } from "./checkpoint-DaD7_Gsb.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-DUkGlK89.js";
2
- import { a as GET, n as syncLocalOAuthCredential, r as GET$1 } from "./credential-sync-BO4DfH9a.js";
1
+ import { Pn as createUserTokenStore } from "./agent-runner-uP7QRc4c.js";
2
+ import { a as GET, n as syncLocalOAuthCredential, r as GET$1 } from "./credential-sync-BWTA3LnL.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-BNfXlq_1.js";
1
+ import { i as abandonTurnRecord } from "./checkpoint-DaD7_Gsb.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-BX5lJRqW.js";
2
- import { v as setSpanAttributes, y as setSpanStatus } from "./logging-Cox1Mgcv.js";
3
- import { a as getChatConfig } from "./config-DuCzUoCo.js";
4
- import { n as pluginCatalogRuntime } from "./catalog-runtime-BSgsPVnr.js";
1
+ import { S as toOptionalTrimmed } from "./client-Ch9Hg9NU.js";
2
+ import { v as setSpanAttributes, y as setSpanStatus } from "./logging-B4sKwmCG.js";
3
+ import { i as getChatConfig } from "./config-JR9wke1W.js";
4
+ import { n as pluginCatalogRuntime } from "./catalog-runtime-C7339Cfm.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-CPjHYOV5.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-Cox1Mgcv.js";
1
+ import { f as logInfo, p as logWarn, v as setSpanAttributes } from "./logging-B4sKwmCG.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-Cox1Mgcv.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-BdApelHS.js";
1
+ import { v as setSpanAttributes, w as withSpan } from "./logging-B4sKwmCG.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-BamYnmhO.js";
3
3
  import { z } from "zod";
4
4
  import { FileSystem, Sandbox } from "@vercel/sandbox";
5
5
  //#region src/chat/sandbox/resources.ts