@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.
- package/CHANGELOG.md +125 -0
- package/README.md +11 -8
- package/dist/{_cloud-attach-HJC672UR.js → _cloud-attach-R6TRWG5L.js} +4 -4
- package/dist/{chunk-QYRK5H6Q.js → chunk-43Q5GWP6.js} +108 -56
- package/dist/chunk-43Q5GWP6.js.map +1 -0
- package/dist/{chunk-ECLLV5JH.js → chunk-72CJTXN6.js} +156 -5
- package/dist/chunk-72CJTXN6.js.map +1 -0
- package/dist/{chunk-R5XIDQFR.js → chunk-BKU34KYY.js} +170 -6
- package/dist/chunk-BKU34KYY.js.map +1 -0
- package/dist/{chunk-4NQXNQ53.js → chunk-E7CHS7ZR.js} +168 -58
- package/dist/chunk-E7CHS7ZR.js.map +1 -0
- package/dist/chunk-MCOU6CZS.js +346 -0
- package/dist/chunk-MCOU6CZS.js.map +1 -0
- package/dist/{chunk-B4QG2MCW.js → chunk-MLMFNN4T.js} +762 -483
- package/dist/chunk-MLMFNN4T.js.map +1 -0
- package/dist/{chunk-2LF5YILI.js → chunk-RSKG7AFU.js} +80 -6
- package/dist/chunk-RSKG7AFU.js.map +1 -0
- package/dist/{chunk-SNTHHWKY.js → chunk-XKH7NTT7.js} +80 -22
- package/dist/chunk-XKH7NTT7.js.map +1 -0
- package/dist/{dist-7KVUIKJX.js → dist-AGTIA7AD.js} +37 -226
- package/dist/dist-AGTIA7AD.js.map +1 -0
- package/dist/{dist-OPIBZ7XM.js → dist-FIFEFKJ7.js} +14 -69
- package/dist/dist-FIFEFKJ7.js.map +1 -0
- package/dist/dist-JZ3XO6EB.js +662 -0
- package/dist/dist-JZ3XO6EB.js.map +1 -0
- package/dist/{dist-OG6NW6SM.js → dist-OGJGZETZ.js} +5 -3
- package/dist/{dist-JAN5VABY.js → dist-S4XR4ACV.js} +25 -177
- package/dist/dist-S4XR4ACV.js.map +1 -0
- package/dist/index.js +2229 -1314
- package/dist/index.js.map +1 -1
- package/dist/{prepared-state-MQHD3M5F-KE4DT3GX.js → prepared-state-MQHD3M5F-Q27AZU53.js} +2 -2
- package/package.json +6 -4
- package/runtime/docker/Dockerfile.box +21 -26
- package/runtime/docker/apps/cli/share/agentbox-setup/SKILL.md +67 -1
- package/runtime/docker/packages/ctl/dist/bin.cjs +361 -43
- package/runtime/docker/packages/sandbox-docker/scripts/agentbox-vnc-start +17 -6
- package/runtime/docker/packages/sandbox-docker/scripts/chromium-resolver +57 -0
- package/runtime/docker/packages/sandbox-docker/scripts/claude-managed-settings.json +2 -1
- package/runtime/e2b/agentbox-checkpoint-cleanup +52 -0
- package/runtime/e2b/agentbox-codex-hooks.json +68 -0
- package/runtime/e2b/agentbox-open +28 -0
- package/runtime/e2b/agentbox-setup-skill.md +263 -0
- package/runtime/e2b/agentbox-vnc-start +102 -0
- package/runtime/e2b/attach-helper.cjs +167 -0
- package/runtime/e2b/claude-managed-settings.json +116 -0
- package/runtime/e2b/ctl.cjs +24158 -0
- package/runtime/e2b/custom-system-CLAUDE.md +46 -0
- package/runtime/e2b/gh-shim +344 -0
- package/runtime/e2b/git-shim +131 -0
- package/runtime/e2b/scripts/build-template.sh +295 -0
- package/runtime/hetzner/agentbox-setup-skill.md +67 -1
- package/runtime/hetzner/agentbox-vnc-start +17 -6
- package/runtime/hetzner/claude-managed-settings.json +2 -1
- package/runtime/hetzner/ctl.cjs +361 -43
- package/runtime/relay/bin.cjs +380 -233
- package/runtime/vercel/agentbox-setup-skill.md +67 -1
- package/runtime/vercel/agentbox-vnc-start +17 -6
- package/runtime/vercel/claude-managed-settings.json +2 -1
- package/runtime/vercel/ctl.cjs +361 -43
- package/share/agentbox-setup/SKILL.md +67 -1
- package/share/host-skills/agentbox-info/SKILL.md +47 -35
- package/dist/chunk-2LF5YILI.js.map +0 -1
- package/dist/chunk-4NQXNQ53.js.map +0 -1
- package/dist/chunk-B4QG2MCW.js.map +0 -1
- package/dist/chunk-ECLLV5JH.js.map +0 -1
- package/dist/chunk-QYRK5H6Q.js.map +0 -1
- package/dist/chunk-R5XIDQFR.js.map +0 -1
- package/dist/chunk-SNTHHWKY.js.map +0 -1
- package/dist/dist-7KVUIKJX.js.map +0 -1
- package/dist/dist-JAN5VABY.js.map +0 -1
- package/dist/dist-OPIBZ7XM.js.map +0 -1
- /package/dist/{_cloud-attach-HJC672UR.js.map → _cloud-attach-R6TRWG5L.js.map} +0 -0
- /package/dist/{dist-OG6NW6SM.js.map → dist-OGJGZETZ.js.map} +0 -0
- /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
|
-
|
|
20
|
-
|
|
26
|
+
updatePreparedState,
|
|
27
|
+
withHetznerRetry,
|
|
28
|
+
writePreparedState
|
|
29
|
+
} from "./chunk-BKU34KYY.js";
|
|
21
30
|
import {
|
|
22
31
|
createCloudProvider
|
|
23
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-E7CHS7ZR.js";
|
|
24
33
|
import {
|
|
25
|
-
|
|
34
|
+
UserFacingError,
|
|
26
35
|
stageClaudeStaticForUpload,
|
|
27
|
-
stageCodexCredentialsForUpload,
|
|
28
36
|
stageCodexStaticForUpload,
|
|
29
|
-
stageOpencodeCredentialsForUpload,
|
|
30
37
|
stageOpencodeStaticForUpload
|
|
31
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-MLMFNN4T.js";
|
|
32
39
|
import {
|
|
33
40
|
computeContextSha256,
|
|
34
|
-
|
|
35
|
-
|
|
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
|
|
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
|
|
53
|
+
import { dirname, join, resolve } from "path";
|
|
53
54
|
import { execa } from "execa";
|
|
54
55
|
import { execa as execa2 } from "execa";
|
|
55
|
-
import { existsSync
|
|
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
|
|
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 =
|
|
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 =
|
|
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(
|
|
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
|
|
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 (
|
|
527
|
+
if (existsSync(controlPath) && await this.isAlive(controlPath)) {
|
|
665
528
|
this.boxes.set(opts.boxId, tunnel);
|
|
666
529
|
return;
|
|
667
530
|
}
|
|
668
|
-
if (
|
|
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 || !
|
|
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 &&
|
|
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 (
|
|
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
|
|
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 (!
|
|
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 (
|
|
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 (
|
|
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-
|
|
1231
|
+
//# sourceMappingURL=dist-AGTIA7AD.js.map
|