@sentry/junior 0.203.0 → 0.204.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 (174) hide show
  1. package/dist/agent-CMyTD4DD.js +17509 -0
  2. package/dist/agent-hooks-Bbcp9e33.js +4040 -0
  3. package/dist/agent-runner-DNb1A49M.js +678 -0
  4. package/dist/api/schema.d.ts +2728 -2639
  5. package/dist/api/schema.js +4 -169
  6. package/dist/api.d.ts +23 -17
  7. package/dist/api.js +3881 -5326
  8. package/dist/app-B1TOqBI8.d.ts +246 -0
  9. package/dist/app.d.ts +4 -520
  10. package/dist/app.js +9522 -11875
  11. package/dist/auth-pause-state-DosEalIG.js +168 -0
  12. package/dist/catalog-runtime-BReos-D4.js +7 -0
  13. package/dist/checkpoint-CNrPyRJN.js +2450 -0
  14. package/dist/cli/chat.d.ts +20 -0
  15. package/dist/cli/chat.js +229 -336
  16. package/dist/cli/check.d.ts +8 -0
  17. package/dist/cli/check.js +513 -806
  18. package/dist/cli/env.d.ts +13 -0
  19. package/dist/cli/env.js +63 -12
  20. package/dist/cli/init.d.ts +3 -0
  21. package/dist/cli/init.js +90 -159
  22. package/dist/cli/main.d.ts +6 -0
  23. package/dist/cli/main.js +43 -64
  24. package/dist/cli/plugins.d.ts +13 -0
  25. package/dist/cli/plugins.js +148 -227
  26. package/dist/cli/run.d.ts +16 -0
  27. package/dist/cli/run.js +52 -8
  28. package/dist/cli/snapshot-create.d.ts +4 -0
  29. package/dist/cli/snapshot-create.js +71 -125
  30. package/dist/cli/upgrade.d.ts +15 -0
  31. package/dist/cli/upgrade.js +232 -335
  32. package/dist/config-nGCW1OTG.js +941 -0
  33. package/dist/context-B45_WqVX.js +298 -0
  34. package/dist/conversation-privacy-B4voFRSm.js +182 -0
  35. package/dist/conversation-work-C6y3T5Hx.js +51 -0
  36. package/dist/credential-sync-kXr1hvO1.js +2660 -0
  37. package/dist/db-BeyXKJOI.d.ts +5 -0
  38. package/dist/destinations-BeBiJeEM.js +29 -0
  39. package/dist/execution-stats-DWfSihcH.js +373 -0
  40. package/dist/executor-DcMSlI5c.js +721 -0
  41. package/dist/experimental-CIXf7Uye.js +46 -0
  42. package/dist/history-ClE4toxe.d.ts +32 -0
  43. package/dist/history-CqTuSAdI.js +441 -0
  44. package/dist/instrumentation.d.ts +3 -3
  45. package/dist/instrumentation.js +130 -176
  46. package/dist/job-queue-Drn_LXlM.js +63 -0
  47. package/dist/logging-BzAk1S_s.js +1210 -0
  48. package/dist/model-profile-CZmVoGdX.js +49 -0
  49. package/dist/nitro.d.ts +31 -36
  50. package/dist/nitro.js +275 -456
  51. package/dist/oauth-callback-server-JiftokvA.js +130 -0
  52. package/dist/oauth-relay-CdCnu80W.js +62 -0
  53. package/dist/package-discovery-7a9YqLhE.js +455 -0
  54. package/dist/pending-auth-CWmSdZVg.js +185 -0
  55. package/dist/plugin-module-BKGOXca2.js +81 -0
  56. package/dist/plugins-BI9A1vKA.d.ts +95 -0
  57. package/dist/plugins-egKWjgue.js +99 -0
  58. package/dist/private-trace-result-BLvBjy_e.js +16 -0
  59. package/dist/profile-CrT5nXbw.js +861 -0
  60. package/dist/registry-DH1xUo2N.js +1419 -0
  61. package/dist/reporting-schema-DosTN__Q.js +105 -0
  62. package/dist/resolve-CZHnfxaS.js +546 -0
  63. package/dist/rolldown-runtime-B4FMCO8f.js +28 -0
  64. package/dist/runner-CZV2sC46.js +392 -0
  65. package/dist/sandbox-egress-signals-bHZfmhbd.js +46 -0
  66. package/dist/schema-Rn8-XEaN.js +1140 -0
  67. package/dist/sentry-CD3SdJl-.js +26 -0
  68. package/dist/skills-CIcDQSgM.js +316 -0
  69. package/dist/spawn-DdkUFRmq.js +29 -0
  70. package/dist/stats-DTUbAb88.js +2634 -0
  71. package/dist/store-C5qxF2ac.d.ts +208 -0
  72. package/dist/task-queue-CJIR4RF7.js +136 -0
  73. package/dist/task-runner-D-O3A-Cp.js +639 -0
  74. package/dist/thread-state-CRc9jTJS.js +431 -0
  75. package/dist/turn-execution-BkinIdJF.js +47 -0
  76. package/dist/turn-lifecycle-DQV19VTW.js +54 -0
  77. package/dist/usage-D3EbSO7w.js +296 -0
  78. package/dist/usage-schema-CKaDkH_j.js +20 -0
  79. package/dist/validation-C2CR-OX3.js +40 -0
  80. package/dist/vercel-queue-DIkVcfK4.js +167 -0
  81. package/dist/vercel.d.ts +6 -6
  82. package/dist/vercel.js +14 -6
  83. package/dist/version-CnXZ614E.d.ts +5 -0
  84. package/dist/version-DxcWdoKa.js +8 -0
  85. package/dist/version.d.ts +2 -4
  86. package/dist/version.js +2 -6
  87. package/dist/web-authorization-RMBxAR_t.js +76 -0
  88. package/dist/web-input-3EPfpf55.js +494 -0
  89. package/dist/work-fGofI7Op.js +509 -0
  90. package/dist/worker-CsOLq-mR.js +625 -0
  91. package/package.json +8 -8
  92. package/dist/agent-hooks-GB2VPTNA.js +0 -51
  93. package/dist/catalog-runtime-UBLIWD3O.js +0 -14
  94. package/dist/chunk-2LYHWMR4.js +0 -46
  95. package/dist/chunk-352OWAZH.js +0 -320
  96. package/dist/chunk-3Y47VMHV.js +0 -6
  97. package/dist/chunk-3YJSKOWF.js +0 -164
  98. package/dist/chunk-4KSSKTQ5.js +0 -229
  99. package/dist/chunk-4UO6FK4G.js +0 -64
  100. package/dist/chunk-5AHX53NQ.js +0 -717
  101. package/dist/chunk-5J3E5FWA.js +0 -700
  102. package/dist/chunk-5PDAG6O3.js +0 -206
  103. package/dist/chunk-6Y5B5PEX.js +0 -80
  104. package/dist/chunk-7GWQ5S5R.js +0 -2086
  105. package/dist/chunk-7H2VZTWN.js +0 -103
  106. package/dist/chunk-7NL7T6VU.js +0 -406
  107. package/dist/chunk-A5L27LE4.js +0 -387
  108. package/dist/chunk-ADIAWL34.js +0 -81
  109. package/dist/chunk-ASTEMBKJ.js +0 -519
  110. package/dist/chunk-CEMMLV5L.js +0 -98
  111. package/dist/chunk-CM5HNV2W.js +0 -131
  112. package/dist/chunk-CRTRBBRI.js +0 -105
  113. package/dist/chunk-DA2KGZZI.js +0 -13
  114. package/dist/chunk-DIB4GX3G.js +0 -8
  115. package/dist/chunk-DKIJ2RP5.js +0 -68
  116. package/dist/chunk-DWPN6SCH.js +0 -172
  117. package/dist/chunk-EDKUFGPL.js +0 -64
  118. package/dist/chunk-ENY6SKIU.js +0 -1228
  119. package/dist/chunk-F4MGCZOX.js +0 -2943
  120. package/dist/chunk-FA6POGLH.js +0 -70
  121. package/dist/chunk-FSUR7GTG.js +0 -20475
  122. package/dist/chunk-GKEOHJL5.js +0 -1856
  123. package/dist/chunk-GMCB6W5Y.js +0 -333
  124. package/dist/chunk-IE2VPG7O.js +0 -1135
  125. package/dist/chunk-IZ5B5IHQ.js +0 -3656
  126. package/dist/chunk-JAL3CH4G.js +0 -27
  127. package/dist/chunk-KIIEUXD3.js +0 -1764
  128. package/dist/chunk-KXU4NIL7.js +0 -692
  129. package/dist/chunk-MTM5IFCY.js +0 -1190
  130. package/dist/chunk-N7TMSOZH.js +0 -235
  131. package/dist/chunk-NCEBK6PH.js +0 -36
  132. package/dist/chunk-NHJU2ZAL.js +0 -56
  133. package/dist/chunk-P6KTRNVC.js +0 -321
  134. package/dist/chunk-PDO5BLNM.js +0 -22
  135. package/dist/chunk-PDRNLLFT.js +0 -3295
  136. package/dist/chunk-PEQXYSSE.js +0 -45
  137. package/dist/chunk-PKEX2AQX.js +0 -198
  138. package/dist/chunk-PSJCGIGO.js +0 -1163
  139. package/dist/chunk-PZUSUL55.js +0 -506
  140. package/dist/chunk-R45M4TUS.js +0 -37
  141. package/dist/chunk-RC745GGZ.js +0 -122
  142. package/dist/chunk-SP3QKZXJ.js +0 -820
  143. package/dist/chunk-TXKUKMVO.js +0 -417
  144. package/dist/chunk-UE4GPWSD.js +0 -931
  145. package/dist/chunk-UIE3R5XU.js +0 -17
  146. package/dist/chunk-UXPG6ZIN.js +0 -84
  147. package/dist/chunk-VFUK3X5B.js +0 -50
  148. package/dist/chunk-VNMJWREK.js +0 -787
  149. package/dist/chunk-VZ7CSOX2.js +0 -706
  150. package/dist/chunk-WCNQJKFT.js +0 -10
  151. package/dist/chunk-WDZR3QQM.js +0 -135
  152. package/dist/chunk-WLYVJCHV.js +0 -1433
  153. package/dist/chunk-WS7NAFTM.js +0 -1520
  154. package/dist/chunk-X6GDDWQH.js +0 -60
  155. package/dist/chunk-XPDEYNQI.js +0 -102
  156. package/dist/chunk-XRW44VGM.js +0 -58
  157. package/dist/chunk-Y2CM7HXH.js +0 -111
  158. package/dist/chunk-Y7X25LFY.js +0 -15
  159. package/dist/conversation-work-VIOQ5ZF3.js +0 -54
  160. package/dist/db-NGDJV7YH.js +0 -26
  161. package/dist/discovery-DWVDM7UK.js +0 -44
  162. package/dist/experimental-P5FZM4CU.js +0 -12
  163. package/dist/oauth-callback-server-YFY7YEGK.js +0 -243
  164. package/dist/oauth-relay-5XPVRPYB.js +0 -8
  165. package/dist/plugins-YTYJMMJF.js +0 -14
  166. package/dist/runner-ORTNSB2Q.js +0 -522
  167. package/dist/sandbox-egress-signals-FIL7EGPR.js +0 -73
  168. package/dist/sentry-MB3NL3IR.js +0 -42
  169. package/dist/skills-H376WQOH.js +0 -27
  170. package/dist/spawn-T43WHLOS.js +0 -42
  171. package/dist/task-runner-LBZWF32V.js +0 -36
  172. package/dist/validation-REJLRKI6.js +0 -17
  173. package/dist/work-3KJ3RE76.js +0 -51
  174. package/dist/worker-QFEBU72E.js +0 -24
@@ -0,0 +1,105 @@
1
+ import { z } from "zod";
2
+ //#region src/reporting-schema.ts
3
+ const healthReportSchema = z.object({
4
+ status: z.literal("ok"),
5
+ service: z.string(),
6
+ timestamp: z.string()
7
+ }).strict();
8
+ const pluginSchema = z.object({
9
+ configKeys: z.array(z.string()),
10
+ description: z.string(),
11
+ displayName: z.string(),
12
+ name: z.string()
13
+ }).strict();
14
+ const pluginsSchema = z.array(pluginSchema);
15
+ const skillReportSchema = z.object({
16
+ name: z.string(),
17
+ pluginProvider: z.string().optional()
18
+ }).strict();
19
+ const skillReportsSchema = z.array(skillReportSchema);
20
+ const pluginPackageContentItemReportSchema = z.object({
21
+ dir: z.string(),
22
+ hasMigrationsDir: z.boolean(),
23
+ hasSkillsDir: z.boolean(),
24
+ packageName: z.string()
25
+ }).strict();
26
+ const pluginPackageContentReportSchema = z.object({
27
+ packageNames: z.array(z.string()),
28
+ packages: z.array(pluginPackageContentItemReportSchema),
29
+ manifestRoots: z.array(z.string()),
30
+ skillRoots: z.array(z.string()),
31
+ tracingIncludes: z.array(z.string())
32
+ }).strict();
33
+ const runtimeInfoReportSchema = z.object({
34
+ cwd: z.string(),
35
+ homeDir: z.string(),
36
+ descriptionText: z.string().optional(),
37
+ providers: z.array(z.string()),
38
+ skills: z.array(skillReportSchema),
39
+ packagedContent: pluginPackageContentReportSchema
40
+ }).strict();
41
+ const pluginOperationalToneSchema = z.enum([
42
+ "danger",
43
+ "good",
44
+ "neutral",
45
+ "warning"
46
+ ]);
47
+ const pluginOperationalMetricSchema = z.object({
48
+ label: z.string(),
49
+ tone: pluginOperationalToneSchema.optional(),
50
+ value: z.string()
51
+ }).strict();
52
+ const pluginOperationalFieldSchema = z.object({
53
+ key: z.string(),
54
+ label: z.string()
55
+ }).strict();
56
+ const pluginOperationalRecordSchema = z.object({
57
+ id: z.string(),
58
+ tone: pluginOperationalToneSchema.optional(),
59
+ values: z.record(z.string(), z.string())
60
+ }).strict();
61
+ const pluginOperationalRecordSetSchema = z.object({
62
+ fields: z.array(pluginOperationalFieldSchema).optional(),
63
+ emptyText: z.string().optional(),
64
+ records: z.array(pluginOperationalRecordSchema).optional(),
65
+ title: z.string()
66
+ }).strict();
67
+ const pluginOperationalBarChartWidgetSchema = z.object({
68
+ categories: z.array(z.object({
69
+ id: z.string().min(1),
70
+ label: z.string().min(1),
71
+ values: z.record(z.string(), z.number().finite())
72
+ }).strict()).max(100),
73
+ description: z.string().optional(),
74
+ emptyText: z.string().optional(),
75
+ id: z.string().min(1),
76
+ series: z.array(z.object({
77
+ format: z.literal("usd").optional(),
78
+ key: z.string().min(1),
79
+ label: z.string().min(1),
80
+ tone: pluginOperationalToneSchema.optional()
81
+ }).strict()).min(1).max(8),
82
+ timeRangeDays: z.array(z.union([
83
+ z.literal(1),
84
+ z.literal(7),
85
+ z.literal(30),
86
+ z.literal(90)
87
+ ])).min(1).max(4).optional(),
88
+ title: z.string().min(1),
89
+ type: z.literal("bar_chart")
90
+ }).strict();
91
+ const pluginOperationalReportSchema = z.object({
92
+ generatedAt: z.string().optional(),
93
+ metrics: z.array(pluginOperationalMetricSchema).optional(),
94
+ recordSets: z.array(pluginOperationalRecordSetSchema).optional(),
95
+ title: z.string().optional(),
96
+ pluginName: z.string(),
97
+ widgets: z.array(pluginOperationalBarChartWidgetSchema).max(12).optional()
98
+ }).strict();
99
+ const pluginOperationalReportFeedSchema = z.object({
100
+ generatedAt: z.string(),
101
+ reports: z.array(pluginOperationalReportSchema),
102
+ source: z.literal("plugins")
103
+ }).strict();
104
+ //#endregion
105
+ export { pluginPackageContentReportSchema as a, runtimeInfoReportSchema as c, pluginPackageContentItemReportSchema as i, skillReportSchema as l, pluginOperationalReportFeedSchema as n, pluginSchema as o, pluginOperationalReportSchema as r, pluginsSchema as s, healthReportSchema as t, skillReportsSchema as u };
@@ -0,0 +1,546 @@
1
+ import { C as withSpan, _ as setSpanAttributes } from "./logging-BzAk1S_s.js";
2
+ import { A as sleep, P as SANDBOX_WORKSPACE_ROOT, r as isStale, t as create, u as isSandboxUnavailableError, v as getVercelSandboxCredentials, w as getStateAdapter, x as runNonInteractiveCommand } from "./profile-CrT5nXbw.js";
3
+ import { z } from "zod";
4
+ import { FileSystem, Sandbox } from "@vercel/sandbox";
5
+ //#region src/chat/sandbox/resources.ts
6
+ let configuredResources;
7
+ function resourcesFromEnv() {
8
+ const value = process.env.SANDBOX_VCPUS?.trim();
9
+ if (!value || !/^\d+$/.test(value)) return;
10
+ const vcpus = Number(value);
11
+ if (!Number.isSafeInteger(vcpus) || vcpus <= 0) return;
12
+ return { vcpus };
13
+ }
14
+ /** Return the app-level sandbox sizing override. */
15
+ function getSandboxResourceConfig() {
16
+ return configuredResources;
17
+ }
18
+ /** Replace app-level sandbox sizing and return the previous setting. */
19
+ function setSandboxResourceConfig(config) {
20
+ const previous = configuredResources;
21
+ if (config?.vcpus === void 0) {
22
+ configuredResources = void 0;
23
+ return previous;
24
+ }
25
+ if (!Number.isSafeInteger(config.vcpus) || config.vcpus <= 0) throw new Error("sandbox.vcpus must be a positive integer");
26
+ configuredResources = { vcpus: config.vcpus };
27
+ return previous;
28
+ }
29
+ /** Resolve app-level sandbox sizing, falling back to the legacy environment setting. */
30
+ function getSandboxResources() {
31
+ return configuredResources ?? resourcesFromEnv();
32
+ }
33
+ //#endregion
34
+ //#region src/chat/sandbox/snapshot/span.ts
35
+ /** Record the reusable snapshot selected for a new Sandbox. */
36
+ function setSnapshotSpanAttributes(snapshot) {
37
+ setSpanAttributes({
38
+ "app.sandbox.source": snapshot.snapshotId ? "snapshot" : "created",
39
+ "app.sandbox.snapshot.cache_hit": snapshot.cacheHit,
40
+ "app.sandbox.snapshot.resolve_outcome": snapshot.resolveOutcome,
41
+ ...snapshot.profileHash ? { "app.sandbox.snapshot.profile_hash": snapshot.profileHash } : void 0,
42
+ "app.sandbox.snapshot.dependency_count": snapshot.dependencyCount,
43
+ ...snapshot.rebuildReason ? { "app.sandbox.snapshot.rebuild_reason": snapshot.rebuildReason } : void 0
44
+ });
45
+ }
46
+ /** Record one stage of dependency snapshot resolution or creation. */
47
+ async function trace(name, op, attributes, callback) {
48
+ return await withSpan(name, op, {}, callback, attributes);
49
+ }
50
+ //#endregion
51
+ //#region src/chat/sandbox/snapshot/install.ts
52
+ async function runOrThrow(sandbox, params, label) {
53
+ const result = await runNonInteractiveCommand(sandbox, params);
54
+ if (result.exitCode === 0) return;
55
+ const detail = result.stderr.trim() || result.stdout.trim() || "command failed";
56
+ throw new Error(`${label} failed: ${detail}`);
57
+ }
58
+ async function tryRun(sandbox, params) {
59
+ return (await runNonInteractiveCommand(sandbox, params)).exitCode === 0;
60
+ }
61
+ async function installGh(sandbox, signal, timeoutMs) {
62
+ if (await tryRun(sandbox, {
63
+ cmd: "dnf",
64
+ args: [
65
+ "install",
66
+ "-y",
67
+ "gh"
68
+ ],
69
+ signal,
70
+ sudo: true,
71
+ timeoutMs
72
+ })) return;
73
+ if (!await tryRun(sandbox, {
74
+ cmd: "dnf",
75
+ args: [
76
+ "config-manager",
77
+ "addrepo",
78
+ "--from-repofile=https://cli.github.com/packages/rpm/gh-cli.repo"
79
+ ],
80
+ signal,
81
+ sudo: true,
82
+ timeoutMs
83
+ })) {
84
+ await runOrThrow(sandbox, {
85
+ cmd: "dnf",
86
+ args: [
87
+ "install",
88
+ "-y",
89
+ "dnf-command(config-manager)"
90
+ ],
91
+ signal,
92
+ sudo: true,
93
+ timeoutMs
94
+ }, "dnf install dnf-command(config-manager)");
95
+ await runOrThrow(sandbox, {
96
+ cmd: "dnf",
97
+ args: [
98
+ "config-manager",
99
+ "--add-repo",
100
+ "https://cli.github.com/packages/rpm/gh-cli.repo"
101
+ ],
102
+ signal,
103
+ sudo: true,
104
+ timeoutMs
105
+ }, "dnf config-manager --add-repo gh-cli.repo");
106
+ }
107
+ await runOrThrow(sandbox, {
108
+ cmd: "dnf",
109
+ args: [
110
+ "install",
111
+ "-y",
112
+ "gh",
113
+ "--repo",
114
+ "gh-cli"
115
+ ],
116
+ signal,
117
+ sudo: true,
118
+ timeoutMs
119
+ }, "dnf install gh --repo gh-cli");
120
+ }
121
+ function filePath(url, sha256) {
122
+ let basename = "package.rpm";
123
+ try {
124
+ const candidate = new URL(url).pathname.split("/").filter(Boolean).at(-1);
125
+ if (candidate) basename = candidate;
126
+ } catch {}
127
+ const sanitized = basename.replace(/[^a-zA-Z0-9._-]/g, "_");
128
+ return `/tmp/junior-runtime-${sha256.slice(0, 12)}-${sanitized}`;
129
+ }
130
+ async function installUrl(sandbox, dependency, signal, timeoutMs) {
131
+ const rpmPath = filePath(dependency.url, dependency.sha256);
132
+ await runOrThrow(sandbox, {
133
+ cmd: "curl",
134
+ args: [
135
+ "-fsSL",
136
+ dependency.url,
137
+ "-o",
138
+ rpmPath
139
+ ],
140
+ signal,
141
+ timeoutMs
142
+ }, `curl download ${dependency.url}`);
143
+ const checksum = await runNonInteractiveCommand(sandbox, {
144
+ cmd: "sha256sum",
145
+ args: [rpmPath],
146
+ signal,
147
+ timeoutMs
148
+ });
149
+ const expected = dependency.sha256;
150
+ const actual = checksum.stdout.trim().split(/\s+/)[0]?.toLowerCase();
151
+ if (checksum.exitCode !== 0) {
152
+ const detail = checksum.stderr.trim() || checksum.stdout.trim() || "command failed";
153
+ throw new Error(`sha256sum failed: ${detail}`);
154
+ }
155
+ if (!actual) throw new Error("sha256sum produced empty output");
156
+ if (actual !== expected) throw new Error(`checksum mismatch for ${dependency.url}: expected ${expected}, got ${actual}`);
157
+ await runOrThrow(sandbox, {
158
+ cmd: "dnf",
159
+ args: [
160
+ "install",
161
+ "-y",
162
+ rpmPath
163
+ ],
164
+ signal,
165
+ sudo: true,
166
+ timeoutMs
167
+ }, `dnf install ${dependency.url}`);
168
+ }
169
+ /** Install declared system and npm dependencies into a snapshot sandbox. */
170
+ async function dependencies(sandbox, values, signal, timeoutMs) {
171
+ const system = values.filter((dependency) => dependency.type === "system");
172
+ const npm = values.filter((dependency) => dependency.type === "npm").map((dependency) => `${dependency.package}@${dependency.version}`);
173
+ if (system.length > 0) await trace("sandbox.snapshot.install_system", "sandbox.snapshot.install.system", { "app.sandbox.snapshot.install.system_count": system.length }, async () => {
174
+ for (const dependency of system) {
175
+ signal?.throwIfAborted();
176
+ if ("url" in dependency) await installUrl(sandbox, dependency, signal, timeoutMs);
177
+ else if (dependency.package === "gh") await installGh(sandbox, signal, timeoutMs);
178
+ else await runOrThrow(sandbox, {
179
+ cmd: "dnf",
180
+ args: [
181
+ "install",
182
+ "-y",
183
+ dependency.package
184
+ ],
185
+ signal,
186
+ sudo: true,
187
+ timeoutMs
188
+ }, `dnf install ${dependency.package}`);
189
+ }
190
+ });
191
+ if (npm.length > 0) await trace("sandbox.snapshot.install_npm", "sandbox.snapshot.install.npm", { "app.sandbox.snapshot.install.npm_count": npm.length }, async () => {
192
+ await runOrThrow(sandbox, {
193
+ cmd: "npm",
194
+ args: [
195
+ "install",
196
+ "--global",
197
+ "--prefix",
198
+ `${SANDBOX_WORKSPACE_ROOT}/.junior`,
199
+ ...npm
200
+ ],
201
+ signal,
202
+ timeoutMs
203
+ }, "npm install");
204
+ });
205
+ }
206
+ /** Run declared postinstall commands after dependency binaries are available. */
207
+ async function postinstall(sandbox, commands, signal, timeoutMs) {
208
+ if (commands.length === 0) return;
209
+ await trace("sandbox.snapshot.runtime_postinstall", "sandbox.snapshot.runtime_postinstall", { "app.sandbox.snapshot.runtime_postinstall.count": commands.length }, async () => {
210
+ for (const command of commands) {
211
+ signal?.throwIfAborted();
212
+ const result = await runNonInteractiveCommand(sandbox, {
213
+ cmd: command.cmd,
214
+ args: command.args,
215
+ login: true,
216
+ pathPrefix: `${SANDBOX_WORKSPACE_ROOT}/.junior/bin:$PATH`,
217
+ signal,
218
+ timeoutMs,
219
+ ...command.sudo !== void 0 ? { sudo: command.sudo } : void 0
220
+ });
221
+ if (result.exitCode !== 0) {
222
+ const detail = result.stderr.trim() || result.stdout.trim() || "command failed";
223
+ throw new Error(`runtime-postinstall ${command.cmd} failed: ${detail}`);
224
+ }
225
+ }
226
+ });
227
+ }
228
+ //#endregion
229
+ //#region src/chat/sandbox/workspace.ts
230
+ /** Bind one tool call's cancellation to every sandbox filesystem operation. */
231
+ function bindSandboxFileSystem(fs, signal) {
232
+ if (!signal) return fs;
233
+ return {
234
+ readFile(filePath, options) {
235
+ signal.throwIfAborted();
236
+ return fs.readFile(filePath, {
237
+ ...options,
238
+ signal
239
+ });
240
+ },
241
+ writeFile(filePath, content, options) {
242
+ signal.throwIfAborted();
243
+ return fs.writeFile(filePath, content, {
244
+ ...options,
245
+ signal
246
+ });
247
+ },
248
+ readdir(filePath) {
249
+ signal.throwIfAborted();
250
+ return fs.readdir(filePath, { signal });
251
+ },
252
+ stat(filePath) {
253
+ signal.throwIfAborted();
254
+ return fs.stat(filePath, { signal });
255
+ }
256
+ };
257
+ }
258
+ /** Pin Junior's sandbox contract to one Vercel session without SDK replay. */
259
+ function createSandboxSession(sandbox, options) {
260
+ const session = sandbox.currentSession();
261
+ const fileSystem = new FileSystem(session);
262
+ const run = async (operation) => {
263
+ try {
264
+ return await operation();
265
+ } catch (error) {
266
+ if (isSandboxUnavailableError(error)) options?.onUnavailable?.(session.sessionId);
267
+ throw error;
268
+ }
269
+ };
270
+ return {
271
+ sandboxId: sandbox.name,
272
+ sessionId: session.sessionId,
273
+ fs: {
274
+ readFile: async (filePath, readOptions) => await run(async () => await fileSystem.readFile(filePath, readOptions)),
275
+ writeFile: async (filePath, content, writeOptions) => await run(async () => await fileSystem.writeFile(filePath, content, writeOptions)),
276
+ readdir: async (filePath, readOptions) => await run(async () => await fileSystem.readdir(filePath, readOptions)),
277
+ stat: async (filePath, statOptions) => await run(async () => await fileSystem.stat(filePath, statOptions))
278
+ },
279
+ extendTimeout(duration) {
280
+ return run(async () => await session.extendTimeout(duration));
281
+ },
282
+ mkDir(path) {
283
+ return run(async () => await session.mkDir(path));
284
+ },
285
+ readFileToBuffer(input) {
286
+ return run(async () => await session.readFileToBuffer(input));
287
+ },
288
+ async runCommand(input) {
289
+ const result = await run(async () => await session.runCommand(input));
290
+ const [stdout, stderr] = await Promise.all([run(async () => await result.stdout()), run(async () => await result.stderr())]);
291
+ return {
292
+ exitCode: result.exitCode,
293
+ stdout,
294
+ stderr
295
+ };
296
+ },
297
+ snapshot(options) {
298
+ return run(async () => {
299
+ return { snapshotId: (await session.snapshot(options)).snapshotId };
300
+ });
301
+ },
302
+ stop() {
303
+ return run(async () => await session.stop());
304
+ },
305
+ update(params) {
306
+ return run(async () => await session.update(params));
307
+ },
308
+ writeFiles(files) {
309
+ return run(async () => await session.writeFiles(files));
310
+ }
311
+ };
312
+ }
313
+ /** Best-effort stop; ignore secondary stop failures during cleanup. */
314
+ async function stopSession(session) {
315
+ if (!session) return;
316
+ try {
317
+ await session.stop();
318
+ } catch {}
319
+ }
320
+ //#endregion
321
+ //#region src/chat/sandbox/snapshot/resolve.ts
322
+ const SNAPSHOT_CACHE_PREFIX = "junior:sandbox_snapshot_profile:v2";
323
+ const SNAPSHOT_LOCK_PREFIX = "junior:sandbox_snapshot_lock";
324
+ const SNAPSHOT_CACHE_TTL_MS = 2592e6;
325
+ const SNAPSHOT_BUILD_LOCK_BUFFER_MS = 3e4;
326
+ const SNAPSHOT_WAIT_FOR_LOCK_BUFFER_MS = 3e4;
327
+ const cachedSnapshotSchema = z.object({
328
+ profileHash: z.string(),
329
+ snapshotId: z.string(),
330
+ runtime: z.string(),
331
+ createdAtMs: z.number(),
332
+ dependencyCount: z.number(),
333
+ buildDurationMs: z.number().int().nonnegative()
334
+ }).strict();
335
+ function profileCacheKey(profileHash) {
336
+ return `${SNAPSHOT_CACHE_PREFIX}:${profileHash}`;
337
+ }
338
+ function profileLockKey(profileHash) {
339
+ return `${SNAPSHOT_LOCK_PREFIX}:${profileHash}`;
340
+ }
341
+ /** Read one cached snapshot pointer; only a missing key is a cache miss. */
342
+ async function getCachedSnapshot(profileHash) {
343
+ const state = getStateAdapter();
344
+ await state.connect();
345
+ const raw = await state.get(profileCacheKey(profileHash));
346
+ if (typeof raw !== "string") return null;
347
+ let value;
348
+ try {
349
+ value = JSON.parse(raw);
350
+ } catch {
351
+ throw new Error(`Invalid cached sandbox snapshot for ${profileHash}`);
352
+ }
353
+ const parsed = cachedSnapshotSchema.safeParse(value);
354
+ if (!parsed.success || parsed.data.profileHash !== profileHash) throw new Error(`Invalid cached sandbox snapshot for ${profileHash}`);
355
+ return parsed.data;
356
+ }
357
+ /** Persist one dependency profile's reusable snapshot pointer. */
358
+ async function setCachedSnapshot(entry) {
359
+ const state = getStateAdapter();
360
+ await state.connect();
361
+ await state.set(profileCacheKey(entry.profileHash), JSON.stringify(entry), SNAPSHOT_CACHE_TTL_MS);
362
+ }
363
+ async function build(value, runtime, timeoutMs, signal, prepare) {
364
+ return await trace("sandbox.snapshot.build", "sandbox.snapshot.build", {
365
+ "app.sandbox.runtime": runtime,
366
+ "app.sandbox.snapshot.dependency_count": value.dependencyCount
367
+ }, async () => {
368
+ const startedAtMs = Date.now();
369
+ const sandboxCredentials = getVercelSandboxCredentials();
370
+ const resources = getSandboxResources();
371
+ const sandbox = createSandboxSession(await Sandbox.create({
372
+ timeout: timeoutMs,
373
+ runtime,
374
+ signal,
375
+ ...sandboxCredentials ?? {},
376
+ ...resources ? { resources } : void 0
377
+ }));
378
+ try {
379
+ await dependencies(sandbox, value.dependencies, signal);
380
+ await postinstall(sandbox, value.postinstall, signal);
381
+ await prepare?.(sandbox);
382
+ return {
383
+ snapshotId: await trace("sandbox.snapshot.capture", "sandbox.snapshot.capture", { "app.sandbox.snapshot.dependency_count": value.dependencyCount }, async () => {
384
+ return (await sandbox.snapshot({ signal })).snapshotId;
385
+ }),
386
+ buildDurationMs: Math.max(0, Date.now() - startedAtMs)
387
+ };
388
+ } finally {
389
+ try {
390
+ await sandbox.stop();
391
+ } catch {}
392
+ }
393
+ });
394
+ }
395
+ /** Run one profile build under a timeout-buffered lock or reuse its result. */
396
+ async function withBuildLock(profileHash, timeoutMs, callback, canUseCachedSnapshot, onWaitingForLock, signal) {
397
+ signal?.throwIfAborted();
398
+ const state = getStateAdapter();
399
+ await state.connect();
400
+ const lockKey = profileLockKey(profileHash);
401
+ const lockTtlMs = timeoutMs + SNAPSHOT_BUILD_LOCK_BUFFER_MS;
402
+ const tryAcquireLock = async () => await state.acquireLock(lockKey, lockTtlMs);
403
+ let lock = await tryAcquireLock();
404
+ if (lock) try {
405
+ return await callback();
406
+ } finally {
407
+ await state.releaseLock(lock);
408
+ }
409
+ return await trace("sandbox.snapshot.lock_wait", "sandbox.snapshot.lock_wait", { "app.sandbox.snapshot.profile_hash": profileHash }, async () => {
410
+ await onWaitingForLock?.();
411
+ const waitUntil = Date.now() + lockTtlMs + SNAPSHOT_WAIT_FOR_LOCK_BUFFER_MS;
412
+ while (Date.now() < waitUntil) {
413
+ signal?.throwIfAborted();
414
+ const cached = await getCachedSnapshot(profileHash);
415
+ if (cached?.snapshotId && canUseCachedSnapshot(cached)) return {
416
+ snapshotId: cached.snapshotId,
417
+ source: "cache_hit_after_lock_wait",
418
+ createdAtMs: cached.createdAtMs,
419
+ buildDurationMs: cached.buildDurationMs
420
+ };
421
+ lock = await tryAcquireLock();
422
+ if (lock) try {
423
+ const result = await callback();
424
+ return {
425
+ snapshotId: result.snapshotId,
426
+ source: result.source === "built" ? "built" : "cache_hit_after_lock_wait",
427
+ createdAtMs: result.createdAtMs,
428
+ buildDurationMs: result.buildDurationMs
429
+ };
430
+ } finally {
431
+ await state.releaseLock(lock);
432
+ }
433
+ await sleep(500, signal);
434
+ }
435
+ signal?.throwIfAborted();
436
+ const cached = await getCachedSnapshot(profileHash);
437
+ if (cached?.snapshotId && canUseCachedSnapshot(cached)) return {
438
+ snapshotId: cached.snapshotId,
439
+ source: "cache_hit_after_lock_wait",
440
+ createdAtMs: cached.createdAtMs,
441
+ buildDurationMs: cached.buildDurationMs
442
+ };
443
+ throw new Error("Timed out waiting for snapshot build lock");
444
+ });
445
+ }
446
+ function toResolveOutcome(forceRebuild, source) {
447
+ if (source === "built") return forceRebuild ? "forced_rebuild" : "rebuilt";
448
+ return source;
449
+ }
450
+ function getRebuildReason(params) {
451
+ if (params.forceRebuild) return params.staleSnapshotId ? "snapshot_missing" : "force_rebuild";
452
+ if (params.cached?.snapshotId && params.shouldRebuildCached) return "floating_stale";
453
+ if (!params.cached?.snapshotId) return "cache_miss";
454
+ }
455
+ /** Resolve or build the reusable snapshot for the current dependency profile. */
456
+ async function resolve(params) {
457
+ return await trace("sandbox.snapshot.resolve", "sandbox.snapshot.resolve", {
458
+ "app.sandbox.runtime": params.runtime,
459
+ "app.sandbox.snapshot.force_rebuild": Boolean(params.forceRebuild)
460
+ }, async () => {
461
+ params.signal?.throwIfAborted();
462
+ await params.onProgress?.("resolve_start");
463
+ const currentProfile = create(params.runtime, params.workspace);
464
+ if (!currentProfile) return {
465
+ dependencyCount: 0,
466
+ cacheHit: false,
467
+ resolveOutcome: "no_profile"
468
+ };
469
+ const cached = await getCachedSnapshot(currentProfile.hash);
470
+ const cachedNeedsRebuild = Boolean(cached?.snapshotId && isStale(currentProfile, cached.createdAtMs));
471
+ if (!params.forceRebuild && cached?.snapshotId && !cachedNeedsRebuild) {
472
+ await params.onProgress?.("cache_hit");
473
+ return {
474
+ snapshotId: cached.snapshotId,
475
+ profileHash: currentProfile.hash,
476
+ dependencyCount: currentProfile.dependencyCount,
477
+ cacheHit: true,
478
+ resolveOutcome: "cache_hit",
479
+ createdAtMs: cached.createdAtMs,
480
+ buildDurationMs: cached.buildDurationMs
481
+ };
482
+ }
483
+ const rebuildReason = getRebuildReason({
484
+ forceRebuild: params.forceRebuild,
485
+ staleSnapshotId: params.staleSnapshotId,
486
+ cached,
487
+ shouldRebuildCached: cachedNeedsRebuild
488
+ });
489
+ const canUseCachedSnapshot = (candidate) => {
490
+ if (params.forceRebuild) {
491
+ if (params.staleSnapshotId) return candidate.snapshotId !== params.staleSnapshotId;
492
+ return candidate.snapshotId !== cached?.snapshotId;
493
+ }
494
+ return !isStale(currentProfile, candidate.createdAtMs);
495
+ };
496
+ const lockResult = await withBuildLock(currentProfile.hash, params.timeoutMs, async () => {
497
+ const latest = await getCachedSnapshot(currentProfile.hash);
498
+ if (latest?.snapshotId && canUseCachedSnapshot(latest)) {
499
+ await params.onProgress?.("cache_hit");
500
+ return {
501
+ snapshotId: latest.snapshotId,
502
+ source: "cache_hit",
503
+ createdAtMs: latest.createdAtMs,
504
+ buildDurationMs: latest.buildDurationMs
505
+ };
506
+ }
507
+ await params.onProgress?.("building_snapshot");
508
+ const built = await build(currentProfile, params.runtime, params.timeoutMs, params.signal, params.prepareWorkspace);
509
+ const createdAtMs = Date.now();
510
+ await setCachedSnapshot({
511
+ profileHash: currentProfile.hash,
512
+ snapshotId: built.snapshotId,
513
+ runtime: params.runtime,
514
+ createdAtMs,
515
+ dependencyCount: currentProfile.dependencyCount,
516
+ buildDurationMs: built.buildDurationMs
517
+ });
518
+ await params.onProgress?.("build_complete");
519
+ return {
520
+ snapshotId: built.snapshotId,
521
+ source: "built",
522
+ createdAtMs,
523
+ buildDurationMs: built.buildDurationMs
524
+ };
525
+ }, canUseCachedSnapshot, async () => {
526
+ await params.onProgress?.("waiting_for_lock");
527
+ }, params.signal);
528
+ return {
529
+ snapshotId: lockResult.snapshotId,
530
+ profileHash: currentProfile.hash,
531
+ dependencyCount: currentProfile.dependencyCount,
532
+ cacheHit: lockResult.source !== "built",
533
+ resolveOutcome: toResolveOutcome(Boolean(params.forceRebuild), lockResult.source),
534
+ createdAtMs: lockResult.createdAtMs,
535
+ buildDurationMs: lockResult.buildDurationMs,
536
+ ...rebuildReason ? { rebuildReason } : void 0
537
+ };
538
+ });
539
+ }
540
+ /** Identify provider errors that mean a referenced snapshot no longer exists. */
541
+ function isMissingError(error) {
542
+ const searchable = error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();
543
+ return searchable.includes("snapshot") && (searchable.includes("not found") || searchable.includes("unknown") || searchable.includes("404"));
544
+ }
545
+ //#endregion
546
+ export { createSandboxSession as a, postinstall as c, getSandboxResources as d, setSandboxResourceConfig as f, bindSandboxFileSystem as i, setSnapshotSpanAttributes as l, isMissingError as n, stopSession as o, resolve as r, dependencies as s, getCachedSnapshot as t, getSandboxResourceConfig as u };
@@ -0,0 +1,28 @@
1
+ import "node:module";
2
+ //#region \0rolldown/runtime.js
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __exportAll = (all, no_symbols) => {
8
+ let target = {};
9
+ for (var name in all) __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true
12
+ });
13
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
14
+ return target;
15
+ };
16
+ var __copyProps = (to, from, except, desc) => {
17
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
18
+ key = keys[i];
19
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
20
+ get: ((k) => from[k]).bind(null, key),
21
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
22
+ });
23
+ }
24
+ return to;
25
+ };
26
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
27
+ //#endregion
28
+ export { __reExport as n, __exportAll as t };