@madarco/agentbox 0.15.0 → 0.16.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 (65) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/{_cloud-attach-R6TRWG5L.js → _cloud-attach-5KJWOASL.js} +4 -4
  3. package/dist/{chunk-RSKG7AFU.js → chunk-3WCEB6RE.js} +2 -2
  4. package/dist/{chunk-XKH7NTT7.js → chunk-DBBUDKKB.js} +248 -5
  5. package/dist/chunk-DBBUDKKB.js.map +1 -0
  6. package/dist/{chunk-MLMFNN4T.js → chunk-GXJNJUEV.js} +688 -197
  7. package/dist/chunk-GXJNJUEV.js.map +1 -0
  8. package/dist/{chunk-MCOU6CZS.js → chunk-NW2UZQV6.js} +10 -6
  9. package/dist/chunk-NW2UZQV6.js.map +1 -0
  10. package/dist/{chunk-E7CHS7ZR.js → chunk-PIK47622.js} +18 -6
  11. package/dist/chunk-PIK47622.js.map +1 -0
  12. package/dist/{chunk-BKU34KYY.js → chunk-QXFNLKJJ.js} +9 -3
  13. package/dist/{chunk-BKU34KYY.js.map → chunk-QXFNLKJJ.js.map} +1 -1
  14. package/dist/{chunk-43Q5GWP6.js → chunk-SB4QTF2T.js} +7 -7
  15. package/dist/{chunk-72CJTXN6.js → chunk-SENASAU4.js} +10 -6
  16. package/dist/{chunk-72CJTXN6.js.map → chunk-SENASAU4.js.map} +1 -1
  17. package/dist/{dist-JZ3XO6EB.js → dist-4IQFJJQI.js} +5 -5
  18. package/dist/{dist-OGJGZETZ.js → dist-7YB7BMNG.js} +5 -5
  19. package/dist/{dist-FIFEFKJ7.js → dist-SL2QSMBE.js} +5 -5
  20. package/dist/{dist-AGTIA7AD.js → dist-VHI5QOSQ.js} +6 -6
  21. package/dist/{dist-S4XR4ACV.js → dist-XC47DSCR.js} +5 -5
  22. package/dist/index.js +210 -68
  23. package/dist/index.js.map +1 -1
  24. package/dist/{prepared-state-MQHD3M5F-Q27AZU53.js → prepared-state-MQHD3M5F-2LANTRL7.js} +2 -2
  25. package/package.json +5 -4
  26. package/runtime/docker/Dockerfile.box +21 -2
  27. package/runtime/docker/apps/cli/share/agentbox-setup/SKILL.md +82 -29
  28. package/runtime/docker/packages/ctl/dist/bin.cjs +10675 -9191
  29. package/runtime/docker/packages/sandbox-docker/scripts/agentbox-checkpoint-cleanup +5 -2
  30. package/runtime/docker/packages/sandbox-docker/scripts/linear-shim +181 -0
  31. package/runtime/docker/packages/sandbox-docker/scripts/ntn-shim +95 -0
  32. package/runtime/e2b/agentbox-checkpoint-cleanup +5 -2
  33. package/runtime/e2b/agentbox-setup-skill.md +82 -29
  34. package/runtime/e2b/ctl.cjs +10675 -9191
  35. package/runtime/e2b/linear-shim +181 -0
  36. package/runtime/e2b/ntn-shim +95 -0
  37. package/runtime/e2b/scripts/build-template.sh +13 -7
  38. package/runtime/hetzner/agentbox-checkpoint-cleanup +5 -2
  39. package/runtime/hetzner/agentbox-setup-skill.md +82 -29
  40. package/runtime/hetzner/ctl.cjs +10675 -9191
  41. package/runtime/hetzner/linear-shim +181 -0
  42. package/runtime/hetzner/ntn-shim +95 -0
  43. package/runtime/hetzner/scripts/install-box.sh +19 -9
  44. package/runtime/relay/bin.cjs +3696 -2895
  45. package/runtime/vercel/agentbox-checkpoint-cleanup +5 -2
  46. package/runtime/vercel/agentbox-setup-skill.md +82 -29
  47. package/runtime/vercel/ctl.cjs +10675 -9191
  48. package/runtime/vercel/linear-shim +181 -0
  49. package/runtime/vercel/ntn-shim +95 -0
  50. package/runtime/vercel/scripts/provision.sh +13 -7
  51. package/share/agentbox-setup/SKILL.md +82 -29
  52. package/share/host-skills/agentbox-info/SKILL.md +1 -1
  53. package/dist/chunk-E7CHS7ZR.js.map +0 -1
  54. package/dist/chunk-MCOU6CZS.js.map +0 -1
  55. package/dist/chunk-MLMFNN4T.js.map +0 -1
  56. package/dist/chunk-XKH7NTT7.js.map +0 -1
  57. /package/dist/{_cloud-attach-R6TRWG5L.js.map → _cloud-attach-5KJWOASL.js.map} +0 -0
  58. /package/dist/{chunk-RSKG7AFU.js.map → chunk-3WCEB6RE.js.map} +0 -0
  59. /package/dist/{chunk-43Q5GWP6.js.map → chunk-SB4QTF2T.js.map} +0 -0
  60. /package/dist/{dist-JZ3XO6EB.js.map → dist-4IQFJJQI.js.map} +0 -0
  61. /package/dist/{dist-OGJGZETZ.js.map → dist-7YB7BMNG.js.map} +0 -0
  62. /package/dist/{dist-FIFEFKJ7.js.map → dist-SL2QSMBE.js.map} +0 -0
  63. /package/dist/{dist-AGTIA7AD.js.map → dist-VHI5QOSQ.js.map} +0 -0
  64. /package/dist/{dist-S4XR4ACV.js.map → dist-XC47DSCR.js.map} +0 -0
  65. /package/dist/{prepared-state-MQHD3M5F-Q27AZU53.js.map → prepared-state-MQHD3M5F-2LANTRL7.js.map} +0 -0
package/dist/index.js CHANGED
@@ -31,7 +31,7 @@ import {
31
31
  statusLine,
32
32
  stripTitleGlyph,
33
33
  subscribePrompts
34
- } from "./chunk-43Q5GWP6.js";
34
+ } from "./chunk-SB4QTF2T.js";
35
35
  import {
36
36
  daytonaBackend,
37
37
  ensureDaytonaCredentials,
@@ -39,7 +39,7 @@ import {
39
39
  readDaytonaCredStatus,
40
40
  readPreparedDaytonaState,
41
41
  secretsPath
42
- } from "./chunk-RSKG7AFU.js";
42
+ } from "./chunk-3WCEB6RE.js";
43
43
  import {
44
44
  detectEgressIp,
45
45
  ensureHetznerCredentials,
@@ -50,7 +50,7 @@ import {
50
50
  readPreparedState,
51
51
  secretsPath as secretsPath2,
52
52
  syncFirewallSource
53
- } from "./chunk-BKU34KYY.js";
53
+ } from "./chunk-QXFNLKJJ.js";
54
54
  import {
55
55
  detectSbx,
56
56
  ensureVercelCredentials,
@@ -59,14 +59,14 @@ import {
59
59
  readPreparedState as readPreparedState2,
60
60
  readVercelCredStatus,
61
61
  secretsPath as secretsPath3
62
- } from "./chunk-72CJTXN6.js";
62
+ } from "./chunk-SENASAU4.js";
63
63
  import {
64
64
  ensureE2bCredentials,
65
65
  maskKey as maskKey4,
66
66
  readE2bCredStatus,
67
67
  readPreparedState as readPreparedState3,
68
68
  secretsPath as secretsPath4
69
- } from "./chunk-MCOU6CZS.js";
69
+ } from "./chunk-NW2UZQV6.js";
70
70
  import {
71
71
  agentSpecsForCloud,
72
72
  currentCloudBaseFingerprint,
@@ -76,12 +76,11 @@ import {
76
76
  probeCloudCheckpoint,
77
77
  resolveCloudCheckpoint,
78
78
  seedAgentVolumesIfFresh
79
- } from "./chunk-E7CHS7ZR.js";
79
+ } from "./chunk-PIK47622.js";
80
80
  import {
81
- AmbiguousBoxError,
81
+ ALL_CONNECTORS,
82
82
  BOX_STATUS_EVENT,
83
83
  BUILT_IN_DEFAULTS,
84
- BoxNotFoundError,
85
84
  CODEX_CREDENTIALS_BACKUP_FILE,
86
85
  ClaudeSessionError,
87
86
  CodexSessionError,
@@ -99,7 +98,6 @@ import {
99
98
  SHARED_CODEX_VOLUME,
100
99
  SHARED_OPENCODE_VOLUME,
101
100
  UserConfigError,
102
- UserFacingError,
103
101
  agentboxHomeBytes,
104
102
  allCheckpointImagesBytes,
105
103
  allocateShellSessionName,
@@ -168,6 +166,8 @@ import {
168
166
  mintHostInitiatedToken,
169
167
  openBoxInFinder,
170
168
  opencodeSessionInfo,
169
+ parseCarrySection,
170
+ parseReplacementsSection,
171
171
  parseShellSessionList,
172
172
  pauseBox,
173
173
  portlessGetUrl,
@@ -193,7 +193,6 @@ import {
193
193
  renderStatusTable,
194
194
  renderTaskTable,
195
195
  resetPortlessCache,
196
- resolveAgentLauncher,
197
196
  resolveBoxImage,
198
197
  resolveBoxSize,
199
198
  resolveCheckpoint,
@@ -232,10 +231,13 @@ import {
232
231
  waitForTmuxPaneContent,
233
232
  warmUpClaudeCredentials,
234
233
  writeJob
235
- } from "./chunk-MLMFNN4T.js";
234
+ } from "./chunk-GXJNJUEV.js";
236
235
  import {
236
+ AmbiguousBoxError,
237
+ BoxNotFoundError,
237
238
  DEFAULT_BOX_IMAGE,
238
239
  STATE_DIR,
240
+ UserFacingError,
239
241
  computeDockerContextFingerprint,
240
242
  ensureImage,
241
243
  hostOpenCommand,
@@ -244,13 +246,15 @@ import {
244
246
  readPreparedDockerState,
245
247
  readState,
246
248
  recordBox,
247
- resolveBoxRef
248
- } from "./chunk-XKH7NTT7.js";
249
+ resolveAgentLauncher,
250
+ resolveBoxRef,
251
+ resolveRuleRefs
252
+ } from "./chunk-DBBUDKKB.js";
249
253
  import "./chunk-G3H2L3O2.js";
250
254
 
251
255
  // src/version.ts
252
- var AGENTBOX_VERSION = true ? "0.15.0" : "0.0.0-dev";
253
- var AGENTBOX_COMMIT = true ? "dfe136d17" : "dev";
256
+ var AGENTBOX_VERSION = true ? "0.16.0" : "0.0.0-dev";
257
+ var AGENTBOX_COMMIT = true ? "de3c2792d" : "dev";
254
258
 
255
259
  // src/index.ts
256
260
  import { Command as Command48 } from "commander";
@@ -1238,12 +1242,13 @@ async function resolveCarry(items, opts) {
1238
1242
  const home = opts.homeDir ?? homedir2();
1239
1243
  const cap = opts.maxBytes ?? BUILT_IN_DEFAULTS.box.cpMaxBytes;
1240
1244
  const projectRoot = opts.projectRoot;
1245
+ const replacements = opts.replacements ?? {};
1241
1246
  const entries = [];
1242
1247
  const errors = [];
1243
1248
  for (const [i, item] of items.entries()) {
1244
1249
  const where = `carry[${String(i)}]`;
1245
1250
  try {
1246
- const entry = await resolveOne(item, { projectRoot, home, cap, where });
1251
+ const entry = await resolveOne(item, { projectRoot, home, cap, where, replacements });
1247
1252
  entries.push(entry);
1248
1253
  } catch (err) {
1249
1254
  errors.push(err instanceof Error ? err.message : String(err));
@@ -1261,6 +1266,15 @@ async function resolveOne(item, ctx) {
1261
1266
  const rawSrc = item.src;
1262
1267
  const rawDest = item.dest;
1263
1268
  const absDest = item.dest;
1269
+ const hasReplaceOpts = !!(item.replaceEnvs || item.replace || item.rules);
1270
+ const replaceRules = [
1271
+ ...resolveRuleRefs(item.rules ?? [], ctx.replacements, `${ctx.where}.rules`),
1272
+ ...item.replace ?? []
1273
+ ];
1274
+ const replaceFields = {
1275
+ ...item.replaceEnvs ? { replaceEnvs: true } : {},
1276
+ ...replaceRules.length > 0 ? { replace: replaceRules } : {}
1277
+ };
1264
1278
  let st;
1265
1279
  try {
1266
1280
  st = await stat3(absSrc);
@@ -1297,6 +1311,11 @@ async function resolveOne(item, ctx) {
1297
1311
  } catch {
1298
1312
  }
1299
1313
  if (st.isDirectory()) {
1314
+ if (hasReplaceOpts) {
1315
+ throw new Error(
1316
+ `${ctx.where}: replaceEnvs/replace/rules are file-only (src "${absSrc}" is a directory)`
1317
+ );
1318
+ }
1300
1319
  const tokens = effectiveExcludes(item.exclude ?? [], true);
1301
1320
  const tarPatterns = toTarExcludes(tokens);
1302
1321
  const bytes = await dirSizeCapped(absSrc, ctx.cap, tokens);
@@ -1335,7 +1354,8 @@ async function resolveOne(item, ctx) {
1335
1354
  ...item.mode !== void 0 ? { mode: item.mode } : {},
1336
1355
  ...item.user !== void 0 ? { user: item.user } : {},
1337
1356
  optional,
1338
- ...symlinkInfo ? { symlinkInfo } : {}
1357
+ ...symlinkInfo ? { symlinkInfo } : {},
1358
+ ...replaceFields
1339
1359
  };
1340
1360
  }
1341
1361
  throw new Error(`${ctx.where}: src "${absSrc}" is neither a regular file nor a directory`);
@@ -1919,6 +1939,7 @@ async function cloudAgentCreate(args) {
1919
1939
  }
1920
1940
 
1921
1941
  // src/lib/carry-gate.ts
1942
+ import { readFile as readFile2 } from "fs/promises";
1922
1943
  import { join as join6 } from "path";
1923
1944
  import { log as log5 } from "@clack/prompts";
1924
1945
 
@@ -2019,12 +2040,20 @@ async function runCarryGate(args) {
2019
2040
  const emit = args.onLog ?? (() => {
2020
2041
  });
2021
2042
  const yamlPath = join6(args.projectRoot, "agentbox.yaml");
2022
- const items = await loadCarrySection(yamlPath);
2043
+ let yamlText = "";
2044
+ try {
2045
+ yamlText = await readFile2(yamlPath, "utf8");
2046
+ } catch (err) {
2047
+ if (err.code !== "ENOENT") throw err;
2048
+ }
2049
+ const items = parseCarrySection(yamlText);
2023
2050
  if (items.length === 0) return { decision: "approve", entries: [] };
2024
2051
  const cfg = await loadEffectiveConfig(args.projectRoot);
2052
+ const replacements = parseReplacementsSection(yamlText);
2025
2053
  const resolved = await resolveCarry(items, {
2026
2054
  projectRoot: args.projectRoot,
2027
- maxBytes: cfg.effective.box.cpMaxBytes
2055
+ maxBytes: cfg.effective.box.cpMaxBytes,
2056
+ replacements
2028
2057
  });
2029
2058
  if (resolved.errors.length > 0) {
2030
2059
  const msg = ["carry: refused to proceed:", ...resolved.errors.map((e) => ` - ${e}`)].join("\n");
@@ -2070,7 +2099,7 @@ async function runQueuedCarryGate(args) {
2070
2099
  }
2071
2100
 
2072
2101
  // src/session-teleport/claude.ts
2073
- import { mkdir, mkdtemp, readdir as readdir2, readFile as readFile2, stat as stat4, writeFile } from "fs/promises";
2102
+ import { mkdir, mkdtemp, readdir as readdir2, readFile as readFile3, stat as stat4, writeFile } from "fs/promises";
2074
2103
  import { existsSync } from "fs";
2075
2104
  import { homedir as homedir4, tmpdir } from "os";
2076
2105
  import { join as join7 } from "path";
@@ -2148,7 +2177,7 @@ async function pickSessionFile(projectDir, mode) {
2148
2177
  return stats[0].full;
2149
2178
  }
2150
2179
  async function rewriteSessionFile(src, dst, hostCwd) {
2151
- const raw = await readFile2(src, "utf8");
2180
+ const raw = await readFile3(src, "utf8");
2152
2181
  const lines = raw.split("\n");
2153
2182
  const out = [];
2154
2183
  for (const line of lines) {
@@ -2178,7 +2207,7 @@ async function rewriteSessionFile(src, dst, hostCwd) {
2178
2207
  }
2179
2208
 
2180
2209
  // src/session-teleport/codex.ts
2181
- import { mkdtemp as mkdtemp2, readdir as readdir3, readFile as readFile3, stat as stat5, writeFile as writeFile2 } from "fs/promises";
2210
+ import { mkdtemp as mkdtemp2, readdir as readdir3, readFile as readFile4, stat as stat5, writeFile as writeFile2 } from "fs/promises";
2182
2211
  import { existsSync as existsSync2 } from "fs";
2183
2212
  import { homedir as homedir5, tmpdir as tmpdir2 } from "os";
2184
2213
  import { join as join8 } from "path";
@@ -2304,7 +2333,7 @@ function extractCodexUuid(filename) {
2304
2333
  async function peekCodexCwd(file) {
2305
2334
  let firstLine3;
2306
2335
  try {
2307
- const buf = await readFile3(file, "utf8");
2336
+ const buf = await readFile4(file, "utf8");
2308
2337
  const nl = buf.indexOf("\n");
2309
2338
  firstLine3 = nl === -1 ? buf : buf.slice(0, nl);
2310
2339
  } catch {
@@ -2320,7 +2349,7 @@ async function peekCodexCwd(file) {
2320
2349
  return null;
2321
2350
  }
2322
2351
  async function rewriteCodexSession(src, dst, hostCwd) {
2323
- const raw = await readFile3(src, "utf8");
2352
+ const raw = await readFile4(src, "utf8");
2324
2353
  const lines = raw.split("\n");
2325
2354
  const out = [];
2326
2355
  for (const line of lines) {
@@ -2390,7 +2419,7 @@ async function uploadTeleport(input) {
2390
2419
  }
2391
2420
 
2392
2421
  // src/session-teleport/plan.ts
2393
- import { mkdtemp as mkdtemp3, readFile as readFile4, writeFile as writeFile3 } from "fs/promises";
2422
+ import { mkdtemp as mkdtemp3, readFile as readFile5, writeFile as writeFile3 } from "fs/promises";
2394
2423
  import { existsSync as existsSync3 } from "fs";
2395
2424
  import { homedir as homedir6, tmpdir as tmpdir3 } from "os";
2396
2425
  import { basename, isAbsolute as isAbsolute2, join as join9, resolve as resolve2 } from "path";
@@ -2411,7 +2440,7 @@ async function resolvePlanTeleport(opts) {
2411
2440
  const name = basename(planFile);
2412
2441
  const stage = await mkdtemp3(join9(tmpdir3(), "agentbox-teleport-plan-"));
2413
2442
  const stagedFile = join9(stage, name);
2414
- const raw = await readFile4(planFile, "utf8");
2443
+ const raw = await readFile5(planFile, "utf8");
2415
2444
  const absCwd = opts.hostCwd ? resolve2(expandHome(opts.hostCwd, hostHome)) : "";
2416
2445
  const rewritten = absCwd ? raw.split(absCwd).join(BOX_WORKSPACE) : raw;
2417
2446
  await writeFile3(stagedFile, rewritten, "utf8");
@@ -2632,13 +2661,13 @@ import { basename as basename2 } from "path";
2632
2661
  async function cloudBackendForProvider(provider) {
2633
2662
  switch (provider) {
2634
2663
  case "daytona":
2635
- return (await import("./dist-FIFEFKJ7.js")).daytonaBackend;
2664
+ return (await import("./dist-SL2QSMBE.js")).daytonaBackend;
2636
2665
  case "hetzner":
2637
- return (await import("./dist-AGTIA7AD.js")).hetznerBackend;
2666
+ return (await import("./dist-VHI5QOSQ.js")).hetznerBackend;
2638
2667
  case "vercel":
2639
- return (await import("./dist-S4XR4ACV.js")).vercelBackend;
2668
+ return (await import("./dist-XC47DSCR.js")).vercelBackend;
2640
2669
  case "e2b":
2641
- return (await import("./dist-JZ3XO6EB.js")).e2bBackend;
2670
+ return (await import("./dist-4IQFJJQI.js")).e2bBackend;
2642
2671
  default:
2643
2672
  return null;
2644
2673
  }
@@ -2646,13 +2675,13 @@ async function cloudBackendForProvider(provider) {
2646
2675
  async function currentCloudBaseFingerprintLive(provider) {
2647
2676
  switch (provider) {
2648
2677
  case "daytona":
2649
- return (await import("./dist-FIFEFKJ7.js")).currentDaytonaBaseFingerprintLive();
2678
+ return (await import("./dist-SL2QSMBE.js")).currentDaytonaBaseFingerprintLive();
2650
2679
  case "hetzner":
2651
- return (await import("./dist-AGTIA7AD.js")).currentHetznerBaseFingerprintLive();
2680
+ return (await import("./dist-VHI5QOSQ.js")).currentHetznerBaseFingerprintLive();
2652
2681
  case "vercel":
2653
- return (await import("./dist-S4XR4ACV.js")).currentVercelBaseFingerprintLive();
2682
+ return (await import("./dist-XC47DSCR.js")).currentVercelBaseFingerprintLive();
2654
2683
  case "e2b":
2655
- return (await import("./dist-JZ3XO6EB.js")).currentE2bBaseFingerprintLive();
2684
+ return (await import("./dist-4IQFJJQI.js")).currentE2bBaseFingerprintLive();
2656
2685
  default:
2657
2686
  return void 0;
2658
2687
  }
@@ -2864,9 +2893,9 @@ function rebuildMinutesFor(provider) {
2864
2893
  case "daytona":
2865
2894
  return "7";
2866
2895
  case "vercel":
2867
- return "25";
2896
+ return "5-10";
2868
2897
  case "hetzner":
2869
- return "35\u201350";
2898
+ return "7-10";
2870
2899
  default:
2871
2900
  return "1";
2872
2901
  }
@@ -2991,7 +3020,7 @@ async function renderDocker(status) {
2991
3020
  }
2992
3021
  async function daytonaStatus() {
2993
3022
  try {
2994
- const mod = await import("./dist-FIFEFKJ7.js");
3023
+ const mod = await import("./dist-SL2QSMBE.js");
2995
3024
  return await mod.getDaytonaStatus();
2996
3025
  } catch (err) {
2997
3026
  return {
@@ -3002,7 +3031,7 @@ async function daytonaStatus() {
3002
3031
  }
3003
3032
  async function e2bStatus() {
3004
3033
  try {
3005
- const mod = await import("./dist-JZ3XO6EB.js");
3034
+ const mod = await import("./dist-4IQFJJQI.js");
3006
3035
  const cred = mod.readE2bCredStatus();
3007
3036
  if (cred.auth === "none") {
3008
3037
  return { configured: false, reason: "not configured \u2014 run `agentbox e2b login`" };
@@ -4145,13 +4174,13 @@ var CLOUD_BACKENDS = ["daytona", "hetzner", "vercel", "e2b"];
4145
4174
  async function cloudProviderFor(backend) {
4146
4175
  switch (backend) {
4147
4176
  case "daytona":
4148
- return (await import("./dist-FIFEFKJ7.js")).daytonaProvider;
4177
+ return (await import("./dist-SL2QSMBE.js")).daytonaProvider;
4149
4178
  case "hetzner":
4150
- return (await import("./dist-AGTIA7AD.js")).hetznerProvider;
4179
+ return (await import("./dist-VHI5QOSQ.js")).hetznerProvider;
4151
4180
  case "vercel":
4152
- return (await import("./dist-S4XR4ACV.js")).vercelProvider;
4181
+ return (await import("./dist-XC47DSCR.js")).vercelProvider;
4153
4182
  case "e2b":
4154
- return (await import("./dist-JZ3XO6EB.js")).e2bProvider;
4183
+ return (await import("./dist-4IQFJJQI.js")).e2bProvider;
4155
4184
  }
4156
4185
  }
4157
4186
  var CHECKPOINT_NOTICE = "Checkpoint in progress \u2014 the box will be unresponsive for a moment";
@@ -6228,18 +6257,19 @@ function fail(message) {
6228
6257
  `);
6229
6258
  process.exit(1);
6230
6259
  }
6260
+ function walkKey(obj, key) {
6261
+ let cur = obj;
6262
+ for (const seg of key.split(".")) {
6263
+ if (cur === void 0 || cur === null || typeof cur !== "object") return void 0;
6264
+ cur = cur[seg];
6265
+ }
6266
+ return cur;
6267
+ }
6231
6268
  function leafValue(loaded, key) {
6232
- const idx = key.indexOf(".");
6233
- const branch = key.slice(0, idx);
6234
- const leaf = key.slice(idx + 1);
6235
- return loaded.effective[branch]?.[leaf];
6269
+ return walkKey(loaded.effective, key);
6236
6270
  }
6237
6271
  function rawLeafFromValues(values, key) {
6238
- if (!values) return void 0;
6239
- const idx = key.indexOf(".");
6240
- const b = values[key.slice(0, idx)];
6241
- if (!b || typeof b !== "object") return void 0;
6242
- return b[key.slice(idx + 1)];
6272
+ return walkKey(values, key);
6243
6273
  }
6244
6274
  function describeSource(source, loaded) {
6245
6275
  switch (source) {
@@ -6964,7 +6994,7 @@ var createCommand = new Command10("create").description(
6964
6994
  }
6965
6995
  outro4("done");
6966
6996
  if (attachClaudeAfter) {
6967
- const { cloudAgentAttach: cloudAgentAttach2 } = await import("./_cloud-attach-R6TRWG5L.js");
6997
+ const { cloudAgentAttach: cloudAgentAttach2 } = await import("./_cloud-attach-5KJWOASL.js");
6968
6998
  await cloudAgentAttach2({
6969
6999
  box: result.record,
6970
7000
  binary: "claude",
@@ -10400,7 +10430,7 @@ async function dockerChecks() {
10400
10430
  ];
10401
10431
  }
10402
10432
  const daemonRes = { label: "docker daemon", status: "ok", detail: "reachable" };
10403
- const mod = await import("./dist-OGJGZETZ.js");
10433
+ const mod = await import("./dist-7YB7BMNG.js");
10404
10434
  let imgRes;
10405
10435
  try {
10406
10436
  const img = await mod.imageInfo(mod.DEFAULT_BOX_IMAGE);
@@ -10431,7 +10461,7 @@ async function dockerChecks() {
10431
10461
  }
10432
10462
  async function daytonaChecks() {
10433
10463
  try {
10434
- const mod = await import("./dist-FIFEFKJ7.js");
10464
+ const mod = await import("./dist-SL2QSMBE.js");
10435
10465
  const status = await mod.getDaytonaStatus();
10436
10466
  if (!status.configured) {
10437
10467
  return [
@@ -10467,7 +10497,7 @@ async function daytonaChecks() {
10467
10497
  }
10468
10498
  async function hetznerChecks() {
10469
10499
  try {
10470
- const mod = await import("./dist-AGTIA7AD.js");
10500
+ const mod = await import("./dist-VHI5QOSQ.js");
10471
10501
  const cred = mod.readHetznerCredStatus();
10472
10502
  const credRes = cred.source === "none" ? {
10473
10503
  label: "credentials",
@@ -10499,7 +10529,7 @@ async function hetznerChecks() {
10499
10529
  }
10500
10530
  async function vercelChecks() {
10501
10531
  try {
10502
- const mod = await import("./dist-S4XR4ACV.js");
10532
+ const mod = await import("./dist-XC47DSCR.js");
10503
10533
  const cred = mod.readVercelCredStatus();
10504
10534
  const credRes = cred.auth === "none" ? {
10505
10535
  label: "credentials",
@@ -10535,7 +10565,7 @@ async function vercelChecks() {
10535
10565
  }
10536
10566
  async function e2bChecks() {
10537
10567
  try {
10538
- const mod = await import("./dist-JZ3XO6EB.js");
10568
+ const mod = await import("./dist-4IQFJJQI.js");
10539
10569
  const cred = mod.readE2bCredStatus();
10540
10570
  const credRes = cred.auth === "none" ? {
10541
10571
  label: "credentials",
@@ -10569,6 +10599,103 @@ async function e2bChecks() {
10569
10599
  ];
10570
10600
  }
10571
10601
  }
10602
+ var INTEGRATION_PROBE_TIMEOUT_MS = 1e4;
10603
+ async function probeIntegrationBin(bin, args) {
10604
+ try {
10605
+ const r = await execa3(bin, [...args], {
10606
+ reject: false,
10607
+ timeout: INTEGRATION_PROBE_TIMEOUT_MS,
10608
+ stdin: "ignore"
10609
+ });
10610
+ const code = r.code;
10611
+ if (code === "ENOENT") {
10612
+ return { exitCode: 127, stdout: "", stderr: r.stderr ?? "", missing: true };
10613
+ }
10614
+ if (r.timedOut) {
10615
+ return {
10616
+ exitCode: 124,
10617
+ stdout: "",
10618
+ stderr: `timed out after ${String(INTEGRATION_PROBE_TIMEOUT_MS)}ms`,
10619
+ missing: false
10620
+ };
10621
+ }
10622
+ return {
10623
+ exitCode: r.exitCode ?? 1,
10624
+ stdout: typeof r.stdout === "string" ? r.stdout : "",
10625
+ stderr: typeof r.stderr === "string" ? r.stderr : "",
10626
+ missing: false
10627
+ };
10628
+ } catch (err) {
10629
+ const code = err.code;
10630
+ return {
10631
+ exitCode: code === "ENOENT" ? 127 : 1,
10632
+ stdout: "",
10633
+ stderr: errSummary(err),
10634
+ missing: code === "ENOENT"
10635
+ };
10636
+ }
10637
+ }
10638
+ async function integrationsChecks(loader = loadEffectiveConfig) {
10639
+ let cfg;
10640
+ try {
10641
+ cfg = await loader(process.cwd());
10642
+ } catch {
10643
+ cfg = { effective: {} };
10644
+ }
10645
+ return Promise.all(
10646
+ ALL_CONNECTORS.map((connector) => checkOneIntegration(connector, cfg.effective.integrations))
10647
+ );
10648
+ }
10649
+ async function checkOneIntegration(connector, integrations) {
10650
+ const svc = connector.service;
10651
+ const enabled = integrations?.[svc]?.enabled === true;
10652
+ if (!enabled) {
10653
+ return {
10654
+ label: svc,
10655
+ status: "info",
10656
+ detail: "disabled",
10657
+ hint: `enable with \`agentbox config set --project integrations.${svc}.enabled true\``
10658
+ };
10659
+ }
10660
+ const version = await probeIntegrationBin(connector.hostBin, connector.detect.versionArgs);
10661
+ if (version.missing || version.exitCode === 127) {
10662
+ return {
10663
+ label: svc,
10664
+ status: "warn",
10665
+ detail: `${connector.hostBin} not installed`,
10666
+ hint: connector.detect.installHint ?? `install the ${svc} CLI (\`${connector.hostBin}\`) on the host`
10667
+ };
10668
+ }
10669
+ if (version.exitCode !== 0) {
10670
+ const tail = firstLine2((version.stderr || version.stdout).trim());
10671
+ return {
10672
+ label: svc,
10673
+ status: "warn",
10674
+ detail: `${connector.hostBin} ${connector.detect.versionArgs.join(" ")} failed${tail ? `: ${tail}` : ""}`
10675
+ };
10676
+ }
10677
+ const versionLine = firstLine2((version.stdout || version.stderr).trim()) || connector.hostBin;
10678
+ if (!connector.detect.authArgs || connector.detect.authArgs.length === 0) {
10679
+ return { label: svc, status: "ok", detail: versionLine };
10680
+ }
10681
+ const auth = await probeIntegrationBin(connector.hostBin, connector.detect.authArgs);
10682
+ if (auth.exitCode === 124) {
10683
+ return {
10684
+ label: svc,
10685
+ status: "warn",
10686
+ detail: `auth check timed out after ${String(INTEGRATION_PROBE_TIMEOUT_MS / 1e3)}s`
10687
+ };
10688
+ }
10689
+ if (auth.exitCode !== 0) {
10690
+ return {
10691
+ label: svc,
10692
+ status: "warn",
10693
+ detail: "not logged in",
10694
+ hint: connector.detect.loginHint ?? `run \`${connector.hostBin} login\``
10695
+ };
10696
+ }
10697
+ return { label: svc, status: "ok", detail: `${versionLine} \xB7 authed` };
10698
+ }
10572
10699
  async function runProviderChecks(name) {
10573
10700
  let results;
10574
10701
  switch (name) {
@@ -10593,7 +10720,8 @@ async function runProviderChecks(name) {
10593
10720
  async function runAllChecks() {
10594
10721
  const sys = { title: "system", results: await runSystemChecks() };
10595
10722
  const providerGroups = await Promise.all(ALL_PROVIDERS.map((n) => runProviderChecks(n)));
10596
- return [sys, ...providerGroups];
10723
+ const integrations = { title: "integrations", results: await integrationsChecks() };
10724
+ return [sys, ...providerGroups, integrations];
10597
10725
  }
10598
10726
  function worstInResults(results) {
10599
10727
  let worst = "ok";
@@ -10619,6 +10747,12 @@ function summaryToken(group) {
10619
10747
  if (worst === "warn") return "system warn";
10620
10748
  return "system ok";
10621
10749
  }
10750
+ if (group.title === "integrations") {
10751
+ if (worst === "fail") return "integrations FAIL";
10752
+ if (worst === "warn") return "integrations check";
10753
+ const anyEnabled = group.results.some((r) => r.status === "ok");
10754
+ return anyEnabled ? "integrations ready" : "integrations off";
10755
+ }
10622
10756
  if (worst === "fail") return `${group.title} FAIL`;
10623
10757
  if (worst === "warn") {
10624
10758
  const cred = group.results.find((r) => r.label === "credentials");
@@ -10630,12 +10764,13 @@ function summaryToken(group) {
10630
10764
  var C_GREEN = "\x1B[32m";
10631
10765
  var C_YELLOW = "\x1B[33m";
10632
10766
  var C_RED = "\x1B[31m";
10767
+ var C_DIM = "\x1B[2m";
10633
10768
  var C_RESET = "\x1B[0m";
10634
10769
  var COLOR = !process.env.NO_COLOR;
10635
10770
  function statusMarker(s) {
10636
- const glyph = s === "ok" ? "\u2713" : s === "warn" ? "\u26A0" : "\u2717";
10771
+ const glyph = s === "ok" ? "\u2713" : s === "info" ? "\xB7" : s === "warn" ? "\u26A0" : "\u2717";
10637
10772
  if (!COLOR) return glyph;
10638
- const color = s === "ok" ? C_GREEN : s === "warn" ? C_YELLOW : C_RED;
10773
+ const color = s === "ok" ? C_GREEN : s === "info" ? C_DIM : s === "warn" ? C_YELLOW : C_RED;
10639
10774
  return `${color}${glyph}${C_RESET}`;
10640
10775
  }
10641
10776
  function formatCompact(groups) {
@@ -10646,6 +10781,7 @@ function pad3(s, width) {
10646
10781
  }
10647
10782
  function statusBadge(s) {
10648
10783
  if (s === "ok") return "[ ok ]";
10784
+ if (s === "info") return "[info]";
10649
10785
  if (s === "warn") return "[warn]";
10650
10786
  return "[FAIL]";
10651
10787
  }
@@ -10966,7 +11102,7 @@ function ensureTty() {
10966
11102
  async function runProviderLogin(name) {
10967
11103
  if (name === "docker") return true;
10968
11104
  if (name === "daytona") {
10969
- const mod2 = await import("./dist-FIFEFKJ7.js");
11105
+ const mod2 = await import("./dist-SL2QSMBE.js");
10970
11106
  const status2 = await mod2.getDaytonaStatus();
10971
11107
  if (status2.configured) {
10972
11108
  log32.info("daytona: already configured");
@@ -10979,7 +11115,7 @@ async function runProviderLogin(name) {
10979
11115
  return true;
10980
11116
  }
10981
11117
  if (name === "hetzner") {
10982
- const mod2 = await import("./dist-AGTIA7AD.js");
11118
+ const mod2 = await import("./dist-VHI5QOSQ.js");
10983
11119
  const status2 = mod2.readHetznerCredStatus();
10984
11120
  if (status2.source !== "none") {
10985
11121
  log32.info("hetzner: already configured");
@@ -10992,7 +11128,7 @@ async function runProviderLogin(name) {
10992
11128
  return true;
10993
11129
  }
10994
11130
  if (name === "vercel") {
10995
- const mod2 = await import("./dist-S4XR4ACV.js");
11131
+ const mod2 = await import("./dist-XC47DSCR.js");
10996
11132
  const status2 = mod2.readVercelCredStatus();
10997
11133
  if (status2.auth !== "none") {
10998
11134
  log32.info(`vercel: already configured (${status2.auth})`);
@@ -11004,7 +11140,7 @@ async function runProviderLogin(name) {
11004
11140
  await mod2.ensureVercelCredentials();
11005
11141
  return true;
11006
11142
  }
11007
- const mod = await import("./dist-JZ3XO6EB.js");
11143
+ const mod = await import("./dist-4IQFJJQI.js");
11008
11144
  const status = mod.readE2bCredStatus();
11009
11145
  if (status.auth !== "none") {
11010
11146
  log32.info(`e2b: already configured (${status.auth})`);
@@ -11189,9 +11325,15 @@ var doctorCommand = new Command28("doctor").description(
11189
11325
  );
11190
11326
  process.exit(1);
11191
11327
  }
11328
+ const [sys, prov, integrations] = await Promise.all([
11329
+ runSystemChecks(),
11330
+ runProviderChecks(name),
11331
+ integrationsChecks()
11332
+ ]);
11192
11333
  groups = [
11193
- { title: "system", results: await runSystemChecks() },
11194
- await runProviderChecks(name)
11334
+ { title: "system", results: sys },
11335
+ prov,
11336
+ { title: "integrations", results: integrations }
11195
11337
  ];
11196
11338
  } else {
11197
11339
  groups = await runAllChecks();
@@ -12210,7 +12352,7 @@ async function pruneCloud(provider, opts) {
12210
12352
  }
12211
12353
 
12212
12354
  // src/commands/queue.ts
12213
- import { readFile as readFile5, stat as stat6 } from "fs/promises";
12355
+ import { readFile as readFile6, stat as stat6 } from "fs/promises";
12214
12356
  import { intro as intro8, log as log37, outro as outro7 } from "@clack/prompts";
12215
12357
  import { Command as Command35 } from "commander";
12216
12358
  var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["done", "failed", "cancelled"]);
@@ -12258,7 +12400,7 @@ var queueShowCommand = new Command35("show").description("Dump a job manifest an
12258
12400
  const tailN = Number.parseInt(opts.tail, 10) || 50;
12259
12401
  try {
12260
12402
  await stat6(job.logPath);
12261
- const text = await readFile5(job.logPath, "utf8");
12403
+ const text = await readFile6(job.logPath, "utf8");
12262
12404
  const lines = text.split(/\r?\n/);
12263
12405
  const slice = lines.slice(Math.max(0, lines.length - tailN - 1));
12264
12406
  process.stdout.write(`