@madarco/agentbox 0.15.0 → 0.17.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/CHANGELOG.md +68 -0
- package/dist/{_cloud-attach-R6TRWG5L.js → _cloud-attach-SGNR6BXP.js} +5 -4
- package/dist/{chunk-BKU34KYY.js → chunk-3JXSW6PN.js} +42 -24
- package/dist/chunk-3JXSW6PN.js.map +1 -0
- package/dist/{chunk-RSKG7AFU.js → chunk-46NXCJ6Z.js} +45 -34
- package/dist/{chunk-RSKG7AFU.js.map → chunk-46NXCJ6Z.js.map} +1 -1
- package/dist/{chunk-43Q5GWP6.js → chunk-5AKAC27L.js} +7 -7
- package/dist/{chunk-XKH7NTT7.js → chunk-6QFPYU4Z.js} +248 -5
- package/dist/chunk-6QFPYU4Z.js.map +1 -0
- package/dist/{chunk-MLMFNN4T.js → chunk-HFQZJO73.js} +688 -197
- package/dist/chunk-HFQZJO73.js.map +1 -0
- package/dist/{chunk-E7CHS7ZR.js → chunk-KTDJ5JTE.js} +18 -6
- package/dist/chunk-KTDJ5JTE.js.map +1 -0
- package/dist/{chunk-72CJTXN6.js → chunk-RXPV3OIX.js} +80 -72
- package/dist/chunk-RXPV3OIX.js.map +1 -0
- package/dist/chunk-WJFZJZIM.js +24 -0
- package/dist/{chunk-MCOU6CZS.js → chunk-XWBFWUY2.js} +30 -22
- package/dist/chunk-XWBFWUY2.js.map +1 -0
- package/dist/{cloud-poller-SUNA6ZQC-2RG5WPRN.js → cloud-poller-SUNA6ZQC-7M5LJHHE.js} +2 -1
- package/dist/{dist-S4XR4ACV.js → dist-433ASGVG.js} +6 -5
- package/dist/{dist-S4XR4ACV.js.map → dist-433ASGVG.js.map} +1 -1
- package/dist/{dist-JZ3XO6EB.js → dist-BO2R55FX.js} +6 -5
- package/dist/{dist-JZ3XO6EB.js.map → dist-BO2R55FX.js.map} +1 -1
- package/dist/{dist-AGTIA7AD.js → dist-CNABE32V.js} +7 -6
- package/dist/{dist-AGTIA7AD.js.map → dist-CNABE32V.js.map} +1 -1
- package/dist/{dist-FIFEFKJ7.js → dist-TEKY3GFT.js} +6 -5
- package/dist/{dist-FIFEFKJ7.js.map → dist-TEKY3GFT.js.map} +1 -1
- package/dist/{dist-OGJGZETZ.js → dist-VAATGBAR.js} +6 -5
- package/dist/index.js +2426 -2094
- package/dist/index.js.map +1 -1
- package/dist/{prepared-state-MQHD3M5F-Q27AZU53.js → prepared-state-MQHD3M5F-OVABNV66.js} +3 -2
- package/dist/prepared-state-MQHD3M5F-OVABNV66.js.map +1 -0
- package/package.json +5 -4
- package/runtime/docker/Dockerfile.box +21 -2
- package/runtime/docker/apps/cli/share/agentbox-setup/SKILL.md +82 -29
- package/runtime/docker/packages/ctl/dist/bin.cjs +10675 -9191
- package/runtime/docker/packages/sandbox-docker/scripts/agentbox-checkpoint-cleanup +5 -2
- package/runtime/docker/packages/sandbox-docker/scripts/linear-shim +181 -0
- package/runtime/docker/packages/sandbox-docker/scripts/ntn-shim +95 -0
- package/runtime/e2b/agentbox-checkpoint-cleanup +5 -2
- package/runtime/e2b/agentbox-setup-skill.md +82 -29
- package/runtime/e2b/ctl.cjs +10675 -9191
- package/runtime/e2b/linear-shim +181 -0
- package/runtime/e2b/ntn-shim +95 -0
- package/runtime/e2b/scripts/build-template.sh +13 -7
- package/runtime/hetzner/agentbox-checkpoint-cleanup +5 -2
- package/runtime/hetzner/agentbox-setup-skill.md +82 -29
- package/runtime/hetzner/ctl.cjs +10675 -9191
- package/runtime/hetzner/linear-shim +181 -0
- package/runtime/hetzner/ntn-shim +95 -0
- package/runtime/hetzner/scripts/install-box.sh +19 -9
- package/runtime/relay/bin.cjs +3696 -2895
- package/runtime/vercel/agentbox-checkpoint-cleanup +5 -2
- package/runtime/vercel/agentbox-setup-skill.md +82 -29
- package/runtime/vercel/ctl.cjs +10675 -9191
- package/runtime/vercel/linear-shim +181 -0
- package/runtime/vercel/ntn-shim +95 -0
- package/runtime/vercel/scripts/provision.sh +13 -7
- package/share/agentbox-setup/SKILL.md +82 -29
- package/share/host-skills/agentbox-info/SKILL.md +1 -1
- package/dist/chunk-72CJTXN6.js.map +0 -1
- package/dist/chunk-BKU34KYY.js.map +0 -1
- package/dist/chunk-E7CHS7ZR.js.map +0 -1
- package/dist/chunk-MCOU6CZS.js.map +0 -1
- package/dist/chunk-MLMFNN4T.js.map +0 -1
- package/dist/chunk-XKH7NTT7.js.map +0 -1
- /package/dist/{_cloud-attach-R6TRWG5L.js.map → _cloud-attach-SGNR6BXP.js.map} +0 -0
- /package/dist/{chunk-43Q5GWP6.js.map → chunk-5AKAC27L.js.map} +0 -0
- /package/dist/{cloud-poller-SUNA6ZQC-2RG5WPRN.js.map → chunk-WJFZJZIM.js.map} +0 -0
- /package/dist/{dist-OGJGZETZ.js.map → cloud-poller-SUNA6ZQC-7M5LJHHE.js.map} +0 -0
- /package/dist/{prepared-state-MQHD3M5F-Q27AZU53.js.map → dist-VAATGBAR.js.map} +0 -0
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
UserFacingError
|
|
4
|
-
} from "./chunk-MLMFNN4T.js";
|
|
5
|
-
import {
|
|
3
|
+
UserFacingError,
|
|
6
4
|
computeContextSha256,
|
|
7
5
|
hostOpenCommand,
|
|
8
6
|
preparedStatePathFor,
|
|
9
7
|
readPreparedStateRaw,
|
|
10
8
|
writePreparedStateRaw
|
|
11
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-6QFPYU4Z.js";
|
|
12
10
|
|
|
13
|
-
// ../../packages/sandbox-vercel/dist/chunk-
|
|
11
|
+
// ../../packages/sandbox-vercel/dist/chunk-LUI2MLLW.js
|
|
14
12
|
import { existsSync, readFileSync } from "fs";
|
|
15
13
|
import { homedir } from "os";
|
|
16
14
|
import { resolve } from "path";
|
|
@@ -27,6 +25,7 @@ import {
|
|
|
27
25
|
import { homedir as homedir3 } from "os";
|
|
28
26
|
import { dirname, resolve as resolve2 } from "path";
|
|
29
27
|
import {
|
|
28
|
+
cancel,
|
|
30
29
|
confirm,
|
|
31
30
|
isCancel,
|
|
32
31
|
intro,
|
|
@@ -349,6 +348,13 @@ async function createProject(token, teamId, name) {
|
|
|
349
348
|
throw err;
|
|
350
349
|
}
|
|
351
350
|
}
|
|
351
|
+
function exitOnCancel(v) {
|
|
352
|
+
if (isCancel(v)) {
|
|
353
|
+
cancel("Cancelled.");
|
|
354
|
+
process.exit(130);
|
|
355
|
+
}
|
|
356
|
+
return v;
|
|
357
|
+
}
|
|
352
358
|
var DASHBOARD_TOKENS_URL = "https://vercel.com/account/settings/tokens";
|
|
353
359
|
var MANAGED_KEYS = [
|
|
354
360
|
"VERCEL_OIDC_TOKEN",
|
|
@@ -369,19 +375,17 @@ Access token (best for CI / headless): personal access token + team id + project
|
|
|
369
375
|
OIDC (short interactive work): export VERCEL_OIDC_TOKEN in your shell or add it to \`~/.agentbox/secrets.env\` (dev token expires ~12h, no headless refresh).`,
|
|
370
376
|
"Credentials required"
|
|
371
377
|
);
|
|
372
|
-
const mode =
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
return;
|
|
384
|
-
}
|
|
378
|
+
const mode = exitOnCancel(
|
|
379
|
+
await select({
|
|
380
|
+
message: "How do you want to authenticate?",
|
|
381
|
+
options: [
|
|
382
|
+
{ value: "cli", label: "Sign in with Vercel (browser) \u2014 recommended for interactive use" },
|
|
383
|
+
{ value: "token", label: "Access token (VERCEL_TOKEN + team + project) \u2014 best for CI / headless" },
|
|
384
|
+
{ value: "oidc", label: "OIDC token (VERCEL_OIDC_TOKEN in env / secrets.env) \u2014 short interactive work" }
|
|
385
|
+
],
|
|
386
|
+
initialValue: "cli"
|
|
387
|
+
})
|
|
388
|
+
);
|
|
385
389
|
if (mode === "cli") {
|
|
386
390
|
await runCliLogin();
|
|
387
391
|
return;
|
|
@@ -405,45 +409,39 @@ Re-do every ~12h; the dev token expires. AgentBox does not harvest .env.local.`,
|
|
|
405
409
|
return;
|
|
406
410
|
}
|
|
407
411
|
const creds = await promptForTokenTrio();
|
|
408
|
-
if (creds === null) return;
|
|
409
412
|
persistCredentials(creds);
|
|
410
413
|
log.success(`Vercel credentials saved to ${secretsPath()}`);
|
|
411
414
|
await ensureSbxInstalled();
|
|
412
415
|
outro("Setup complete.");
|
|
413
416
|
}
|
|
414
417
|
async function promptForTokenTrio() {
|
|
415
|
-
const openIt =
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
418
|
+
const openIt = exitOnCancel(
|
|
419
|
+
await confirm({
|
|
420
|
+
message: `Open ${DASHBOARD_TOKENS_URL} to create a token?`,
|
|
421
|
+
initialValue: true
|
|
422
|
+
})
|
|
423
|
+
);
|
|
420
424
|
if (openIt) openDashboard();
|
|
421
|
-
const token =
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
validate: (v) => v && v.trim().length > 0 ? void 0 : "Cannot be empty"
|
|
442
|
-
});
|
|
443
|
-
if (isCancel(projectId)) {
|
|
444
|
-
log.warn("Vercel setup cancelled.");
|
|
445
|
-
return null;
|
|
446
|
-
}
|
|
425
|
+
const token = exitOnCancel(
|
|
426
|
+
await password({
|
|
427
|
+
message: "Paste your Vercel access token",
|
|
428
|
+
validate: (v) => v && v.trim().length > 0 ? void 0 : "Cannot be empty"
|
|
429
|
+
})
|
|
430
|
+
);
|
|
431
|
+
const teamId = exitOnCancel(
|
|
432
|
+
await text({
|
|
433
|
+
message: "Team ID (team settings \u2192 General)",
|
|
434
|
+
placeholder: "team_...",
|
|
435
|
+
validate: (v) => v && v.trim().length > 0 ? void 0 : "Cannot be empty"
|
|
436
|
+
})
|
|
437
|
+
);
|
|
438
|
+
const projectId = exitOnCancel(
|
|
439
|
+
await text({
|
|
440
|
+
message: "Project ID (project settings \u2192 General)",
|
|
441
|
+
placeholder: "prj_...",
|
|
442
|
+
validate: (v) => v && v.trim().length > 0 ? void 0 : "Cannot be empty"
|
|
443
|
+
})
|
|
444
|
+
);
|
|
447
445
|
return { token: token.trim(), teamId: teamId.trim(), projectId: projectId.trim() };
|
|
448
446
|
}
|
|
449
447
|
function persistCredentials(creds) {
|
|
@@ -498,11 +496,13 @@ function writeManaged(record) {
|
|
|
498
496
|
async function ensureSbxInstalled() {
|
|
499
497
|
let det = await detectSbx();
|
|
500
498
|
if (!det.installed) {
|
|
501
|
-
const doInstall =
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
499
|
+
const doInstall = exitOnCancel(
|
|
500
|
+
await confirm({
|
|
501
|
+
message: `The Vercel sandbox CLI (needed for interactive attach) isn't installed. Install it now? (${installSbxHint()})`,
|
|
502
|
+
initialValue: true
|
|
503
|
+
})
|
|
504
|
+
);
|
|
505
|
+
if (!doInstall) {
|
|
506
506
|
log.warn(
|
|
507
507
|
`Install it with \`${installSbxHint()}\` to use \`agentbox shell|claude|codex|opencode\` on Vercel boxes.`
|
|
508
508
|
);
|
|
@@ -578,23 +578,25 @@ async function resolveProjectId(token, teamId) {
|
|
|
578
578
|
}
|
|
579
579
|
const CREATE = "__create__";
|
|
580
580
|
const preferred = projects.find((p) => p.name === "agentbox") ?? projects.find((p) => p.name === "vercel-sandbox-default-project");
|
|
581
|
-
const choice =
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
581
|
+
const choice = exitOnCancel(
|
|
582
|
+
await select({
|
|
583
|
+
message: "Which Vercel project should sandboxes run under?",
|
|
584
|
+
options: [
|
|
585
|
+
...projects.map((p) => ({ value: p.id, label: p.name })),
|
|
586
|
+
{ value: CREATE, label: "Create a new project\u2026" }
|
|
587
|
+
],
|
|
588
|
+
initialValue: preferred ? preferred.id : CREATE
|
|
589
|
+
})
|
|
590
|
+
);
|
|
590
591
|
if (choice !== CREATE) return choice;
|
|
591
|
-
const name =
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
592
|
+
const name = exitOnCancel(
|
|
593
|
+
await text({
|
|
594
|
+
message: "New project name",
|
|
595
|
+
placeholder: "agentbox",
|
|
596
|
+
defaultValue: "agentbox",
|
|
597
|
+
validate: (v) => v && v.trim().length > 0 ? void 0 : "Cannot be empty"
|
|
598
|
+
})
|
|
599
|
+
);
|
|
598
600
|
try {
|
|
599
601
|
const created = await createProject(token, teamId, name.trim() || "agentbox");
|
|
600
602
|
return created.id;
|
|
@@ -676,6 +678,8 @@ var RUNTIME_ASSETS = [
|
|
|
676
678
|
{ name: "agentbox-open", remotePath: "/tmp/agentbox-open", remoteMode: 493 },
|
|
677
679
|
{ name: "gh-shim", remotePath: "/tmp/agentbox-gh-shim", remoteMode: 493 },
|
|
678
680
|
{ name: "git-shim", remotePath: "/tmp/agentbox-git-shim", remoteMode: 493 },
|
|
681
|
+
{ name: "ntn-shim", remotePath: "/tmp/agentbox-ntn-shim", remoteMode: 493 },
|
|
682
|
+
{ name: "linear-shim", remotePath: "/tmp/agentbox-linear-shim", remoteMode: 493 },
|
|
679
683
|
{ name: "custom-system-CLAUDE.md", remotePath: "/tmp/agentbox-custom-CLAUDE.md", remoteMode: 420 },
|
|
680
684
|
{ name: "claude-managed-settings.json", remotePath: "/tmp/agentbox-managed-settings.json", remoteMode: 420 },
|
|
681
685
|
{ name: "agentbox-codex-hooks.json", remotePath: "/tmp/agentbox-codex-hooks.json", remoteMode: 420 },
|
|
@@ -692,6 +696,8 @@ function candidatesFor(name, opts = {}) {
|
|
|
692
696
|
"agentbox-open": ["packages/sandbox-docker/scripts/agentbox-open"],
|
|
693
697
|
"gh-shim": ["packages/sandbox-docker/scripts/gh-shim"],
|
|
694
698
|
"git-shim": ["packages/sandbox-docker/scripts/git-shim"],
|
|
699
|
+
"ntn-shim": ["packages/sandbox-docker/scripts/ntn-shim"],
|
|
700
|
+
"linear-shim": ["packages/sandbox-docker/scripts/linear-shim"],
|
|
695
701
|
"custom-system-CLAUDE.md": ["packages/sandbox-vercel/scripts/custom-system-CLAUDE.md"],
|
|
696
702
|
"claude-managed-settings.json": ["packages/sandbox-docker/scripts/claude-managed-settings.json"],
|
|
697
703
|
"agentbox-codex-hooks.json": ["packages/sandbox-docker/scripts/agentbox-codex-hooks.json"],
|
|
@@ -705,6 +711,8 @@ function candidatesFor(name, opts = {}) {
|
|
|
705
711
|
"agentbox-open": ["vercel/agentbox-open", "docker/packages/sandbox-docker/scripts/agentbox-open"],
|
|
706
712
|
"gh-shim": ["vercel/gh-shim", "docker/packages/sandbox-docker/scripts/gh-shim"],
|
|
707
713
|
"git-shim": ["vercel/git-shim", "docker/packages/sandbox-docker/scripts/git-shim"],
|
|
714
|
+
"ntn-shim": ["vercel/ntn-shim", "docker/packages/sandbox-docker/scripts/ntn-shim"],
|
|
715
|
+
"linear-shim": ["vercel/linear-shim", "docker/packages/sandbox-docker/scripts/linear-shim"],
|
|
708
716
|
"custom-system-CLAUDE.md": ["vercel/custom-system-CLAUDE.md"],
|
|
709
717
|
"claude-managed-settings.json": ["vercel/claude-managed-settings.json", "docker/packages/sandbox-docker/scripts/claude-managed-settings.json"],
|
|
710
718
|
"agentbox-codex-hooks.json": ["vercel/agentbox-codex-hooks.json", "docker/packages/sandbox-docker/scripts/agentbox-codex-hooks.json"],
|
|
@@ -813,4 +821,4 @@ export {
|
|
|
813
821
|
currentVercelBaseFingerprintLive,
|
|
814
822
|
ensureVercelBaseSnapshot
|
|
815
823
|
};
|
|
816
|
-
//# sourceMappingURL=chunk-
|
|
824
|
+
//# sourceMappingURL=chunk-RXPV3OIX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../packages/sandbox-vercel/src/env-loader.ts","../../../packages/sandbox-vercel/src/sbx-cli.ts","../../../packages/sandbox-vercel/src/credentials.ts","../../../packages/sandbox-vercel/src/cli-store.ts","../../../packages/sandbox-vercel/src/sdk.ts","../../../packages/sandbox-vercel/src/vercel-rest.ts","../../../packages/sandbox-vercel/src/runtime-assets.ts","../../../packages/sandbox-vercel/src/prepared-state.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { resolve } from 'node:path';\n\n/**\n * Vercel env auto-loader. The `@vercel/sandbox` SDK reads `VERCEL_OIDC_TOKEN`\n * from `process.env`; for the access-token path we read `VERCEL_TOKEN` +\n * `VERCEL_TEAM_ID` + `VERCEL_PROJECT_ID` and thread them into every SDK call as\n * explicit `Credentials`. We pull all of these in from `~/.agentbox/secrets.env`\n * (written by `agentbox vercel login`) so the SDK Just Works after a one-time\n * login — exactly the daytona/hetzner model.\n *\n * Lookup order (first wins; process.env is never overwritten):\n * 1. `process.env` (already set in the shell).\n * 2. `~/.agentbox/secrets.env` — written by `agentbox vercel login`.\n *\n * Project-level `.env` / `.env.local` are intentionally NOT consulted: those\n * files belong to the app code being developed, and a `VERCEL_*` value there\n * (e.g. a `vercel env pull` OIDC token, or the app's own deploy token) is meant\n * for in-box code, not for the host CLI to harvest and provision sandboxes with.\n * Put host credentials in `~/.agentbox/secrets.env` (or the shell env).\n *\n * Only Vercel-prefixed keys are imported; the rest of the file is left alone.\n * Idempotent and side-effect-free after the first call.\n */\nconst VERCEL_KEYS = [\n 'VERCEL_OIDC_TOKEN',\n 'VERCEL_TOKEN',\n 'VERCEL_TEAM_ID',\n 'VERCEL_PROJECT_ID',\n // Marker for CLI-login mode (`agentbox vercel login` → `sandbox login`). The\n // access token is NOT stored here — it's read live from the Vercel CLI store;\n // only this marker + team/project ids are persisted.\n 'VERCEL_AUTH_SOURCE',\n] as const;\n\nlet loaded = false;\n\nexport function ensureVercelEnvLoaded(): void {\n if (loaded) return;\n loaded = true;\n importVercelFromFile(resolve(homedir(), '.agentbox', 'secrets.env'), VERCEL_KEYS);\n}\n\n/**\n * Force a re-read of `~/.agentbox/secrets.env`. Used by the interactive\n * `agentbox vercel login` flow after it persists the credential trio, so the\n * same process can pick it up without a restart.\n */\nexport function reloadVercelEnv(): void {\n loaded = false;\n ensureVercelEnvLoaded();\n}\n\nfunction importVercelFromFile(path: string, keys: readonly string[]): void {\n if (!existsSync(path)) return;\n let body: string;\n try {\n body = readFileSync(path, 'utf8');\n } catch {\n return;\n }\n const parsed = parseEnvFile(body);\n for (const key of keys) {\n if (process.env[key] !== undefined) continue;\n const value = parsed[key];\n if (typeof value === 'string') {\n process.env[key] = value;\n }\n }\n}\n\n/**\n * Minimal `.env` parser: handles `KEY=value`, `KEY=\"value\"`, `KEY='value'`,\n * `export KEY=value`, blank lines, and `#` comments. No variable\n * interpolation — predictable over feature-complete (matches the daytona\n * loader's behavior).\n */\nexport function parseEnvFile(body: string): Record<string, string> {\n const out: Record<string, string> = {};\n for (const rawLine of body.split(/\\r?\\n/)) {\n const line = rawLine.trim();\n if (line.length === 0 || line.startsWith('#')) continue;\n const stripped = line.startsWith('export ') ? line.slice('export '.length) : line;\n const eq = stripped.indexOf('=');\n if (eq <= 0) continue;\n const key = stripped.slice(0, eq).trim();\n let value = stripped.slice(eq + 1).trim();\n if (\n value.length >= 2 &&\n ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\")))\n ) {\n value = value.slice(1, -1);\n }\n out[key] = value;\n }\n return out;\n}\n","/**\n * Driver for the official Vercel Sandbox CLI (`sandbox` / `sbx`, installed via\n * `npm i -g sandbox`). AgentBox's CLI-login auth mode uses it for two things:\n * - `loginSbx` — run `sandbox login` interactively so the user completes\n * the browser OAuth and the CLI writes its own credential store.\n * - `refreshSbxToken` — run a cheap read command (`sandbox list`) which makes\n * the CLI lazily refresh its access token from its stored refresh token\n * when the token is stale. Verified non-interactive: a stale token is\n * refreshed without opening a browser.\n *\n * Mirrors the probe/install patterns in sandbox-docker/src/portless.ts: execa\n * with `reject:false` for never-throw probes, spawnSync with inherited stdio for\n * the interactive login.\n */\n\nimport { spawnSync } from 'node:child_process';\nimport { execa } from 'execa';\n\n/**\n * Binaries the Sandbox CLI installs. `sbx` is the short alias; we prefer it but\n * fall back to `sandbox`. Pinned here so a future rename is a one-line fix.\n */\nconst SBX_BINS = ['sbx', 'sandbox'] as const;\n\nexport interface SbxState {\n /** A Sandbox CLI binary resolved on PATH and answered `--version`. */\n installed: boolean;\n /** The binary name that answered (`sbx` or `sandbox`), when installed. */\n bin?: string;\n /** Version string, when installed. */\n version?: string;\n}\n\nlet cached: SbxState | null = null;\n\n/**\n * Probe the host for the Sandbox CLI. Cached per-process (install state can't\n * change mid-command); `resetSbxCache` clears it after an install or for tests.\n */\nexport async function detectSbx(): Promise<SbxState> {\n if (cached !== null) return cached;\n for (const bin of SBX_BINS) {\n try {\n const r = await execa(bin, ['--version'], { reject: false });\n if (r.exitCode === 0) {\n cached = { installed: true, bin, version: (r.stdout ?? '').trim() || undefined };\n return cached;\n }\n } catch {\n // try the next bin name\n }\n }\n cached = { installed: false };\n return cached;\n}\n\n/** Drop the per-process probe cache so the next `detectSbx()` re-probes. */\nexport function resetSbxCache(): void {\n cached = null;\n}\n\n/** Command the user should run to install the Sandbox CLI. */\nexport function installSbxHint(): string {\n return 'npm install -g sandbox';\n}\n\n/** Install the Sandbox CLI globally (`npm install -g sandbox`). Never throws. */\nexport async function installSbx(): Promise<boolean> {\n try {\n const r = await execa('npm', ['install', '-g', 'sandbox'], { reject: false });\n return r.exitCode === 0;\n } catch {\n return false;\n }\n}\n\n/**\n * Run `sandbox login` with inherited stdio so the user sees the CLI's own\n * browser-OAuth output and can interact with it. Blocking, like the interactive\n * agent launch path. Returns the exit status (0 = success).\n */\nexport function loginSbx(bin: string): number {\n const r = spawnSync(bin, ['login'], { stdio: 'inherit' });\n return r.status ?? 1;\n}\n\n/**\n * Trigger the CLI's lazy token refresh by running a cheap read command. The CLI\n * refreshes its access token from the stored refresh token when the token is\n * stale and leaves a still-valid token untouched, so this is safe to call\n * eagerly. Non-interactive (stdin from /dev/null); returns true on exit 0.\n */\nexport async function refreshSbxToken(bin: string): Promise<boolean> {\n try {\n const r = await execa(bin, ['list'], {\n reject: false,\n timeout: 30_000,\n stdin: 'ignore',\n });\n return r.exitCode === 0;\n } catch {\n return false;\n }\n}\n","import {\n chmodSync,\n existsSync,\n mkdirSync,\n readFileSync,\n renameSync,\n writeFileSync,\n} from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, resolve } from 'node:path';\nimport { hostOpenCommand } from '@agentbox/sandbox-core';\nimport {\n cancel,\n confirm,\n isCancel,\n intro,\n log,\n note,\n outro,\n password,\n select,\n spinner,\n text,\n} from '@clack/prompts';\nimport { ensureVercelEnvLoaded, reloadVercelEnv } from './env-loader.js';\n\n// Ctrl+C at a prompt resolves with the cancel symbol; turn that into a real\n// quit so the command never silently continues as if the user answered \"No\".\nfunction exitOnCancel<T>(v: T | symbol): T {\n if (isCancel(v)) {\n cancel('Cancelled.');\n process.exit(130);\n }\n return v as T;\n}\nimport { hasUsableCredentials } from './sdk.js';\nimport { cliStorePaths, isNearExpiry, readCliAuth, readCliCurrentTeam } from './cli-store.js';\nimport { detectSbx, installSbx, installSbxHint, loginSbx, resetSbxCache } from './sbx-cli.js';\nimport { createProject, getUser, listProjects, type VercelProject } from './vercel-rest.js';\n\nconst DASHBOARD_TOKENS_URL = 'https://vercel.com/account/settings/tokens';\n\n/**\n * Keys we manage in `~/.agentbox/secrets.env`. On reconfigure we strip prior\n * values for these before appending so the file never accumulates duplicates.\n * `VERCEL_AUTH_SOURCE` is the CLI-login marker; the access token itself is never\n * stored here in that mode (it's read live from the Vercel CLI store).\n */\nconst MANAGED_KEYS = [\n 'VERCEL_OIDC_TOKEN',\n 'VERCEL_TOKEN',\n 'VERCEL_TEAM_ID',\n 'VERCEL_PROJECT_ID',\n 'VERCEL_AUTH_SOURCE',\n] as const;\n\nexport interface EnsureVercelCredentialsOptions {\n /** Re-prompt even when valid credentials are already present (`agentbox vercel login`). */\n force?: boolean;\n}\n\n/**\n * First-run interactive setup for Vercel credentials. The access-token path\n * persists a `VERCEL_TOKEN` trio to `~/.agentbox/secrets.env` (the canonical\n * store, matching daytona/hetzner). OIDC is also supported, but the token must\n * be present in the shell env or in `~/.agentbox/secrets.env` — agentbox does\n * NOT harvest `.env.local` (that file belongs to the app being developed).\n *\n * No-op when credentials are already configured. Silent no-op when stdin isn't\n * a TTY so scripted/CI callers get the SDK's \"not configured\" error instead of\n * a hung prompt.\n */\nexport async function ensureVercelCredentials(\n opts: EnsureVercelCredentialsOptions = {},\n): Promise<void> {\n ensureVercelEnvLoaded();\n\n if (!opts.force && hasUsableCredentials()) return;\n if (!process.stdin.isTTY) return;\n\n intro('Vercel setup');\n note(\n `AgentBox needs Vercel credentials to provision sandboxes.\\n` +\n `Sign in with Vercel (recommended): drives the Vercel \\`sandbox\\` CLI through a browser login, then reads the token from the CLI's own store and keeps it fresh — no token to paste.\\n` +\n `Access token (best for CI / headless): personal access token + team id + project id, saved to \\`~/.agentbox/secrets.env\\`.\\n` +\n `OIDC (short interactive work): export VERCEL_OIDC_TOKEN in your shell or add it to \\`~/.agentbox/secrets.env\\` (dev token expires ~12h, no headless refresh).`,\n 'Credentials required',\n );\n\n const mode = exitOnCancel(\n await select({\n message: 'How do you want to authenticate?',\n options: [\n { value: 'cli', label: 'Sign in with Vercel (browser) — recommended for interactive use' },\n { value: 'token', label: 'Access token (VERCEL_TOKEN + team + project) — best for CI / headless' },\n { value: 'oidc', label: 'OIDC token (VERCEL_OIDC_TOKEN in env / secrets.env) — short interactive work' },\n ],\n initialValue: 'cli',\n }),\n );\n\n if (mode === 'cli') {\n await runCliLogin();\n return;\n }\n\n if (mode === 'oidc') {\n note(\n `Get an OIDC token with \\`vercel link\\` then \\`vercel env pull\\`, then make it visible to AgentBox by either:\\n` +\n ` export VERCEL_OIDC_TOKEN=<token> # in this shell\\n` +\n ` echo \"VERCEL_OIDC_TOKEN=<token>\" >> ~/.agentbox/secrets.env\\n` +\n `Re-do every ~12h; the dev token expires. AgentBox does not harvest .env.local.`,\n 'OIDC setup',\n );\n // Re-read in case the user already added the token to secrets.env.\n reloadVercelEnv();\n if (process.env.VERCEL_OIDC_TOKEN) {\n log.success('Found VERCEL_OIDC_TOKEN — Vercel is configured.');\n await ensureSbxInstalled();\n outro('Setup complete.');\n } else {\n log.warn('No VERCEL_OIDC_TOKEN found yet — set it as above, then re-run `agentbox vercel login`.');\n }\n return;\n }\n\n const creds = await promptForTokenTrio();\n persistCredentials(creds);\n log.success(`Vercel credentials saved to ${secretsPath()}`);\n await ensureSbxInstalled();\n outro('Setup complete.');\n}\n\ninterface TokenTrio {\n token: string;\n teamId: string;\n projectId: string;\n}\n\nasync function promptForTokenTrio(): Promise<TokenTrio> {\n const openIt = exitOnCancel(\n await confirm({\n message: `Open ${DASHBOARD_TOKENS_URL} to create a token?`,\n initialValue: true,\n }),\n );\n if (openIt) openDashboard();\n\n const token = exitOnCancel(\n await password({\n message: 'Paste your Vercel access token',\n validate: (v) => (v && v.trim().length > 0 ? undefined : 'Cannot be empty'),\n }),\n );\n const teamId = exitOnCancel(\n await text({\n message: 'Team ID (team settings → General)',\n placeholder: 'team_...',\n validate: (v) => (v && v.trim().length > 0 ? undefined : 'Cannot be empty'),\n }),\n );\n const projectId = exitOnCancel(\n await text({\n message: 'Project ID (project settings → General)',\n placeholder: 'prj_...',\n validate: (v) => (v && v.trim().length > 0 ? undefined : 'Cannot be empty'),\n }),\n );\n return { token: token.trim(), teamId: teamId.trim(), projectId: projectId.trim() };\n}\n\nfunction persistCredentials(creds: TokenTrio): void {\n writeManaged({\n VERCEL_TOKEN: creds.token,\n VERCEL_TEAM_ID: creds.teamId,\n VERCEL_PROJECT_ID: creds.projectId,\n });\n}\n\n/**\n * Persist the CLI-login marker + cached stable ids. The access token is\n * deliberately omitted — it's read live from the Vercel CLI store on each call\n * and refreshed there, so the only thing we cache is the team/project scope.\n */\nfunction persistCliCredentials(ids: { teamId: string; projectId: string }): void {\n writeManaged({\n VERCEL_AUTH_SOURCE: 'cli',\n VERCEL_TEAM_ID: ids.teamId,\n VERCEL_PROJECT_ID: ids.projectId,\n });\n}\n\n/**\n * Atomically rewrite the managed Vercel keys in `~/.agentbox/secrets.env`:\n * strip every prior value for a `MANAGED_KEYS` entry, then append exactly the\n * keys in `record` (mode 0600, temp-file + rename). Also mirrors the record\n * into `process.env` (and clears the other managed keys there) so the current\n * run uses the new values immediately.\n */\nfunction writeManaged(record: Record<string, string>): void {\n for (const k of MANAGED_KEYS) delete process.env[k];\n for (const [k, v] of Object.entries(record)) process.env[k] = v;\n\n const path = secretsPath();\n mkdirSync(dirname(path), { recursive: true });\n\n let existing = '';\n if (existsSync(path)) {\n try {\n existing = readFileSync(path, 'utf8');\n } catch {\n existing = '';\n }\n }\n const kept = existing\n .split(/\\r?\\n/)\n .filter((line) => {\n const stripped = line.startsWith('export ') ? line.slice('export '.length) : line;\n const eq = stripped.indexOf('=');\n if (eq <= 0) return true;\n const key = stripped.slice(0, eq).trim();\n return !(MANAGED_KEYS as readonly string[]).includes(key);\n })\n .join('\\n')\n .replace(/\\s+$/u, '');\n\n const lines = Object.entries(record).map(([k, v]) => `${k}=${v}`);\n const body = (kept ? `${kept}\\n` : '') + lines.join('\\n') + '\\n';\n\n const tmp = `${path}.tmp`;\n writeFileSync(tmp, body, { mode: 0o600 });\n try {\n chmodSync(tmp, 0o600);\n } catch {\n // chmod best-effort; writeFileSync mode already covers most filesystems.\n }\n renameSync(tmp, path);\n try {\n chmodSync(path, 0o600);\n } catch {\n // ignore — already attempted above\n }\n}\n\n/**\n * The full CLI-login flow: make sure the Vercel `sandbox` CLI is installed (offer\n * to install it), run its browser OAuth, harvest the team id from the CLI store,\n * let the user pick a project to scope sandboxes to, and persist the marker +\n * ids. The access token is never stored — `resolveCredentials` reads it live.\n */\n/**\n * Make sure the Vercel `sandbox` CLI is on PATH, offering to install it. Every\n * login mode ensures it because interactive attach (`agentbox shell|claude|\n * codex|opencode` on a vercel box) drives `sbx exec` for a real PTY. Returns the\n * resolved bin, or null if absent / declined / install failed (callers warn).\n */\nasync function ensureSbxInstalled(): Promise<{ bin: string } | null> {\n let det = await detectSbx();\n if (!det.installed) {\n const doInstall = exitOnCancel(\n await confirm({\n message: `The Vercel sandbox CLI (needed for interactive attach) isn't installed. Install it now? (${installSbxHint()})`,\n initialValue: true,\n }),\n );\n if (!doInstall) {\n log.warn(\n `Install it with \\`${installSbxHint()}\\` to use \\`agentbox shell|claude|codex|opencode\\` on Vercel boxes.`,\n );\n return null;\n }\n const sp = spinner();\n sp.start('Installing the Vercel sandbox CLI…');\n const ok = await installSbx();\n resetSbxCache();\n det = await detectSbx();\n if (!ok || !det.installed || !det.bin) {\n sp.stop('Install failed.');\n log.warn(`Could not install the sandbox CLI — run \\`${installSbxHint()}\\` manually.`);\n return null;\n }\n sp.stop(`Installed sandbox CLI${det.version ? ` ${det.version}` : ''}.`);\n }\n return det.bin ? { bin: det.bin } : null;\n}\n\nasync function runCliLogin(): Promise<void> {\n const det = await ensureSbxInstalled();\n if (!det) {\n log.warn('The Vercel sandbox CLI is required to sign in this way — install it, then re-run `agentbox vercel login`.');\n return;\n }\n\n note('A browser window will open to sign in to Vercel.', 'Vercel sign-in');\n const status = loginSbx(det.bin);\n if (status !== 0) {\n log.warn('Vercel sign-in did not complete — re-run `agentbox vercel login` to try again.');\n return;\n }\n\n const harvested = harvestCliCredentials();\n if (!harvested) {\n log.warn('Sign-in finished but no credentials were found in the Vercel CLI store. Try again.');\n return;\n }\n\n // Validate the token early so a bad/expired session fails here, not mid-op.\n try {\n await getUser(harvested.token);\n } catch (err) {\n log.warn(\n `The Vercel session looks invalid (${err instanceof Error ? err.message : String(err)}). ` +\n 'Re-run `agentbox vercel login`.',\n );\n return;\n }\n\n const projectId = await resolveProjectId(harvested.token, harvested.teamId);\n if (projectId === null) {\n log.warn('No project selected — re-run `agentbox vercel login` to finish setup.');\n return;\n }\n\n persistCliCredentials({ teamId: harvested.teamId, projectId });\n reloadVercelEnv();\n log.success(`Signed in with Vercel — credentials managed by the sandbox CLI (saved scope to ${secretsPath()}).`);\n outro('Setup complete.');\n}\n\n/**\n * Read the live token + team id from the Vercel CLI store. teamId prefers an\n * already-cached `VERCEL_TEAM_ID` (e.g. from a prior login) and falls back to\n * the CLI's `currentTeam`. Null when the CLI isn't logged in.\n */\nfunction harvestCliCredentials(): { token: string; teamId: string } | null {\n const auth = readCliAuth();\n if (!auth) return null;\n const teamId = process.env.VERCEL_TEAM_ID ?? readCliCurrentTeam();\n if (!teamId) return null;\n return { token: auth.token, teamId };\n}\n\n/**\n * Pick the Vercel project sandboxes run under. Lists the team's projects in a\n * clack select (pre-selecting an existing `agentbox` / sandbox-default project),\n * plus a \"create a new project\" entry. Returns the project id, or null if the\n * user cancelled. Non-interactive callers reuse/create an `agentbox` project.\n */\nasync function resolveProjectId(token: string, teamId: string): Promise<string | null> {\n let projects: VercelProject[] = [];\n const sp = spinner();\n sp.start('Loading your Vercel projects…');\n try {\n projects = await listProjects(token, teamId);\n sp.stop(`Found ${projects.length} project${projects.length === 1 ? '' : 's'}.`);\n } catch (err) {\n sp.stop('Could not list projects.');\n log.warn(`Failed to list Vercel projects: ${err instanceof Error ? err.message : String(err)}`);\n return null;\n }\n\n const CREATE = '__create__';\n const preferred =\n projects.find((p) => p.name === 'agentbox') ??\n projects.find((p) => p.name === 'vercel-sandbox-default-project');\n const choice = exitOnCancel(\n await select({\n message: 'Which Vercel project should sandboxes run under?',\n options: [\n ...projects.map((p) => ({ value: p.id, label: p.name })),\n { value: CREATE, label: 'Create a new project…' },\n ],\n initialValue: preferred ? preferred.id : CREATE,\n }),\n );\n\n if (choice !== CREATE) return choice;\n\n const name = exitOnCancel(\n await text({\n message: 'New project name',\n placeholder: 'agentbox',\n defaultValue: 'agentbox',\n validate: (v) => (v && v.trim().length > 0 ? undefined : 'Cannot be empty'),\n }),\n );\n try {\n const created = await createProject(token, teamId, name.trim() || 'agentbox');\n return created.id;\n } catch (err) {\n log.warn(`Could not create the project: ${err instanceof Error ? err.message : String(err)}`);\n return null;\n }\n}\n\nfunction openDashboard(): void {\n // Lazy import keeps node:child_process out of the module's load cost.\n import('node:child_process')\n .then(({ spawnSync }) => {\n const r = spawnSync(hostOpenCommand(), [DASHBOARD_TOKENS_URL], { stdio: 'ignore' });\n if (r.status !== 0) {\n log.warn(`Could not auto-open the browser — visit ${DASHBOARD_TOKENS_URL} manually.`);\n }\n })\n .catch(() => {\n log.warn(`Could not auto-open the browser — visit ${DASHBOARD_TOKENS_URL} manually.`);\n });\n}\n\nexport function secretsPath(): string {\n return resolve(homedir(), '.agentbox', 'secrets.env');\n}\n\nexport interface VercelCredStatus {\n /** Which auth mode is configured. */\n auth: 'oidc' | 'cli' | 'token' | 'none';\n /** Legacy alias kept for callers that branch on OIDC. */\n oidc: boolean;\n token?: string;\n teamId?: string;\n projectId?: string;\n source: 'env' | 'secrets.env' | 'cli-store' | 'none';\n /**\n * CLI mode only: details about the live Vercel CLI session. Whether the\n * `sandbox` CLI is *installed* needs an async probe (`detectSbx`) and is not\n * reported here — the status printer probes it separately.\n */\n cli?: {\n /** A logged-in session was found in the CLI store. */\n loggedIn: boolean;\n /** Unix seconds the live access token expires at, when known. */\n expiresAt?: number;\n /** True when the token is at/near expiry (a refresh would fire). */\n nearExpiry?: boolean;\n /** Path to the CLI's `auth.json`. */\n authPath: string;\n };\n}\n\nexport function readVercelCredStatus(): VercelCredStatus {\n const shellHad = !!process.env.VERCEL_OIDC_TOKEN || !!process.env.VERCEL_TOKEN;\n ensureVercelEnvLoaded();\n const oidc = !!process.env.VERCEL_OIDC_TOKEN;\n const teamId = process.env.VERCEL_TEAM_ID;\n const projectId = process.env.VERCEL_PROJECT_ID;\n\n if (oidc) {\n return { auth: 'oidc', oidc: true, teamId, projectId, source: shellHad ? 'env' : 'secrets.env' };\n }\n\n if (process.env.VERCEL_AUTH_SOURCE === 'cli') {\n const auth = readCliAuth();\n return {\n auth: 'cli',\n oidc: false,\n token: auth?.token,\n teamId,\n projectId,\n source: 'cli-store',\n cli: {\n loggedIn: !!auth,\n expiresAt: auth?.expiresAt,\n nearExpiry: auth ? isNearExpiry(auth) : undefined,\n authPath: cliStorePaths().authPath,\n },\n };\n }\n\n const token = process.env.VERCEL_TOKEN;\n if (!token) return { auth: 'none', oidc: false, source: 'none' };\n return {\n auth: 'token',\n oidc: false,\n token,\n teamId,\n projectId,\n source: shellHad ? 'env' : 'secrets.env',\n };\n}\n\nexport function maskKey(value: string): string {\n if (value.length <= 8) return '*'.repeat(value.length);\n return `${value.slice(0, 4)}…${'*'.repeat(8)}${value.slice(-4)}`;\n}\n","/**\n * Reader for the Vercel CLI's own credential store — written by `sandbox login`\n * / `vercel login` (the `sandbox`/`sbx` CLI and `vercel` CLI share one store).\n *\n * AgentBox's \"CLI-login\" auth mode (see credentials.ts) drives that CLI for the\n * browser OAuth, then reads the resulting OAuth access token live from here on\n * every SDK call rather than copying it into `secrets.env`: the token is a\n * short-lived, opaque `vca_…` access token that the CLI refreshes lazily from\n * its stored refresh token, so the CLI store is the single self-refreshing\n * source of truth. We only cache the stable bits (team/project id + a marker)\n * in `secrets.env`.\n *\n * Pure FS + path logic — no clack, no execa — so it stays trivially testable.\n */\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n/** The shape of the CLI's `auth.json` (only the fields we consume). */\nexport interface VercelCliAuth {\n /** Opaque OAuth access token (`vca_…`). NOT a JWT — expiry is `expiresAt`. */\n token: string;\n /** Unix seconds. Absent on some CLI versions → treated as near-expiry. */\n expiresAt?: number;\n /** Present but unused by us; the CLI uses it to self-refresh `token`. */\n refreshToken?: string;\n}\n\n/**\n * Resolve the `com.vercel.cli` data directory the way the CLI itself does\n * (xdg-app-paths-style), per platform:\n * - macOS: ~/Library/Application Support/com.vercel.cli\n * - Windows: %APPDATA%\\com.vercel.cli\n * - else: $XDG_DATA_HOME/com.vercel.cli (default ~/.local/share/...)\n *\n * `AGENTBOX_VERCEL_CLI_DIR` overrides outright — for tests and the rare install\n * that relocates the store.\n */\nexport function vercelCliDir(): string {\n const override = process.env.AGENTBOX_VERCEL_CLI_DIR;\n if (override && override.trim().length > 0) return override.trim();\n\n const name = 'com.vercel.cli';\n if (process.platform === 'darwin') {\n return join(homedir(), 'Library', 'Application Support', name);\n }\n if (process.platform === 'win32') {\n const appData = process.env.APPDATA;\n if (appData && appData.trim().length > 0) return join(appData, name);\n return join(homedir(), 'AppData', 'Roaming', name);\n }\n const xdg = process.env.XDG_DATA_HOME;\n const base = xdg && xdg.trim().length > 0 ? xdg.trim() : join(homedir(), '.local', 'share');\n return join(base, name);\n}\n\n/** Absolute paths to the CLI store files, for status/diagnostics. */\nexport function cliStorePaths(): { authPath: string; configPath: string } {\n const dir = vercelCliDir();\n return { authPath: join(dir, 'auth.json'), configPath: join(dir, 'config.json') };\n}\n\nfunction readJson(path: string): unknown {\n if (!existsSync(path)) return null;\n try {\n return JSON.parse(readFileSync(path, 'utf8'));\n } catch {\n return null;\n }\n}\n\n/**\n * Read the live access token from the CLI store. Returns null when the store is\n * missing / unparseable / has no token (CLI never logged in, or logged out) so\n * callers can surface a clear \"run `agentbox vercel login`\" error.\n */\nexport function readCliAuth(): VercelCliAuth | null {\n const raw = readJson(cliStorePaths().authPath) as Record<string, unknown> | null;\n if (!raw || typeof raw.token !== 'string' || raw.token.length === 0) return null;\n return {\n token: raw.token,\n expiresAt: typeof raw.expiresAt === 'number' ? raw.expiresAt : undefined,\n refreshToken: typeof raw.refreshToken === 'string' ? raw.refreshToken : undefined,\n };\n}\n\n/** Read the CLI's currently-selected team (`config.json` `currentTeam`). */\nexport function readCliCurrentTeam(): string | null {\n const raw = readJson(cliStorePaths().configPath) as Record<string, unknown> | null;\n return raw && typeof raw.currentTeam === 'string' && raw.currentTeam.length > 0\n ? raw.currentTeam\n : null;\n}\n\n/**\n * Whether the access token is at/near expiry and should be refreshed before\n * use. A missing `expiresAt` is treated as near-expiry so we always probe a\n * refresh rather than ship a token of unknown age. `skewSec` is the safety\n * window: refresh if the token expires within that many seconds.\n */\nexport function isNearExpiry(auth: VercelCliAuth, skewSec = 120): boolean {\n if (auth.expiresAt === undefined) return true;\n return auth.expiresAt * 1000 < Date.now() + skewSec * 1000;\n}\n","/**\n * Thin loader around `@vercel/sandbox`. Resolves the auth credentials once and\n * threads them into every SDK call.\n *\n * Three auth modes (in precedence order):\n * - OIDC: `VERCEL_OIDC_TOKEN` in env → decode the JWT for owner/project and\n * pass `{ token, teamId, projectId }` explicitly.\n * - CLI-login: `VERCEL_AUTH_SOURCE=cli` → read the live OAuth access token\n * from the Vercel CLI's own store (`auth.json`) and the cached team/project\n * ids from `secrets.env`. The token is never copied to `secrets.env`; the\n * CLI store is the self-refreshing source of truth. `ensureFreshCredentials`\n * refreshes it (via the `sbx` CLI) before use when it's near expiry.\n * - Access token: `VERCEL_TOKEN` + `VERCEL_TEAM_ID` + `VERCEL_PROJECT_ID` →\n * passed explicitly as `{ token, teamId, projectId }` on each call, since\n * the SDK does NOT read those from env automatically.\n */\n\nimport { ensureVercelEnvLoaded } from './env-loader.js';\nimport { isNearExpiry, readCliAuth, readCliCurrentTeam } from './cli-store.js';\nimport { detectSbx, refreshSbxToken } from './sbx-cli.js';\n\nexport interface VercelCredentials {\n token: string;\n teamId: string;\n projectId: string;\n}\n\n/**\n * Resolve the credentials to thread into SDK calls. Throws when nothing is\n * configured (or an OIDC token has expired) so callers get a clear, actionable\n * error instead of an opaque SDK auth failure.\n *\n * For OIDC we do NOT return `{}` and let the SDK read the env var: the SDK's\n * env-OIDC path (`@vercel/oidc`) tries to *refresh* the token via the Vercel\n * CLI's `.vercel/project.json` + cached auth, which an agentbox box doesn't\n * have, so it fails with \"Could not get credentials from OIDC context\". Instead\n * we decode the OIDC JWT — which embeds `owner_id` (teamId) and `project_id` —\n * and pass `{ token, teamId, projectId }` explicitly, which uses the SDK's\n * direct-credentials path (the OIDC token is itself a valid API bearer).\n */\nexport function resolveCredentials(): VercelCredentials {\n ensureVercelEnvLoaded();\n const oidc = process.env.VERCEL_OIDC_TOKEN;\n if (oidc) {\n const claims = decodeOidcClaims(oidc);\n if (!claims) {\n throw new Error(\n 'VERCEL_OIDC_TOKEN is set but could not be decoded (not a valid Vercel OIDC JWT). ' +\n 'Re-run `vercel env pull`, or use the VERCEL_TOKEN + VERCEL_TEAM_ID + VERCEL_PROJECT_ID trio.',\n );\n }\n if (claims.exp !== undefined && claims.exp * 1000 < Date.now()) {\n throw new Error(\n 'VERCEL_OIDC_TOKEN has expired (Vercel dev OIDC tokens last ~12h). ' +\n 'Re-run `vercel env pull` to refresh it, then retry.',\n );\n }\n return { token: oidc, teamId: claims.teamId, projectId: claims.projectId };\n }\n if (process.env.VERCEL_AUTH_SOURCE === 'cli') {\n const auth = readCliAuth();\n if (!auth) {\n throw new Error(\n 'Vercel CLI session not found — run `agentbox vercel login` (or `sbx login`) to sign in again.',\n );\n }\n const teamId = process.env.VERCEL_TEAM_ID ?? readCliCurrentTeam() ?? undefined;\n const projectId = process.env.VERCEL_PROJECT_ID;\n if (!teamId || !projectId) {\n throw new Error(\n 'Vercel CLI auth is missing the team/project id — re-run `agentbox vercel login`.',\n );\n }\n // Live token straight from the CLI store; nothing cached on disk.\n return { token: auth.token, teamId, projectId };\n }\n const token = process.env.VERCEL_TOKEN;\n const teamId = process.env.VERCEL_TEAM_ID;\n const projectId = process.env.VERCEL_PROJECT_ID;\n if (token && teamId && projectId) return { token, teamId, projectId };\n throw new Error(\n 'Vercel credentials not configured.\\n' +\n 'Either run `vercel link && vercel env pull` to get a VERCEL_OIDC_TOKEN, ' +\n 'or set VERCEL_TOKEN + VERCEL_TEAM_ID + VERCEL_PROJECT_ID ' +\n '(see `agentbox vercel login`).',\n );\n}\n\ninterface OidcClaims {\n teamId: string;\n projectId: string;\n exp?: number;\n}\n\n/** Decode the `owner_id`/`project_id`/`exp` claims from a Vercel OIDC JWT. */\nfunction decodeOidcClaims(token: string): OidcClaims | null {\n const parts = token.split('.');\n if (parts.length < 2 || !parts[1]) return null;\n try {\n const payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString('utf8')) as {\n owner_id?: unknown;\n project_id?: unknown;\n exp?: unknown;\n };\n if (typeof payload.owner_id !== 'string' || typeof payload.project_id !== 'string') return null;\n return {\n teamId: payload.owner_id,\n projectId: payload.project_id,\n exp: typeof payload.exp === 'number' ? payload.exp : undefined,\n };\n } catch {\n return null;\n }\n}\n\n/** True when any auth mode is configured. Used by the credential gate. */\nexport function hasUsableCredentials(): boolean {\n ensureVercelEnvLoaded();\n if (process.env.VERCEL_OIDC_TOKEN) return true;\n if (\n process.env.VERCEL_AUTH_SOURCE === 'cli' &&\n process.env.VERCEL_TEAM_ID &&\n process.env.VERCEL_PROJECT_ID &&\n readCliAuth()\n ) {\n return true;\n }\n return Boolean(\n process.env.VERCEL_TOKEN && process.env.VERCEL_TEAM_ID && process.env.VERCEL_PROJECT_ID,\n );\n}\n\n/**\n * Refresh the CLI-login access token before use when it's near expiry. No-op\n * for the OIDC and access-token modes (nothing to refresh). For CLI mode: if the\n * live token in the CLI store is within the safety window, run a cheap `sbx`\n * read command, which makes the CLI rotate its own token from the stored refresh\n * token, then re-read `secrets.env`. Throws an actionable error when the CLI is\n * gone or the refresh fails (e.g. the refresh token itself expired).\n *\n * Call this once at the top of each backend operation, BEFORE the (sync)\n * `resolveCredentials()` reads the token. An in-process single-flight collapses\n * concurrent ops onto one refresh; cross-process races are harmless (the CLI\n * writes its store atomically and a fresh-token refresh is a no-op).\n */\nlet inflightRefresh: Promise<void> | null = null;\n\nexport function ensureFreshCredentials(): Promise<void> {\n ensureVercelEnvLoaded();\n if (process.env.VERCEL_AUTH_SOURCE !== 'cli') return Promise.resolve();\n if (inflightRefresh) return inflightRefresh;\n inflightRefresh = refreshCliToken().finally(() => {\n inflightRefresh = null;\n });\n return inflightRefresh;\n}\n\nasync function refreshCliToken(): Promise<void> {\n const auth = readCliAuth();\n if (!auth) return; // resolveCredentials() will throw the clear \"logged out\" error\n if (!isNearExpiry(auth)) return; // still valid — no work\n\n const det = await detectSbx();\n if (!det.installed || !det.bin) {\n throw new Error(\n 'Vercel access token is near expiry and the `sandbox` CLI is no longer installed — ' +\n 'reinstall it (`npm install -g sandbox`) or run `agentbox vercel login`.',\n );\n }\n const ok = await refreshSbxToken(det.bin);\n if (!ok) {\n throw new Error(\n 'Vercel token refresh failed — run `agentbox vercel login` (the refresh token may have expired).',\n );\n }\n // The token lives in the CLI store, not secrets.env — refreshSbxToken rotated\n // auth.json in place, so the next readCliAuth() returns the fresh token.\n const fresh = readCliAuth();\n if (!fresh || isNearExpiry(fresh, 0)) {\n throw new Error(\n 'Vercel token is still stale after a refresh attempt — run `agentbox vercel login`.',\n );\n }\n}\n\n// Re-export the SDK surface we use so the rest of the package imports from one\n// place (and tests can mock `./sdk.js` instead of the package).\nexport { Sandbox, Snapshot } from '@vercel/sandbox';\nexport type { Sandbox as SandboxType } from '@vercel/sandbox';\n","/**\n * Minimal Vercel REST helpers used by the CLI-login auth flow. The Sandbox SDK\n * requires a projectId on every call, but the OAuth access token harvested from\n * the CLI is team-scoped with no project — so after login we list the team's\n * projects (and optionally create one) to resolve a project to scope sandboxes\n * to. Plain `fetch`; no SDK. Each call takes the harvested `(token, teamId)`.\n */\n\nconst API = 'https://api.vercel.com';\n\nexport interface VercelProject {\n id: string;\n name: string;\n}\n\nclass VercelApiError extends Error {\n constructor(\n readonly status: number,\n message: string,\n ) {\n super(message);\n this.name = 'VercelApiError';\n }\n}\n\nasync function api(\n token: string,\n path: string,\n init?: { method?: string; body?: unknown },\n): Promise<unknown> {\n const res = await fetch(`${API}${path}`, {\n method: init?.method ?? 'GET',\n headers: {\n Authorization: `Bearer ${token}`,\n ...(init?.body ? { 'Content-Type': 'application/json' } : {}),\n },\n body: init?.body ? JSON.stringify(init.body) : undefined,\n });\n const text = await res.text();\n let json: unknown = null;\n try {\n json = text ? JSON.parse(text) : null;\n } catch {\n json = null;\n }\n if (!res.ok) {\n const detail =\n (json as { error?: { message?: string } } | null)?.error?.message ??\n text ??\n res.statusText;\n throw new VercelApiError(res.status, `Vercel API ${res.status}: ${detail}`);\n }\n return json;\n}\n\n/** Validate the token and return the authenticated user (probe / status). */\nexport async function getUser(token: string): Promise<{ id: string; username?: string }> {\n const json = (await api(token, '/v2/user')) as {\n user?: { id: string; username?: string };\n };\n const user = json.user;\n if (!user?.id) throw new Error('Vercel /v2/user returned no user');\n return user;\n}\n\n/** List the team's projects (id + name). Paginates up to `limit` (default 100). */\nexport async function listProjects(\n token: string,\n teamId: string,\n limit = 100,\n): Promise<VercelProject[]> {\n const json = (await api(\n token,\n `/v9/projects?teamId=${encodeURIComponent(teamId)}&limit=${limit}`,\n )) as { projects?: Array<{ id: string; name: string }> };\n return (json.projects ?? []).map((p) => ({ id: p.id, name: p.name }));\n}\n\n/**\n * Create a project under the team. On a 409 (name already taken) re-list and\n * return the existing project of that name, so the caller treats create as\n * idempotent.\n */\nexport async function createProject(\n token: string,\n teamId: string,\n name: string,\n): Promise<VercelProject> {\n try {\n const json = (await api(token, `/v9/projects?teamId=${encodeURIComponent(teamId)}`, {\n method: 'POST',\n body: { name },\n })) as { id: string; name: string };\n return { id: json.id, name: json.name };\n } catch (err) {\n if (err instanceof VercelApiError && err.status === 409) {\n const existing = (await listProjects(token, teamId)).find((p) => p.name === name);\n if (existing) return existing;\n }\n throw err;\n }\n}\n","/**\n * Resolver for the on-disk files shipped into a fresh Vercel sandbox during\n * `prepareVercel()`. Same idea as the hetzner resolver: a flat list of files to\n * upload via `sandbox.writeFiles`, each resolved from either the staged CLI\n * runtime tree or the monorepo source tree.\n *\n * Lookup order per file:\n * 1. The CLI's staged runtime tree: `<cliRoot>/runtime/vercel/...`.\n * 2. The monorepo source tree (dev fallback) under `packages/`.\n *\n * Any missing file throws a clear error naming the paths tried. Note: no\n * dockerd helper — Vercel can't run nested containers.\n */\n\nimport { existsSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst SELF = dirname(fileURLToPath(import.meta.url));\n\nexport function findStagedCliRuntimeRoot(): string | undefined {\n const candidates = [\n resolve(SELF, '..', 'runtime'),\n resolve(SELF, '..', '..', 'runtime'),\n ];\n for (const c of candidates) {\n if (existsSync(resolve(c, 'vercel', 'scripts', 'provision.sh'))) return c;\n }\n return undefined;\n}\n\nexport interface RuntimeAsset {\n /** Logical name (used in error messages + log lines). */\n name: string;\n /** Absolute path on the box (writeFiles target). */\n remotePath: string;\n /** File mode to apply after upload. */\n remoteMode: number;\n}\n\n/**\n * Where each asset lands inside the sandbox. provision.sh reads them from these\n * fixed paths. The agent/runtime helpers go straight to /usr/local/bin; baked\n * config files to /tmp for provision.sh to `install` into place.\n */\nexport const RUNTIME_ASSETS: readonly RuntimeAsset[] = [\n { name: 'provision.sh', remotePath: '/tmp/agentbox-provision.sh', remoteMode: 0o755 },\n { name: 'agentbox-ctl', remotePath: '/tmp/agentbox-ctl', remoteMode: 0o755 },\n { name: 'agentbox-vnc-start', remotePath: '/tmp/agentbox-vnc-start', remoteMode: 0o755 },\n { name: 'agentbox-checkpoint-cleanup', remotePath: '/tmp/agentbox-checkpoint-cleanup', remoteMode: 0o755 },\n { name: 'agentbox-open', remotePath: '/tmp/agentbox-open', remoteMode: 0o755 },\n { name: 'gh-shim', remotePath: '/tmp/agentbox-gh-shim', remoteMode: 0o755 },\n { name: 'git-shim', remotePath: '/tmp/agentbox-git-shim', remoteMode: 0o755 },\n { name: 'ntn-shim', remotePath: '/tmp/agentbox-ntn-shim', remoteMode: 0o755 },\n { name: 'linear-shim', remotePath: '/tmp/agentbox-linear-shim', remoteMode: 0o755 },\n { name: 'custom-system-CLAUDE.md', remotePath: '/tmp/agentbox-custom-CLAUDE.md', remoteMode: 0o644 },\n { name: 'claude-managed-settings.json', remotePath: '/tmp/agentbox-managed-settings.json', remoteMode: 0o644 },\n { name: 'agentbox-codex-hooks.json', remotePath: '/tmp/agentbox-codex-hooks.json', remoteMode: 0o644 },\n { name: 'agentbox-setup-skill.md', remotePath: '/tmp/agentbox-setup-skill.md', remoteMode: 0o644 },\n] as const;\n\nexport interface ResolvedAsset extends RuntimeAsset {\n localPath: string;\n}\n\nexport function candidatesFor(\n name: string,\n opts: { cliRuntimeRoot?: string; repoRoot?: string } = {},\n): string[] {\n const cliRoot = opts.cliRuntimeRoot;\n const monorepo = opts.repoRoot ?? guessRepoRoot();\n\n const monorepoRelative: Record<string, string[]> = {\n 'provision.sh': ['packages/sandbox-vercel/scripts/provision.sh'],\n 'agentbox-ctl': ['packages/ctl/dist/bin.cjs'],\n 'agentbox-vnc-start': ['packages/sandbox-docker/scripts/agentbox-vnc-start'],\n 'agentbox-checkpoint-cleanup': ['packages/sandbox-docker/scripts/agentbox-checkpoint-cleanup'],\n 'agentbox-open': ['packages/sandbox-docker/scripts/agentbox-open'],\n 'gh-shim': ['packages/sandbox-docker/scripts/gh-shim'],\n 'git-shim': ['packages/sandbox-docker/scripts/git-shim'],\n 'ntn-shim': ['packages/sandbox-docker/scripts/ntn-shim'],\n 'linear-shim': ['packages/sandbox-docker/scripts/linear-shim'],\n 'custom-system-CLAUDE.md': ['packages/sandbox-vercel/scripts/custom-system-CLAUDE.md'],\n 'claude-managed-settings.json': ['packages/sandbox-docker/scripts/claude-managed-settings.json'],\n 'agentbox-codex-hooks.json': ['packages/sandbox-docker/scripts/agentbox-codex-hooks.json'],\n 'agentbox-setup-skill.md': ['apps/cli/share/agentbox-setup/SKILL.md'],\n };\n\n const cliRelative: Record<string, string[]> = {\n 'provision.sh': ['vercel/scripts/provision.sh'],\n 'agentbox-ctl': ['vercel/ctl.cjs'],\n 'agentbox-vnc-start': ['vercel/agentbox-vnc-start', 'docker/packages/sandbox-docker/scripts/agentbox-vnc-start'],\n 'agentbox-checkpoint-cleanup': ['vercel/agentbox-checkpoint-cleanup', 'docker/packages/sandbox-docker/scripts/agentbox-checkpoint-cleanup'],\n 'agentbox-open': ['vercel/agentbox-open', 'docker/packages/sandbox-docker/scripts/agentbox-open'],\n 'gh-shim': ['vercel/gh-shim', 'docker/packages/sandbox-docker/scripts/gh-shim'],\n 'git-shim': ['vercel/git-shim', 'docker/packages/sandbox-docker/scripts/git-shim'],\n 'ntn-shim': ['vercel/ntn-shim', 'docker/packages/sandbox-docker/scripts/ntn-shim'],\n 'linear-shim': ['vercel/linear-shim', 'docker/packages/sandbox-docker/scripts/linear-shim'],\n 'custom-system-CLAUDE.md': ['vercel/custom-system-CLAUDE.md'],\n 'claude-managed-settings.json': ['vercel/claude-managed-settings.json', 'docker/packages/sandbox-docker/scripts/claude-managed-settings.json'],\n 'agentbox-codex-hooks.json': ['vercel/agentbox-codex-hooks.json', 'docker/packages/sandbox-docker/scripts/agentbox-codex-hooks.json'],\n 'agentbox-setup-skill.md': ['vercel/agentbox-setup-skill.md', 'docker/apps/cli/share/agentbox-setup/SKILL.md'],\n };\n\n const out: string[] = [];\n if (cliRoot) {\n for (const rel of cliRelative[name] ?? []) out.push(resolve(cliRoot, rel));\n }\n for (const rel of monorepoRelative[name] ?? []) out.push(resolve(monorepo, rel));\n return out;\n}\n\nexport function resolveRuntimeAssets(\n opts: { cliRuntimeRoot?: string; repoRoot?: string } = {},\n): ResolvedAsset[] {\n const out: ResolvedAsset[] = [];\n const missing: Array<{ name: string; tried: string[] }> = [];\n for (const asset of RUNTIME_ASSETS) {\n const cands = candidatesFor(asset.name, opts);\n const hit = cands.find((p) => existsSync(p));\n if (!hit) {\n missing.push({ name: asset.name, tried: cands });\n continue;\n }\n out.push({ ...asset, localPath: hit });\n }\n if (missing.length > 0) {\n const lines = missing.flatMap((m) => [` - ${m.name}: tried`, ...m.tried.map((p) => ` ${p}`)]);\n throw new Error(\n `vercel: could not resolve runtime assets needed to bake the base snapshot:\\n` +\n lines.join('\\n') +\n `\\n\\nIf running from the monorepo, ensure \\`pnpm -w build\\` has run so packages/ctl/dist/bin.cjs exists.`,\n );\n }\n return out;\n}\n\nfunction guessRepoRoot(): string {\n let cur = SELF;\n for (let i = 0; i < 8; i++) {\n if (existsSync(resolve(cur, 'pnpm-workspace.yaml'))) return cur;\n const parent = dirname(cur);\n if (parent === cur) break;\n cur = parent;\n }\n return SELF;\n}\n","/**\n * Persisted record of what `agentbox prepare --provider vercel` has built.\n * Lives at `~/.agentbox/vercel-prepared.json` so the auto-prepare gate\n * (`ensureVercelBaseSnapshot()`) and `backend.provision` can resolve the base\n * snapshot to boot every box from.\n *\n * Single tier for now — the shared base snapshot (AL2023 + deps + agentbox-ctl\n * + agents). A per-project snapshot tier (matching the hetzner/daytona shape)\n * is a future optimization tracked in docs/vercel-backlog.md.\n *\n * Schema versioned so future shape changes can migrate; only `schema: 1` is\n * accepted today.\n */\n\nimport { computeContextSha256, readPreparedStateRaw, writePreparedStateRaw, preparedStatePathFor } from '@agentbox/sandbox-core';\nimport { UserFacingError } from '@agentbox/core';\nimport { findStagedCliRuntimeRoot, resolveRuntimeAssets } from './runtime-assets.js';\n\nconst SCHEMA = 1 as const;\n\nexport interface PreparedVercelBase {\n /** Vercel snapshot id (opaque). The thing `Sandbox.create({ source }) ` boots from. */\n snapshotId: string;\n /** Deterministic SHA-256 of the prepare build context (provision.sh + assets). */\n contextSha256?: string;\n /** CLI version that produced this snapshot (informational). */\n cliVersion?: string;\n /** Git short SHA of the CLI build (informational). */\n cliCommit?: string;\n /** ISO timestamp of bake completion. */\n createdAt: string;\n}\n\nexport interface PreparedVercelState {\n schema: typeof SCHEMA;\n /** The shared base snapshot. Absent until first `agentbox prepare`. */\n base?: PreparedVercelBase;\n}\n\nexport function preparedStatePath(): string {\n return preparedStatePathFor('vercel');\n}\n\nexport function readPreparedState(): PreparedVercelState {\n const raw = readPreparedStateRaw('vercel');\n if (raw === null || typeof raw !== 'object') return { schema: SCHEMA };\n const parsed = raw as Partial<PreparedVercelState>;\n if (parsed.schema !== SCHEMA) {\n // Unknown/missing schema: refuse to read — the next prepare overwrites it.\n return { schema: SCHEMA };\n }\n return { schema: SCHEMA, base: parsed.base };\n}\n\nexport function writePreparedState(state: PreparedVercelState): void {\n writePreparedStateRaw('vercel', state);\n}\n\n/** Update one field of the state without forcing callers to read/merge/write. */\nexport function updatePreparedState(mutate: (s: PreparedVercelState) => void): void {\n const s = readPreparedState();\n mutate(s);\n writePreparedState(s);\n}\n\n/**\n * Compute the CURRENT build-context fingerprint for the vercel base snapshot\n * (the SHA over every file `prepare` would `writeFiles` into the builder\n * sandbox). Side-effect-free — never builds. Returns `undefined` when the\n * runtime assets can't be resolved (dev tree without `pnpm -w build`) so\n * the CLI can degrade to \"can't tell, don't nag\".\n *\n * Used by `evaluateBaseFreshness` to compare against the stored value in\n * `vercel-prepared.json.base.contextSha256`. Must produce a byte-identical\n * hash to the one `prepare` writes — both go through the same\n * `resolveRuntimeAssets` + `computeContextSha256` chain.\n */\nexport async function currentVercelBaseFingerprintLive(): Promise<string | undefined> {\n try {\n const assets = resolveRuntimeAssets({ cliRuntimeRoot: findStagedCliRuntimeRoot() });\n return await computeContextSha256(\n assets.map((a) => ({ rel: a.name, abs: a.localPath })),\n );\n } catch {\n return undefined;\n }\n}\n\n/**\n * First-use gate. If no base snapshot is recorded, throw an actionable error\n * pointing at `agentbox prepare --provider vercel`. Called by `backend.provision`\n * (indirectly via the snapshot resolution) and usable by the CLI.\n */\nexport function ensureVercelBaseSnapshot(): void {\n const state = readPreparedState();\n if (state.base !== undefined) return;\n throw new UserFacingError(\n 'no Vercel base snapshot found.\\n' +\n 'Run `agentbox prepare --provider vercel` first — Vercel cannot build images ' +\n 'from a Dockerfile, so the base snapshot is a one-time prerequisite for cloud boxes.',\n );\n}\n"],"mappings":"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","names":["existsSync","readFileSync","homedir","resolve","existsSync","readFileSync","homedir","dirname","resolve","homedir","existsSync","readFileSync","teamId","projectId","text","spawnSync","resolve","dirname"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
19
|
+
|
|
20
|
+
export {
|
|
21
|
+
__export,
|
|
22
|
+
__reExport
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=chunk-WJFZJZIM.js.map
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
UserFacingError
|
|
4
|
-
} from "./chunk-MLMFNN4T.js";
|
|
5
|
-
import {
|
|
3
|
+
UserFacingError,
|
|
6
4
|
computeContextSha256,
|
|
7
5
|
hostOpenCommand,
|
|
8
6
|
preparedStatePathFor,
|
|
9
7
|
readPreparedStateRaw,
|
|
10
8
|
writePreparedStateRaw
|
|
11
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-6QFPYU4Z.js";
|
|
12
10
|
|
|
13
|
-
// ../../packages/sandbox-e2b/dist/chunk-
|
|
11
|
+
// ../../packages/sandbox-e2b/dist/chunk-PJJ652RN.js
|
|
14
12
|
import { existsSync, readFileSync } from "fs";
|
|
15
13
|
import { homedir } from "os";
|
|
16
14
|
import { resolve } from "path";
|
|
@@ -26,6 +24,7 @@ import {
|
|
|
26
24
|
import { homedir as homedir2 } from "os";
|
|
27
25
|
import { dirname, resolve as resolve2 } from "path";
|
|
28
26
|
import {
|
|
27
|
+
cancel,
|
|
29
28
|
confirm,
|
|
30
29
|
intro,
|
|
31
30
|
isCancel,
|
|
@@ -96,6 +95,13 @@ function hasUsableCredentials() {
|
|
|
96
95
|
ensureE2bEnvLoaded();
|
|
97
96
|
return Boolean(process.env.E2B_API_KEY);
|
|
98
97
|
}
|
|
98
|
+
function exitOnCancel(v) {
|
|
99
|
+
if (isCancel(v)) {
|
|
100
|
+
cancel("Cancelled.");
|
|
101
|
+
process.exit(130);
|
|
102
|
+
}
|
|
103
|
+
return v;
|
|
104
|
+
}
|
|
99
105
|
var DASHBOARD_KEYS_URL = "https://e2b.dev/dashboard?tab=keys";
|
|
100
106
|
var MANAGED_KEYS = ["E2B_API_KEY"];
|
|
101
107
|
async function ensureE2bCredentials(opts = {}) {
|
|
@@ -109,23 +115,19 @@ Get one from ${DASHBOARD_KEYS_URL} (free tier available), then paste it below.
|
|
|
109
115
|
The key is stored in \`~/.agentbox/secrets.env\` (mode 0600) \u2014 no .env.local harvesting.`,
|
|
110
116
|
"Credentials required"
|
|
111
117
|
);
|
|
112
|
-
const openIt =
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
118
|
+
const openIt = exitOnCancel(
|
|
119
|
+
await confirm({
|
|
120
|
+
message: `Open ${DASHBOARD_KEYS_URL} to create a key?`,
|
|
121
|
+
initialValue: true
|
|
122
|
+
})
|
|
123
|
+
);
|
|
120
124
|
if (openIt) openDashboard();
|
|
121
|
-
const key =
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
125
|
+
const key = exitOnCancel(
|
|
126
|
+
await password({
|
|
127
|
+
message: "Paste your E2B API key",
|
|
128
|
+
validate: (v) => v && v.trim().length > 0 ? void 0 : "Cannot be empty"
|
|
129
|
+
})
|
|
130
|
+
);
|
|
129
131
|
persistCredentials({ apiKey: key.trim() });
|
|
130
132
|
reloadE2bEnv();
|
|
131
133
|
log.success(`E2B credentials saved to ${secretsPath()}`);
|
|
@@ -209,6 +211,8 @@ var RUNTIME_ASSETS = [
|
|
|
209
211
|
{ name: "agentbox-open", remotePath: "/tmp/agentbox-open", remoteMode: 493 },
|
|
210
212
|
{ name: "gh-shim", remotePath: "/tmp/agentbox-gh-shim", remoteMode: 493 },
|
|
211
213
|
{ name: "git-shim", remotePath: "/tmp/agentbox-git-shim", remoteMode: 493 },
|
|
214
|
+
{ name: "ntn-shim", remotePath: "/tmp/agentbox-ntn-shim", remoteMode: 493 },
|
|
215
|
+
{ name: "linear-shim", remotePath: "/tmp/agentbox-linear-shim", remoteMode: 493 },
|
|
212
216
|
{ name: "custom-system-CLAUDE.md", remotePath: "/tmp/agentbox-custom-CLAUDE.md", remoteMode: 420 },
|
|
213
217
|
{ name: "claude-managed-settings.json", remotePath: "/tmp/agentbox-managed-settings.json", remoteMode: 420 },
|
|
214
218
|
{ name: "agentbox-codex-hooks.json", remotePath: "/tmp/agentbox-codex-hooks.json", remoteMode: 420 },
|
|
@@ -225,6 +229,8 @@ function candidatesFor(name, opts = {}) {
|
|
|
225
229
|
"agentbox-open": ["packages/sandbox-docker/scripts/agentbox-open"],
|
|
226
230
|
"gh-shim": ["packages/sandbox-docker/scripts/gh-shim"],
|
|
227
231
|
"git-shim": ["packages/sandbox-docker/scripts/git-shim"],
|
|
232
|
+
"ntn-shim": ["packages/sandbox-docker/scripts/ntn-shim"],
|
|
233
|
+
"linear-shim": ["packages/sandbox-docker/scripts/linear-shim"],
|
|
228
234
|
"custom-system-CLAUDE.md": ["packages/sandbox-e2b/scripts/custom-system-CLAUDE.md"],
|
|
229
235
|
"claude-managed-settings.json": ["packages/sandbox-docker/scripts/claude-managed-settings.json"],
|
|
230
236
|
"agentbox-codex-hooks.json": ["packages/sandbox-docker/scripts/agentbox-codex-hooks.json"],
|
|
@@ -238,6 +244,8 @@ function candidatesFor(name, opts = {}) {
|
|
|
238
244
|
"agentbox-open": ["e2b/agentbox-open", "docker/packages/sandbox-docker/scripts/agentbox-open"],
|
|
239
245
|
"gh-shim": ["e2b/gh-shim", "docker/packages/sandbox-docker/scripts/gh-shim"],
|
|
240
246
|
"git-shim": ["e2b/git-shim", "docker/packages/sandbox-docker/scripts/git-shim"],
|
|
247
|
+
"ntn-shim": ["e2b/ntn-shim", "docker/packages/sandbox-docker/scripts/ntn-shim"],
|
|
248
|
+
"linear-shim": ["e2b/linear-shim", "docker/packages/sandbox-docker/scripts/linear-shim"],
|
|
241
249
|
"custom-system-CLAUDE.md": ["e2b/custom-system-CLAUDE.md"],
|
|
242
250
|
"claude-managed-settings.json": ["e2b/claude-managed-settings.json", "docker/packages/sandbox-docker/scripts/claude-managed-settings.json"],
|
|
243
251
|
"agentbox-codex-hooks.json": ["e2b/agentbox-codex-hooks.json", "docker/packages/sandbox-docker/scripts/agentbox-codex-hooks.json"],
|
|
@@ -343,4 +351,4 @@ export {
|
|
|
343
351
|
currentE2bBaseFingerprintLive,
|
|
344
352
|
ensureE2bBaseTemplate
|
|
345
353
|
};
|
|
346
|
-
//# sourceMappingURL=chunk-
|
|
354
|
+
//# sourceMappingURL=chunk-XWBFWUY2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../packages/sandbox-e2b/src/env-loader.ts","../../../packages/sandbox-e2b/src/sdk.ts","../../../packages/sandbox-e2b/src/credentials.ts","../../../packages/sandbox-e2b/src/runtime-assets.ts","../../../packages/sandbox-e2b/src/prepared-state.ts"],"sourcesContent":["/**\n * E2B env auto-loader. The `e2b` SDK reads `E2B_API_KEY` (and optionally\n * `E2B_DOMAIN` for non-default deployments) from `process.env`. We seed those\n * from `~/.agentbox/secrets.env` (written by `agentbox e2b login`) so the SDK\n * Just Works after a one-time login — same pattern as the daytona / hetzner /\n * vercel env-loaders.\n *\n * Lookup order (first wins; process.env is never overwritten):\n * 1. `process.env` (already set in the shell).\n * 2. `~/.agentbox/secrets.env` — written by `agentbox e2b login`.\n *\n * Project-level `.env` / `.env.local` are intentionally NOT consulted: those\n * files belong to the app code being developed. Put host credentials in\n * `~/.agentbox/secrets.env` (or the shell env).\n *\n * Only E2B-prefixed keys are imported; the rest of the file is left alone.\n * Idempotent and side-effect-free after the first call.\n */\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { resolve } from 'node:path';\n\nconst E2B_KEYS = ['E2B_API_KEY', 'E2B_DOMAIN'] as const;\n\nlet loaded = false;\n\nexport function ensureE2bEnvLoaded(): void {\n if (loaded) return;\n loaded = true;\n importE2bFromFile(resolve(homedir(), '.agentbox', 'secrets.env'), E2B_KEYS);\n}\n\n/**\n * Force a re-read of `~/.agentbox/secrets.env`. Used by the interactive\n * `agentbox e2b login` flow after it persists the API key, so the same process\n * can pick it up without a restart.\n */\nexport function reloadE2bEnv(): void {\n loaded = false;\n ensureE2bEnvLoaded();\n}\n\nfunction importE2bFromFile(path: string, keys: readonly string[]): void {\n if (!existsSync(path)) return;\n let body: string;\n try {\n body = readFileSync(path, 'utf8');\n } catch {\n return;\n }\n const parsed = parseEnvFile(body);\n for (const key of keys) {\n if (process.env[key] !== undefined) continue;\n const value = parsed[key];\n if (typeof value === 'string') {\n process.env[key] = value;\n }\n }\n}\n\n/**\n * Minimal `.env` parser: handles `KEY=value`, `KEY=\"value\"`, `KEY='value'`,\n * `export KEY=value`, blank lines, and `#` comments. No variable interpolation\n * — predictable over feature-complete (matches the daytona / vercel loaders).\n */\nexport function parseEnvFile(body: string): Record<string, string> {\n const out: Record<string, string> = {};\n for (const rawLine of body.split(/\\r?\\n/)) {\n const line = rawLine.trim();\n if (line.length === 0 || line.startsWith('#')) continue;\n const stripped = line.startsWith('export ') ? line.slice('export '.length) : line;\n const eq = stripped.indexOf('=');\n if (eq <= 0) continue;\n const key = stripped.slice(0, eq).trim();\n let value = stripped.slice(eq + 1).trim();\n if (\n value.length >= 2 &&\n ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\")))\n ) {\n value = value.slice(1, -1);\n }\n out[key] = value;\n }\n return out;\n}\n","/**\n * Thin wrapper around the `e2b` SDK. Resolves the API key once and re-exports\n * the SDK surface the rest of the package uses from a single place (so tests\n * can mock `./sdk.js` instead of the package).\n *\n * E2B only ships one auth mode for first-party use: a single API key. The SDK\n * already reads `process.env.E2B_API_KEY` on each call, but we still expose\n * `resolveApiKey()` so callers can fail loud with an actionable error before\n * the SDK throws a generic \"401 unauthorized\" deep inside an op.\n */\n\nimport { Sandbox, Template } from 'e2b';\nimport { ensureE2bEnvLoaded } from './env-loader.js';\n\nexport { Sandbox, Template };\nexport type { SandboxOpts, SandboxInfo, SandboxState, SandboxListOpts, LogEntry, BuildInfo } from 'e2b';\n\n/**\n * Return the configured E2B API key. Throws an actionable error when nothing\n * is configured. Idempotent — env-loader caches itself after first call.\n */\nexport function resolveApiKey(): string {\n ensureE2bEnvLoaded();\n const k = process.env.E2B_API_KEY;\n if (!k) {\n throw new Error(\n 'E2B credentials not configured.\\n' +\n 'Run `agentbox e2b login` to paste your API key (from https://e2b.dev/dashboard?tab=keys), ' +\n 'or set E2B_API_KEY in the environment / ~/.agentbox/secrets.env.',\n );\n }\n return k;\n}\n\n/** True when an API key is configured. Used by the credential gate. */\nexport function hasUsableCredentials(): boolean {\n ensureE2bEnvLoaded();\n return Boolean(process.env.E2B_API_KEY);\n}\n","/**\n * Interactive E2B credential setup. Single mode — paste an API key from\n * https://e2b.dev/dashboard?tab=keys — much simpler than vercel's three-mode\n * flow. Persists to `~/.agentbox/secrets.env` (the canonical store, matching\n * daytona / hetzner / vercel).\n *\n * Non-interactive callers (no TTY): silent no-op, so scripted/CI runs surface\n * the SDK's own \"not configured\" error instead of hanging on a prompt.\n */\n\nimport {\n chmodSync,\n existsSync,\n mkdirSync,\n readFileSync,\n renameSync,\n writeFileSync,\n} from 'node:fs';\nimport { homedir } from 'node:os';\nimport { dirname, resolve } from 'node:path';\nimport { hostOpenCommand } from '@agentbox/sandbox-core';\nimport {\n cancel,\n confirm,\n intro,\n isCancel,\n log,\n note,\n outro,\n password,\n} from '@clack/prompts';\nimport { ensureE2bEnvLoaded, reloadE2bEnv } from './env-loader.js';\nimport { hasUsableCredentials } from './sdk.js';\n\n// Ctrl+C at a prompt resolves with the cancel symbol; turn that into a real\n// quit so the command never silently continues as if the user answered \"No\".\nfunction exitOnCancel<T>(v: T | symbol): T {\n if (isCancel(v)) {\n cancel('Cancelled.');\n process.exit(130);\n }\n return v as T;\n}\n\nconst DASHBOARD_KEYS_URL = 'https://e2b.dev/dashboard?tab=keys';\n\n/**\n * Keys we manage in `~/.agentbox/secrets.env`. On reconfigure we strip prior\n * values for these before appending so the file never accumulates duplicates.\n */\nconst MANAGED_KEYS = ['E2B_API_KEY'] as const;\n\nexport interface EnsureE2bCredentialsOptions {\n /** Re-prompt even when valid credentials are already present (`agentbox e2b login`). */\n force?: boolean;\n}\n\nexport async function ensureE2bCredentials(\n opts: EnsureE2bCredentialsOptions = {},\n): Promise<void> {\n ensureE2bEnvLoaded();\n\n if (!opts.force && hasUsableCredentials()) return;\n if (!process.stdin.isTTY) return;\n\n intro('E2B setup');\n note(\n `AgentBox needs an E2B API key to provision sandboxes.\\n` +\n `Get one from ${DASHBOARD_KEYS_URL} (free tier available), then paste it below.\\n` +\n `The key is stored in \\`~/.agentbox/secrets.env\\` (mode 0600) — no .env.local harvesting.`,\n 'Credentials required',\n );\n\n const openIt = exitOnCancel(\n await confirm({\n message: `Open ${DASHBOARD_KEYS_URL} to create a key?`,\n initialValue: true,\n }),\n );\n if (openIt) openDashboard();\n\n const key = exitOnCancel(\n await password({\n message: 'Paste your E2B API key',\n validate: (v) => (v && v.trim().length > 0 ? undefined : 'Cannot be empty'),\n }),\n );\n\n persistCredentials({ apiKey: key.trim() });\n reloadE2bEnv();\n log.success(`E2B credentials saved to ${secretsPath()}`);\n outro('Setup complete.');\n}\n\nfunction persistCredentials(creds: { apiKey: string }): void {\n writeManaged({ E2B_API_KEY: creds.apiKey });\n}\n\n/**\n * Atomically rewrite the managed E2B keys in `~/.agentbox/secrets.env`:\n * strip every prior value for a `MANAGED_KEYS` entry, then append exactly the\n * keys in `record` (mode 0600, temp-file + rename). Also mirrors the record\n * into `process.env` so the current run uses the new values immediately.\n */\nfunction writeManaged(record: Record<string, string>): void {\n for (const k of MANAGED_KEYS) delete process.env[k];\n for (const [k, v] of Object.entries(record)) process.env[k] = v;\n\n const path = secretsPath();\n mkdirSync(dirname(path), { recursive: true });\n\n let existing = '';\n if (existsSync(path)) {\n try {\n existing = readFileSync(path, 'utf8');\n } catch {\n existing = '';\n }\n }\n const kept = existing\n .split(/\\r?\\n/)\n .filter((line) => {\n const stripped = line.startsWith('export ') ? line.slice('export '.length) : line;\n const eq = stripped.indexOf('=');\n if (eq <= 0) return true;\n const key = stripped.slice(0, eq).trim();\n return !(MANAGED_KEYS as readonly string[]).includes(key);\n })\n .join('\\n')\n .replace(/\\s+$/u, '');\n\n const lines = Object.entries(record).map(([k, v]) => `${k}=${v}`);\n const body = (kept ? `${kept}\\n` : '') + lines.join('\\n') + '\\n';\n\n const tmp = `${path}.tmp`;\n writeFileSync(tmp, body, { mode: 0o600 });\n try {\n chmodSync(tmp, 0o600);\n } catch {\n // chmod best-effort; writeFileSync mode already covers most filesystems.\n }\n renameSync(tmp, path);\n try {\n chmodSync(path, 0o600);\n } catch {\n // ignore — already attempted above\n }\n}\n\nfunction openDashboard(): void {\n import('node:child_process')\n .then(({ spawnSync }) => {\n const r = spawnSync(hostOpenCommand(), [DASHBOARD_KEYS_URL], { stdio: 'ignore' });\n if (r.status !== 0) {\n log.warn(`Could not auto-open the browser — visit ${DASHBOARD_KEYS_URL} manually.`);\n }\n })\n .catch(() => {\n log.warn(`Could not auto-open the browser — visit ${DASHBOARD_KEYS_URL} manually.`);\n });\n}\n\nexport function secretsPath(): string {\n return resolve(homedir(), '.agentbox', 'secrets.env');\n}\n\nexport interface E2bCredStatus {\n auth: 'key' | 'none';\n token?: string;\n source: 'env' | 'secrets.env' | 'none';\n}\n\nexport function readE2bCredStatus(): E2bCredStatus {\n const shellHad = process.env.E2B_API_KEY !== undefined;\n ensureE2bEnvLoaded();\n const key = process.env.E2B_API_KEY;\n if (!key) return { auth: 'none', source: 'none' };\n return { auth: 'key', token: key, source: shellHad ? 'env' : 'secrets.env' };\n}\n\nexport function maskKey(value: string): string {\n if (value.length <= 8) return '*'.repeat(value.length);\n return `${value.slice(0, 4)}…${'*'.repeat(8)}${value.slice(-4)}`;\n}\n","/**\n * Resolver for the runtime payload baked into the E2B base template during\n * `prepareE2b()`. Same idea as the vercel resolver: a flat list of files to\n * `template.copy` into the build context, each resolved from either the\n * staged CLI runtime tree or the monorepo source tree.\n *\n * Lookup order per file:\n * 1. The CLI's staged runtime tree: `<cliRoot>/e2b/...`.\n * 2. The monorepo source tree (dev fallback) under `packages/`.\n *\n * Any missing file throws a clear error naming the paths tried. Note: no\n * dockerd helper — E2B microVMs can't run nested containers.\n */\n\nimport { existsSync } from 'node:fs';\nimport { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst SELF = dirname(fileURLToPath(import.meta.url));\n\nexport function findStagedCliRuntimeRoot(): string | undefined {\n const candidates = [resolve(SELF, '..', 'runtime'), resolve(SELF, '..', '..', 'runtime')];\n for (const c of candidates) {\n if (existsSync(resolve(c, 'e2b', 'scripts', 'build-template.sh'))) return c;\n }\n return undefined;\n}\n\nexport interface RuntimeAsset {\n /** Logical name (used in error messages + log lines). */\n name: string;\n /** Absolute path inside the template's build filesystem (Template.copy target). */\n remotePath: string;\n /** File mode to apply after upload. */\n remoteMode: number;\n}\n\n/**\n * Where each asset lands inside the sandbox during template build. build-template.sh\n * reads them from these fixed paths. The agent/runtime helpers go straight to\n * /usr/local/bin via the script; baked config files to /tmp for the script to\n * `install` into place.\n */\nexport const RUNTIME_ASSETS: readonly RuntimeAsset[] = [\n { name: 'build-template.sh', remotePath: '/tmp/agentbox-build-template.sh', remoteMode: 0o755 },\n { name: 'agentbox-ctl', remotePath: '/tmp/agentbox-ctl', remoteMode: 0o755 },\n { name: 'agentbox-vnc-start', remotePath: '/tmp/agentbox-vnc-start', remoteMode: 0o755 },\n { name: 'agentbox-checkpoint-cleanup', remotePath: '/tmp/agentbox-checkpoint-cleanup', remoteMode: 0o755 },\n { name: 'agentbox-open', remotePath: '/tmp/agentbox-open', remoteMode: 0o755 },\n { name: 'gh-shim', remotePath: '/tmp/agentbox-gh-shim', remoteMode: 0o755 },\n { name: 'git-shim', remotePath: '/tmp/agentbox-git-shim', remoteMode: 0o755 },\n { name: 'ntn-shim', remotePath: '/tmp/agentbox-ntn-shim', remoteMode: 0o755 },\n { name: 'linear-shim', remotePath: '/tmp/agentbox-linear-shim', remoteMode: 0o755 },\n { name: 'custom-system-CLAUDE.md', remotePath: '/tmp/agentbox-custom-CLAUDE.md', remoteMode: 0o644 },\n { name: 'claude-managed-settings.json', remotePath: '/tmp/agentbox-managed-settings.json', remoteMode: 0o644 },\n { name: 'agentbox-codex-hooks.json', remotePath: '/tmp/agentbox-codex-hooks.json', remoteMode: 0o644 },\n { name: 'agentbox-setup-skill.md', remotePath: '/tmp/agentbox-setup-skill.md', remoteMode: 0o644 },\n] as const;\n\nexport interface ResolvedAsset extends RuntimeAsset {\n localPath: string;\n}\n\nexport function candidatesFor(\n name: string,\n opts: { cliRuntimeRoot?: string; repoRoot?: string } = {},\n): string[] {\n const cliRoot = opts.cliRuntimeRoot;\n const monorepo = opts.repoRoot ?? guessRepoRoot();\n\n const monorepoRelative: Record<string, string[]> = {\n 'build-template.sh': ['packages/sandbox-e2b/scripts/build-template.sh'],\n 'agentbox-ctl': ['packages/ctl/dist/bin.cjs'],\n 'agentbox-vnc-start': ['packages/sandbox-docker/scripts/agentbox-vnc-start'],\n 'agentbox-checkpoint-cleanup': ['packages/sandbox-docker/scripts/agentbox-checkpoint-cleanup'],\n 'agentbox-open': ['packages/sandbox-docker/scripts/agentbox-open'],\n 'gh-shim': ['packages/sandbox-docker/scripts/gh-shim'],\n 'git-shim': ['packages/sandbox-docker/scripts/git-shim'],\n 'ntn-shim': ['packages/sandbox-docker/scripts/ntn-shim'],\n 'linear-shim': ['packages/sandbox-docker/scripts/linear-shim'],\n 'custom-system-CLAUDE.md': ['packages/sandbox-e2b/scripts/custom-system-CLAUDE.md'],\n 'claude-managed-settings.json': ['packages/sandbox-docker/scripts/claude-managed-settings.json'],\n 'agentbox-codex-hooks.json': ['packages/sandbox-docker/scripts/agentbox-codex-hooks.json'],\n 'agentbox-setup-skill.md': ['apps/cli/share/agentbox-setup/SKILL.md'],\n };\n\n const cliRelative: Record<string, string[]> = {\n 'build-template.sh': ['e2b/scripts/build-template.sh'],\n 'agentbox-ctl': ['e2b/ctl.cjs'],\n 'agentbox-vnc-start': ['e2b/agentbox-vnc-start', 'docker/packages/sandbox-docker/scripts/agentbox-vnc-start'],\n 'agentbox-checkpoint-cleanup': ['e2b/agentbox-checkpoint-cleanup', 'docker/packages/sandbox-docker/scripts/agentbox-checkpoint-cleanup'],\n 'agentbox-open': ['e2b/agentbox-open', 'docker/packages/sandbox-docker/scripts/agentbox-open'],\n 'gh-shim': ['e2b/gh-shim', 'docker/packages/sandbox-docker/scripts/gh-shim'],\n 'git-shim': ['e2b/git-shim', 'docker/packages/sandbox-docker/scripts/git-shim'],\n 'ntn-shim': ['e2b/ntn-shim', 'docker/packages/sandbox-docker/scripts/ntn-shim'],\n 'linear-shim': ['e2b/linear-shim', 'docker/packages/sandbox-docker/scripts/linear-shim'],\n 'custom-system-CLAUDE.md': ['e2b/custom-system-CLAUDE.md'],\n 'claude-managed-settings.json': ['e2b/claude-managed-settings.json', 'docker/packages/sandbox-docker/scripts/claude-managed-settings.json'],\n 'agentbox-codex-hooks.json': ['e2b/agentbox-codex-hooks.json', 'docker/packages/sandbox-docker/scripts/agentbox-codex-hooks.json'],\n 'agentbox-setup-skill.md': ['e2b/agentbox-setup-skill.md', 'docker/apps/cli/share/agentbox-setup/SKILL.md'],\n };\n\n const out: string[] = [];\n if (cliRoot) {\n for (const rel of cliRelative[name] ?? []) out.push(resolve(cliRoot, rel));\n }\n for (const rel of monorepoRelative[name] ?? []) out.push(resolve(monorepo, rel));\n return out;\n}\n\nexport function resolveRuntimeAssets(\n opts: { cliRuntimeRoot?: string; repoRoot?: string } = {},\n): ResolvedAsset[] {\n const out: ResolvedAsset[] = [];\n const missing: Array<{ name: string; tried: string[] }> = [];\n for (const asset of RUNTIME_ASSETS) {\n const cands = candidatesFor(asset.name, opts);\n const hit = cands.find((p) => existsSync(p));\n if (!hit) {\n missing.push({ name: asset.name, tried: cands });\n continue;\n }\n out.push({ ...asset, localPath: hit });\n }\n if (missing.length > 0) {\n const lines = missing.flatMap((m) => [` - ${m.name}: tried`, ...m.tried.map((p) => ` ${p}`)]);\n throw new Error(\n `e2b: could not resolve runtime assets needed to bake the base template:\\n` +\n lines.join('\\n') +\n `\\n\\nIf running from the monorepo, ensure \\`pnpm -w build\\` has run so packages/ctl/dist/bin.cjs exists.`,\n );\n }\n return out;\n}\n\nfunction guessRepoRoot(): string {\n let cur = SELF;\n for (let i = 0; i < 8; i++) {\n if (existsSync(resolve(cur, 'pnpm-workspace.yaml'))) return cur;\n const parent = dirname(cur);\n if (parent === cur) break;\n cur = parent;\n }\n return SELF;\n}\n","/**\n * Persisted record of what `agentbox prepare --provider e2b` has built.\n * Lives at `~/.agentbox/e2b-prepared.json` so the auto-prepare gate\n * (`ensureE2bBaseTemplate()`) and `backend.provision` can resolve the base\n * template every box boots from.\n *\n * Single tier for now — the shared base template (Debian + agentbox-ctl +\n * agents). Templates on E2B are id+tag-addressed reusable resources, so unlike\n * Vercel snapshots we don't worry about per-box snapshot eviction; one template\n * is reused for every create.\n *\n * Schema versioned so future shape changes can migrate; only `schema: 1` is\n * accepted today.\n */\n\nimport { computeContextSha256, readPreparedStateRaw, writePreparedStateRaw, preparedStatePathFor } from '@agentbox/sandbox-core';\nimport { UserFacingError } from '@agentbox/core';\nimport { findStagedCliRuntimeRoot, resolveRuntimeAssets } from './runtime-assets.js';\n\nconst SCHEMA = 1 as const;\n\nexport interface PreparedE2bBase {\n /** Opaque E2B template id (e.g. `tmpl_xxxx` or `name:tag`). Sandbox.create({ template }) boots from this. */\n templateId: string;\n /** Human-friendly template name passed to Template.build (e.g. `agentbox-base:latest`). */\n templateName?: string;\n /** Deterministic SHA-256 of the build context (build script + assets). */\n contextSha256?: string;\n /** CLI version that produced this template (informational). */\n cliVersion?: string;\n /** Git short SHA of the CLI build (informational). */\n cliCommit?: string;\n /** ISO timestamp of bake completion. */\n createdAt: string;\n}\n\nexport interface PreparedE2bState {\n schema: typeof SCHEMA;\n /** The shared base template. Absent until first `agentbox prepare`. */\n base?: PreparedE2bBase;\n}\n\nexport function preparedStatePath(): string {\n return preparedStatePathFor('e2b');\n}\n\nexport function readPreparedState(): PreparedE2bState {\n const raw = readPreparedStateRaw('e2b');\n if (raw === null || typeof raw !== 'object') return { schema: SCHEMA };\n const parsed = raw as Partial<PreparedE2bState>;\n if (parsed.schema !== SCHEMA) {\n // Unknown/missing schema: refuse to read — the next prepare overwrites it.\n return { schema: SCHEMA };\n }\n return { schema: SCHEMA, base: parsed.base };\n}\n\nexport function writePreparedState(state: PreparedE2bState): void {\n writePreparedStateRaw('e2b', state);\n}\n\n/** Update one field of the state without forcing callers to read/merge/write. */\nexport function updatePreparedState(mutate: (s: PreparedE2bState) => void): void {\n const s = readPreparedState();\n mutate(s);\n writePreparedState(s);\n}\n\n/**\n * Compute the CURRENT build-context fingerprint for the e2b base template\n * (the SHA over every file `prepare` would copy into the Template build).\n * Side-effect-free — never builds. Returns `undefined` when the runtime\n * assets can't be resolved (dev tree without `pnpm -w build`) so the CLI\n * can degrade to \"can't tell, don't nag\" rather than flag a false stale.\n *\n * Used by `evaluateBaseFreshness` to compare against the stored value in\n * `e2b-prepared.json.base.contextSha256`. Must produce a byte-identical\n * hash to the one `prepare` writes — both go through the same\n * `resolveRuntimeAssets` + `computeContextSha256` chain.\n */\nexport async function currentE2bBaseFingerprintLive(): Promise<string | undefined> {\n try {\n const assets = resolveRuntimeAssets({ cliRuntimeRoot: findStagedCliRuntimeRoot() });\n return await computeContextSha256(\n assets.map((a) => ({ rel: a.name, abs: a.localPath })),\n );\n } catch {\n return undefined;\n }\n}\n\n/**\n * First-use gate. If no base template is recorded, throw an actionable error\n * pointing at `agentbox prepare --provider e2b`. Called by `backend.provision`\n * (so `create` / `claude` trip it but `prepare` itself does not — same shape\n * as the hetzner/vercel gates).\n */\nexport function ensureE2bBaseTemplate(): void {\n const state = readPreparedState();\n if (state.base !== undefined) return;\n throw new UserFacingError(\n 'no E2B base template found.\\n' +\n 'Run `agentbox prepare --provider e2b` first — it bakes a custom template ' +\n 'with the agentbox runtime (agentbox-ctl, vscode user, claude/codex/opencode, tmux) ' +\n 'so per-box `create` boots ready in seconds.',\n );\n}\n"],"mappings":"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","names":["existsSync","readFileSync","homedir","resolve","existsSync","dirname","resolve","existsSync","readFileSync","resolve","homedir","dirname"]}
|