@outerlayer/cli 0.33.0-next.20261023002325 → 0.33.0-next.20261023003700

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 (42) hide show
  1. package/dist/{build-G4GUF6LT.js → build-SEAQVLD5.js} +2 -2
  2. package/dist/{build-disk-3GL3KKEB.js → build-disk-JHTMPRAA.js} +3 -5
  3. package/dist/build-info.json +1 -1
  4. package/dist/{builder-3CUKTVSY.js → builder-Y4P7QARW.js} +2 -3
  5. package/dist/{check-64FD5G3X.js → check-MRYFTLOO.js} +12 -14
  6. package/dist/{chunk-JRZCRIEO.js → chunk-2EGCI2VW.js} +2881 -2561
  7. package/dist/{chunk-LJUIG5K4.js → chunk-3RIFVLPO.js} +5 -5
  8. package/dist/{chunk-QFQC5K4J.js → chunk-7HHNGZS5.js} +33 -21
  9. package/dist/{chunk-YERR22SY.js → chunk-DISTLL2Q.js} +1 -1
  10. package/dist/{chunk-GFVDC5S3.js → chunk-FR7HWWCF.js} +34 -3
  11. package/dist/{chunk-LYE3KB6L.js → chunk-HE4FBF4T.js} +2 -2
  12. package/dist/{chunk-TGHBOXKJ.js → chunk-NE63JADS.js} +2 -2
  13. package/dist/{chunk-DGI66PGY.js → chunk-PWH3BEZF.js} +30 -270
  14. package/dist/{chunk-3DCB3GOV.js → chunk-RQJMN5TJ.js} +6 -4
  15. package/dist/{chunk-CANYZTD5.js → chunk-SDU2IE22.js} +40 -13
  16. package/dist/chunk-W2AEL4BJ.js +179 -0
  17. package/dist/{chunk-OOCAF3ID.js → chunk-XHHTMFCX.js} +1 -1
  18. package/dist/{chunk-JPG43G6Y.js → chunk-YXHKCHWG.js} +1 -1
  19. package/dist/{cli-WKRURGHC.js → cli-K6XGL4EZ.js} +39 -39
  20. package/dist/{command-WG54AUHK.js → command-7FAIIQGF.js} +8 -9
  21. package/dist/{config-LZSFW2O3.js → config-QXMUWJAQ.js} +9 -2
  22. package/dist/{container-start-DQKFQ3CL.js → container-start-CVP3NTDG.js} +9 -10
  23. package/dist/{docker-4ERXWTRW.js → docker-ANW76BNW.js} +2 -3
  24. package/dist/{doctor-GRCEYJXA.js → doctor-GJAHI3KU.js} +16 -21
  25. package/dist/{emit-demo-cmd-JSVI56WY.js → emit-demo-cmd-6DF2QIAS.js} +1 -1
  26. package/dist/index.js +1 -1
  27. package/dist/{init-WNO4NAO7.js → init-XDOKWBL2.js} +8 -9
  28. package/dist/{init-OKJAI77M.js → init-ZQ5B3TJZ.js} +8 -9
  29. package/dist/{init-cmd-PFW4XTG7.js → init-cmd-YMGW2WXJ.js} +1 -1
  30. package/dist/install-QPA7DQHO.js +19 -0
  31. package/dist/{loop-2SITCQ6H.js → loop-UJL2UCUM.js} +12 -14
  32. package/dist/{machine-YHBCNRUO.js → machine-2YPAFFCH.js} +8 -9
  33. package/dist/{runner-env-QYE7KZFP.js → runner-env-HOUXKWIJ.js} +10 -4
  34. package/dist/{runner-identity-FIHOECSH.js → runner-identity-KPUVTRLS.js} +2 -3
  35. package/dist/{runner-key-YUKU2MWK.js → runner-key-FUJD66R6.js} +8 -9
  36. package/dist/{status-VBQJMFEX.js → status-2KNTILGQ.js} +9 -10
  37. package/dist/{work-claim-cmd-MFND6Z4S.js → work-claim-cmd-NJNOQFQE.js} +5 -2
  38. package/package.json +1 -1
  39. package/dist/chunk-XWFSAOC7.js +0 -111
  40. package/dist/chunk-YJLHUKYS.js +0 -38
  41. package/dist/chunk-YYYRBYWG.js +0 -32
  42. package/dist/install-GQUCHIGE.js +0 -13
@@ -1195,8 +1195,8 @@ function doctorExitCode(checks) {
1195
1195
 
1196
1196
  // src/doctor-report.ts
1197
1197
  async function gatherDoctorChecks() {
1198
- const { DEFAULT_BUILD_DISK } = await import('./build-disk-3GL3KKEB.js');
1199
- const { defaultRunnerConfigPath, hasRunnerBlock, loadRunnerConfig, runnerVmOf } = await import('./config-LZSFW2O3.js');
1198
+ const { DEFAULT_BUILD_DISK, DEFAULT_CACHE_DISK } = await import('./build-disk-JHTMPRAA.js');
1199
+ const { defaultRunnerConfigPath, hasRunnerBlock, loadRunnerConfig, runnerVmOf } = await import('./config-QXMUWJAQ.js');
1200
1200
  const configPath = defaultRunnerConfigPath();
1201
1201
  const runnerHost = hasRunnerBlock(configPath);
1202
1202
  const hooks = (() => {
@@ -1217,7 +1217,7 @@ async function gatherDoctorChecks() {
1217
1217
  const { runnerVmCheck } = await import('./doctor-53F2PYY7.js');
1218
1218
  checks.push(runnerVmCheck(configPath, { lima: realLima(), home: homeFromEnv(), instance: runnerVm.instance }));
1219
1219
  } else if (hasRunnerBlock(configPath)) {
1220
- const { runnerHostChecks } = await import('./doctor-GRCEYJXA.js');
1220
+ const { runnerHostChecks } = await import('./doctor-GJAHI3KU.js');
1221
1221
  const gateway = (() => {
1222
1222
  try {
1223
1223
  const { url, apiKey, appId } = loadRunnerConfig(configPath);
@@ -1236,7 +1236,7 @@ async function gatherDoctorChecks() {
1236
1236
  const runner = (() => {
1237
1237
  try {
1238
1238
  const { concurrency, build, housekeeping, managed } = loadRunnerConfig(configPath);
1239
- return { concurrency, buildMemory: build?.memory ?? "8g", buildDisk: build?.disk ?? DEFAULT_BUILD_DISK, minFreeDisk: housekeeping?.minFreeDisk, allowHosts: build?.allowHosts, ...build?.imageBuild === void 0 ? {} : { imageBuild: build.imageBuild }, ...managed === true ? { managed } : {} };
1239
+ return { concurrency, buildMemory: build?.memory ?? "8g", buildDisk: build?.disk ?? DEFAULT_BUILD_DISK, cacheDisk: build?.cacheDisk ?? DEFAULT_CACHE_DISK, minFreeDisk: housekeeping?.minFreeDisk, allowHosts: build?.allowHosts, ...build?.imageBuild === void 0 ? {} : { imageBuild: build.imageBuild }, ...managed === true ? { managed } : {} };
1240
1240
  } catch {
1241
1241
  return void 0;
1242
1242
  }
@@ -1245,7 +1245,7 @@ async function gatherDoctorChecks() {
1245
1245
  const { existsSync: existsSync3 } = await import('fs');
1246
1246
  if (process.platform !== "linux" || !existsSync3("/run/systemd/system")) return void 0;
1247
1247
  const { inspectService, realInspectProbes } = await import('./inspect-DNLXTXLA.js');
1248
- const { DEFAULT_UNIT_NAME } = await import('./install-GQUCHIGE.js');
1248
+ const { DEFAULT_UNIT_NAME } = await import('./install-QPA7DQHO.js');
1249
1249
  const { dirname: dirname2 } = await import('path');
1250
1250
  return inspectService(DEFAULT_UNIT_NAME, dirname2(configPath), realInspectProbes());
1251
1251
  })();
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { placeholderQueues, placeholderProblem } from './chunk-JRZCRIEO.js';
4
- import { checkFit } from './chunk-LYE3KB6L.js';
5
- import { realBuildDiskProbe, checkDiskFit, DEFAULT_BUILD_DISK } from './chunk-XWFSAOC7.js';
6
- import { builderDiskPinned } from './chunk-TGHBOXKJ.js';
7
- import { builtinKind, imageBuildOf } from './chunk-3DCB3GOV.js';
3
+ import { placeholderQueues, placeholderProblem } from './chunk-2EGCI2VW.js';
4
+ import { checkFit } from './chunk-HE4FBF4T.js';
5
+ import { builtinKind, imageBuildOf } from './chunk-RQJMN5TJ.js';
6
+ import { realBuildDiskProbe, checkDiskFit, DEFAULT_CACHE_DISK, DEFAULT_BUILD_DISK } from './chunk-W2AEL4BJ.js';
7
+ import { builderDiskPinned } from './chunk-NE63JADS.js';
8
8
  import { claudeCredentialVariablesSet, claudeCredential } from './chunk-BALIE3BA.js';
9
9
  import { closeSync, openSync, constants } from 'fs';
10
10
  import { totalmem } from 'os';
@@ -80,12 +80,17 @@ function managedFactsOf(config, probes) {
80
80
  builderDiskPinned: probes.builderDiskPinned ?? builderDiskPinned()
81
81
  };
82
82
  }
83
- function checkBlocked(config, probes) {
83
+ function keepsHostBuilder(config, builderDiskIsPinned) {
84
+ return !(builtinKind(config.hooks.provision) === "vm" && imageBuildOf(config) === "vm" && (builderDiskIsPinned ?? builderDiskPinned()));
85
+ }
86
+ function checkBlockedWithSlots(config, probes) {
87
+ const blocked = (reason) => ({ blocked: { reason } });
88
+ let slots;
84
89
  const placeholders = placeholderQueues(config);
85
- if (placeholders.length > 0) return { reason: `${placeholderProblem(placeholders)}. The runner takes work again once the config is edited` };
90
+ if (placeholders.length > 0) return blocked(`${placeholderProblem(placeholders)}. The runner takes work again once the config is edited`);
86
91
  if (config.managed === true) {
87
92
  const unmet = managedProblems(managedFactsOf(config, probes))[0];
88
- if (unmet !== void 0) return { reason: unmet.reason };
93
+ if (unmet !== void 0) return blocked(unmet.reason);
89
94
  }
90
95
  const kind = builtinKind(config.hooks.provision);
91
96
  if (kind === "container" || kind === "vm") {
@@ -96,39 +101,46 @@ function checkBlocked(config, probes) {
96
101
  });
97
102
  if (!fit.fits) {
98
103
  const advice = probes.inImage === true ? "Set OUTERLAYER_BUILD_MEMORY or OUTERLAYER_CONCURRENCY in the env file and recreate the container, or give the machine more memory" : `Lower runner.concurrency or runner.build.memory in ${config.configPath}`;
99
- return { reason: `${fit.message}. ${advice}` };
104
+ return blocked(`${fit.message}. ${advice}`);
100
105
  }
101
106
  const facts = probes.buildDisk?.(kind, config.configPath);
102
107
  if (facts !== void 0) {
103
- const diskFit = checkDiskFit({ concurrency: config.concurrency, buildDisk: config.build?.disk ?? DEFAULT_BUILD_DISK, facts });
104
- if (!diskFit.fits) {
105
- const advice = probes.inImage === true ? "Set OUTERLAYER_CONCURRENCY in the env file and recreate the container, or give the machine more disk" : `Lower runner.concurrency or runner.build.disk in ${config.configPath}`;
106
- return { reason: `${diskFit.message}. ${advice}` };
108
+ const diskFit = checkDiskFit({ concurrency: config.concurrency, buildDisk: config.build?.disk ?? DEFAULT_BUILD_DISK, cacheDisk: config.build?.cacheDisk ?? DEFAULT_CACHE_DISK, facts });
109
+ slots = diskFit.slots;
110
+ if (diskFit.slots < 1) {
111
+ const advice = probes.inImage === true ? "Set OUTERLAYER_CONCURRENCY in the env file and recreate the container, or give the machine more disk" : `Lower runner.build.disk${kind === "vm" ? " or runner.build.cacheDisk" : ""} in ${config.configPath}, or give the machine more disk`;
112
+ return { blocked: { reason: `${diskFit.message}. ${advice}` }, slots };
107
113
  }
108
114
  }
109
115
  }
110
116
  const kvm = kind === "vm" ? probes.kvm() : "usable";
111
117
  if (kvm === "absent") {
112
- return { reason: "/dev/kvm does not exist on this machine, so builtin:vm cannot start a microVM. Use a host with KVM enabled, or builtin:container hooks" };
118
+ return { blocked: { reason: "/dev/kvm does not exist on this machine, so builtin:vm cannot start a microVM. Use a host with KVM enabled, or builtin:container hooks" }, slots };
113
119
  }
114
120
  if (kvm !== "usable") {
115
121
  return {
116
- reason: "the runner cannot open /dev/kvm, so builtin:vm cannot start a microVM. Add the runner's account to the kvm group, then restart the service, because a service reads its groups only when it starts"
122
+ slots,
123
+ blocked: {
124
+ reason: "the runner cannot open /dev/kvm, so builtin:vm cannot start a microVM. Add the runner's account to the kvm group, then restart the service, because a service reads its groups only when it starts"
125
+ }
117
126
  };
118
127
  }
119
- if (kind === "container" || kind === "vm") {
128
+ if ((kind === "container" || kind === "vm") && keepsHostBuilder(config, probes.builderDiskPinned)) {
120
129
  const builder = probes.imageBuilder;
121
130
  if (builder === "unknown") {
122
- return { reason: "the runner is still preparing its image builder, the container that limits image builds to runner.build.memory, so it claims nothing yet" };
131
+ return { blocked: { reason: "the runner is still preparing its image builder, the container that limits image builds to runner.build.memory, so it claims nothing yet" }, slots };
123
132
  }
124
- if (builder !== "usable") return { reason: `${builder.problem}. The runner takes work again once its image builder works` };
133
+ if (builder !== "usable") return { blocked: { reason: `${builder.problem}. The runner takes work again once its image builder works` }, slots };
125
134
  }
126
135
  if (kind !== "own" && claudeCredential(probes.env) === void 0) {
127
136
  return {
128
- reason: "there is no Claude credential in the runner's environment. Store CLAUDE_CODE_OAUTH_TOKEN (from `claude setup-token`) or ANTHROPIC_API_KEY with `outerlayer runner init --agent claude`, which writes the claude.env beside the config, then restart the service"
137
+ slots,
138
+ blocked: {
139
+ reason: "there is no Claude credential in the runner's environment. Store CLAUDE_CODE_OAUTH_TOKEN (from `claude setup-token`) or ANTHROPIC_API_KEY with `outerlayer runner init --agent claude`, which writes the claude.env beside the config, then restart the service"
140
+ }
129
141
  };
130
142
  }
131
- return void 0;
143
+ return { slots };
132
144
  }
133
145
 
134
- export { checkBlocked, managedFactsOf, managedProblems, realBlockedProbes };
146
+ export { checkBlockedWithSlots, keepsHostBuilder, managedFactsOf, managedProblems, realBlockedProbes };
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { DEFAULT_UNIT_NAME } from './chunk-LYE3KB6L.js';
3
+ import { DEFAULT_UNIT_NAME } from './chunk-HE4FBF4T.js';
4
4
  import { RUNNER_FILE_MODE } from './chunk-PA6CK6WQ.js';
5
5
  import { claudeEnvPath, withoutCredentialLines } from './chunk-BALIE3BA.js';
6
6
  import { parseRunnerEnv } from './chunk-HACGUL52.js';
@@ -1,8 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { RecipeError } from './chunk-3Z3MPR55.js';
4
- import { BUILDKIT_IMAGE } from './chunk-TGHBOXKJ.js';
5
- import { parseSize } from './chunk-YJLHUKYS.js';
4
+ import { BUILDKIT_IMAGE } from './chunk-NE63JADS.js';
6
5
  import { compareVersions } from './chunk-5DNCFOXA.js';
7
6
  import { ensureHostKey } from './chunk-SOI6K5DY.js';
8
7
  import { RUNNER_DIR_MODE, RUNNER_FILE_MODE, runnerDir, jobsDir } from './chunk-PA6CK6WQ.js';
@@ -17,6 +16,38 @@ import { createRequire as createRequire$1 } from 'module';
17
16
  import { fileURLToPath } from 'url';
18
17
 
19
18
  createRequire(import.meta.url);
19
+
20
+ // src/runner/container/disk.ts
21
+ var UNITS = { "": 1, k: 1024, m: 1024 ** 2, g: 1024 ** 3 };
22
+ function parseSize(text) {
23
+ const match = /^(\d+(?:\.\d+)?)([kKmMgG]?)$/.exec(text);
24
+ if (match === null) return void 0;
25
+ const bytes = Number(match[1]) * UNITS[match[2].toLowerCase()];
26
+ return bytes > 0 ? bytes : void 0;
27
+ }
28
+ function exceedsDisk(usedKilobytes, limit) {
29
+ const bytes = parseSize(limit);
30
+ return usedKilobytes * 1024 > (bytes ?? Number.POSITIVE_INFINITY);
31
+ }
32
+ var TOTAL = /^(\d+)\t\/build$/;
33
+ var GONE = /: No such file or directory$/;
34
+ var LINE_MAX = 200;
35
+ function readDu(result) {
36
+ const stdoutLines = result.stdout.split("\n");
37
+ const totalAt = stdoutLines.map((line) => TOTAL.test(line)).lastIndexOf(true);
38
+ const kib = totalAt === -1 ? void 0 : Number(TOTAL.exec(stdoutLines[totalAt])[1]);
39
+ const lines2 = [...result.stderr.split("\n"), ...stdoutLines.filter((_, index) => index !== totalAt)].map((line) => line.trim()).filter((line) => line !== "");
40
+ const other = lines2.find((line) => !GONE.test(line));
41
+ if (kib !== void 0 && result.status === 0) return { kib };
42
+ if (kib !== void 0 && other === void 0 && lines2.length > 0) return { kib };
43
+ const detail = other === void 0 ? "" : `: ${cut(other.replace(/[\u0000-\u001f\u007f]/g, " "))}`;
44
+ return { ...kib === void 0 ? {} : { kib }, failure: `docker exec exited ${result.status}${detail}` };
45
+ }
46
+ function cut(line) {
47
+ const head = line.slice(0, LINE_MAX);
48
+ const last = head.charCodeAt(head.length - 1);
49
+ return last >= 55296 && last <= 56319 ? head.slice(0, -1) : head;
50
+ }
20
51
  var PACKAGE = "@devcontainers/cli";
21
52
  function buildRootFromDist(moduleDir = dirname(fileURLToPath(import.meta.url))) {
22
53
  try {
@@ -732,4 +763,4 @@ function ensureBuilder(rawRun, spec, options = {}) {
732
763
  );
733
764
  }
734
765
 
735
- export { BUILD_LABEL, COMMAND_DIR, HASH_ARGV, JUDGE_DIR, JUDGE_ITEMS, JUDGE_MAX_TURNS, JUDGE_PROGRAM, JUDGE_REPORT, MAX_ITEMS_BYTES, MAX_REPORT_BYTES, MIN_BUILDX_VERSION, RUNNER_LABEL, builderName, builderNameFor, builderSpec, buildxState, childEnvironment, containerExecArgs, containerRunArgs, createDockerHost, dockerIdentity, ensureBuilder, ensureFailureCount, ensureRunnerIdentity, isOutOfMemory, judgeCommand, parseProgramHash, pathLabelValue, prepareRunArgs, proxyEnvironment, readJobFile, readJobFileChecked, readRunnerIdentity, resolveDevcontainerCli, runnerLabelValue, spawnRun, trackImageBuild, withAnswerProtocol, writeJobFile };
766
+ export { BUILD_LABEL, COMMAND_DIR, HASH_ARGV, JUDGE_DIR, JUDGE_ITEMS, JUDGE_MAX_TURNS, JUDGE_PROGRAM, JUDGE_REPORT, MAX_ITEMS_BYTES, MAX_REPORT_BYTES, MIN_BUILDX_VERSION, RUNNER_LABEL, builderName, builderNameFor, builderSpec, buildxState, childEnvironment, containerExecArgs, containerRunArgs, createDockerHost, dockerIdentity, ensureBuilder, ensureFailureCount, ensureRunnerIdentity, exceedsDisk, isOutOfMemory, judgeCommand, parseProgramHash, parseSize, pathLabelValue, prepareRunArgs, proxyEnvironment, readDu, readJobFile, readJobFileChecked, readRunnerIdentity, resolveDevcontainerCli, runnerLabelValue, spawnRun, trackImageBuild, withAnswerProtocol, writeJobFile };
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { builtinKind } from './chunk-3DCB3GOV.js';
4
- import { parseSize } from './chunk-YJLHUKYS.js';
3
+ import { builtinKind } from './chunk-RQJMN5TJ.js';
4
+ import { parseSize } from './chunk-FR7HWWCF.js';
5
5
  import { runnerDir } from './chunk-PA6CK6WQ.js';
6
6
  import { CLAUDE_CREDENTIAL_ID, CLAUDE_ENV_FILE, credentialLineIn, withoutCredentialLines } from './chunk-BALIE3BA.js';
7
7
  import { FD_SLOTS_PER_BUILD, FD_STORE_ENV } from './chunk-HACGUL52.js';
@@ -44,10 +44,10 @@ function guestAssetsPinned(arch) {
44
44
  var JAILER_BINARY_SHA256 = {
45
45
  x86_64: "65ef226e96f0ceda55ba643f445801ef2cc0ea667ef67cad8ac4f406c9c8434f"
46
46
  };
47
- var HOST_HELPER_ASSETS_VERSION = "10";
47
+ var HOST_HELPER_ASSETS_VERSION = "13";
48
48
  var HOST_HELPER_BASE_URL = `https://github.com/outerlayerai/guest-assets/releases/download/guest-${HOST_HELPER_ASSETS_VERSION}`;
49
49
  var HOST_HELPER_SHA256 = {
50
- x86_64: "caa06b7206cceae6d8fc569781b269817ca66cb2ccfe177740fda042ed46bfcc"
50
+ x86_64: "0d6cdbce1e5a5e084726b1d1b1cc0bc208f6662fe8d10a1d7a91e8573035505f"
51
51
  };
52
52
  function hostHelperPinned(arch = "x86_64", hashes = HOST_HELPER_SHA256) {
53
53
  return hashes[arch] !== "0".repeat(64);
@@ -6,23 +6,23 @@ import { writeDockerClientConfig } from './chunk-6LBSAW6I.js';
6
6
  import { zodProblem } from './chunk-I3LTIAOR.js';
7
7
  import { senderPidfile } from './chunk-Q2CMEQV7.js';
8
8
  import { installScrubContext } from './chunk-2N67C6IV.js';
9
- import { ADDED_USER, shellQuote, GH_CONFIG_YML, ghHostsYml, AssetError, obtainImage, ensureRootfs, makeBuildsDirPrivate, gitRemoteFor, startServicesFor, createLeaseChannel, createBuildDisk, machineConfig, startJailedInto, resolveAgentUser, AgentUserError, runBuildSteps, LEASE_SECONDS, createContainerRuntime, stopContainer, cleanupContainer, outOfMemoryReason, containerSenderCommand, signalInContainer, syncInContainer, copyTranscriptsFromContainer, MANAGED_UNJAILED_REASON, senderAliveScript, helperFirecrackerNote, isLiteralAddress, stopJailed, deleteBuildDisk, startCheckContainer, lifecycleSteps, lifecycleFailureReason, writeEvalInput, DeliveryFailure, EVAL_INPUT_NAME, copyTranscripts, senderSignalScript, containerJudgeEnvironment, ROOT_DISK_ID_PREFIX, copyJudgeTree } from './chunk-JRZCRIEO.js';
10
- import { readBranchHead, fetchCommit, diffBetween } from './chunk-JPG43G6Y.js';
9
+ import { ADDED_USER, shellQuote, GH_CONFIG_YML, ghHostsYml, AssetError, obtainImage, ensureRootfs, makeBuildsDirPrivate, gitRemoteFor, startServicesFor, createLeaseChannel, createBuildDisk, machineConfig, startJailedInto, resolveAgentUser, AgentUserError, runBuildSteps, startHostServices, LEASE_SECONDS, createContainerRuntime, stopContainer, cleanupContainer, outOfMemoryReason, closeHostBuild, containerSenderCommand, hostCommandEnvironment, execArgv, signalInContainer, syncInContainer, copyTranscriptsFromContainer, MANAGED_UNJAILED_REASON, senderAliveScript, helperFirecrackerNote, stopJailed, deleteBuildDisk, startCheckContainer, lifecycleSteps, lifecycleFailureReason, writeEvalInput, DeliveryFailure, EVAL_INPUT_NAME, copyTranscripts, senderSignalScript, containerJudgeEnvironment, ROOT_DISK_ID_PREFIX, copyJudgeTree } from './chunk-2EGCI2VW.js';
10
+ import { readBranchHead, fetchCommit, diffBetween } from './chunk-YXHKCHWG.js';
11
11
  import { isSameProcess, startTimeOf } from './chunk-JBJTC3UU.js';
12
12
  import { waitForAgent, vmExecArgs } from './chunk-5THSC6BD.js';
13
13
  import { socketPathProblem, vsockLinks, LEASE_LINK, linkVsockSockets } from './chunk-L26V6ILJ.js';
14
14
  import { describeCallFailure, resolveGoverningSource, prefetchGovernedContext, refusalCode, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, logStamp, createRunnerLog, removeKeptContext, formatDuration, retrySend, formatClock, WORKFLOW_PERMISSION_REASON, keptContextTree } from './chunk-T5REPMNL.js';
15
- import { HASH_ARGV, parseProgramHash, JUDGE_PROGRAM, writeJobFile, readJobFile, childEnvironment, withAnswerProtocol, judgeCommand, MAX_REPORT_BYTES, JUDGE_MAX_TURNS, JUDGE_DIR, COMMAND_DIR, MAX_ITEMS_BYTES } from './chunk-GFVDC5S3.js';
16
- import { CLAUDE_CODE_VERSION, FIRECRACKER_VERSION } from './chunk-TGHBOXKJ.js';
17
- import { imageBuildOf, isBuiltinContainer, isBuiltinProcess, isBuiltinVm, DEFAULT_CHECK_TIME_LIMIT_MINUTES } from './chunk-3DCB3GOV.js';
18
- import { parseSize } from './chunk-YJLHUKYS.js';
15
+ import { imageBuildOf, isBuiltinContainer, isBuiltinProcess, isBuiltinVm, DEFAULT_CHECK_TIME_LIMIT_MINUTES } from './chunk-RQJMN5TJ.js';
16
+ import { DEFAULT_CACHE_DISK, formatBytes, allocatedBytes } from './chunk-W2AEL4BJ.js';
17
+ import { parseSize, HASH_ARGV, parseProgramHash, JUDGE_PROGRAM, writeJobFile, readJobFile, childEnvironment, withAnswerProtocol, judgeCommand, MAX_REPORT_BYTES, JUDGE_MAX_TURNS, JUDGE_DIR, COMMAND_DIR, MAX_ITEMS_BYTES } from './chunk-FR7HWWCF.js';
18
+ import { CLAUDE_CODE_VERSION, FIRECRACKER_VERSION } from './chunk-NE63JADS.js';
19
19
  import { WorkCommandError, postJson, isSignatureRefusal, getJson } from './chunk-VT4TTJPG.js';
20
20
  import { planArtifactUpload } from './chunk-EWVYQLD3.js';
21
21
  import { scrubText } from './chunk-5DNCFOXA.js';
22
22
  import { readCloudConfig } from './chunk-PJDQPF5N.js';
23
23
  import { signerFor } from './chunk-SOI6K5DY.js';
24
24
  import { RUNNER_FILE_MODE, runnerDir, buildDir, vsockPath, jobConsolePath } from './chunk-PA6CK6WQ.js';
25
- import { JOB_MOUNT, claudeCredential, repositoriesOf, primaryOf, buildEnvironment, CHECKOUT_DIR, parseIsolation, proxyEnvironment, withProxyWarningHidden, containerLocalAddress, destinationEnvironment, CLAUDE_CREDENTIAL_VARIABLES, builtInEnvironment, withHooksPath, startBuildServices, BUILT_IN_NAMES, AGENT_CREDENTIAL_MISSING, sharedUserEnvironment, headerVariables, authorEnvironment, withTunnelRecord, commitIdentityRecord, buildMavenSettingsXml, mavenSettingsXml, namesGlobalSettings, MAVEN_NO_PROXY_NOTE, mavenArgs, MAVEN_SPACE_NOTE, writeMavenSettings, RELAY_PORT, repositoryPath, lifecycleWorkdir, CHECK_ITEMS_FILE, MAVEN_SETTINGS_FILE, currentClaudeCredential, removedClaudeCredentialValues, checkEnvironment, EVAL_INPUT_DIR } from './chunk-BALIE3BA.js';
25
+ import { JOB_MOUNT, claudeCredential, repositoriesOf, primaryOf, buildEnvironment, CHECKOUT_DIR, AGENT_CREDENTIAL_MISSING, sharedUserEnvironment, headerVariables, authorEnvironment, withTunnelRecord, commitIdentityRecord, buildMavenSettingsXml, RELAY_PORT, repositoryPath, lifecycleWorkdir, CHECK_ITEMS_FILE, MAVEN_SETTINGS_FILE, CLAUDE_CREDENTIAL_VARIABLES, currentClaudeCredential, removedClaudeCredentialValues, checkEnvironment, EVAL_INPUT_DIR } from './chunk-BALIE3BA.js';
26
26
  import { resolvePackRoot } from './chunk-G63KT5I5.js';
27
27
  import { MAINTAINED_SKILLS } from './chunk-CDDED64E.js';
28
28
  import { resolveVersion } from './chunk-RA3O54FC.js';
@@ -31,8 +31,8 @@ import { CheckItemsSchema, CHECK_ITEM_REASON_MAX_LENGTH } from './chunk-E6CO3MJE
31
31
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
32
32
  import { fdName } from './chunk-HACGUL52.js';
33
33
  import { RUNNER_WORDED_REASONS, UNKNOWN_TRACKING_REASON } from './chunk-MESOOLF4.js';
34
- import { existsSync, statSync, appendFileSync, rmSync, mkdirSync, chmodSync, writeFileSync, accessSync, constants, openSync, readFileSync, closeSync, readdirSync, lstatSync, fstatSync, readSync, realpathSync } from 'fs';
35
- import { join, isAbsolute, dirname, delimiter, sep } from 'path';
34
+ import { existsSync, statSync, appendFileSync, rmSync, mkdirSync, chmodSync, writeFileSync, openSync, readFileSync, closeSync, readdirSync, lstatSync, fstatSync, readSync, realpathSync } from 'fs';
35
+ import { join, dirname, delimiter, sep } from 'path';
36
36
  import { once } from 'events';
37
37
  import { createServer } from 'net';
38
38
  import { spawn, spawnSync } from 'child_process';
@@ -355,7 +355,7 @@ async function provisionMicroVm(input) {
355
355
  inBuilder: {
356
356
  kernel: assets.kernel,
357
357
  firecracker: assets.firecracker,
358
- limits,
358
+ limits: { ...limits, cacheDiskBytes: parseSize(config.build?.cacheDisk ?? DEFAULT_CACHE_DISK) ?? parseSize(DEFAULT_CACHE_DISK) },
359
359
  memory: config.build?.memory,
360
360
  allowHosts: config.build?.allowHosts,
361
361
  managed: config.managed === true,
@@ -1050,7 +1050,7 @@ async function stopBuildMicroVm(runtime, state, jobDir) {
1050
1050
  await runtime.vm.firecracker.stop(state.firecracker);
1051
1051
  if (runtime.vm.firecracker.alive(state.firecracker)) throw new Error(`the microVM (pid ${state.firecracker.pid}) is still running after it was stopped`);
1052
1052
  }
1053
- async function cleanupMicroVm(runtime, state, jobDir, warn) {
1053
+ async function cleanupMicroVm(runtime, state, jobDir, warn, onBuildDisk) {
1054
1054
  const failures = [];
1055
1055
  if (jobDir !== void 0) await copyHookErrors(runtime, state, jobDir);
1056
1056
  if (state.jailed !== void 0) {
@@ -1074,6 +1074,13 @@ async function cleanupMicroVm(runtime, state, jobDir, warn) {
1074
1074
  failures.push(`the build's cgroup ${state.cgroup} was not removed: ${describeCallFailure(err)}`);
1075
1075
  }
1076
1076
  }
1077
+ if (state.buildDisk !== void 0 && existsSync(state.buildDisk)) {
1078
+ try {
1079
+ onBuildDisk?.(allocatedBytes(state.buildDisk));
1080
+ } catch (err) {
1081
+ failures.push(`the build disk's peak size was not recorded: ${describeCallFailure(err)}`);
1082
+ }
1083
+ }
1077
1084
  if (state.buildDisk !== void 0) deleteBuildDisk(state.buildDisk);
1078
1085
  runtime.leases.get(state.buildId)?.close();
1079
1086
  runtime.leases.delete(state.buildId);
@@ -1217,263 +1224,6 @@ async function sampleGuest(runtime, state) {
1217
1224
  return void 0;
1218
1225
  }
1219
1226
  }
1220
- function provisionEnvironment(base, input) {
1221
- return {
1222
- ...base,
1223
- OUTERLAYER_BUILD_DIR: input.buildDir,
1224
- ...input.repository === void 0 || input.repository === null || input.repository === "" ? {} : { OUTERLAYER_REPOSITORY: input.repository },
1225
- ...input.recipeCommit === void 0 ? {} : { OUTERLAYER_RECIPE_COMMIT: input.recipeCommit },
1226
- OUTERLAYER_MEMORY: input.limits.memory,
1227
- OUTERLAYER_CPUS: String(input.limits.cpus),
1228
- OUTERLAYER_PIDS: String(input.limits.pids),
1229
- OUTERLAYER_DISK: input.limits.disk
1230
- };
1231
- }
1232
- function unspecified(address) {
1233
- if (!address.includes(":")) return address === "0.0.0.0";
1234
- const normal = new URL(`http://[${address}]/`).hostname;
1235
- return normal === "[::]" || normal === "[::ffff:0:0]";
1236
- }
1237
- function parseBroker(text2) {
1238
- const match = /^(?:\[([0-9a-fA-F:.]+)\]|([0-9.]+)):(\d{1,5})$/.exec(text2);
1239
- if (match === null) return void 0;
1240
- const host = match[1] ?? match[2];
1241
- const port = Number(match[3]);
1242
- if (!isLiteralAddress(host) || unspecified(host) || port < 1 || port > 65535) return void 0;
1243
- return { host, port, text: text2 };
1244
- }
1245
- function readReport(path) {
1246
- const named = `provision.out names recipe ${path}`;
1247
- if (!isAbsolute(path)) return { problem: `${named}, which is not an absolute path` };
1248
- let text2;
1249
- try {
1250
- text2 = readFileSync(path, "utf8");
1251
- } catch {
1252
- return { problem: `${named}, which does not exist` };
1253
- }
1254
- try {
1255
- const parsed = JSON.parse(text2);
1256
- const lifecycle = parsed.apply?.lifecycle;
1257
- if (typeof parsed.sourceCommit === "string" && typeof parsed.recipeKey === "string" && typeof parsed.imageId === "string" && typeof lifecycle === "object" && lifecycle !== null && Object.values(lifecycle).every((entries) => Array.isArray(entries) && entries.every((entry) => typeof entry === "object" && entry !== null))) {
1258
- return { report: { ...parsed, ignored: Array.isArray(parsed.ignored) ? parsed.ignored : [] } };
1259
- }
1260
- } catch {
1261
- }
1262
- return { problem: `${named}, which is not a recipe report` };
1263
- }
1264
- function resolveHostBuild(keys) {
1265
- const build = { isolation: parseIsolation(keys.isolation) };
1266
- if (keys.exec !== void 0) {
1267
- const named = `provision.out names exec ${keys.exec}`;
1268
- if (!isAbsolute(keys.exec)) return { ok: false, reason: `${named}, which is not an absolute path` };
1269
- try {
1270
- if (!statSync(keys.exec).isFile()) return { ok: false, reason: `${named}, which is not an executable file` };
1271
- accessSync(keys.exec, constants.X_OK);
1272
- } catch {
1273
- return { ok: false, reason: `${named}, which is not an executable file` };
1274
- }
1275
- build.exec = keys.exec;
1276
- }
1277
- if (keys.broker !== void 0) {
1278
- const broker = parseBroker(keys.broker);
1279
- if (broker === void 0) {
1280
- return { ok: false, reason: `provision.out names broker ${keys.broker}, which is not <IP>:<port> with a literal address that is not 0.0.0.0 or ::` };
1281
- }
1282
- build.broker = broker;
1283
- }
1284
- if (keys.recipe !== void 0) {
1285
- const read = readReport(keys.recipe);
1286
- if ("problem" in read) return { ok: false, reason: read.problem };
1287
- build.recipe = read.report;
1288
- build.recipePath = keys.recipe;
1289
- }
1290
- return { ok: true, build };
1291
- }
1292
- function hostEnvironment(build, cliVersion) {
1293
- const report = build.recipe;
1294
- return {
1295
- isolation: build.isolation,
1296
- ...report === void 0 ? {} : {
1297
- recipe: { sourceCommit: report.sourceCommit, key: report.recipeKey, path: report.recipe },
1298
- imageId: report.imageId,
1299
- ignoredProperties: report.ignored.map(({ property, source }) => ({ property, source }))
1300
- },
1301
- cliVersion
1302
- };
1303
- }
1304
- var CD_INTO_WORKDIR = 'cd -- "$0" && exec "$@"';
1305
- function execArgv(workdir, argv) {
1306
- return ["/bin/sh", "-c", CD_INTO_WORKDIR, workdir, ...argv];
1307
- }
1308
- function execCommandLine(exec, workdir, cmdline) {
1309
- return [exec, ...execArgv(workdir, ["/bin/sh", "-c", cmdline])].map(shellQuote).join(" ");
1310
- }
1311
- function proxyUrlFor(build) {
1312
- if (build.broker === void 0) return `http://127.0.0.1:${RELAY_PORT}`;
1313
- return `http://${build.broker}`;
1314
- }
1315
- function withMavenArgs(env, settingsFile, note) {
1316
- const team = env.MAVEN_ARGS;
1317
- if (team !== void 0 && namesGlobalSettings(team)) {
1318
- note?.(MAVEN_NO_PROXY_NOTE);
1319
- return;
1320
- }
1321
- if (settingsFile !== void 0) env.MAVEN_ARGS = mavenArgs(settingsFile, team).value;
1322
- }
1323
- function hostMavenSettings(env, buildDir2, note) {
1324
- if (/\s/.test(buildDir2)) {
1325
- note?.(MAVEN_SPACE_NOTE);
1326
- return void 0;
1327
- }
1328
- if (!existsSync(buildDir2)) return void 0;
1329
- try {
1330
- return writeMavenSettings(buildDir2, env.HTTPS_PROXY, env.NO_PROXY);
1331
- } catch (err) {
1332
- note?.(`the build's Maven settings could not be written, so its Maven gets no proxy from the runner: ${describeCallFailure(err)}`);
1333
- return void 0;
1334
- }
1335
- }
1336
- function execProxyEnvironment(build) {
1337
- const brokerHost = build.broker === void 0 ? void 0 : build.broker.slice(0, build.broker.lastIndexOf(":")).replace(/^\[|\]$/g, "");
1338
- return proxyEnvironment(proxyUrlFor(build), brokerHost);
1339
- }
1340
- var WRITE_MAVEN_SETTINGS = 'd=$(git rev-parse --absolute-git-dir) || exit 1; d="$d/outerlayer/maven"; mkdir -p "$d" && printf "%s" "$1" > "$d/settings.xml" && printf "%s\\n" "$d/settings.xml"';
1341
- var MAVEN_WRITE_TIMEOUT_MS = 1e4;
1342
- function runWithSpawn(spawnFn = spawn) {
1343
- return (file, args, env, timeoutMs) => new Promise((resolve) => {
1344
- let stdout = "";
1345
- let stderr = "";
1346
- let timer;
1347
- let settled = false;
1348
- const finish = (result) => {
1349
- if (settled) return;
1350
- settled = true;
1351
- if (timer !== void 0) clearTimeout(timer);
1352
- resolve({ status: null, signal: null, stdout, stderr, ...result });
1353
- };
1354
- let child;
1355
- try {
1356
- child = spawnFn(file, args, { env, stdio: ["ignore", "pipe", "pipe"] });
1357
- } catch (err) {
1358
- finish({ error: err instanceof Error ? err : new Error(String(err)) });
1359
- return;
1360
- }
1361
- timer = setTimeout(() => {
1362
- child.kill("SIGKILL");
1363
- finish({ error: new Error(`it did not finish in ${timeoutMs / 1e3}s`) });
1364
- }, timeoutMs);
1365
- child.stdout?.on("data", (chunk) => {
1366
- stdout += String(chunk);
1367
- });
1368
- child.stderr?.on("data", (chunk) => {
1369
- stderr += String(chunk);
1370
- });
1371
- child.on("error", (err) => finish({ error: err }));
1372
- child.on("close", (status, signal) => finish({ status, signal }));
1373
- });
1374
- }
1375
- async function deliverMavenSettings(build, workdir, base, run, timeoutMs = MAVEN_WRITE_TIMEOUT_MS) {
1376
- if (build.exec === void 0) return { reason: "the build has no exec" };
1377
- const env = { ...base, ...execProxyEnvironment(build) };
1378
- const ran = await run(build.exec, execArgv(workdir, ["/bin/sh", "-c", WRITE_MAVEN_SETTINGS, "sh", mavenSettingsXml(env.HTTPS_PROXY, env.NO_PROXY)]), env, timeoutMs);
1379
- if (ran.error !== void 0) return { reason: describeCallFailure(ran.error) };
1380
- const said = ran.stderr.trim().split("\n")[0];
1381
- if (ran.status !== 0) return { reason: `the write exited ${ran.status ?? ran.signal}${said === "" ? "" : `: ${said}`}` };
1382
- const lines = ran.stdout.trim().split("\n");
1383
- const path = lines[lines.length - 1].trim();
1384
- if (!isAbsolute(path)) return { reason: "the write did not report an absolute path" };
1385
- if (/\s/.test(path)) return { reason: MAVEN_SPACE_REASON };
1386
- return { path };
1387
- }
1388
- var MAVEN_SPACE_REASON = "the settings file's path has whitespace in it, which Maven cannot read from MAVEN_ARGS";
1389
- async function deliverExecMaven(build, workdir, base, run, note) {
1390
- if (build?.exec === void 0) return;
1391
- const delivered = await deliverMavenSettings(build, workdir, base, run);
1392
- if ("path" in delivered) build.mavenSettings = delivered.path;
1393
- else note(`the build's Maven gets no proxy from the runner: ${delivered.reason}`);
1394
- }
1395
- function onceNote(write) {
1396
- const seen = /* @__PURE__ */ new Set();
1397
- return (line) => {
1398
- if (seen.has(line)) return;
1399
- seen.add(line);
1400
- write(line);
1401
- };
1402
- }
1403
- function attemptNote(log, tag) {
1404
- return onceNote((line) => log.line(`${tag} ${line}`));
1405
- }
1406
- function hostCommandEnvironment(base, build, config, hooksPath, note) {
1407
- let env = { ...base };
1408
- if (build.exec !== void 0) {
1409
- Object.assign(env, execProxyEnvironment(build));
1410
- withMavenArgs(env, build.mavenSettings, note);
1411
- } else if (build.proxyPort !== void 0) {
1412
- Object.assign(env, proxyEnvironment(`http://127.0.0.1:${build.proxyPort}`));
1413
- env.NODE_OPTIONS = withProxyWarningHidden(env.NODE_OPTIONS);
1414
- withMavenArgs(env, hostMavenSettings(env, build.buildDir, note), note);
1415
- }
1416
- const ports = build.destinations ?? [];
1417
- const portOf = (name) => ports.find((entry) => entry.name === name)?.port;
1418
- (config.build?.destinations ?? []).forEach((destination, index) => {
1419
- const port = portOf(destination.name);
1420
- const address = build.exec !== void 0 ? containerLocalAddress(index) : port === void 0 ? void 0 : `http://127.0.0.1:${port}/`;
1421
- if (address !== void 0) Object.assign(env, destinationEnvironment([destination], () => address));
1422
- });
1423
- if (build.builtIns === true) {
1424
- const credential = claudeCredential(base);
1425
- for (const name of CLAUDE_CREDENTIAL_VARIABLES) delete env[name];
1426
- Object.assign(env, builtInEnvironment((name) => `http://127.0.0.1:${portOf(name) ?? 0}`, credential));
1427
- }
1428
- if (build.exec === void 0 && hooksPath !== void 0) env = withHooksPath(env, hooksPath);
1429
- return env;
1430
- }
1431
- async function startHostServices(input) {
1432
- const { runtime, config, build } = input;
1433
- const destinations = config.build?.destinations ?? [];
1434
- const services = await startBuildServices({
1435
- startTunnel: runtime.startTunnel,
1436
- tunnelOptions: runtime.tunnelOptions,
1437
- buildDir: build.buildDir,
1438
- jobDir: input.jobDir,
1439
- destinations,
1440
- allowHosts: config.build?.allowHosts,
1441
- serve: input.process ? "tcp" : "both",
1442
- proxy: input.process,
1443
- ...input.process ? { builtIns: { gatewayUrl: config.url, itemKey: input.itemKey, claudeUpstream: runtime.claudeUpstream } } : {},
1444
- ports: {
1445
- proxy: build.proxyPort,
1446
- destinations: build.destinations?.filter((d) => !BUILT_IN_NAMES.includes(d.name)).map((d) => d.port),
1447
- builtIns: Object.fromEntries((build.destinations ?? []).filter((d) => BUILT_IN_NAMES.includes(d.name)).map((d) => [d.name, d.port]))
1448
- },
1449
- hostEnv: runtime.hostEnv,
1450
- destinationOptions: runtime.destinationOptions,
1451
- ...input.routeLog === void 0 ? {} : { log: input.routeLog }
1452
- });
1453
- build.proxyPort = services.proxyPort;
1454
- build.destinations = [
1455
- ...destinations.map((destination, index) => ({ name: destination.name, port: services.destinationPorts[index] })),
1456
- ...Object.entries(services.builtInPorts).map(([name, port]) => ({ name, port }))
1457
- ];
1458
- if (input.process) build.builtIns = true;
1459
- runtime.tunnels.set(build.buildId, services);
1460
- if (build.broker !== void 0) await listenOnBroker(services, build.broker);
1461
- return services;
1462
- }
1463
- async function listenOnBroker(tunnel, broker) {
1464
- const parsed = parseBroker(broker);
1465
- if (parsed === void 0) throw new Error(`${broker} is not a broker address`);
1466
- await tunnel.listenTcp({ host: parsed.host, port: parsed.port });
1467
- }
1468
- async function closeHostBuild(runtime, build) {
1469
- const tunnel = runtime.tunnels.get(build.buildId);
1470
- if (tunnel !== void 0) {
1471
- runtime.tunnels.delete(build.buildId);
1472
- await tunnel.close();
1473
- }
1474
- rmSync(build.buildDir, { recursive: true, force: true });
1475
- if (build.workDir !== void 0) rmSync(build.workDir, { recursive: true, force: true });
1476
- }
1477
1227
 
1478
1228
  // src/runner/verdict.ts
1479
1229
  var VERDICT_SETTLE_MS = 5 * 6e4;
@@ -3336,7 +3086,17 @@ async function finishJob(job, jobDirPath, outcome, config, deps, ending) {
3336
3086
  let cleanedUp = true;
3337
3087
  tunnelRecord = vmBuild.runtime.tunnels.get(vmBuild.state.buildId)?.record();
3338
3088
  try {
3339
- await cleanupMicroVm(vmBuild.runtime, vmBuild.state, jobDirPath, (text2) => log.error(`${tag} ${text2}`));
3089
+ await cleanupMicroVm(
3090
+ vmBuild.runtime,
3091
+ vmBuild.state,
3092
+ jobDirPath,
3093
+ (text2) => log.error(`${tag} ${text2}`),
3094
+ (bytes) => {
3095
+ job.buildDiskPeakBytes = bytes;
3096
+ writeJobFile(join(jobDirPath, "job.json"), job);
3097
+ log.line(`${tag} build disk peak ${formatBytes(bytes)}`);
3098
+ }
3099
+ );
3340
3100
  } catch (err) {
3341
3101
  cleanedUp = false;
3342
3102
  log.error(`${tag} cleanup failed: ${describeCallFailure(err)} \xB7 continuing`);
@@ -3787,4 +3547,4 @@ async function stopSender(input) {
3787
3547
  }
3788
3548
  }
3789
3549
 
3790
- export { ALREADY_RELEASED, AttemptLogBook, EXIT_CODE_FILE, GUEST_USAGE_INTERVAL_MS, MICROVM_COMMAND_DIR, RENEW_INTERVAL_SECONDS, appendCommandLog, attemptNote, commandLogOffset, deliverCommitHooks, deliverExecMaven, describeHookEnd, execArgv, execCommandLine, finishJob, foldSample, hookLimitsFor, hostCommandEnvironment, hostEnvironment, inTeardown, isContainerTracked, isGroupAlive, isIdle, isMicroVmTracked, isReadable, isTimedOut, isTracked, isUnfinished, jobEnv, judgeProbe, listAdoptableJobs, listTrackedJobs, listUnreadableJobs, listenOnBroker, microVmCommandLine, microVmOomKills, needsRenew, outcomeFromExitCode, probeCommand, probeMicroVmCommand, provisionEnvironment, provisionMicroVm, provisionProcess, readCpuUsec, readProvisionOut, recoverLostJobs, releaseLease, renewLease, resolveHostBuild, restartSender, retryFailedReleases, runCommand, runHook, runWithSpawn, sampleGuest, serveLease, setStage, startHostServices, startMicroVmCommand, startSender, stopOrphanedMicroVms, unfinishedJobs, vmAlive, workdirProblem, writeGuestGhConfig };
3550
+ export { ALREADY_RELEASED, AttemptLogBook, EXIT_CODE_FILE, GUEST_USAGE_INTERVAL_MS, MICROVM_COMMAND_DIR, RENEW_INTERVAL_SECONDS, appendCommandLog, commandLogOffset, deliverCommitHooks, describeHookEnd, finishJob, foldSample, hookLimitsFor, inTeardown, isContainerTracked, isGroupAlive, isIdle, isMicroVmTracked, isReadable, isTimedOut, isTracked, isUnfinished, jobEnv, judgeProbe, listAdoptableJobs, listTrackedJobs, listUnreadableJobs, microVmCommandLine, microVmOomKills, needsRenew, outcomeFromExitCode, probeCommand, probeMicroVmCommand, provisionMicroVm, provisionProcess, readCpuUsec, readProvisionOut, recoverLostJobs, releaseLease, renewLease, restartSender, retryFailedReleases, runCommand, runHook, sampleGuest, serveLease, setStage, startMicroVmCommand, startSender, stopOrphanedMicroVms, unfinishedJobs, vmAlive, workdirProblem, writeGuestGhConfig };
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { parseSize } from './chunk-YJLHUKYS.js';
3
+ import { DEFAULT_CACHE_DISK, DEFAULT_BUILD_DISK } from './chunk-W2AEL4BJ.js';
4
+ import { parseSize } from './chunk-FR7HWWCF.js';
4
5
  import { isRefusedInConfig, resolveDestinations, isReservedVariable } from './chunk-BALIE3BA.js';
5
6
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
6
7
  import { existsSync, statSync, accessSync, constants, readFileSync } from 'fs';
@@ -72,12 +73,12 @@ var DEFAULT_IDLE_LIMIT_MINUTES = 30;
72
73
  var DEFAULT_CHECK_TIME_LIMIT_MINUTES = 10;
73
74
  var CHECKS_KEYS = ["timeLimitMinutes"];
74
75
  var MAX_CHECK_TIME_LIMIT_MINUTES = 240;
75
- var DEFAULT_BUILD = { memory: "8g", cpus: 4, pids: 4096, disk: "40g", variables: [] };
76
+ var DEFAULT_BUILD = { memory: "8g", cpus: 4, pids: 4096, disk: DEFAULT_BUILD_DISK, cacheDisk: DEFAULT_CACHE_DISK, variables: [] };
76
77
  function imageBuildOf(config) {
77
78
  if (builtinKind(config.hooks.provision) !== "vm") return "host";
78
79
  return config.build?.imageBuild ?? "vm";
79
80
  }
80
- var BUILD_KEYS = ["memory", "cpus", "pids", "disk", "variables", "destinations", "allowHosts", "imageBuild"];
81
+ var BUILD_KEYS = ["memory", "cpus", "pids", "disk", "cacheDisk", "variables", "destinations", "allowHosts", "imageBuild"];
81
82
  var HOUSEKEEPING_KEYS = ["jobsKeepDays", "buildCacheMax", "minFreeDisk"];
82
83
  var DEFAULT_JOBS_KEEP_DAYS = 30;
83
84
  var DEFAULT_BUILD_CACHE_MAX = "20g";
@@ -404,7 +405,7 @@ function resolveBuild(configPath, block) {
404
405
  const near = nearestKey(key, BUILD_KEYS);
405
406
  fail(configPath, `runner.build.${key}`, near ? `is not a key this block accepts; did you mean ${near}?` : "is not a key this block accepts");
406
407
  }
407
- for (const key of ["memory", "disk"]) {
408
+ for (const key of ["memory", "disk", "cacheDisk"]) {
408
409
  const value = given[key];
409
410
  if (value === void 0) continue;
410
411
  if (typeof value !== "string" || parseSize(value) === void 0) fail(configPath, `runner.build.${key}`, 'must be a size such as "8g" or "512m"');
@@ -446,6 +447,7 @@ function resolveBuild(configPath, block) {
446
447
  cpus: given.cpus ?? DEFAULT_BUILD.cpus,
447
448
  pids: given.pids ?? DEFAULT_BUILD.pids,
448
449
  disk: given.disk ?? DEFAULT_BUILD.disk,
450
+ cacheDisk: given.cacheDisk ?? DEFAULT_BUILD.cacheDisk,
449
451
  variables,
450
452
  ...destinations.length === 0 ? {} : { destinations },
451
453
  ...allowHosts === void 0 ? {} : { allowHosts },