@sentry/junior 0.258.0 → 0.260.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 (77) hide show
  1. package/dist/adapter-Dj5BTJRd.js +270 -0
  2. package/dist/{admin-My1SLGVO.js → admin-tzkZDqrH.js} +1 -1
  3. package/dist/{agent-hooks-BJ_5mlRH.js → agent-hooks-V4Hfc2tB.js} +711 -697
  4. package/dist/{agent-runner-DGsFQw72.js → agent-runner-DvTUyGTY.js} +751 -2508
  5. package/dist/api/schema.d.ts +239 -54
  6. package/dist/api/schema.js +4 -4
  7. package/dist/api.js +218 -57
  8. package/dist/{app-PX2H1PxU.d.ts → app-BsBUs3rF.d.ts} +6 -3
  9. package/dist/app.d.ts +2 -2
  10. package/dist/app.js +31 -31
  11. package/dist/{assistant-reply-H1M-91oF.js → assistant-reply-CEOMzsWy.js} +1 -1
  12. package/dist/{automation-DWBFBenG.js → automation-DrpcA-SX.js} +3 -0
  13. package/dist/{briefs-vYoK85rJ.js → briefs-BSCkyYqs.js} +4 -4
  14. package/dist/{catalog-runtime-BN4DVxco.js → catalog-runtime-Bpcs2b2L.js} +1 -1
  15. package/dist/cli/chat.d.ts +1 -1
  16. package/dist/cli/chat.js +16 -16
  17. package/dist/cli/check.js +3 -3
  18. package/dist/cli/main.js +6 -2
  19. package/dist/cli/plugins.d.ts +1 -1
  20. package/dist/cli/plugins.js +4 -4
  21. package/dist/cli/run.d.ts +2 -1
  22. package/dist/cli/run.js +2 -1
  23. package/dist/cli/snapshot-create.js +4 -3
  24. package/dist/cli/upgrade.d.ts +1 -1
  25. package/dist/cli/upgrade.js +3 -3
  26. package/dist/{client-DbyHuMFU.js → client-JeyzRwsT.js} +57 -4
  27. package/dist/{config-_WO_AjCB.js → config-ULs6Zl9b.js} +5 -2
  28. package/dist/{connections-ag_1JOhB.js → connections-CZ7HhEmN.js} +174 -10
  29. package/dist/{conversation-DjN3mlog.js → conversation-CvuKJ3tA.js} +108 -155
  30. package/dist/{conversation-privacy-DHP_xnVj.js → conversation-privacy-BQSlZXgV.js} +1 -1
  31. package/dist/{credential-sync-B-CPX_ag.js → credential-sync-BKcv5rBe.js} +14 -177
  32. package/dist/{executor-RvG6kVe1.js → executor-BoGNVEDn.js} +3 -2
  33. package/dist/{images-C2J_bj2g.js → images-BBmDXQCB.js} +3 -3
  34. package/dist/instrumentation.js +2 -2
  35. package/dist/{job-queue-DVe37it2.js → job-queue-CbdVyaCo.js} +1 -1
  36. package/dist/{logging-DsHONhVm.js → logging-DSMmkHXG.js} +1 -1
  37. package/dist/{message-DyitL8no.js → message-zaj5gBbS.js} +3 -3
  38. package/dist/nitro.d.ts +2 -2
  39. package/dist/nitro.js +3 -3
  40. package/dist/{oauth-callback-server-CDby-pCn.js → oauth-callback-server-yYFG8Own.js} +2 -2
  41. package/dist/{plugins-B11Mfkmv.d.ts → plugins-B_0Cr0MO.d.ts} +5 -1
  42. package/dist/{profile-DpYjfKke.js → profile-ByWkAY7L.js} +24 -293
  43. package/dist/{prompt-xgpyMtg7.js → prompt-DeVax2qO.js} +1 -1
  44. package/dist/{registry-Du566MtJ.js → registry-BL-osYWN.js} +41 -2
  45. package/dist/{resolve-ClCIgh8E.js → resolve-HuPG2VMB.js} +9 -4
  46. package/dist/{result-BBbKA61B.js → result-DS7V4a3-.js} +9 -14
  47. package/dist/{runner-CCuqFSqx.js → runner-Cba_OfGl.js} +11 -11
  48. package/dist/{sandbox-egress-signals-DY1mbKF4.js → sandbox-egress-signals-C7NcPzea.js} +1 -1
  49. package/dist/{schema-DrMh3NtR.js → schema-OzL8Zw4H.js} +82 -3
  50. package/dist/service-account-DqwHhwJA.js +120 -0
  51. package/dist/service-account-Ko1Xs--F.js +661 -0
  52. package/dist/{session-stop-CIoFiwwe.js → session-stop-HfKx-pky.js} +180 -22
  53. package/dist/{skills-DyQBLIrK.js → skills-D6_bcAuW.js} +2 -2
  54. package/dist/{spawn-Dqfeo7XP.js → spawn-BWqK6EwM.js} +2 -2
  55. package/dist/{store-DJLwq4x8.js → store-DzRbd5VT.js} +6 -6
  56. package/dist/{task-queue-BzW4MaWU.js → task-queue-9LICOzcL.js} +3 -3
  57. package/dist/{task-runner-D3qJh4fK.js → task-runner-DGnd_B5X.js} +10 -10
  58. package/dist/{tasks-CEXKTASS.js → tasks-CjrS098O.js} +4928 -2389
  59. package/dist/thread-state-CqkYowEz.js +184 -0
  60. package/dist/{turn-failure-response-CWx7aNIh.js → turn-failure-response-BkKmGqFt.js} +8 -9
  61. package/dist/{turn-lifecycle-C9JFst7-.js → turn-lifecycle-DYv8IV6w.js} +1 -1
  62. package/dist/{turn-session-routing-CUxtfpr7.js → turn-session-routing-TaVhKmdz.js} +1 -1
  63. package/dist/{validation-BHRxa5G4.js → validation-BrXMYPyo.js} +1 -1
  64. package/dist/{version-C0U6rHg0.js → version-Ct049vav.js} +1 -1
  65. package/dist/version.js +1 -1
  66. package/dist/{viewer-CGvvRqKp.js → viewer-C-J0ewlH.js} +19 -10
  67. package/dist/{web-input-Keb5GRWj.js → web-input-C_xB3RXp.js} +41 -37
  68. package/dist/{work-DRcsJ3hV.js → work-D829Ue7k.js} +9 -10
  69. package/dist/{worker-Cjo-QqPq.js → worker-BRTYzlpk.js} +5 -5
  70. package/migrations/0061_workspace_vcpus.sql +1 -0
  71. package/migrations/meta/0061_snapshot.json +3471 -0
  72. package/migrations/meta/_journal.json +7 -0
  73. package/package.json +6 -6
  74. package/dist/experimental-BNK1l1jv.js +0 -49
  75. package/dist/oauth-authorization-djQn5Nhy.js +0 -97
  76. package/dist/pending-auth-D8J1uJUS.js +0 -442
  77. package/dist/thread-state-W3f6kAtz.js +0 -426
@@ -1,11 +1,7 @@
1
- import { S as toOptionalTrimmed } from "./client-DbyHuMFU.js";
2
- import { b as setSpanStatus, y as setSpanAttributes } from "./logging-DsHONhVm.js";
3
- import { i as getChatConfig } from "./config-_WO_AjCB.js";
4
- import { n as pluginCatalogRuntime } from "./catalog-runtime-BN4DVxco.js";
1
+ import { C as toOptionalTrimmed } from "./client-JeyzRwsT.js";
2
+ import { b as setSpanStatus, y as setSpanAttributes } from "./logging-DSMmkHXG.js";
3
+ import { n as pluginCatalogRuntime } from "./catalog-runtime-Bpcs2b2L.js";
5
4
  import { createHash } from "node:crypto";
6
- import { createMemoryState } from "@chat-adapter/state-memory";
7
- import { createRedisState } from "@chat-adapter/state-redis";
8
- import { setTimeout as setTimeout$1 } from "node:timers/promises";
9
5
  // src/chat/sandbox/paths.ts
10
6
  function normalizeWorkspaceRoot(input) {
11
7
  const candidate = (input ?? "").trim();
@@ -28,291 +24,6 @@ function sandboxSkillPathResolution(skillName) {
28
24
  const skillDir = sandboxSkillDir(skillName);
29
25
  return `Resolve relative paths in this skill against ${skillDir}. For bash commands from this skill, cd to ${skillDir} first or use absolute paths.`;
30
26
  }
31
- // src/chat/sleep.ts
32
- /** Wait for a duration, rejecting with the owning signal reason when cancelled. */
33
- function sleep(ms, signal) {
34
- if (!signal) return new Promise((resolve) => setTimeout(resolve, ms));
35
- return new Promise((resolve, reject) => {
36
- if (signal.aborted) {
37
- reject(signal.reason);
38
- return;
39
- }
40
- const timeoutId = setTimeout(() => {
41
- signal.removeEventListener("abort", onAbort);
42
- resolve();
43
- }, ms);
44
- const onAbort = () => {
45
- clearTimeout(timeoutId);
46
- reject(signal.reason);
47
- };
48
- signal.addEventListener("abort", onAbort, { once: true });
49
- });
50
- }
51
- // src/chat/state/locks.ts
52
- const ACTIVE_LOCK_TTL_MS = 9e4;
53
- const MUTATION_LOCK_TTL_MS = 1e4;
54
- /**
55
- * Acquire a lock for long-running work that the queued state adapter should
56
- * keep alive while the owning invocation is still making progress.
57
- */
58
- async function acquireActiveLock(state, threadId) {
59
- return await state.acquireLock(threadId, ACTIVE_LOCK_TTL_MS);
60
- }
61
- /**
62
- * Run work under one lock, optionally waiting for the current owner.
63
- * `keepAlive` is for multi-store mutations that must retain ownership until all
64
- * side effects finish; callers should still fence each blind write.
65
- */
66
- async function withLock(state, key, run, options = {}) {
67
- const startedAtMs = Date.now();
68
- let lock;
69
- while (true) {
70
- lock = await state.acquireLock(key, options.ttlMs ?? 9e4);
71
- if (lock) break;
72
- if (Date.now() - startedAtMs >= (options.waitMs ?? 0)) return { acquired: false };
73
- await setTimeout$1(options.retryMs ?? 25, void 0, { ref: false });
74
- }
75
- const ttlMs = options.ttlMs ?? 9e4;
76
- const heartbeat = options.keepAlive ? setInterval(() => {
77
- state.extendLock(lock, ttlMs);
78
- }, Math.max(1, Math.floor(ttlMs / 3))) : void 0;
79
- heartbeat?.unref();
80
- try {
81
- return {
82
- acquired: true,
83
- value: await run(lock)
84
- };
85
- } finally {
86
- if (heartbeat) clearInterval(heartbeat);
87
- await state.releaseLock(lock);
88
- }
89
- }
90
- /**
91
- * Prove lock ownership immediately before a blind write.
92
- *
93
- * Whole-record mutations must stop if their lock expired rather than overwrite
94
- * state committed by a newer owner.
95
- */
96
- async function fenceLock(state, lock, ttlMs = MUTATION_LOCK_TTL_MS) {
97
- if (!await state.extendLock(lock, ttlMs)) throw new Error(`Lock ownership was lost before write for ${lock.threadId}`);
98
- }
99
- // src/chat/state/adapter.ts
100
- const ACTIVE_LOCK_HEARTBEAT_MS = 3e4;
101
- let stateAdapter;
102
- let redisStateAdapter;
103
- /** Lazily connect state operations, including queued-adapter lock heartbeats. */
104
- function createConnectingStateAdapter(base) {
105
- const connected = async (operation) => {
106
- await base.connect();
107
- return await operation();
108
- };
109
- return {
110
- appendToList: (key, value, options) => connected(() => base.appendToList(key, value, options)),
111
- connect: () => base.connect(),
112
- disconnect: () => base.disconnect(),
113
- subscribe: (threadId) => connected(() => base.subscribe(threadId)),
114
- unsubscribe: (threadId) => connected(() => base.unsubscribe(threadId)),
115
- isSubscribed: (threadId) => connected(() => base.isSubscribed(threadId)),
116
- acquireLock: (threadId, ttlMs) => connected(() => base.acquireLock(threadId, ttlMs)),
117
- releaseLock: (lock) => connected(() => base.releaseLock(lock)),
118
- extendLock: (lock, ttlMs) => connected(() => base.extendLock(lock, ttlMs)),
119
- forceReleaseLock: (threadId) => connected(() => base.forceReleaseLock(threadId)),
120
- enqueue: (threadId, entry, maxSize) => connected(() => base.enqueue(threadId, entry, maxSize)),
121
- dequeue: (threadId) => connected(() => base.dequeue(threadId)),
122
- queueDepth: (threadId) => connected(() => base.queueDepth(threadId)),
123
- get: (key) => connected(() => base.get(key)),
124
- getList: (key) => connected(() => base.getList(key)),
125
- set: (key, value, ttlMs) => connected(() => base.set(key, value, ttlMs)),
126
- setIfNotExists: (key, value, ttlMs) => connected(() => base.setIfNotExists(key, value, ttlMs)),
127
- delete: (key) => connected(() => base.delete(key))
128
- };
129
- }
130
- function createPrefixedStateAdapter(base, prefix) {
131
- const prefixed = (value) => `${prefix}:${value}`;
132
- const unprefixed = (value) => value.startsWith(`${prefix}:`) ? value.slice(prefix.length + 1) : value;
133
- const prefixLock = (lock) => ({
134
- ...lock,
135
- threadId: prefixed(lock.threadId)
136
- });
137
- const unprefixLock = (lock) => ({
138
- ...lock,
139
- threadId: unprefixed(lock.threadId)
140
- });
141
- return {
142
- appendToList: (key, value, options) => base.appendToList(prefixed(key), value, options),
143
- connect: () => base.connect(),
144
- disconnect: () => base.disconnect(),
145
- subscribe: (threadId) => base.subscribe(prefixed(threadId)),
146
- unsubscribe: (threadId) => base.unsubscribe(prefixed(threadId)),
147
- isSubscribed: (threadId) => base.isSubscribed(prefixed(threadId)),
148
- acquireLock: async (threadId, ttlMs) => {
149
- const lock = await base.acquireLock(prefixed(threadId), ttlMs);
150
- return lock ? unprefixLock(lock) : null;
151
- },
152
- releaseLock: (lock) => base.releaseLock(prefixLock(lock)),
153
- extendLock: async (lock, ttlMs) => {
154
- const prefixedLock = prefixLock(lock);
155
- const extended = await base.extendLock(prefixedLock, ttlMs);
156
- if (extended) lock.expiresAt = prefixedLock.expiresAt;
157
- return extended;
158
- },
159
- forceReleaseLock: (threadId) => base.forceReleaseLock(prefixed(threadId)),
160
- enqueue: (threadId, entry, maxSize) => base.enqueue(prefixed(threadId), entry, maxSize),
161
- dequeue: (threadId) => base.dequeue(prefixed(threadId)),
162
- queueDepth: (threadId) => base.queueDepth(prefixed(threadId)),
163
- get: (key) => base.get(prefixed(key)),
164
- getList: (key) => base.getList(prefixed(key)),
165
- set: (key, value, ttlMs) => base.set(prefixed(key), value, ttlMs),
166
- setIfNotExists: (key, value, ttlMs) => base.setIfNotExists(prefixed(key), value, ttlMs),
167
- delete: (key) => base.delete(prefixed(key))
168
- };
169
- }
170
- function createQueuedStateAdapter(base, options) {
171
- const heartbeats = /* @__PURE__ */ new Map();
172
- const shouldHeartbeatLock = (ttlMs) => ttlMs === ACTIVE_LOCK_TTL_MS;
173
- const heartbeatKey = (lock) => `${lock.threadId}:${lock.token}`;
174
- const stopHeartbeatByKey = (key) => {
175
- const heartbeat = heartbeats.get(key);
176
- if (!heartbeat) return;
177
- clearInterval(heartbeat.timer);
178
- heartbeats.delete(key);
179
- };
180
- const stopHeartbeat = (lock) => {
181
- stopHeartbeatByKey(heartbeatKey(lock));
182
- };
183
- const stopHeartbeatsForThread = (threadId) => {
184
- for (const [key, heartbeat] of heartbeats) if (heartbeat.lock.threadId === threadId) stopHeartbeatByKey(key);
185
- };
186
- const stopAllHeartbeats = () => {
187
- for (const key of heartbeats.keys()) stopHeartbeatByKey(key);
188
- };
189
- const runHeartbeat = async (key) => {
190
- const heartbeat = heartbeats.get(key);
191
- if (!heartbeat || heartbeat.inFlight) return;
192
- heartbeat.inFlight = true;
193
- try {
194
- if (Date.now() - heartbeat.startedAtMs >= options.activeLockMaxAgeMs) {
195
- stopHeartbeatByKey(key);
196
- return;
197
- }
198
- if (!await base.extendLock(heartbeat.lock, heartbeat.ttlMs)) {
199
- stopHeartbeatByKey(key);
200
- return;
201
- }
202
- heartbeat.lock.expiresAt = Date.now() + heartbeat.ttlMs;
203
- } catch {} finally {
204
- const current = heartbeats.get(key);
205
- if (current === heartbeat) current.inFlight = false;
206
- }
207
- };
208
- const startOrUpdateHeartbeat = (lock, ttlMs) => {
209
- const key = heartbeatKey(lock);
210
- const existing = heartbeats.get(key);
211
- if (existing) {
212
- existing.ttlMs = ttlMs;
213
- return;
214
- }
215
- const timer = setInterval(() => {
216
- runHeartbeat(key);
217
- }, ACTIVE_LOCK_HEARTBEAT_MS);
218
- timer.unref?.();
219
- heartbeats.set(key, {
220
- inFlight: false,
221
- lock,
222
- startedAtMs: Date.now(),
223
- timer,
224
- ttlMs
225
- });
226
- };
227
- const acquireLock = async (threadId, ttlMs) => {
228
- const lock = await base.acquireLock(threadId, ttlMs);
229
- if (lock && shouldHeartbeatLock(ttlMs)) startOrUpdateHeartbeat(lock, ttlMs);
230
- return lock;
231
- };
232
- return {
233
- appendToList: (key, value, options) => base.appendToList(key, value, options),
234
- connect: () => base.connect(),
235
- disconnect: async () => {
236
- stopAllHeartbeats();
237
- await base.disconnect();
238
- },
239
- subscribe: (threadId) => base.subscribe(threadId),
240
- unsubscribe: (threadId) => base.unsubscribe(threadId),
241
- isSubscribed: (threadId) => base.isSubscribed(threadId),
242
- acquireLock,
243
- releaseLock: async (lock) => {
244
- stopHeartbeat(lock);
245
- await base.releaseLock(lock);
246
- },
247
- extendLock: async (lock, ttlMs) => {
248
- const extended = await base.extendLock(lock, ttlMs);
249
- if (extended) {
250
- lock.expiresAt = Date.now() + ttlMs;
251
- if (shouldHeartbeatLock(ttlMs)) startOrUpdateHeartbeat(lock, ttlMs);
252
- else stopHeartbeat(lock);
253
- } else stopHeartbeat(lock);
254
- return extended;
255
- },
256
- forceReleaseLock: async (threadId) => {
257
- stopHeartbeatsForThread(threadId);
258
- await base.forceReleaseLock(threadId);
259
- },
260
- enqueue: (threadId, entry, maxSize) => base.enqueue(threadId, entry, maxSize),
261
- dequeue: (threadId) => base.dequeue(threadId),
262
- queueDepth: (threadId) => base.queueDepth(threadId),
263
- get: (key) => base.get(key),
264
- getList: (key) => base.getList(key),
265
- set: (key, value, ttlMs) => base.set(key, value, ttlMs),
266
- setIfNotExists: (key, value, ttlMs) => base.setIfNotExists(key, value, ttlMs),
267
- delete: (key) => base.delete(key)
268
- };
269
- }
270
- function withOptionalPrefix(base, prefix) {
271
- return prefix ? createPrefixedStateAdapter(base, prefix) : base;
272
- }
273
- function createStateAdapter() {
274
- const config = getChatConfig();
275
- const activeLockMaxAgeMs = config.bot.turnTimeoutMs + ACTIVE_LOCK_TTL_MS;
276
- if (config.state.adapter === "memory") {
277
- redisStateAdapter = void 0;
278
- return createQueuedStateAdapter(createConnectingStateAdapter(withOptionalPrefix(createMemoryState(), config.state.keyPrefix)), { activeLockMaxAgeMs });
279
- }
280
- if (!config.state.redisUrl) throw new Error("REDIS_URL is required for durable Slack thread state");
281
- const redisState = createRedisState({ url: config.state.redisUrl });
282
- redisStateAdapter = redisState;
283
- return createQueuedStateAdapter(createConnectingStateAdapter(withOptionalPrefix(redisState, config.state.keyPrefix)), { activeLockMaxAgeMs });
284
- }
285
- function getOptionalRedisStateAdapter() {
286
- getStateAdapter();
287
- return redisStateAdapter;
288
- }
289
- async function getConnectedStateContext() {
290
- const adapter = getStateAdapter();
291
- await adapter.connect();
292
- return {
293
- redisStateAdapter: getOptionalRedisStateAdapter(),
294
- stateAdapter: adapter
295
- };
296
- }
297
- /** Return the Redis adapter only when the caller is using the default state adapter. */
298
- async function getDefaultRedisStateAdapterFor(adapter) {
299
- if (adapter !== stateAdapter) return;
300
- const context = await getConnectedStateContext();
301
- return context.stateAdapter === adapter ? context.redisStateAdapter : void 0;
302
- }
303
- function getStateAdapter() {
304
- if (!stateAdapter) stateAdapter = createStateAdapter();
305
- return stateAdapter;
306
- }
307
- async function disconnectStateAdapter() {
308
- if (!stateAdapter) return;
309
- try {
310
- await stateAdapter.disconnect();
311
- } finally {
312
- stateAdapter = void 0;
313
- redisStateAdapter = void 0;
314
- }
315
- }
316
27
  // src/chat/sandbox/noninteractive-command.ts
317
28
  const NON_INTERACTIVE_ENV = {
318
29
  CI: "1",
@@ -378,6 +89,26 @@ async function runNonInteractiveCommand(sandbox, input) {
378
89
  };
379
90
  return await sandbox.runCommand(command);
380
91
  }
92
+ // src/chat/sleep.ts
93
+ /** Wait for a duration, rejecting with the owning signal reason when cancelled. */
94
+ function sleep(ms, signal) {
95
+ if (!signal) return new Promise((resolve) => setTimeout(resolve, ms));
96
+ return new Promise((resolve, reject) => {
97
+ if (signal.aborted) {
98
+ reject(signal.reason);
99
+ return;
100
+ }
101
+ const timeoutId = setTimeout(() => {
102
+ signal.removeEventListener("abort", onAbort);
103
+ resolve();
104
+ }, ms);
105
+ const onAbort = () => {
106
+ clearTimeout(timeoutId);
107
+ reject(signal.reason);
108
+ };
109
+ signal.addEventListener("abort", onAbort, { once: true });
110
+ });
111
+ }
381
112
  // src/chat/sandbox/credentials.ts
382
113
  /**
383
114
  * Resolve explicit Vercel Sandbox credentials, or return undefined to let
@@ -841,4 +572,4 @@ function isStale(profile, createdAtMs) {
841
572
  const maxAgeMs = floatingMaxAgeMs();
842
573
  return maxAgeMs === 0 || Date.now() - createdAtMs > maxAgeMs;
843
574
  }
844
- export { SANDBOX_DATA_ROOT as A, getDefaultRedisStateAdapterFor as C, fenceLock as D, acquireActiveLock as E, sandboxSkillFile as F, sandboxSkillPathResolution as I, SANDBOX_SKILLS_ROOT as M, SANDBOX_WORKSPACE_ROOT as N, withLock as O, sandboxSkillDir as P, disconnectStateAdapter as S, MUTATION_LOCK_TTL_MS as T, workspaceSnapshotNotReadyUserMessage as _, isAbortError as a, buildNonInteractiveShellScript as b, isSandboxCommandStreamInterruptedError as c, isSnapshottingError as d, throwSandboxOperationError as f, isWorkspaceSnapshotNotReadyError as g, getWorkspaceSnapshotNotReadyError as h, ensureDockerDaemon as i, SANDBOX_REPOS_ROOT as j, sleep as k, isSandboxMissingError as l, WorkspaceSnapshotNotReadyError as m, hash as n, isAlreadyExistsError as o, wrapSandboxSetupError as p, isStale as r, isSandboxApiTransientError as s, create as t, isSandboxUnavailableError as u, getVercelSandboxCredentials as v, getStateAdapter as w, runNonInteractiveCommand as x, buildCommandScript as y };
575
+ export { SANDBOX_DATA_ROOT as C, sandboxSkillDir as D, SANDBOX_WORKSPACE_ROOT as E, sandboxSkillFile as O, runNonInteractiveCommand as S, SANDBOX_SKILLS_ROOT as T, workspaceSnapshotNotReadyUserMessage as _, isAbortError as a, buildCommandScript as b, isSandboxCommandStreamInterruptedError as c, isSnapshottingError as d, throwSandboxOperationError as f, isWorkspaceSnapshotNotReadyError as g, getWorkspaceSnapshotNotReadyError as h, ensureDockerDaemon as i, sandboxSkillPathResolution as k, isSandboxMissingError as l, WorkspaceSnapshotNotReadyError as m, hash as n, isAlreadyExistsError as o, wrapSandboxSetupError as p, isStale as r, isSandboxApiTransientError as s, create as t, isSandboxUnavailableError as u, getVercelSandboxCredentials as v, SANDBOX_REPOS_ROOT as w, buildNonInteractiveShellScript as x, sleep as y };
@@ -1,4 +1,4 @@
1
- import { H as conversationBriefSchema, U as parseBriefInput, V as briefOutcomeStatusSchema } from "./conversation-DjN3mlog.js";
1
+ import { J as parseBriefInput, K as briefOutcomeStatusSchema, q as conversationBriefSchema } from "./conversation-CvuKJ3tA.js";
2
2
  import { z } from "zod";
3
3
  // src/chat/briefs/generate.ts
4
4
  const MAX_INPUT_CHARS = 6e4;
@@ -1,4 +1,4 @@
1
- import { m as logWarn, p as logInfo, y as setSpanAttributes } from "./logging-DsHONhVm.js";
1
+ import { m as logWarn, p as logInfo, y as setSpanAttributes } from "./logging-DSMmkHXG.js";
2
2
  import { a as isUserActor, o as parseActorUserId } from "./actor-tlxzqaRe.js";
3
3
  import { n as normalizePluginPackageNames, o as pluginRoots, t as discoverInstalledPluginPackageContent } from "./package-discovery-DJBompdd.js";
4
4
  import path from "node:path";
@@ -49,6 +49,13 @@ function mcpOauthClientSource(oauthClient) {
49
49
  setDefined$1(result, "authorize-params", oauthClient.authorizeParams);
50
50
  return result;
51
51
  }
52
+ /** Convert a camelCase `accounts` block to its plugin.yaml source keys. */
53
+ function accountsSource(accounts) {
54
+ const result = {};
55
+ setDefined$1(result, "user-oauth", accounts.userOAuth);
56
+ setDefined$1(result, "service-account", accounts.serviceAccount);
57
+ return result;
58
+ }
52
59
  function inlineMcpSource(mcp) {
53
60
  if (mcp === void 0 || !isRecord(mcp)) return mcp;
54
61
  const result = {};
@@ -99,6 +106,7 @@ function inlineManifestSource(manifest) {
99
106
  setDefined$1(result, "runtime-postinstall", manifest.runtimePostinstall);
100
107
  setDefined$1(result, "mcp", inlineMcpSource(manifest.mcp));
101
108
  setDefined$1(result, "oauth", inlineOauthSource(manifest.oauth));
109
+ setDefined$1(result, "accounts", manifest.accounts && accountsSource(manifest.accounts));
102
110
  setDefined$1(result, "target", inlineTargetSource(manifest.name, manifest.target));
103
111
  return result;
104
112
  }
@@ -249,6 +257,10 @@ const mcpOauthClientSourceSchema = z.object({
249
257
  scope: nonEmptyTrimmedString.optional(),
250
258
  "authorize-params": stringMapSchema.optional()
251
259
  }).passthrough();
260
+ const accountsSourceSchema = z.object({
261
+ "user-oauth": z.boolean().optional(),
262
+ "service-account": z.object({ tools: nonEmptyStringArraySchema("tools") }).strict().optional()
263
+ }).strict();
252
264
  const mcpSourceSchema = z.object({
253
265
  transport: nonEmptyTrimmedString.refine((value) => value === "http", { error: "must be \"http\"" }).optional(),
254
266
  url: httpsUrlString,
@@ -277,6 +289,7 @@ const manifestSourceSchema = z.object({
277
289
  "env-vars": z.record(z.string(), z.unknown(), { error: "must be an object" }).optional(),
278
290
  mcp: z.record(z.string(), z.unknown(), { error: "must be an object" }).optional(),
279
291
  oauth: z.record(z.string(), z.unknown(), { error: "must be an object" }).optional(),
292
+ accounts: z.record(z.string(), z.unknown(), { error: "must be an object" }).optional(),
280
293
  target: z.record(z.string(), z.unknown(), { error: "must be an object" }).optional()
281
294
  }).passthrough();
282
295
  function setDefined(target, key, value) {
@@ -335,6 +348,7 @@ function manifestConfigPatch(config) {
335
348
  result.oauth = oauth;
336
349
  }
337
350
  }
351
+ if (config.accounts !== void 0) result.accounts = config.accounts && accountsSource(config.accounts);
338
352
  if (config.target !== void 0) {
339
353
  if (!config.target) result.target = null;
340
354
  else {
@@ -620,6 +634,28 @@ function normalizeMcp(data, envVars, name) {
620
634
  ...result.data["wrapped-tools"] ? { wrappedTools: result.data["wrapped-tools"] } : void 0
621
635
  };
622
636
  }
637
+ /**
638
+ * Validate which accounts the plugin may use against the surfaces that
639
+ * support them. Today only MCP OAuth stores a service account.
640
+ */
641
+ function normalizeAccounts(data, mcp, name) {
642
+ const result = accountsSourceSchema.safeParse(data);
643
+ if (!result.success) throw new Error(issueMessage(result.error, `Plugin ${name} accounts`));
644
+ const userOAuth = result.data["user-oauth"];
645
+ const serviceAccount = result.data["service-account"];
646
+ if (userOAuth === false && !serviceAccount) throw new Error(`Plugin ${name} accounts.user-oauth false requires accounts.service-account`);
647
+ if (!serviceAccount) return;
648
+ if (!mcp || mcp.auth || mcp.oauthClient) throw new Error(`Plugin ${name} accounts.service-account requires mcp without auth or oauth-client`);
649
+ if (mcp.allowedTools) {
650
+ const loadedTools = /* @__PURE__ */ new Set([...mcp.allowedTools, ...mcp.wrappedTools ?? []]);
651
+ const unknownTools = serviceAccount.tools.filter((tool) => !loadedTools.has(tool));
652
+ if (unknownTools.length > 0) throw new Error(`Plugin ${name} accounts.service-account.tools must be listed in mcp.allowed-tools or mcp.wrapped-tools: ${unknownTools.join(", ")}`);
653
+ }
654
+ return {
655
+ ...userOAuth === false ? { userOAuth } : void 0,
656
+ serviceAccount: { tools: serviceAccount.tools }
657
+ };
658
+ }
623
659
  function parseManifestSource(parsedSource, dir, config, options) {
624
660
  const source = applyManifestConfig(parsedSource, config);
625
661
  const sourceResult = manifestSourceSchema.safeParse(source);
@@ -638,6 +674,7 @@ function parseManifestSource(parsedSource, dir, config, options) {
638
674
  if (path === "env-vars") throw new Error(`Plugin ${String(parsedSource.name ?? "unknown")} env-vars must be an object`);
639
675
  if (path === "mcp") throw new Error(`Plugin ${String(parsedSource.name ?? "unknown")} mcp must be an object`);
640
676
  if (path === "oauth") throw new Error(`Plugin ${String(parsedSource.name ?? "unknown")} oauth must be an object`);
677
+ if (path === "accounts") throw new Error(`Plugin ${String(parsedSource.name ?? "unknown")} accounts must be an object`);
641
678
  if (path === "target") throw new Error(`Plugin ${String(parsedSource.name ?? "unknown")} target must be an object`);
642
679
  throw new Error(issue?.message ?? `Invalid plugin manifest in ${dir}`);
643
680
  }
@@ -656,6 +693,7 @@ function parseManifestSource(parsedSource, dir, config, options) {
656
693
  const runtimeDependencies = data["runtime-dependencies"] ? normalizeRuntimeDependencies(data["runtime-dependencies"], data.name) : void 0;
657
694
  const runtimePostinstall = data["runtime-postinstall"] ? normalizeRuntimePostinstall(data["runtime-postinstall"], data.name) : void 0;
658
695
  const mcp = data.mcp ? normalizeMcp(data.mcp, envVars, data.name) : void 0;
696
+ const accounts = data.accounts ? normalizeAccounts(data.accounts, mcp, data.name) : void 0;
659
697
  const manifest = {
660
698
  name: data.name,
661
699
  displayName: data["display-name"],
@@ -668,7 +706,8 @@ function parseManifestSource(parsedSource, dir, config, options) {
668
706
  ...credentials ? { credentials } : void 0,
669
707
  ...runtimeDependencies ? { runtimeDependencies } : void 0,
670
708
  ...runtimePostinstall ? { runtimePostinstall } : void 0,
671
- ...mcp ? { mcp } : void 0
709
+ ...mcp ? { mcp } : void 0,
710
+ ...accounts ? { accounts } : void 0
672
711
  };
673
712
  if (data.oauth) {
674
713
  if (!credentials && options?.allowHookManagedEgress !== true) throw new Error(`Plugin ${data.name} oauth requires credentials`);
@@ -1,5 +1,6 @@
1
- import { T as withSpan, y as setSpanAttributes } from "./logging-DsHONhVm.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-DpYjfKke.js";
1
+ import { T as withSpan, y as setSpanAttributes } from "./logging-DSMmkHXG.js";
2
+ import { r as getStateAdapter } from "./adapter-Dj5BTJRd.js";
3
+ import { E as SANDBOX_WORKSPACE_ROOT, S as runNonInteractiveCommand, r as isStale, t as create, u as isSandboxUnavailableError, v as getVercelSandboxCredentials, y as sleep } from "./profile-ByWkAY7L.js";
3
4
  import { z } from "zod";
4
5
  import { FileSystem, Sandbox } from "@vercel/sandbox";
5
6
  // src/chat/sandbox/resources.ts
@@ -26,8 +27,12 @@ function setSandboxResourceConfig(config) {
26
27
  configuredResources = { vcpus: config.vcpus };
27
28
  return previous;
28
29
  }
29
- /** Resolve app-level sandbox sizing, falling back to the legacy environment setting. */
30
- function getSandboxResources() {
30
+ /**
31
+ * Resolve sandbox sizing. A Workspace vCPU setting wins over the app setting,
32
+ * which wins over the legacy environment setting.
33
+ */
34
+ function getSandboxResources(workspace) {
35
+ if (workspace?.vcpus) return { vcpus: workspace.vcpus };
31
36
  return configuredResources ?? resourcesFromEnv();
32
37
  }
33
38
  // src/chat/sandbox/snapshot/span.ts
@@ -1,19 +1,14 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
2
- import { $ as getAgentInvocation, X as createAgentInvocationFromLatest, ct as isTerminalAgentInvocation, et as getAgentInvocationIdForEvents, ft as markAgentInvocationParentMailboxAppended, it as getAgentInvocationResultMessageId, nt as getAgentInvocationIdForResult, st as getLatestAgentInvocationForConversation, tt as getAgentInvocationIdForMessage } from "./agent-runner-DGsFQw72.js";
2
+ import { Ft as listTurnSummaries, Pt as getTurnRecord } from "./tasks-CjrS098O.js";
3
3
  import { t as createActor } from "./actor-tlxzqaRe.js";
4
- import { f as credentialContextForActor } from "./registry-Du566MtJ.js";
5
- import { Q as listTurnSummaries, Z as getTurnRecord } from "./tasks-CEXKTASS.js";
6
- import { a as EVENT_WAIT_MS, c as timerWatchCredentialSubject, s as isEventMailboxMetadata } from "./session-stop-CIoFiwwe.js";
7
- import { a as EVENT_SYSTEM_ACTOR, i as EVENT_MESSAGE_AUTHOR, o as isEventConversationMessage } from "./prompt-xgpyMtg7.js";
8
- import { r as appendAndEnqueueInboundMessage } from "./store-DJLwq4x8.js";
9
- import { r as enqueueAgentInvocation } from "./work-DRcsJ3hV.js";
4
+ import { f as credentialContextForActor } from "./registry-BL-osYWN.js";
5
+ import { $ as getAgentInvocationIdForResult, Q as getAgentInvocationIdForMessage, X as getAgentInvocation, Z as getAgentInvocationIdForEvents, at as isTerminalAgentInvocation, it as getLatestAgentInvocationForConversation, lt as markAgentInvocationParentMailboxAppended, q as createAgentInvocationFromLatest, tt as getAgentInvocationResultMessageId } from "./agent-runner-DvTUyGTY.js";
6
+ import { a as EVENT_SYSTEM_ACTOR, i as EVENT_MESSAGE_AUTHOR, o as isEventConversationMessage } from "./prompt-DeVax2qO.js";
7
+ import { a as EVENT_WAIT_MS, c as isEventMailboxMetadata, l as renderEventBatchText, u as timerWatchCredentialSubject } from "./session-stop-HfKx-pky.js";
8
+ import { r as appendAndEnqueueInboundMessage } from "./store-DzRbd5VT.js";
9
+ import { r as enqueueAgentInvocation } from "./work-D829Ue7k.js";
10
10
  import { z } from "zod";
11
11
  import { createEventSource, createLocalSource, createWebSource } from "@sentry/junior-plugin-api";
12
- // src/chat/task-execution/mailbox-input.ts
13
- /** Join non-empty mailbox Message text for one Turn. */
14
- function joinMailboxText(messages) {
15
- return messages.map((message) => message.input.text.trim()).filter(Boolean).join("\n\n");
16
- }
17
12
  // src/chat/conversations/web-mailbox.ts
18
13
  /** Parse web mailbox metadata written before Source and Actor were complete. */
19
14
  const legacyWebMailboxMetadataSchema = z.object({
@@ -405,7 +400,7 @@ async function startAgentInvocationsForChildInput(context, options) {
405
400
  };
406
401
  const { actor, source } = events[0];
407
402
  const invocation = await createAgentInvocationFromLatest({
408
- input: joinMailboxText(messages),
403
+ input: renderEventBatchText(messages),
409
404
  invocationId: getAgentInvocationIdForEvents(messages[0].inboundMessageId),
410
405
  latest,
411
406
  runAs: {
@@ -456,4 +451,4 @@ async function withAgentInvocationResultActors(work) {
456
451
  }))
457
452
  };
458
453
  }
459
- export { withAgentInvocationResultActors as a, resolveMailboxTurnWork as c, legacyWebMailboxMetadataSchema as d, joinMailboxText as f, startAgentInvocationsForChildInput as i, sourceFromTurnInput as l, enqueueAgentMessageToParent as n, getAuthPausedConversationTurnId as o, result_exports as r, getEventBatchDelayMs as s, enqueueAgentInvocationResult as t, turnInputFactsFromConversationMessage as u };
454
+ export { withAgentInvocationResultActors as a, resolveMailboxTurnWork as c, legacyWebMailboxMetadataSchema as d, startAgentInvocationsForChildInput as i, sourceFromTurnInput as l, enqueueAgentMessageToParent as n, getAuthPausedConversationTurnId as o, result_exports as r, getEventBatchDelayMs as s, enqueueAgentInvocationResult as t, turnInputFactsFromConversationMessage as u };
@@ -1,14 +1,14 @@
1
- import { f as logException, w as withLogContext, x as setTags } from "./logging-DsHONhVm.js";
2
- import { c as getConversationEventStore, u as getConversationStore } from "./viewer-CGvvRqKp.js";
3
- import { f as credentialContextForActor } from "./registry-Du566MtJ.js";
4
- import { $t as buildConversationContext, Gt as persistConversationMessages, It as recordAuthorizationCompleted, Wt as hydrateConversationMessages, an as normalizeConversationText, cn as upsertConversationMessage, et as persistWithRetry, in as markConversationMessage, kt as loadProjection, on as recordDeliveredAssistantMessage, q as saveTurnCheckpoint, wt as commitAcceptedReply } from "./tasks-CEXKTASS.js";
5
- import { K as messageCardText } from "./conversation-DjN3mlog.js";
6
- import { f as markTurnFailed, p as startActiveTurn, t as authorizationId } from "./oauth-authorization-djQn5Nhy.js";
7
- import { n as getAssistantReplyText } from "./assistant-reply-H1M-91oF.js";
8
- import { n as scheduleSessionCompletedPluginTasks, t as processPluginTask } from "./task-runner-D3qJh4fK.js";
9
- import { t as ConversationTurnLifecycleService } from "./turn-lifecycle-C9JFst7-.js";
10
- import { n as getPersistedSandboxState, o as persistThreadStateById, r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-W3f6kAtz.js";
11
- import { d as loadPendingMessageCards, i as completeAuthPauseTurn, l as buildDeliveredTurnStatePatch, t as finalizeFailedTurnReplyWithEvent } from "./turn-failure-response-CWx7aNIh.js";
1
+ import { At as saveTurnCheckpoint, I as loadProjection, Q as persistConversationMessages, U as recordAuthorizationCompleted, Wt as persistWithRetry, Z as hydrateConversationMessages, dt as markConversationMessage, ft as normalizeConversationText, ht as upsertConversationMessage, j as commitAcceptedReply, ot as buildConversationContext, pt as recordDeliveredAssistantMessage, yt as authorizationId } from "./tasks-CjrS098O.js";
2
+ import { f as logException, w as withLogContext, x as setTags } from "./logging-DSMmkHXG.js";
3
+ import { c as getConversationEventStore, u as getConversationStore } from "./viewer-C-J0ewlH.js";
4
+ import { f as credentialContextForActor } from "./registry-BL-osYWN.js";
5
+ import { It as markTurnFailed, Lt as startActiveTurn } from "./agent-runner-DvTUyGTY.js";
6
+ import { P as messageCardText } from "./conversation-CvuKJ3tA.js";
7
+ import { n as getAssistantReplyText } from "./assistant-reply-CEOMzsWy.js";
8
+ import { n as scheduleSessionCompletedPluginTasks, t as processPluginTask } from "./task-runner-DGnd_B5X.js";
9
+ import { t as ConversationTurnLifecycleService } from "./turn-lifecycle-DYv8IV6w.js";
10
+ import { n as getPersistedSandboxState, o as persistThreadStateById, r as getPersistedThreadState, s as coerceThreadConversationState } from "./thread-state-CqkYowEz.js";
11
+ import { d as loadPendingMessageCards, i as completeAuthPauseTurn, l as buildDeliveredTurnStatePatch, t as finalizeFailedTurnReplyWithEvent } from "./turn-failure-response-BkKmGqFt.js";
12
12
  import { randomUUID } from "node:crypto";
13
13
  import { createLocalSource, localDestinationSchema } from "@sentry/junior-plugin-api";
14
14
  // src/chat/local/runner.ts
@@ -1,4 +1,4 @@
1
- import { Mt as sandboxEgressSignalsResponseSchema } from "./agent-runner-DGsFQw72.js";
1
+ import { Mn as sandboxEgressSignalsResponseSchema } from "./tasks-CjrS098O.js";
2
2
  // 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;