@madarco/agentbox 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/CHANGELOG.md +125 -0
  2. package/README.md +11 -8
  3. package/dist/{_cloud-attach-HJC672UR.js → _cloud-attach-R6TRWG5L.js} +4 -4
  4. package/dist/{chunk-QYRK5H6Q.js → chunk-43Q5GWP6.js} +108 -56
  5. package/dist/chunk-43Q5GWP6.js.map +1 -0
  6. package/dist/{chunk-ECLLV5JH.js → chunk-72CJTXN6.js} +156 -5
  7. package/dist/chunk-72CJTXN6.js.map +1 -0
  8. package/dist/{chunk-R5XIDQFR.js → chunk-BKU34KYY.js} +170 -6
  9. package/dist/chunk-BKU34KYY.js.map +1 -0
  10. package/dist/{chunk-4NQXNQ53.js → chunk-E7CHS7ZR.js} +168 -58
  11. package/dist/chunk-E7CHS7ZR.js.map +1 -0
  12. package/dist/chunk-MCOU6CZS.js +346 -0
  13. package/dist/chunk-MCOU6CZS.js.map +1 -0
  14. package/dist/{chunk-B4QG2MCW.js → chunk-MLMFNN4T.js} +762 -483
  15. package/dist/chunk-MLMFNN4T.js.map +1 -0
  16. package/dist/{chunk-2LF5YILI.js → chunk-RSKG7AFU.js} +80 -6
  17. package/dist/chunk-RSKG7AFU.js.map +1 -0
  18. package/dist/{chunk-SNTHHWKY.js → chunk-XKH7NTT7.js} +80 -22
  19. package/dist/chunk-XKH7NTT7.js.map +1 -0
  20. package/dist/{dist-7KVUIKJX.js → dist-AGTIA7AD.js} +37 -226
  21. package/dist/dist-AGTIA7AD.js.map +1 -0
  22. package/dist/{dist-OPIBZ7XM.js → dist-FIFEFKJ7.js} +14 -69
  23. package/dist/dist-FIFEFKJ7.js.map +1 -0
  24. package/dist/dist-JZ3XO6EB.js +662 -0
  25. package/dist/dist-JZ3XO6EB.js.map +1 -0
  26. package/dist/{dist-OG6NW6SM.js → dist-OGJGZETZ.js} +5 -3
  27. package/dist/{dist-JAN5VABY.js → dist-S4XR4ACV.js} +25 -177
  28. package/dist/dist-S4XR4ACV.js.map +1 -0
  29. package/dist/index.js +2229 -1314
  30. package/dist/index.js.map +1 -1
  31. package/dist/{prepared-state-MQHD3M5F-KE4DT3GX.js → prepared-state-MQHD3M5F-Q27AZU53.js} +2 -2
  32. package/package.json +6 -4
  33. package/runtime/docker/Dockerfile.box +21 -26
  34. package/runtime/docker/apps/cli/share/agentbox-setup/SKILL.md +67 -1
  35. package/runtime/docker/packages/ctl/dist/bin.cjs +361 -43
  36. package/runtime/docker/packages/sandbox-docker/scripts/agentbox-vnc-start +17 -6
  37. package/runtime/docker/packages/sandbox-docker/scripts/chromium-resolver +57 -0
  38. package/runtime/docker/packages/sandbox-docker/scripts/claude-managed-settings.json +2 -1
  39. package/runtime/e2b/agentbox-checkpoint-cleanup +52 -0
  40. package/runtime/e2b/agentbox-codex-hooks.json +68 -0
  41. package/runtime/e2b/agentbox-open +28 -0
  42. package/runtime/e2b/agentbox-setup-skill.md +263 -0
  43. package/runtime/e2b/agentbox-vnc-start +102 -0
  44. package/runtime/e2b/attach-helper.cjs +167 -0
  45. package/runtime/e2b/claude-managed-settings.json +116 -0
  46. package/runtime/e2b/ctl.cjs +24158 -0
  47. package/runtime/e2b/custom-system-CLAUDE.md +46 -0
  48. package/runtime/e2b/gh-shim +344 -0
  49. package/runtime/e2b/git-shim +131 -0
  50. package/runtime/e2b/scripts/build-template.sh +295 -0
  51. package/runtime/hetzner/agentbox-setup-skill.md +67 -1
  52. package/runtime/hetzner/agentbox-vnc-start +17 -6
  53. package/runtime/hetzner/claude-managed-settings.json +2 -1
  54. package/runtime/hetzner/ctl.cjs +361 -43
  55. package/runtime/relay/bin.cjs +380 -233
  56. package/runtime/vercel/agentbox-setup-skill.md +67 -1
  57. package/runtime/vercel/agentbox-vnc-start +17 -6
  58. package/runtime/vercel/claude-managed-settings.json +2 -1
  59. package/runtime/vercel/ctl.cjs +361 -43
  60. package/share/agentbox-setup/SKILL.md +67 -1
  61. package/share/host-skills/agentbox-info/SKILL.md +47 -35
  62. package/dist/chunk-2LF5YILI.js.map +0 -1
  63. package/dist/chunk-4NQXNQ53.js.map +0 -1
  64. package/dist/chunk-B4QG2MCW.js.map +0 -1
  65. package/dist/chunk-ECLLV5JH.js.map +0 -1
  66. package/dist/chunk-QYRK5H6Q.js.map +0 -1
  67. package/dist/chunk-R5XIDQFR.js.map +0 -1
  68. package/dist/chunk-SNTHHWKY.js.map +0 -1
  69. package/dist/dist-7KVUIKJX.js.map +0 -1
  70. package/dist/dist-JAN5VABY.js.map +0 -1
  71. package/dist/dist-OPIBZ7XM.js.map +0 -1
  72. /package/dist/{_cloud-attach-HJC672UR.js.map → _cloud-attach-R6TRWG5L.js.map} +0 -0
  73. /package/dist/{dist-OG6NW6SM.js.map → dist-OGJGZETZ.js.map} +0 -0
  74. /package/dist/{prepared-state-MQHD3M5F-KE4DT3GX.js.map → prepared-state-MQHD3M5F-Q27AZU53.js.map} +0 -0
@@ -2,61 +2,62 @@
2
2
  import {
3
3
  DEFAULT_HCLOUD_ENDPOINT,
4
4
  HetznerApiError,
5
+ RUNTIME_ASSETS,
6
+ candidatesFor,
5
7
  createPerBoxFirewall,
8
+ currentHetznerBaseFingerprintLive,
6
9
  deletePerBoxFirewall,
7
10
  detectEgressIp,
8
11
  ensureHetznerCredentials,
9
12
  ensureHetznerEnvLoaded,
13
+ findStagedCliRuntimeRoot,
10
14
  isAttemptTimeout,
11
15
  isRetriable,
12
16
  makeHetznerClient,
13
17
  maskKey,
14
18
  normalizeSourceCidr,
19
+ preparedStatePath,
15
20
  readHetznerCredStatus,
21
+ readPreparedState,
22
+ resolveRuntimeAssets,
16
23
  secretsPath,
17
24
  sshOnlyInboundRule,
18
25
  syncFirewallSource,
19
- withHetznerRetry
20
- } from "./chunk-R5XIDQFR.js";
26
+ updatePreparedState,
27
+ withHetznerRetry,
28
+ writePreparedState
29
+ } from "./chunk-BKU34KYY.js";
21
30
  import {
22
31
  createCloudProvider
23
- } from "./chunk-4NQXNQ53.js";
32
+ } from "./chunk-E7CHS7ZR.js";
24
33
  import {
25
- stageClaudeCredentialsForUpload,
34
+ UserFacingError,
26
35
  stageClaudeStaticForUpload,
27
- stageCodexCredentialsForUpload,
28
36
  stageCodexStaticForUpload,
29
- stageOpencodeCredentialsForUpload,
30
37
  stageOpencodeStaticForUpload
31
- } from "./chunk-B4QG2MCW.js";
38
+ } from "./chunk-MLMFNN4T.js";
32
39
  import {
33
40
  computeContextSha256,
34
- preparedStatePathFor,
35
- readCliStamp,
36
- readPreparedStateRaw,
37
- writePreparedStateRaw
38
- } from "./chunk-SNTHHWKY.js";
41
+ readCliStamp
42
+ } from "./chunk-XKH7NTT7.js";
39
43
  import "./chunk-G3H2L3O2.js";
40
44
 
41
45
  // ../../packages/sandbox-hetzner/dist/index.js
42
- import { existsSync as existsSync3 } from "fs";
46
+ import { existsSync as existsSync2 } from "fs";
43
47
  import { rm as rm2, rename, mkdir as mkdir3 } from "fs/promises";
44
48
  import { join as join4 } from "path";
45
49
  import { execa as execa4 } from "execa";
46
50
  import { resolve as resolvePath } from "path";
47
51
  import { join as join2 } from "path";
48
- import { existsSync } from "fs";
49
- import { dirname, resolve } from "path";
50
- import { fileURLToPath } from "url";
51
52
  import { mkdir, readFile } from "fs/promises";
52
- import { dirname as dirname2, join, resolve as resolve2 } from "path";
53
+ import { dirname, join, resolve } from "path";
53
54
  import { execa } from "execa";
54
55
  import { execa as execa2 } from "execa";
55
- import { existsSync as existsSync2 } from "fs";
56
+ import { existsSync } from "fs";
56
57
  import { mkdir as mkdir2, rm } from "fs/promises";
57
58
  import { createServer } from "net";
58
59
  import { homedir } from "os";
59
- import { dirname as dirname3, join as join3, resolve as resolve3 } from "path";
60
+ import { dirname as dirname2, join as join3, resolve as resolve2 } from "path";
60
61
  import { execa as execa3 } from "execa";
61
62
  function generatePrepareCloudInit(opts) {
62
63
  const pubkey = opts.sshPubkey.trim();
@@ -147,146 +148,8 @@ async function pollUntil(label, check, opts = {}) {
147
148
  interval = Math.min(interval * 2, max);
148
149
  }
149
150
  }
150
- var SCHEMA = 2;
151
- function preparedStatePath() {
152
- return preparedStatePathFor("hetzner");
153
- }
154
- function readPreparedState() {
155
- const raw = readPreparedStateRaw("hetzner");
156
- if (raw === null || typeof raw !== "object") return { schema: SCHEMA };
157
- const parsed = raw;
158
- if (parsed.schema === 1) {
159
- const v1 = parsed;
160
- return migrateFromV1(v1);
161
- }
162
- if (parsed.schema !== SCHEMA) {
163
- return { schema: SCHEMA };
164
- }
165
- return {
166
- schema: SCHEMA,
167
- base: parsed.base
168
- };
169
- }
170
- function migrateFromV1(v1) {
171
- const base = v1.base ? {
172
- imageId: v1.base.imageId,
173
- description: v1.base.description,
174
- createdAt: v1.base.createdAt,
175
- contextSha256: v1.base.installScriptSha256
176
- } : void 0;
177
- return {
178
- schema: SCHEMA,
179
- base
180
- };
181
- }
182
- function writePreparedState(state) {
183
- writePreparedStateRaw("hetzner", state);
184
- }
185
- function updatePreparedState(mutate) {
186
- const s = readPreparedState();
187
- mutate(s);
188
- writePreparedState(s);
189
- }
190
- var SELF = dirname(fileURLToPath(import.meta.url));
191
- function findStagedCliRuntimeRoot() {
192
- const candidates = [
193
- resolve(SELF, "..", "runtime"),
194
- // <cliRoot>/dist/.. → <cliRoot> then /runtime
195
- resolve(SELF, "..", "..", "runtime")
196
- // chunk-NNNN.js at <cliRoot>/dist/<sub>/.. → <cliRoot>/runtime
197
- ];
198
- for (const c of candidates) {
199
- if (existsSync(resolve(c, "hetzner", "scripts", "install-box.sh"))) return c;
200
- }
201
- return void 0;
202
- }
203
- var RUNTIME_ASSETS = [
204
- { name: "install-box.sh", remoteBasename: "agentbox-install.sh", remoteMode: 493 },
205
- { name: "agentbox-ctl", remoteBasename: "agentbox-ctl", remoteMode: 493 },
206
- { name: "agentbox-vnc-start", remoteBasename: "agentbox-vnc-start", remoteMode: 493 },
207
- { name: "agentbox-dockerd-start", remoteBasename: "agentbox-dockerd-start", remoteMode: 493 },
208
- { name: "agentbox-checkpoint-cleanup", remoteBasename: "agentbox-checkpoint-cleanup", remoteMode: 493 },
209
- { name: "agentbox-open", remoteBasename: "agentbox-open", remoteMode: 493 },
210
- { name: "gh-shim", remoteBasename: "agentbox-gh-shim", remoteMode: 493 },
211
- { name: "git-shim", remoteBasename: "agentbox-git-shim", remoteMode: 493 },
212
- { name: "custom-system-CLAUDE.md", remoteBasename: "agentbox-custom-CLAUDE.md", remoteMode: 420 },
213
- { name: "claude-managed-settings.json", remoteBasename: "agentbox-managed-settings.json", remoteMode: 420 },
214
- { name: "agentbox-codex-hooks.json", remoteBasename: "agentbox-codex-hooks.json", remoteMode: 420 },
215
- { name: "agentbox-setup-skill.md", remoteBasename: "agentbox-setup-skill.md", remoteMode: 420 }
216
- ];
217
- function candidatesFor(name, opts = {}) {
218
- const cliRoot = opts.cliRuntimeRoot;
219
- const monorepo = opts.repoRoot ?? guessRepoRoot();
220
- const monorepoRelative = {
221
- "install-box.sh": ["packages/sandbox-hetzner/scripts/install-box.sh"],
222
- "agentbox-ctl": ["packages/ctl/dist/bin.cjs"],
223
- "agentbox-vnc-start": ["packages/sandbox-docker/scripts/agentbox-vnc-start"],
224
- "agentbox-dockerd-start": ["packages/sandbox-docker/scripts/agentbox-dockerd-start"],
225
- "agentbox-checkpoint-cleanup": ["packages/sandbox-docker/scripts/agentbox-checkpoint-cleanup"],
226
- "agentbox-open": ["packages/sandbox-docker/scripts/agentbox-open"],
227
- "gh-shim": ["packages/sandbox-docker/scripts/gh-shim"],
228
- "git-shim": ["packages/sandbox-docker/scripts/git-shim"],
229
- "custom-system-CLAUDE.md": ["packages/sandbox-hetzner/scripts/custom-system-CLAUDE.md"],
230
- "claude-managed-settings.json": ["packages/sandbox-docker/scripts/claude-managed-settings.json"],
231
- "agentbox-codex-hooks.json": ["packages/sandbox-docker/scripts/agentbox-codex-hooks.json"],
232
- "agentbox-setup-skill.md": ["apps/cli/share/agentbox-setup/SKILL.md"]
233
- };
234
- const cliRelative = {
235
- "install-box.sh": ["hetzner/scripts/install-box.sh"],
236
- "agentbox-ctl": ["hetzner/ctl.cjs"],
237
- "agentbox-vnc-start": ["hetzner/agentbox-vnc-start", "docker/packages/sandbox-docker/scripts/agentbox-vnc-start"],
238
- "agentbox-dockerd-start": ["hetzner/agentbox-dockerd-start", "docker/packages/sandbox-docker/scripts/agentbox-dockerd-start"],
239
- "agentbox-checkpoint-cleanup": ["hetzner/agentbox-checkpoint-cleanup", "docker/packages/sandbox-docker/scripts/agentbox-checkpoint-cleanup"],
240
- "agentbox-open": ["hetzner/agentbox-open", "docker/packages/sandbox-docker/scripts/agentbox-open"],
241
- "gh-shim": ["hetzner/gh-shim", "docker/packages/sandbox-docker/scripts/gh-shim"],
242
- "git-shim": ["hetzner/git-shim", "docker/packages/sandbox-docker/scripts/git-shim"],
243
- "custom-system-CLAUDE.md": ["hetzner/custom-system-CLAUDE.md"],
244
- "claude-managed-settings.json": ["hetzner/claude-managed-settings.json", "docker/packages/sandbox-docker/scripts/claude-managed-settings.json"],
245
- "agentbox-codex-hooks.json": ["hetzner/agentbox-codex-hooks.json", "docker/packages/sandbox-docker/scripts/agentbox-codex-hooks.json"],
246
- "agentbox-setup-skill.md": ["hetzner/agentbox-setup-skill.md", "docker/apps/cli/share/agentbox-setup/SKILL.md"]
247
- };
248
- const out = [];
249
- if (cliRoot) {
250
- for (const rel of cliRelative[name] ?? []) out.push(resolve(cliRoot, rel));
251
- }
252
- for (const rel of monorepoRelative[name] ?? []) out.push(resolve(monorepo, rel));
253
- return out;
254
- }
255
- function resolveRuntimeAssets(opts = {}) {
256
- const out = [];
257
- const missing = [];
258
- for (const asset of RUNTIME_ASSETS) {
259
- const cands = candidatesFor(asset.name, opts);
260
- const hit = cands.find((p) => existsSync(p));
261
- if (!hit) {
262
- missing.push({ name: asset.name, tried: cands });
263
- continue;
264
- }
265
- out.push({ ...asset, localPath: hit });
266
- }
267
- if (missing.length > 0) {
268
- const lines = missing.flatMap((m) => [` - ${m.name}: tried`, ...m.tried.map((p) => ` ${p}`)]);
269
- throw new Error(
270
- `hetzner: could not resolve runtime assets \u2014 these files are needed to install on the prepare VPS:
271
- ` + lines.join("\n") + `
272
-
273
- If you are running from the monorepo, ensure \`pnpm -w build\` has run so packages/ctl/dist/bin.cjs exists. If you are running from a published CLI bundle, the runtime/hetzner tree should be staged automatically.`
274
- );
275
- }
276
- return out;
277
- }
278
- function guessRepoRoot() {
279
- let cur = SELF;
280
- for (let i = 0; i < 8; i++) {
281
- if (existsSync(resolve(cur, "pnpm-workspace.yaml"))) return cur;
282
- const parent = dirname(cur);
283
- if (parent === cur) break;
284
- cur = parent;
285
- }
286
- return SELF;
287
- }
288
151
  async function mintSshKey(targetDir, comment) {
289
- const dir = resolve2(targetDir);
152
+ const dir = resolve(targetDir);
290
153
  const priv = join(dir, "id_ed25519");
291
154
  const pub = `${priv}.pub`;
292
155
  await mkdir(dir, { recursive: true, mode: 448 });
@@ -299,14 +162,14 @@ async function mintSshKey(targetDir, comment) {
299
162
  return { dir, privatePath: priv, publicPath: pub, publicKey };
300
163
  }
301
164
  async function mintPrepareKey() {
302
- const root = resolve2(homedirOrCwd(), ".agentbox", "hetzner", `prepare-${Date.now().toString(36)}`);
165
+ const root = resolve(homedirOrCwd(), ".agentbox", "hetzner", `prepare-${Date.now().toString(36)}`);
303
166
  const key = await mintSshKey(root, `agentbox-prepare-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`);
304
167
  return {
305
168
  ...key,
306
169
  cleanup: async () => {
307
170
  try {
308
171
  const { rm: rm3 } = await import("fs/promises");
309
- await rm3(dirname2(key.privatePath), { recursive: true, force: true });
172
+ await rm3(dirname(key.privatePath), { recursive: true, force: true });
310
173
  } catch {
311
174
  }
312
175
  }
@@ -633,7 +496,7 @@ var prepareHetznerProvider = (req) => prepareHetzner({
633
496
  async function ensureHetznerBaseSnapshot() {
634
497
  const state = readPreparedState();
635
498
  if (state.base !== void 0) return;
636
- throw new Error(
499
+ throw new UserFacingError(
637
500
  "no Hetzner base snapshot found.\nRun `agentbox prepare --provider hetzner` first (Hetzner cannot build images from a Dockerfile,\nso the base snapshot is a one-time prerequisite for cloud boxes on this backend)."
638
501
  );
639
502
  }
@@ -661,11 +524,11 @@ var SshTunnelManager = class {
661
524
  boxSshDir,
662
525
  forwards: /* @__PURE__ */ new Map()
663
526
  };
664
- if (existsSync2(controlPath) && await this.isAlive(controlPath)) {
527
+ if (existsSync(controlPath) && await this.isAlive(controlPath)) {
665
528
  this.boxes.set(opts.boxId, tunnel);
666
529
  return;
667
530
  }
668
- if (existsSync2(controlPath)) {
531
+ if (existsSync(controlPath)) {
669
532
  await rm(controlPath, { force: true });
670
533
  }
671
534
  const connectTimeout = opts.connectTimeoutSeconds ?? 10;
@@ -697,7 +560,7 @@ var SshTunnelManager = class {
697
560
  `${user}@${opts.vpsHost}`
698
561
  ];
699
562
  const res = await execa3("ssh", argv, { reject: false });
700
- if (res.exitCode !== 0 || !existsSync2(controlPath)) {
563
+ if (res.exitCode !== 0 || !existsSync(controlPath)) {
701
564
  throw new Error(
702
565
  `ssh ControlMaster failed for ${opts.boxId} (exit ${String(res.exitCode)}): ${res.stderr || res.stdout || "(no output)"}`
703
566
  );
@@ -759,7 +622,7 @@ var SshTunnelManager = class {
759
622
  const existing = this.boxes.get(opts.boxId);
760
623
  if (existing) {
761
624
  const alive = await this.isAlive(existing.controlPath);
762
- if (!alive && existsSync2(existing.controlPath)) {
625
+ if (!alive && existsSync(existing.controlPath)) {
763
626
  try {
764
627
  await execa3(
765
628
  "ssh",
@@ -798,7 +661,7 @@ var SshTunnelManager = class {
798
661
  async close(boxId) {
799
662
  const tunnel = this.boxes.get(boxId);
800
663
  if (!tunnel) return;
801
- if (existsSync2(tunnel.controlPath)) {
664
+ if (existsSync(tunnel.controlPath)) {
802
665
  await execa3("ssh", ["-O", "exit", "-S", tunnel.controlPath, "dummy"], { reject: false });
803
666
  await rm(tunnel.controlPath, { force: true });
804
667
  }
@@ -844,7 +707,7 @@ var SshTunnelManager = class {
844
707
  }
845
708
  };
846
709
  function defaultBoxSshDir(boxId) {
847
- return resolve3(homedir(), ".agentbox", "boxes", boxId, "ssh");
710
+ return resolve2(homedir(), ".agentbox", "boxes", boxId, "ssh");
848
711
  }
849
712
  async function pickFreePort() {
850
713
  return new Promise((resolveOk, reject) => {
@@ -976,7 +839,7 @@ async function ensureLiveTarget(sandboxId) {
976
839
  throw new Error(`hetzner: server ${String(id)} has no IPv4 address`);
977
840
  }
978
841
  const state = await ensurePerBoxState(sandboxId);
979
- if (!existsSync3(state.identity)) {
842
+ if (!existsSync2(state.identity)) {
980
843
  throw new Error(
981
844
  `hetzner: per-box SSH key missing for sandbox ${sandboxId} (expected at ${state.identity}). If this box was created by a different host, you'll need to re-create it on this host.`
982
845
  );
@@ -1068,14 +931,6 @@ var hetznerBackend = {
1068
931
  }
1069
932
  await ensureTunnel(sandboxId, state, vpsIp);
1070
933
  progress("ssh up; ControlMaster open");
1071
- const liveTarget = buildSshTarget(state, vpsIp, tunnels.controlPath(sandboxId));
1072
- try {
1073
- await pushHetznerAgentCredentials(liveTarget, onLog);
1074
- } catch (credErr) {
1075
- onLog(
1076
- `hetzner: WARN \u2014 agent credential push failed (${credErr instanceof Error ? credErr.message : String(credErr)}); in-box claude/codex/opencode will prompt for interactive login`
1077
- );
1078
- }
1079
934
  return { sandboxId };
1080
935
  } catch (err) {
1081
936
  if (serverId !== null) {
@@ -1095,10 +950,10 @@ var hetznerBackend = {
1095
950
  }
1096
951
  }
1097
952
  try {
1098
- if (existsSync3(key.dir)) await rm2(key.dir, { recursive: true, force: true });
953
+ if (existsSync2(key.dir)) await rm2(key.dir, { recursive: true, force: true });
1099
954
  if (serverId !== null) {
1100
955
  const finalDir = perBoxDir(String(serverId));
1101
- if (existsSync3(finalDir)) await rm2(finalDir, { recursive: true, force: true });
956
+ if (existsSync2(finalDir)) await rm2(finalDir, { recursive: true, force: true });
1102
957
  }
1103
958
  } catch {
1104
959
  }
@@ -1322,58 +1177,13 @@ var hetznerBackend = {
1322
1177
  }
1323
1178
  }
1324
1179
  };
1325
- async function pushHetznerAgentCredentials(target, log) {
1326
- const specs = [
1327
- { kind: "claude", stage: stageClaudeCredentialsForUpload, dest: "/home/vscode/.agentbox-creds/claude" },
1328
- { kind: "codex", stage: stageCodexCredentialsForUpload, dest: "/home/vscode/.agentbox-creds/codex" },
1329
- { kind: "opencode", stage: stageOpencodeCredentialsForUpload, dest: "/home/vscode/.agentbox-creds/opencode" }
1330
- ];
1331
- for (const spec of specs) {
1332
- const staged = await spec.stage();
1333
- for (const w of staged.warnings) log(`hetzner: [${spec.kind}-creds] ${w}`);
1334
- try {
1335
- if (!staged.tarballPath) {
1336
- log(`hetzner: ${spec.kind}: no host credentials to push (skipping)`);
1337
- continue;
1338
- }
1339
- const remote = `/tmp/agentbox-${spec.kind}-creds.tar.gz`;
1340
- const argv = [
1341
- ...sshOptArgs(target),
1342
- staged.tarballPath,
1343
- `${target.user}@${target.host}:${remote}`
1344
- ];
1345
- const scpRes = await execa4("scp", argv, { reject: false, timeout: 12e4 });
1346
- if (scpRes.exitCode !== 0) {
1347
- throw new Error(
1348
- `scp ${spec.kind} credentials failed (exit ${String(scpRes.exitCode)}): ${scpRes.stderr ?? ""}`
1349
- );
1350
- }
1351
- const extract = await execa4(
1352
- "ssh",
1353
- [
1354
- ...sshOptArgs(target),
1355
- `${target.user}@${target.host}`,
1356
- `sudo -u vscode mkdir -p ${spec.dest} && sudo -u vscode tar -xzf ${remote} -C ${spec.dest} --no-same-permissions --no-same-owner -m && rm -f ${remote}`
1357
- ],
1358
- { reject: false, timeout: 3e4 }
1359
- );
1360
- if (extract.exitCode !== 0) {
1361
- throw new Error(
1362
- `${spec.kind} credential extract failed (exit ${String(extract.exitCode)}): ${extract.stderr ?? ""}`
1363
- );
1364
- }
1365
- log(`hetzner: ${spec.kind}: credentials pushed`);
1366
- } finally {
1367
- await staged.cleanup();
1368
- }
1369
- }
1370
- }
1371
1180
  var cloudProvider = createCloudProvider(hetznerBackend, {
1372
1181
  defaultResources: { cpu: 2, memory: 4, disk: 40 }
1373
1182
  });
1374
1183
  var hetznerProvider = {
1375
1184
  ...cloudProvider,
1376
- prepare: prepareHetznerProvider
1185
+ prepare: prepareHetznerProvider,
1186
+ baseFingerprint: () => currentHetznerBaseFingerprintLive()
1377
1187
  };
1378
1188
  export {
1379
1189
  DEFAULT_HCLOUD_ENDPOINT,
@@ -1382,6 +1192,7 @@ export {
1382
1192
  RUNTIME_ASSETS,
1383
1193
  candidatesFor,
1384
1194
  createPerBoxFirewall,
1195
+ currentHetznerBaseFingerprintLive,
1385
1196
  deletePerBoxFirewall,
1386
1197
  detectEgressIp,
1387
1198
  ensureHetznerBaseSnapshot,
@@ -1417,4 +1228,4 @@ export {
1417
1228
  withHetznerRetry,
1418
1229
  writePreparedState
1419
1230
  };
1420
- //# sourceMappingURL=dist-7KVUIKJX.js.map
1231
+ //# sourceMappingURL=dist-AGTIA7AD.js.map