@sentry/junior 0.203.0 → 0.205.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.
- package/dist/agent-D4nu8MQV.js +17521 -0
- package/dist/agent-hooks-DXHpTJ4m.js +4042 -0
- package/dist/agent-runner-C04colea.js +678 -0
- package/dist/api/schema.d.ts +2736 -2639
- package/dist/api/schema.js +4 -169
- package/dist/api.d.ts +23 -17
- package/dist/api.js +3881 -5326
- package/dist/app-Cb776lL8.d.ts +247 -0
- package/dist/app.d.ts +4 -520
- package/dist/app.js +9524 -11875
- package/dist/auth-pause-state-C2P3guS1.js +168 -0
- package/dist/catalog-runtime-CXw3asJD.js +7 -0
- package/dist/checkpoint-CrViJ8Ps.js +2450 -0
- package/dist/cli/chat.d.ts +20 -0
- package/dist/cli/chat.js +229 -336
- package/dist/cli/check.d.ts +8 -0
- package/dist/cli/check.js +513 -806
- package/dist/cli/env.d.ts +13 -0
- package/dist/cli/env.js +63 -12
- package/dist/cli/init.d.ts +3 -0
- package/dist/cli/init.js +90 -159
- package/dist/cli/main.d.ts +6 -0
- package/dist/cli/main.js +43 -64
- package/dist/cli/plugins.d.ts +13 -0
- package/dist/cli/plugins.js +148 -227
- package/dist/cli/run.d.ts +16 -0
- package/dist/cli/run.js +52 -8
- package/dist/cli/snapshot-create.d.ts +4 -0
- package/dist/cli/snapshot-create.js +71 -125
- package/dist/cli/upgrade.d.ts +15 -0
- package/dist/cli/upgrade.js +232 -335
- package/dist/config-BOtJQ7Pc.js +941 -0
- package/dist/context-B45_WqVX.js +298 -0
- package/dist/conversation-privacy-BZRA6Pes.js +182 -0
- package/dist/conversation-work-C6y3T5Hx.js +51 -0
- package/dist/credential-sync-Bep34IB_.js +2661 -0
- package/dist/db-BeyXKJOI.d.ts +5 -0
- package/dist/destinations-BeBiJeEM.js +29 -0
- package/dist/execution-stats-B6lgWxCK.js +373 -0
- package/dist/executor-BlUhFL7_.js +721 -0
- package/dist/experimental-CIXf7Uye.js +46 -0
- package/dist/history-ClE4toxe.d.ts +32 -0
- package/dist/history-CqTuSAdI.js +441 -0
- package/dist/instrumentation.d.ts +3 -3
- package/dist/instrumentation.js +130 -176
- package/dist/job-queue-DLMqIK74.js +63 -0
- package/dist/logging-BMJzdDlP.js +1210 -0
- package/dist/model-profile-CZmVoGdX.js +49 -0
- package/dist/nitro.d.ts +31 -36
- package/dist/nitro.js +275 -456
- package/dist/oauth-callback-server-WwG5_Zgm.js +130 -0
- package/dist/oauth-relay-CdCnu80W.js +62 -0
- package/dist/package-discovery-7a9YqLhE.js +455 -0
- package/dist/pending-auth-CUbXq06G.js +185 -0
- package/dist/plugin-module-BKGOXca2.js +81 -0
- package/dist/plugins-BI9A1vKA.d.ts +95 -0
- package/dist/plugins-egKWjgue.js +99 -0
- package/dist/private-trace-result-BLvBjy_e.js +16 -0
- package/dist/profile-T0tXE4zu.js +861 -0
- package/dist/registry-BA0__8ai.js +1419 -0
- package/dist/reporting-schema-DosTN__Q.js +105 -0
- package/dist/resolve-bvD1ORdv.js +546 -0
- package/dist/rolldown-runtime-B4FMCO8f.js +28 -0
- package/dist/runner-BXYxfIUL.js +392 -0
- package/dist/sandbox-egress-signals-ngEPjSEW.js +46 -0
- package/dist/schema-Rn8-XEaN.js +1140 -0
- package/dist/sentry-CD3SdJl-.js +26 -0
- package/dist/skills-DJOlYdBs.js +316 -0
- package/dist/spawn-h0R1bTEo.js +29 -0
- package/dist/stats-3YZn-Swi.js +2648 -0
- package/dist/store-C5qxF2ac.d.ts +208 -0
- package/dist/task-queue-CoXwd2eq.js +136 -0
- package/dist/task-runner-B2_mJZj0.js +639 -0
- package/dist/thread-state-CqZ1m-es.js +431 -0
- package/dist/turn-execution-fI6PZ0iI.js +47 -0
- package/dist/turn-lifecycle-CcnwrOcp.js +54 -0
- package/dist/usage-B5SfMb3H.js +296 -0
- package/dist/usage-schema-CKaDkH_j.js +20 -0
- package/dist/validation-DfWcvhuS.js +40 -0
- package/dist/vercel-queue-DIkVcfK4.js +167 -0
- package/dist/vercel.d.ts +6 -6
- package/dist/vercel.js +14 -6
- package/dist/version-CnXZ614E.d.ts +5 -0
- package/dist/version-oD-oPrbO.js +8 -0
- package/dist/version.d.ts +2 -4
- package/dist/version.js +2 -6
- package/dist/web-authorization-Crbzlmzo.js +76 -0
- package/dist/web-input-BOuq3oKK.js +494 -0
- package/dist/work-B91LQKHr.js +509 -0
- package/dist/worker-BcRRTe6k.js +625 -0
- package/package.json +9 -9
- package/dist/agent-hooks-GB2VPTNA.js +0 -51
- package/dist/catalog-runtime-UBLIWD3O.js +0 -14
- package/dist/chunk-2LYHWMR4.js +0 -46
- package/dist/chunk-352OWAZH.js +0 -320
- package/dist/chunk-3Y47VMHV.js +0 -6
- package/dist/chunk-3YJSKOWF.js +0 -164
- package/dist/chunk-4KSSKTQ5.js +0 -229
- package/dist/chunk-4UO6FK4G.js +0 -64
- package/dist/chunk-5AHX53NQ.js +0 -717
- package/dist/chunk-5J3E5FWA.js +0 -700
- package/dist/chunk-5PDAG6O3.js +0 -206
- package/dist/chunk-6Y5B5PEX.js +0 -80
- package/dist/chunk-7GWQ5S5R.js +0 -2086
- package/dist/chunk-7H2VZTWN.js +0 -103
- package/dist/chunk-7NL7T6VU.js +0 -406
- package/dist/chunk-A5L27LE4.js +0 -387
- package/dist/chunk-ADIAWL34.js +0 -81
- package/dist/chunk-ASTEMBKJ.js +0 -519
- package/dist/chunk-CEMMLV5L.js +0 -98
- package/dist/chunk-CM5HNV2W.js +0 -131
- package/dist/chunk-CRTRBBRI.js +0 -105
- package/dist/chunk-DA2KGZZI.js +0 -13
- package/dist/chunk-DIB4GX3G.js +0 -8
- package/dist/chunk-DKIJ2RP5.js +0 -68
- package/dist/chunk-DWPN6SCH.js +0 -172
- package/dist/chunk-EDKUFGPL.js +0 -64
- package/dist/chunk-ENY6SKIU.js +0 -1228
- package/dist/chunk-F4MGCZOX.js +0 -2943
- package/dist/chunk-FA6POGLH.js +0 -70
- package/dist/chunk-FSUR7GTG.js +0 -20475
- package/dist/chunk-GKEOHJL5.js +0 -1856
- package/dist/chunk-GMCB6W5Y.js +0 -333
- package/dist/chunk-IE2VPG7O.js +0 -1135
- package/dist/chunk-IZ5B5IHQ.js +0 -3656
- package/dist/chunk-JAL3CH4G.js +0 -27
- package/dist/chunk-KIIEUXD3.js +0 -1764
- package/dist/chunk-KXU4NIL7.js +0 -692
- package/dist/chunk-MTM5IFCY.js +0 -1190
- package/dist/chunk-N7TMSOZH.js +0 -235
- package/dist/chunk-NCEBK6PH.js +0 -36
- package/dist/chunk-NHJU2ZAL.js +0 -56
- package/dist/chunk-P6KTRNVC.js +0 -321
- package/dist/chunk-PDO5BLNM.js +0 -22
- package/dist/chunk-PDRNLLFT.js +0 -3295
- package/dist/chunk-PEQXYSSE.js +0 -45
- package/dist/chunk-PKEX2AQX.js +0 -198
- package/dist/chunk-PSJCGIGO.js +0 -1163
- package/dist/chunk-PZUSUL55.js +0 -506
- package/dist/chunk-R45M4TUS.js +0 -37
- package/dist/chunk-RC745GGZ.js +0 -122
- package/dist/chunk-SP3QKZXJ.js +0 -820
- package/dist/chunk-TXKUKMVO.js +0 -417
- package/dist/chunk-UE4GPWSD.js +0 -931
- package/dist/chunk-UIE3R5XU.js +0 -17
- package/dist/chunk-UXPG6ZIN.js +0 -84
- package/dist/chunk-VFUK3X5B.js +0 -50
- package/dist/chunk-VNMJWREK.js +0 -787
- package/dist/chunk-VZ7CSOX2.js +0 -706
- package/dist/chunk-WCNQJKFT.js +0 -10
- package/dist/chunk-WDZR3QQM.js +0 -135
- package/dist/chunk-WLYVJCHV.js +0 -1433
- package/dist/chunk-WS7NAFTM.js +0 -1520
- package/dist/chunk-X6GDDWQH.js +0 -60
- package/dist/chunk-XPDEYNQI.js +0 -102
- package/dist/chunk-XRW44VGM.js +0 -58
- package/dist/chunk-Y2CM7HXH.js +0 -111
- package/dist/chunk-Y7X25LFY.js +0 -15
- package/dist/conversation-work-VIOQ5ZF3.js +0 -54
- package/dist/db-NGDJV7YH.js +0 -26
- package/dist/discovery-DWVDM7UK.js +0 -44
- package/dist/experimental-P5FZM4CU.js +0 -12
- package/dist/oauth-callback-server-YFY7YEGK.js +0 -243
- package/dist/oauth-relay-5XPVRPYB.js +0 -8
- package/dist/plugins-YTYJMMJF.js +0 -14
- package/dist/runner-ORTNSB2Q.js +0 -522
- package/dist/sandbox-egress-signals-FIL7EGPR.js +0 -73
- package/dist/sentry-MB3NL3IR.js +0 -42
- package/dist/skills-H376WQOH.js +0 -27
- package/dist/spawn-T43WHLOS.js +0 -42
- package/dist/task-runner-LBZWF32V.js +0 -36
- package/dist/validation-REJLRKI6.js +0 -17
- package/dist/work-3KJ3RE76.js +0 -51
- package/dist/worker-QFEBU72E.js +0 -24
package/dist/chunk-VZ7CSOX2.js
DELETED
|
@@ -1,706 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
SANDBOX_WORKSPACE_ROOT,
|
|
3
|
-
create,
|
|
4
|
-
getVercelSandboxCredentials,
|
|
5
|
-
isSandboxUnavailableError,
|
|
6
|
-
isStale,
|
|
7
|
-
runNonInteractiveCommand,
|
|
8
|
-
sleep
|
|
9
|
-
} from "./chunk-5AHX53NQ.js";
|
|
10
|
-
import {
|
|
11
|
-
getStateAdapter
|
|
12
|
-
} from "./chunk-P6KTRNVC.js";
|
|
13
|
-
import {
|
|
14
|
-
setSpanAttributes,
|
|
15
|
-
withSpan
|
|
16
|
-
} from "./chunk-WS7NAFTM.js";
|
|
17
|
-
|
|
18
|
-
// src/chat/sandbox/resources.ts
|
|
19
|
-
var configuredResources;
|
|
20
|
-
function resourcesFromEnv() {
|
|
21
|
-
const value = process.env.SANDBOX_VCPUS?.trim();
|
|
22
|
-
if (!value || !/^\d+$/.test(value)) {
|
|
23
|
-
return void 0;
|
|
24
|
-
}
|
|
25
|
-
const vcpus = Number(value);
|
|
26
|
-
if (!Number.isSafeInteger(vcpus) || vcpus <= 0) {
|
|
27
|
-
return void 0;
|
|
28
|
-
}
|
|
29
|
-
return { vcpus };
|
|
30
|
-
}
|
|
31
|
-
function getSandboxResourceConfig() {
|
|
32
|
-
return configuredResources;
|
|
33
|
-
}
|
|
34
|
-
function setSandboxResourceConfig(config) {
|
|
35
|
-
const previous = configuredResources;
|
|
36
|
-
if (config?.vcpus === void 0) {
|
|
37
|
-
configuredResources = void 0;
|
|
38
|
-
return previous;
|
|
39
|
-
}
|
|
40
|
-
if (!Number.isSafeInteger(config.vcpus) || config.vcpus <= 0) {
|
|
41
|
-
throw new Error("sandbox.vcpus must be a positive integer");
|
|
42
|
-
}
|
|
43
|
-
configuredResources = { vcpus: config.vcpus };
|
|
44
|
-
return previous;
|
|
45
|
-
}
|
|
46
|
-
function getSandboxResources() {
|
|
47
|
-
return configuredResources ?? resourcesFromEnv();
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// src/chat/sandbox/snapshot/resolve.ts
|
|
51
|
-
import { Sandbox } from "@vercel/sandbox";
|
|
52
|
-
import { z } from "zod";
|
|
53
|
-
|
|
54
|
-
// src/chat/sandbox/snapshot/span.ts
|
|
55
|
-
function setSnapshotSpanAttributes(snapshot) {
|
|
56
|
-
setSpanAttributes({
|
|
57
|
-
"app.sandbox.source": snapshot.snapshotId ? "snapshot" : "created",
|
|
58
|
-
"app.sandbox.snapshot.cache_hit": snapshot.cacheHit,
|
|
59
|
-
"app.sandbox.snapshot.resolve_outcome": snapshot.resolveOutcome,
|
|
60
|
-
...snapshot.profileHash ? { "app.sandbox.snapshot.profile_hash": snapshot.profileHash } : void 0,
|
|
61
|
-
"app.sandbox.snapshot.dependency_count": snapshot.dependencyCount,
|
|
62
|
-
...snapshot.rebuildReason ? { "app.sandbox.snapshot.rebuild_reason": snapshot.rebuildReason } : void 0
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
async function trace(name, op, attributes, callback) {
|
|
66
|
-
return await withSpan(name, op, {}, callback, attributes);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// src/chat/sandbox/snapshot/install.ts
|
|
70
|
-
async function runOrThrow(sandbox, params, label) {
|
|
71
|
-
const result = await runNonInteractiveCommand(sandbox, params);
|
|
72
|
-
if (result.exitCode === 0) {
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
const detail = result.stderr.trim() || result.stdout.trim() || "command failed";
|
|
76
|
-
throw new Error(`${label} failed: ${detail}`);
|
|
77
|
-
}
|
|
78
|
-
async function tryRun(sandbox, params) {
|
|
79
|
-
const result = await runNonInteractiveCommand(sandbox, params);
|
|
80
|
-
return result.exitCode === 0;
|
|
81
|
-
}
|
|
82
|
-
async function installGh(sandbox, signal, timeoutMs) {
|
|
83
|
-
const installed = await tryRun(sandbox, {
|
|
84
|
-
cmd: "dnf",
|
|
85
|
-
args: ["install", "-y", "gh"],
|
|
86
|
-
signal,
|
|
87
|
-
sudo: true,
|
|
88
|
-
timeoutMs
|
|
89
|
-
});
|
|
90
|
-
if (installed) {
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
const repoAdded = await tryRun(sandbox, {
|
|
94
|
-
cmd: "dnf",
|
|
95
|
-
args: [
|
|
96
|
-
"config-manager",
|
|
97
|
-
"addrepo",
|
|
98
|
-
"--from-repofile=https://cli.github.com/packages/rpm/gh-cli.repo"
|
|
99
|
-
],
|
|
100
|
-
signal,
|
|
101
|
-
sudo: true,
|
|
102
|
-
timeoutMs
|
|
103
|
-
});
|
|
104
|
-
if (!repoAdded) {
|
|
105
|
-
await runOrThrow(
|
|
106
|
-
sandbox,
|
|
107
|
-
{
|
|
108
|
-
cmd: "dnf",
|
|
109
|
-
args: ["install", "-y", "dnf-command(config-manager)"],
|
|
110
|
-
signal,
|
|
111
|
-
sudo: true,
|
|
112
|
-
timeoutMs
|
|
113
|
-
},
|
|
114
|
-
"dnf install dnf-command(config-manager)"
|
|
115
|
-
);
|
|
116
|
-
await runOrThrow(
|
|
117
|
-
sandbox,
|
|
118
|
-
{
|
|
119
|
-
cmd: "dnf",
|
|
120
|
-
args: [
|
|
121
|
-
"config-manager",
|
|
122
|
-
"--add-repo",
|
|
123
|
-
"https://cli.github.com/packages/rpm/gh-cli.repo"
|
|
124
|
-
],
|
|
125
|
-
signal,
|
|
126
|
-
sudo: true,
|
|
127
|
-
timeoutMs
|
|
128
|
-
},
|
|
129
|
-
"dnf config-manager --add-repo gh-cli.repo"
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
await runOrThrow(
|
|
133
|
-
sandbox,
|
|
134
|
-
{
|
|
135
|
-
cmd: "dnf",
|
|
136
|
-
args: ["install", "-y", "gh", "--repo", "gh-cli"],
|
|
137
|
-
signal,
|
|
138
|
-
sudo: true,
|
|
139
|
-
timeoutMs
|
|
140
|
-
},
|
|
141
|
-
"dnf install gh --repo gh-cli"
|
|
142
|
-
);
|
|
143
|
-
}
|
|
144
|
-
function filePath(url, sha256) {
|
|
145
|
-
let basename = "package.rpm";
|
|
146
|
-
try {
|
|
147
|
-
const candidate = new URL(url).pathname.split("/").filter(Boolean).at(-1);
|
|
148
|
-
if (candidate) {
|
|
149
|
-
basename = candidate;
|
|
150
|
-
}
|
|
151
|
-
} catch {
|
|
152
|
-
}
|
|
153
|
-
const sanitized = basename.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
154
|
-
return `/tmp/junior-runtime-${sha256.slice(0, 12)}-${sanitized}`;
|
|
155
|
-
}
|
|
156
|
-
async function installUrl(sandbox, dependency, signal, timeoutMs) {
|
|
157
|
-
const rpmPath = filePath(dependency.url, dependency.sha256);
|
|
158
|
-
await runOrThrow(
|
|
159
|
-
sandbox,
|
|
160
|
-
{
|
|
161
|
-
cmd: "curl",
|
|
162
|
-
args: ["-fsSL", dependency.url, "-o", rpmPath],
|
|
163
|
-
signal,
|
|
164
|
-
timeoutMs
|
|
165
|
-
},
|
|
166
|
-
`curl download ${dependency.url}`
|
|
167
|
-
);
|
|
168
|
-
const checksum = await runNonInteractiveCommand(sandbox, {
|
|
169
|
-
cmd: "sha256sum",
|
|
170
|
-
args: [rpmPath],
|
|
171
|
-
signal,
|
|
172
|
-
timeoutMs
|
|
173
|
-
});
|
|
174
|
-
const expected = dependency.sha256;
|
|
175
|
-
const actual = checksum.stdout.trim().split(/\s+/)[0]?.toLowerCase();
|
|
176
|
-
if (checksum.exitCode !== 0) {
|
|
177
|
-
const detail = checksum.stderr.trim() || checksum.stdout.trim() || "command failed";
|
|
178
|
-
throw new Error(`sha256sum failed: ${detail}`);
|
|
179
|
-
}
|
|
180
|
-
if (!actual) {
|
|
181
|
-
throw new Error("sha256sum produced empty output");
|
|
182
|
-
}
|
|
183
|
-
if (actual !== expected) {
|
|
184
|
-
throw new Error(
|
|
185
|
-
`checksum mismatch for ${dependency.url}: expected ${expected}, got ${actual}`
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
await runOrThrow(
|
|
189
|
-
sandbox,
|
|
190
|
-
{
|
|
191
|
-
cmd: "dnf",
|
|
192
|
-
args: ["install", "-y", rpmPath],
|
|
193
|
-
signal,
|
|
194
|
-
sudo: true,
|
|
195
|
-
timeoutMs
|
|
196
|
-
},
|
|
197
|
-
`dnf install ${dependency.url}`
|
|
198
|
-
);
|
|
199
|
-
}
|
|
200
|
-
async function dependencies(sandbox, values, signal, timeoutMs) {
|
|
201
|
-
const system = values.filter(
|
|
202
|
-
(dependency) => dependency.type === "system"
|
|
203
|
-
);
|
|
204
|
-
const npm = values.filter(
|
|
205
|
-
(dependency) => dependency.type === "npm"
|
|
206
|
-
).map((dependency) => `${dependency.package}@${dependency.version}`);
|
|
207
|
-
if (system.length > 0) {
|
|
208
|
-
await trace(
|
|
209
|
-
"sandbox.snapshot.install_system",
|
|
210
|
-
"sandbox.snapshot.install.system",
|
|
211
|
-
{
|
|
212
|
-
"app.sandbox.snapshot.install.system_count": system.length
|
|
213
|
-
},
|
|
214
|
-
async () => {
|
|
215
|
-
for (const dependency of system) {
|
|
216
|
-
signal?.throwIfAborted();
|
|
217
|
-
if ("url" in dependency) {
|
|
218
|
-
await installUrl(sandbox, dependency, signal, timeoutMs);
|
|
219
|
-
} else if (dependency.package === "gh") {
|
|
220
|
-
await installGh(sandbox, signal, timeoutMs);
|
|
221
|
-
} else {
|
|
222
|
-
await runOrThrow(
|
|
223
|
-
sandbox,
|
|
224
|
-
{
|
|
225
|
-
cmd: "dnf",
|
|
226
|
-
args: ["install", "-y", dependency.package],
|
|
227
|
-
signal,
|
|
228
|
-
sudo: true,
|
|
229
|
-
timeoutMs
|
|
230
|
-
},
|
|
231
|
-
`dnf install ${dependency.package}`
|
|
232
|
-
);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
);
|
|
237
|
-
}
|
|
238
|
-
if (npm.length > 0) {
|
|
239
|
-
await trace(
|
|
240
|
-
"sandbox.snapshot.install_npm",
|
|
241
|
-
"sandbox.snapshot.install.npm",
|
|
242
|
-
{
|
|
243
|
-
"app.sandbox.snapshot.install.npm_count": npm.length
|
|
244
|
-
},
|
|
245
|
-
async () => {
|
|
246
|
-
await runOrThrow(
|
|
247
|
-
sandbox,
|
|
248
|
-
{
|
|
249
|
-
cmd: "npm",
|
|
250
|
-
args: [
|
|
251
|
-
"install",
|
|
252
|
-
"--global",
|
|
253
|
-
"--prefix",
|
|
254
|
-
`${SANDBOX_WORKSPACE_ROOT}/.junior`,
|
|
255
|
-
...npm
|
|
256
|
-
],
|
|
257
|
-
signal,
|
|
258
|
-
timeoutMs
|
|
259
|
-
},
|
|
260
|
-
"npm install"
|
|
261
|
-
);
|
|
262
|
-
}
|
|
263
|
-
);
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
async function postinstall(sandbox, commands, signal, timeoutMs) {
|
|
267
|
-
if (commands.length === 0) {
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
await trace(
|
|
271
|
-
"sandbox.snapshot.runtime_postinstall",
|
|
272
|
-
"sandbox.snapshot.runtime_postinstall",
|
|
273
|
-
{
|
|
274
|
-
"app.sandbox.snapshot.runtime_postinstall.count": commands.length
|
|
275
|
-
},
|
|
276
|
-
async () => {
|
|
277
|
-
for (const command of commands) {
|
|
278
|
-
signal?.throwIfAborted();
|
|
279
|
-
const result = await runNonInteractiveCommand(sandbox, {
|
|
280
|
-
cmd: command.cmd,
|
|
281
|
-
args: command.args,
|
|
282
|
-
login: true,
|
|
283
|
-
pathPrefix: `${SANDBOX_WORKSPACE_ROOT}/.junior/bin:$PATH`,
|
|
284
|
-
signal,
|
|
285
|
-
timeoutMs,
|
|
286
|
-
...command.sudo !== void 0 ? { sudo: command.sudo } : void 0
|
|
287
|
-
});
|
|
288
|
-
if (result.exitCode !== 0) {
|
|
289
|
-
const detail = result.stderr.trim() || result.stdout.trim() || "command failed";
|
|
290
|
-
throw new Error(
|
|
291
|
-
`runtime-postinstall ${command.cmd} failed: ${detail}`
|
|
292
|
-
);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// src/chat/sandbox/workspace.ts
|
|
300
|
-
import {
|
|
301
|
-
FileSystem
|
|
302
|
-
} from "@vercel/sandbox";
|
|
303
|
-
function bindSandboxFileSystem(fs, signal) {
|
|
304
|
-
if (!signal) {
|
|
305
|
-
return fs;
|
|
306
|
-
}
|
|
307
|
-
return {
|
|
308
|
-
readFile(filePath2, options) {
|
|
309
|
-
signal.throwIfAborted();
|
|
310
|
-
return fs.readFile(filePath2, { ...options, signal });
|
|
311
|
-
},
|
|
312
|
-
writeFile(filePath2, content, options) {
|
|
313
|
-
signal.throwIfAborted();
|
|
314
|
-
return fs.writeFile(filePath2, content, { ...options, signal });
|
|
315
|
-
},
|
|
316
|
-
readdir(filePath2) {
|
|
317
|
-
signal.throwIfAborted();
|
|
318
|
-
return fs.readdir(filePath2, { signal });
|
|
319
|
-
},
|
|
320
|
-
stat(filePath2) {
|
|
321
|
-
signal.throwIfAborted();
|
|
322
|
-
return fs.stat(filePath2, { signal });
|
|
323
|
-
}
|
|
324
|
-
};
|
|
325
|
-
}
|
|
326
|
-
function createSandboxSession(sandbox, options) {
|
|
327
|
-
const session = sandbox.currentSession();
|
|
328
|
-
const fileSystem = new FileSystem(session);
|
|
329
|
-
const run = async (operation) => {
|
|
330
|
-
try {
|
|
331
|
-
return await operation();
|
|
332
|
-
} catch (error) {
|
|
333
|
-
if (isSandboxUnavailableError(error)) {
|
|
334
|
-
options?.onUnavailable?.(session.sessionId);
|
|
335
|
-
}
|
|
336
|
-
throw error;
|
|
337
|
-
}
|
|
338
|
-
};
|
|
339
|
-
const fs = {
|
|
340
|
-
readFile: async (filePath2, readOptions) => await run(async () => await fileSystem.readFile(filePath2, readOptions)),
|
|
341
|
-
writeFile: async (filePath2, content, writeOptions) => await run(
|
|
342
|
-
async () => await fileSystem.writeFile(filePath2, content, writeOptions)
|
|
343
|
-
),
|
|
344
|
-
readdir: async (filePath2, readOptions) => await run(async () => await fileSystem.readdir(filePath2, readOptions)),
|
|
345
|
-
stat: async (filePath2, statOptions) => await run(async () => await fileSystem.stat(filePath2, statOptions))
|
|
346
|
-
};
|
|
347
|
-
return {
|
|
348
|
-
sandboxId: sandbox.name,
|
|
349
|
-
sessionId: session.sessionId,
|
|
350
|
-
fs,
|
|
351
|
-
extendTimeout(duration) {
|
|
352
|
-
return run(async () => await session.extendTimeout(duration));
|
|
353
|
-
},
|
|
354
|
-
mkDir(path) {
|
|
355
|
-
return run(async () => await session.mkDir(path));
|
|
356
|
-
},
|
|
357
|
-
readFileToBuffer(input) {
|
|
358
|
-
return run(async () => await session.readFileToBuffer(input));
|
|
359
|
-
},
|
|
360
|
-
async runCommand(input) {
|
|
361
|
-
const result = await run(async () => await session.runCommand(input));
|
|
362
|
-
const [stdout, stderr] = await Promise.all([
|
|
363
|
-
run(async () => await result.stdout()),
|
|
364
|
-
run(async () => await result.stderr())
|
|
365
|
-
]);
|
|
366
|
-
return {
|
|
367
|
-
exitCode: result.exitCode,
|
|
368
|
-
stdout,
|
|
369
|
-
stderr
|
|
370
|
-
};
|
|
371
|
-
},
|
|
372
|
-
snapshot(options2) {
|
|
373
|
-
return run(async () => {
|
|
374
|
-
const snapshot = await session.snapshot(options2);
|
|
375
|
-
return { snapshotId: snapshot.snapshotId };
|
|
376
|
-
});
|
|
377
|
-
},
|
|
378
|
-
stop() {
|
|
379
|
-
return run(async () => await session.stop());
|
|
380
|
-
},
|
|
381
|
-
update(params) {
|
|
382
|
-
return run(async () => await session.update(params));
|
|
383
|
-
},
|
|
384
|
-
writeFiles(files) {
|
|
385
|
-
return run(async () => await session.writeFiles(files));
|
|
386
|
-
}
|
|
387
|
-
};
|
|
388
|
-
}
|
|
389
|
-
async function stopSession(session) {
|
|
390
|
-
if (!session) return;
|
|
391
|
-
try {
|
|
392
|
-
await session.stop();
|
|
393
|
-
} catch {
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
// src/chat/sandbox/snapshot/resolve.ts
|
|
398
|
-
var SNAPSHOT_CACHE_PREFIX = "junior:sandbox_snapshot_profile:v2";
|
|
399
|
-
var SNAPSHOT_LOCK_PREFIX = "junior:sandbox_snapshot_lock";
|
|
400
|
-
var SNAPSHOT_CACHE_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
401
|
-
var SNAPSHOT_BUILD_LOCK_BUFFER_MS = 30 * 1e3;
|
|
402
|
-
var SNAPSHOT_WAIT_FOR_LOCK_BUFFER_MS = 30 * 1e3;
|
|
403
|
-
var cachedSnapshotSchema = z.object({
|
|
404
|
-
profileHash: z.string(),
|
|
405
|
-
snapshotId: z.string(),
|
|
406
|
-
runtime: z.string(),
|
|
407
|
-
createdAtMs: z.number(),
|
|
408
|
-
dependencyCount: z.number(),
|
|
409
|
-
buildDurationMs: z.number().int().nonnegative()
|
|
410
|
-
}).strict();
|
|
411
|
-
function profileCacheKey(profileHash) {
|
|
412
|
-
return `${SNAPSHOT_CACHE_PREFIX}:${profileHash}`;
|
|
413
|
-
}
|
|
414
|
-
function profileLockKey(profileHash) {
|
|
415
|
-
return `${SNAPSHOT_LOCK_PREFIX}:${profileHash}`;
|
|
416
|
-
}
|
|
417
|
-
async function getCachedSnapshot(profileHash) {
|
|
418
|
-
const state = getStateAdapter();
|
|
419
|
-
await state.connect();
|
|
420
|
-
const raw = await state.get(profileCacheKey(profileHash));
|
|
421
|
-
if (typeof raw !== "string") {
|
|
422
|
-
return null;
|
|
423
|
-
}
|
|
424
|
-
let value;
|
|
425
|
-
try {
|
|
426
|
-
value = JSON.parse(raw);
|
|
427
|
-
} catch {
|
|
428
|
-
throw new Error(`Invalid cached sandbox snapshot for ${profileHash}`);
|
|
429
|
-
}
|
|
430
|
-
const parsed = cachedSnapshotSchema.safeParse(value);
|
|
431
|
-
if (!parsed.success || parsed.data.profileHash !== profileHash) {
|
|
432
|
-
throw new Error(`Invalid cached sandbox snapshot for ${profileHash}`);
|
|
433
|
-
}
|
|
434
|
-
return parsed.data;
|
|
435
|
-
}
|
|
436
|
-
async function setCachedSnapshot(entry) {
|
|
437
|
-
const state = getStateAdapter();
|
|
438
|
-
await state.connect();
|
|
439
|
-
await state.set(
|
|
440
|
-
profileCacheKey(entry.profileHash),
|
|
441
|
-
JSON.stringify(entry),
|
|
442
|
-
SNAPSHOT_CACHE_TTL_MS
|
|
443
|
-
);
|
|
444
|
-
}
|
|
445
|
-
async function build(value, runtime, timeoutMs, signal, prepare) {
|
|
446
|
-
return await trace(
|
|
447
|
-
"sandbox.snapshot.build",
|
|
448
|
-
"sandbox.snapshot.build",
|
|
449
|
-
{
|
|
450
|
-
"app.sandbox.runtime": runtime,
|
|
451
|
-
"app.sandbox.snapshot.dependency_count": value.dependencyCount
|
|
452
|
-
},
|
|
453
|
-
async () => {
|
|
454
|
-
const startedAtMs = Date.now();
|
|
455
|
-
const sandboxCredentials = getVercelSandboxCredentials();
|
|
456
|
-
const resources = getSandboxResources();
|
|
457
|
-
const sandbox = createSandboxSession(
|
|
458
|
-
await Sandbox.create({
|
|
459
|
-
timeout: timeoutMs,
|
|
460
|
-
runtime,
|
|
461
|
-
signal,
|
|
462
|
-
...sandboxCredentials ?? {},
|
|
463
|
-
...resources ? { resources } : void 0
|
|
464
|
-
})
|
|
465
|
-
);
|
|
466
|
-
try {
|
|
467
|
-
await dependencies(sandbox, value.dependencies, signal);
|
|
468
|
-
await postinstall(sandbox, value.postinstall, signal);
|
|
469
|
-
await prepare?.(sandbox);
|
|
470
|
-
const snapshotId = await trace(
|
|
471
|
-
"sandbox.snapshot.capture",
|
|
472
|
-
"sandbox.snapshot.capture",
|
|
473
|
-
{
|
|
474
|
-
"app.sandbox.snapshot.dependency_count": value.dependencyCount
|
|
475
|
-
},
|
|
476
|
-
async () => {
|
|
477
|
-
const snapshot = await sandbox.snapshot({ signal });
|
|
478
|
-
return snapshot.snapshotId;
|
|
479
|
-
}
|
|
480
|
-
);
|
|
481
|
-
return {
|
|
482
|
-
snapshotId,
|
|
483
|
-
buildDurationMs: Math.max(0, Date.now() - startedAtMs)
|
|
484
|
-
};
|
|
485
|
-
} finally {
|
|
486
|
-
try {
|
|
487
|
-
await sandbox.stop();
|
|
488
|
-
} catch {
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
);
|
|
493
|
-
}
|
|
494
|
-
async function withBuildLock(profileHash, timeoutMs, callback, canUseCachedSnapshot, onWaitingForLock, signal) {
|
|
495
|
-
signal?.throwIfAborted();
|
|
496
|
-
const state = getStateAdapter();
|
|
497
|
-
await state.connect();
|
|
498
|
-
const lockKey = profileLockKey(profileHash);
|
|
499
|
-
const lockTtlMs = timeoutMs + SNAPSHOT_BUILD_LOCK_BUFFER_MS;
|
|
500
|
-
const tryAcquireLock = async () => await state.acquireLock(lockKey, lockTtlMs);
|
|
501
|
-
let lock = await tryAcquireLock();
|
|
502
|
-
if (lock) {
|
|
503
|
-
try {
|
|
504
|
-
return await callback();
|
|
505
|
-
} finally {
|
|
506
|
-
await state.releaseLock(lock);
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
return await trace(
|
|
510
|
-
"sandbox.snapshot.lock_wait",
|
|
511
|
-
"sandbox.snapshot.lock_wait",
|
|
512
|
-
{
|
|
513
|
-
"app.sandbox.snapshot.profile_hash": profileHash
|
|
514
|
-
},
|
|
515
|
-
async () => {
|
|
516
|
-
await onWaitingForLock?.();
|
|
517
|
-
const waitUntil = Date.now() + lockTtlMs + SNAPSHOT_WAIT_FOR_LOCK_BUFFER_MS;
|
|
518
|
-
while (Date.now() < waitUntil) {
|
|
519
|
-
signal?.throwIfAborted();
|
|
520
|
-
const cached2 = await getCachedSnapshot(profileHash);
|
|
521
|
-
if (cached2?.snapshotId && canUseCachedSnapshot(cached2)) {
|
|
522
|
-
return {
|
|
523
|
-
snapshotId: cached2.snapshotId,
|
|
524
|
-
source: "cache_hit_after_lock_wait",
|
|
525
|
-
createdAtMs: cached2.createdAtMs,
|
|
526
|
-
buildDurationMs: cached2.buildDurationMs
|
|
527
|
-
};
|
|
528
|
-
}
|
|
529
|
-
lock = await tryAcquireLock();
|
|
530
|
-
if (lock) {
|
|
531
|
-
try {
|
|
532
|
-
const result = await callback();
|
|
533
|
-
return {
|
|
534
|
-
snapshotId: result.snapshotId,
|
|
535
|
-
source: result.source === "built" ? "built" : "cache_hit_after_lock_wait",
|
|
536
|
-
createdAtMs: result.createdAtMs,
|
|
537
|
-
buildDurationMs: result.buildDurationMs
|
|
538
|
-
};
|
|
539
|
-
} finally {
|
|
540
|
-
await state.releaseLock(lock);
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
await sleep(500, signal);
|
|
544
|
-
}
|
|
545
|
-
signal?.throwIfAborted();
|
|
546
|
-
const cached = await getCachedSnapshot(profileHash);
|
|
547
|
-
if (cached?.snapshotId && canUseCachedSnapshot(cached)) {
|
|
548
|
-
return {
|
|
549
|
-
snapshotId: cached.snapshotId,
|
|
550
|
-
source: "cache_hit_after_lock_wait",
|
|
551
|
-
createdAtMs: cached.createdAtMs,
|
|
552
|
-
buildDurationMs: cached.buildDurationMs
|
|
553
|
-
};
|
|
554
|
-
}
|
|
555
|
-
throw new Error("Timed out waiting for snapshot build lock");
|
|
556
|
-
}
|
|
557
|
-
);
|
|
558
|
-
}
|
|
559
|
-
function toResolveOutcome(forceRebuild, source) {
|
|
560
|
-
if (source === "built") {
|
|
561
|
-
return forceRebuild ? "forced_rebuild" : "rebuilt";
|
|
562
|
-
}
|
|
563
|
-
return source;
|
|
564
|
-
}
|
|
565
|
-
function getRebuildReason(params) {
|
|
566
|
-
if (params.forceRebuild) {
|
|
567
|
-
return params.staleSnapshotId ? "snapshot_missing" : "force_rebuild";
|
|
568
|
-
}
|
|
569
|
-
if (params.cached?.snapshotId && params.shouldRebuildCached) {
|
|
570
|
-
return "floating_stale";
|
|
571
|
-
}
|
|
572
|
-
if (!params.cached?.snapshotId) {
|
|
573
|
-
return "cache_miss";
|
|
574
|
-
}
|
|
575
|
-
return void 0;
|
|
576
|
-
}
|
|
577
|
-
async function resolve(params) {
|
|
578
|
-
return await trace(
|
|
579
|
-
"sandbox.snapshot.resolve",
|
|
580
|
-
"sandbox.snapshot.resolve",
|
|
581
|
-
{
|
|
582
|
-
"app.sandbox.runtime": params.runtime,
|
|
583
|
-
"app.sandbox.snapshot.force_rebuild": Boolean(params.forceRebuild)
|
|
584
|
-
},
|
|
585
|
-
async () => {
|
|
586
|
-
params.signal?.throwIfAborted();
|
|
587
|
-
await params.onProgress?.("resolve_start");
|
|
588
|
-
const currentProfile = create(params.runtime, params.workspace);
|
|
589
|
-
if (!currentProfile) {
|
|
590
|
-
return {
|
|
591
|
-
dependencyCount: 0,
|
|
592
|
-
cacheHit: false,
|
|
593
|
-
resolveOutcome: "no_profile"
|
|
594
|
-
};
|
|
595
|
-
}
|
|
596
|
-
const cached = await getCachedSnapshot(currentProfile.hash);
|
|
597
|
-
const cachedNeedsRebuild = Boolean(
|
|
598
|
-
cached?.snapshotId && isStale(currentProfile, cached.createdAtMs)
|
|
599
|
-
);
|
|
600
|
-
if (!params.forceRebuild && cached?.snapshotId && !cachedNeedsRebuild) {
|
|
601
|
-
await params.onProgress?.("cache_hit");
|
|
602
|
-
return {
|
|
603
|
-
snapshotId: cached.snapshotId,
|
|
604
|
-
profileHash: currentProfile.hash,
|
|
605
|
-
dependencyCount: currentProfile.dependencyCount,
|
|
606
|
-
cacheHit: true,
|
|
607
|
-
resolveOutcome: "cache_hit",
|
|
608
|
-
createdAtMs: cached.createdAtMs,
|
|
609
|
-
buildDurationMs: cached.buildDurationMs
|
|
610
|
-
};
|
|
611
|
-
}
|
|
612
|
-
const rebuildReason = getRebuildReason({
|
|
613
|
-
forceRebuild: params.forceRebuild,
|
|
614
|
-
staleSnapshotId: params.staleSnapshotId,
|
|
615
|
-
cached,
|
|
616
|
-
shouldRebuildCached: cachedNeedsRebuild
|
|
617
|
-
});
|
|
618
|
-
const canUseCachedSnapshot = (candidate) => {
|
|
619
|
-
if (params.forceRebuild) {
|
|
620
|
-
if (params.staleSnapshotId) {
|
|
621
|
-
return candidate.snapshotId !== params.staleSnapshotId;
|
|
622
|
-
}
|
|
623
|
-
return candidate.snapshotId !== cached?.snapshotId;
|
|
624
|
-
}
|
|
625
|
-
return !isStale(currentProfile, candidate.createdAtMs);
|
|
626
|
-
};
|
|
627
|
-
const lockResult = await withBuildLock(
|
|
628
|
-
currentProfile.hash,
|
|
629
|
-
params.timeoutMs,
|
|
630
|
-
async () => {
|
|
631
|
-
const latest = await getCachedSnapshot(currentProfile.hash);
|
|
632
|
-
if (latest?.snapshotId && canUseCachedSnapshot(latest)) {
|
|
633
|
-
await params.onProgress?.("cache_hit");
|
|
634
|
-
return {
|
|
635
|
-
snapshotId: latest.snapshotId,
|
|
636
|
-
source: "cache_hit",
|
|
637
|
-
createdAtMs: latest.createdAtMs,
|
|
638
|
-
buildDurationMs: latest.buildDurationMs
|
|
639
|
-
};
|
|
640
|
-
}
|
|
641
|
-
await params.onProgress?.("building_snapshot");
|
|
642
|
-
const built = await build(
|
|
643
|
-
currentProfile,
|
|
644
|
-
params.runtime,
|
|
645
|
-
params.timeoutMs,
|
|
646
|
-
params.signal,
|
|
647
|
-
params.prepareWorkspace
|
|
648
|
-
);
|
|
649
|
-
const createdAtMs = Date.now();
|
|
650
|
-
await setCachedSnapshot({
|
|
651
|
-
profileHash: currentProfile.hash,
|
|
652
|
-
snapshotId: built.snapshotId,
|
|
653
|
-
runtime: params.runtime,
|
|
654
|
-
createdAtMs,
|
|
655
|
-
dependencyCount: currentProfile.dependencyCount,
|
|
656
|
-
buildDurationMs: built.buildDurationMs
|
|
657
|
-
});
|
|
658
|
-
await params.onProgress?.("build_complete");
|
|
659
|
-
return {
|
|
660
|
-
snapshotId: built.snapshotId,
|
|
661
|
-
source: "built",
|
|
662
|
-
createdAtMs,
|
|
663
|
-
buildDurationMs: built.buildDurationMs
|
|
664
|
-
};
|
|
665
|
-
},
|
|
666
|
-
canUseCachedSnapshot,
|
|
667
|
-
async () => {
|
|
668
|
-
await params.onProgress?.("waiting_for_lock");
|
|
669
|
-
},
|
|
670
|
-
params.signal
|
|
671
|
-
);
|
|
672
|
-
return {
|
|
673
|
-
snapshotId: lockResult.snapshotId,
|
|
674
|
-
profileHash: currentProfile.hash,
|
|
675
|
-
dependencyCount: currentProfile.dependencyCount,
|
|
676
|
-
cacheHit: lockResult.source !== "built",
|
|
677
|
-
resolveOutcome: toResolveOutcome(
|
|
678
|
-
Boolean(params.forceRebuild),
|
|
679
|
-
lockResult.source
|
|
680
|
-
),
|
|
681
|
-
createdAtMs: lockResult.createdAtMs,
|
|
682
|
-
buildDurationMs: lockResult.buildDurationMs,
|
|
683
|
-
...rebuildReason ? { rebuildReason } : void 0
|
|
684
|
-
};
|
|
685
|
-
}
|
|
686
|
-
);
|
|
687
|
-
}
|
|
688
|
-
function isMissingError(error) {
|
|
689
|
-
const searchable = error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();
|
|
690
|
-
return searchable.includes("snapshot") && (searchable.includes("not found") || searchable.includes("unknown") || searchable.includes("404"));
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
export {
|
|
694
|
-
getSandboxResourceConfig,
|
|
695
|
-
setSandboxResourceConfig,
|
|
696
|
-
getSandboxResources,
|
|
697
|
-
setSnapshotSpanAttributes,
|
|
698
|
-
dependencies,
|
|
699
|
-
postinstall,
|
|
700
|
-
bindSandboxFileSystem,
|
|
701
|
-
createSandboxSession,
|
|
702
|
-
stopSession,
|
|
703
|
-
getCachedSnapshot,
|
|
704
|
-
resolve,
|
|
705
|
-
isMissingError
|
|
706
|
-
};
|