@outerlayer/cli 0.34.0-next.20261027190442 → 0.34.0-next.20261028002917

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 (123) hide show
  1. package/dist/{agent-setup-THDNZ5ME.js → agent-setup-6FPE6EYN.js} +6 -6
  2. package/dist/{bridge-MLB57JP6.js → bridge-JGIHPGMY.js} +2 -2
  3. package/dist/{build-25GDCEZ7.js → build-AAQ4PVP2.js} +9 -9
  4. package/dist/{build-disk-NFMQCZM3.js → build-disk-L7JRQA22.js} +7 -7
  5. package/dist/build-info.json +1 -1
  6. package/dist/{builder-OWDGC3VQ.js → builder-LMLAVVVF.js} +6 -6
  7. package/dist/{check-IFHLERRX.js → check-ZULOZVV4.js} +38 -38
  8. package/dist/{chunk-JO4SAEHH.js → chunk-23XAA7YD.js} +2 -2
  9. package/dist/{chunk-7SJNVGVC.js → chunk-32FAPJFD.js} +5 -5
  10. package/dist/{chunk-4HA4S3U2.js → chunk-3E7QAXUW.js} +152 -7
  11. package/dist/{chunk-3FTIUB7I.js → chunk-3X6OSXSB.js} +1 -1
  12. package/dist/{chunk-3RRYEZAC.js → chunk-3XOLOV5A.js} +3 -3
  13. package/dist/{chunk-PMIW6OGQ.js → chunk-4A5OJOCR.js} +9 -9
  14. package/dist/{chunk-NO6E72RM.js → chunk-4J5GRWAY.js} +1 -1
  15. package/dist/{chunk-4QQJTJUN.js → chunk-57WFXHCB.js} +1 -1
  16. package/dist/{chunk-36M4KVBT.js → chunk-5IUC2B6J.js} +2 -2
  17. package/dist/{chunk-7TLGRE5F.js → chunk-5LUN7TTR.js} +2 -2
  18. package/dist/{chunk-OP2L7OXA.js → chunk-6LS62EO4.js} +3 -3
  19. package/dist/{chunk-FVVHQIZR.js → chunk-6OLXDSQ6.js} +1 -1
  20. package/dist/{chunk-AV5T7HV3.js → chunk-6Q7O4MRI.js} +1 -1
  21. package/dist/{chunk-UZIAZXXO.js → chunk-77D5ENBA.js} +1 -1
  22. package/dist/{chunk-FLHBUQ2W.js → chunk-AHWMY3MS.js} +155 -10
  23. package/dist/{chunk-3VJYDWFV.js → chunk-AJTGTSNA.js} +1 -1
  24. package/dist/{chunk-5FHBVV25.js → chunk-BQ4C47K2.js} +7 -7
  25. package/dist/{chunk-EYJRVHBN.js → chunk-BTDBDTUY.js} +2 -2
  26. package/dist/{chunk-X7M73LKT.js → chunk-CM4J53WZ.js} +1 -1
  27. package/dist/{chunk-WX2HW2G2.js → chunk-D3CT6XQ4.js} +10 -3
  28. package/dist/{chunk-HJCNWEQK.js → chunk-D6SH7DWA.js} +2 -2
  29. package/dist/{chunk-LYX2RRSF.js → chunk-EGJY6MBC.js} +2 -2
  30. package/dist/{chunk-T6ALNN3H.js → chunk-F3BGTGQC.js} +1 -1
  31. package/dist/{chunk-BS3OYFAD.js → chunk-G4SOMWXL.js} +1 -1
  32. package/dist/{chunk-BS4CZMT6.js → chunk-GET5HKLM.js} +1 -1
  33. package/dist/{chunk-6IMQXBTZ.js → chunk-GJYGOFF3.js} +5 -5
  34. package/dist/{chunk-Y4WJ4BLX.js → chunk-GMEXR6PY.js} +6 -6
  35. package/dist/{chunk-JWMJMQRF.js → chunk-GXMMILQ4.js} +4 -4
  36. package/dist/{chunk-WR2GRWK3.js → chunk-I4YOWQH7.js} +1 -1
  37. package/dist/{chunk-S5U6RKQX.js → chunk-ILTVAD5Y.js} +47 -176
  38. package/dist/{chunk-QRIE4JZE.js → chunk-JXY66VYX.js} +2 -2
  39. package/dist/{chunk-CMMEJJTL.js → chunk-KTVZ7TZY.js} +2 -2
  40. package/dist/{chunk-GMKDAF37.js → chunk-L2OARQKP.js} +17 -98
  41. package/dist/{chunk-CFJOONWM.js → chunk-LBKCYEJT.js} +1 -1
  42. package/dist/{chunk-OHTMTMFX.js → chunk-NBETYM32.js} +4 -4
  43. package/dist/{chunk-MXAYUZJF.js → chunk-NCKH3KCM.js} +5 -5
  44. package/dist/{chunk-RCAMBC3H.js → chunk-NOEJGR4X.js} +2 -2
  45. package/dist/{chunk-62URQYCB.js → chunk-PAGB3DCI.js} +1 -1
  46. package/dist/{chunk-Y7MF32DM.js → chunk-PBI4CM4M.js} +67 -60
  47. package/dist/{chunk-JVNQNKHV.js → chunk-PHIQHIRJ.js} +1 -1
  48. package/dist/{chunk-7Q7GQELE.js → chunk-PPQTTJSW.js} +5 -5
  49. package/dist/{chunk-GPO7F757.js → chunk-QJ2SNBHL.js} +1 -1
  50. package/dist/{chunk-W246VXU4.js → chunk-QNF7LT7W.js} +2 -2
  51. package/dist/{chunk-Z4LFCJT6.js → chunk-SWCOWG2C.js} +2 -2
  52. package/dist/{chunk-SKAML7GB.js → chunk-SYMBXSAT.js} +3 -3
  53. package/dist/{chunk-5ARXP3BP.js → chunk-UEDRRWZ3.js} +3 -3
  54. package/dist/{chunk-LSFP57LI.js → chunk-VB4QD4WN.js} +273 -122
  55. package/dist/{chunk-RJZZFAXS.js → chunk-VKYU4HHW.js} +1 -1
  56. package/dist/{chunk-2YPOSVC7.js → chunk-WEQMLC7P.js} +3 -3
  57. package/dist/{chunk-ANFNZCXZ.js → chunk-WSVE5QGL.js} +4 -4
  58. package/dist/{claude-launcher-LYGS66AC.js → claude-launcher-GGZEWVYJ.js} +1 -1
  59. package/dist/{cli-7S4PEKAV.js → cli-6WPETUBZ.js} +110 -110
  60. package/dist/{command-GQVFZHJ2.js → command-NSTOWAZ6.js} +26 -26
  61. package/dist/{config-5NWSCHIO.js → config-YPUOOZB6.js} +8 -8
  62. package/dist/{connect-cmd-HB3K3AHE.js → connect-cmd-RPEEANNE.js} +5 -5
  63. package/dist/{container-start-WRD3YZQR.js → container-start-OOBTGHWF.js} +32 -32
  64. package/dist/{context-show-cmd-RJIQS2KF.js → context-show-cmd-R5WCECOT.js} +6 -6
  65. package/dist/{control-plane-launch-TS4DFJF4.js → control-plane-launch-55CJGYBK.js} +5 -5
  66. package/dist/{demo-record-cmd-VVZGUCWB.js → demo-record-cmd-SFOWQPL7.js} +4 -4
  67. package/dist/{demo-voice-cmd-3ADGIWK6.js → demo-voice-cmd-ZOBRVHOK.js} +12 -12
  68. package/dist/{docker-5VGCFZV2.js → docker-VPJW5LXB.js} +6 -6
  69. package/dist/{doctor-N4I6IEKP.js → doctor-O2EJAPZB.js} +70 -27
  70. package/dist/{emit-artifact-cmd-WJT7AXTZ.js → emit-artifact-cmd-HBFYBXJR.js} +10 -10
  71. package/dist/{emit-criteria-cmd-45IYB535.js → emit-criteria-cmd-TPUL7M2R.js} +7 -7
  72. package/dist/{emit-demo-cmd-AIIQNPXS.js → emit-demo-cmd-5CUT7W3R.js} +12 -12
  73. package/dist/{emit-finding-cmd-6YTJK2NA.js → emit-finding-cmd-IKHGMACP.js} +7 -7
  74. package/dist/{emit-result-cmd-TZGFY743.js → emit-result-cmd-F7CI6SNZ.js} +9 -9
  75. package/dist/{emit-step-cmd-LGBTIAXC.js → emit-step-cmd-DVEKGHK7.js} +7 -7
  76. package/dist/{exec-client-LR67CA24.js → exec-client-H2JG36OS.js} +3 -3
  77. package/dist/find-unit-ACTOZVVS.js +19 -0
  78. package/dist/{findings-cmd-ETJXUDQI.js → findings-cmd-ODKZ462L.js} +7 -7
  79. package/dist/{fleet-readiness-MYIMDBF7.js → fleet-readiness-UHCBNW6A.js} +5 -5
  80. package/dist/{governing-source-GBJTVMK2.js → governing-source-SRECHKPR.js} +9 -9
  81. package/dist/{guest-init-GXPOW53F.js → guest-init-6FUC4XZX.js} +4 -4
  82. package/dist/{hook-fast-5WOGLR7V.js → hook-fast-WM6YZVBJ.js} +1 -1
  83. package/dist/{host-checks-33ZTDTSH.js → host-checks-FLIHLR35.js} +30 -30
  84. package/dist/{pending-6DDSCXUD.js → host-key-OSWPVMIA.js} +3 -3
  85. package/dist/{image-tag-OYHGRHVV.js → image-tag-LF3NEGSL.js} +3 -3
  86. package/dist/index.js +4 -4
  87. package/dist/{init-OXCOPKHP.js → init-LPD75DCX.js} +23 -23
  88. package/dist/{init-2YOAKLDN.js → init-OX677NNB.js} +23 -23
  89. package/dist/{init-cmd-BUWWUQKM.js → init-cmd-ZCLVC5RR.js} +10 -10
  90. package/dist/{init-update-TXQHBY3H.js → init-update-POKSLQDQ.js} +8 -8
  91. package/dist/{install-cmd-VZGXSS73.js → install-cmd-6SQVZEXL.js} +5 -5
  92. package/dist/{logs-42QPBCMC.js → logs-QHXZTSKZ.js} +2 -2
  93. package/dist/{loop-M3XDFD6O.js → loop-WM62DR42.js} +37 -37
  94. package/dist/{machine-3BI2SGAK.js → machine-7VPFAC6L.js} +23 -23
  95. package/dist/{mcp-serve-cmd-LYJQO6U4.js → mcp-serve-cmd-J32K42HM.js} +4 -4
  96. package/dist/{paths-QLFRPIKS.js → paths-4ZGWWNTG.js} +2 -2
  97. package/dist/{host-key-GAZM4EOH.js → pending-CRXJKKKI.js} +3 -3
  98. package/dist/{pidfile-WLZ427QQ.js → pidfile-VLZPRIBZ.js} +3 -3
  99. package/dist/{record-WGCMQLQS.js → record-4ZJPJTWO.js} +3 -3
  100. package/dist/{runner-env-6FSJOSWS.js → runner-env-W53VDVOK.js} +10 -10
  101. package/dist/{runner-identity-XODZ7YBP.js → runner-identity-BH42S2MU.js} +6 -6
  102. package/dist/{runner-key-KMTC4NCQ.js → runner-key-ESAZRV3A.js} +23 -23
  103. package/dist/{session-sender-U54EQJNR.js → session-sender-UB45MUKV.js} +10 -10
  104. package/dist/{spec-cmd-EM24GTAM.js → spec-cmd-H5B55O5L.js} +8 -8
  105. package/dist/{status-WVCQCBDQ.js → status-L2OYAZHY.js} +30 -30
  106. package/dist/{sync-cmd-Y5RKWVF7.js → sync-cmd-IWA5ZTI2.js} +9 -9
  107. package/dist/{update-steps-2D4YQAW2.js → update-steps-FWQ5ASZ6.js} +31 -31
  108. package/dist/{watch-X5VYY4LH.js → watch-NOEBVS6U.js} +9 -9
  109. package/dist/{work-claim-cmd-IU3YJQKR.js → work-claim-cmd-7P7U3OQ6.js} +14 -14
  110. package/dist/{work-cmd-LUKJHAMH.js → work-cmd-77GUT7LY.js} +7 -7
  111. package/dist/{work-comment-cmd-BDNFAVKL.js → work-comment-cmd-VS3BSPGM.js} +8 -8
  112. package/dist/{work-demo-cmd-GPDJHU6F.js → work-demo-cmd-S3GXBYIA.js} +7 -7
  113. package/dist/{work-logs-cmd-B6EX4RPE.js → work-logs-cmd-6BXIINCM.js} +7 -7
  114. package/dist/{work-open-pr-cmd-TRXDCMSG.js → work-open-pr-cmd-EPOFWJDC.js} +8 -8
  115. package/dist/{work-pr-cmd-5GUR5SIU.js → work-pr-cmd-DYSYOP74.js} +7 -7
  116. package/dist/{work-proofs-cmd-5BYAAW3H.js → work-proofs-cmd-DS2VX4E4.js} +8 -8
  117. package/dist/{work-proofs-record-USD4JWFP.js → work-proofs-record-LIQGUDWH.js} +15 -15
  118. package/dist/{work-stop-cmd-J47GZB2N.js → work-stop-cmd-HYQTDNUY.js} +7 -7
  119. package/package.json +1 -1
  120. package/skill-pack/maintained/outerlayer-build/SKILL.md +8 -0
  121. package/skill-pack/maintained/outerlayer-build/references/agent-briefs.md +8 -0
  122. package/skill-pack/maintained/outerlayer-build/references/review-loop.md +2 -2
  123. package/dist/find-unit-YGDFVHVU.js +0 -19
@@ -1,30 +1,30 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { sha256OfFile, downloadPinned, VoiceDownloadError } from './chunk-2PGI6RDE.js';
4
- import { readDefaultBranchHead, cloneRepository, buildRepositoryImage, prepareImageBuild, KEY_PREFIX, TAG_HOST, SHARED_OWNER, SHARED_NAME, metadataFromLabels, writeRecord } from './chunk-5FHBVV25.js';
5
- import { FETCHED_DIR, toolsDockerfile, FETCHED_FFMPEG, FETCHED_GH, FETCHED_TINI, FETCHED_HEADLESS_SHELL, FETCHED_PLAYWRIGHT_FFMPEG, FETCHED_VOICE_DIR } from './chunk-CMMEJJTL.js';
4
+ import { readDefaultBranchHead, cloneRepository, buildRepositoryImage, prepareImageBuild, KEY_PREFIX, TAG_HOST, SHARED_OWNER, SHARED_NAME, metadataFromLabels, writeRecord } from './chunk-BQ4C47K2.js';
5
+ import { FETCHED_DIR, toolsDockerfile, FETCHED_FFMPEG, FETCHED_GH, FETCHED_TINI, FETCHED_HEADLESS_SHELL, FETCHED_PLAYWRIGHT_FFMPEG, FETCHED_VOICE_DIR } from './chunk-KTVZ7TZY.js';
6
6
  import { currentCliBuild } from './chunk-OGFGZQA3.js';
7
- import { runExec, execCapture, waitForAgent } from './chunk-JVNQNKHV.js';
8
- import { GUEST_CID, linkVsockSockets } from './chunk-BS3OYFAD.js';
9
- import { retrySend, describeCallFailure, keepStagedContext, controlPlaneTokenFailure, refusalCode, resolveGoverningSource, prefetchGovernedContext, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, shimScript, WORKFLOW_PERMISSION_REASON } from './chunk-7Q7GQELE.js';
10
- import { runnerImageVersion } from './chunk-CFJOONWM.js';
11
- import { hasStoredCredential, AGENT_COMMANDS, storeClaudeCredential, credentialFromStdin, isAgentName } from './chunk-OP2L7OXA.js';
12
- import { optionalEgress, runnerCredentialProblem, builtinKind, allowHostProblem, systemClock, emptyEgressCounts, hostAllowed } from './chunk-JWMJMQRF.js';
13
- import { formatBytes, allocatedBytes } from './chunk-LYX2RRSF.js';
14
- import { createDockerHost, builderSpec, runnerLabelValue, RUNNER_LABEL, BUILD_LABEL, prepareRunArgs, containerRunArgs, HASH_ARGV, parseProgramHash, JUDGE_PROGRAM, containerExecArgs, childEnvironment, readDu, JUDGE_DIR, MAX_ITEMS_BYTES, JUDGE_ITEMS, MAX_REPORT_BYTES, JUDGE_REPORT, spawnRun } from './chunk-FLHBUQ2W.js';
15
- import { RecipeError, DOCKER_FEATURE, universalImagePending, writeSanitizedRecipe, classifyProperties } from './chunk-X7M73LKT.js';
16
- import { firecrackerArch, MICROVM_ARCHES, FIRECRACKER_VERSION, hostHelperPinned, CLAUDE_CODE_VERSION, builderDiskPinned, guestAssetsPinned, GUEST_HELPER_SHA256, GUEST_ASSETS_BASE_URL, GUEST_KERNEL_SHA256, JAILER_BINARY_SHA256, FIRECRACKER_BINARY_SHA256, FIRECRACKER_SHA256, GUEST_ASSETS_VERSION, BUILDER_DISK_VERSION, universalImagePinned, UNIVERSAL_IMAGE, UNIVERSAL_IMAGE_DIGEST, UNIVERSAL_IMAGE_REPOSITORY, UNIVERSAL_IMAGE_SOURCE, FFMPEG_STATIC, FFMPEG_BUILD_TAG, GH_SHA256, GH_VERSION, TINI_SHA256, TINI_VERSION, HEADLESS_SHELL, HEADLESS_SHELL_BASE_URL, PLAYWRIGHT_FFMPEG, PLAYWRIGHT_FFMPEG_BASE_URL, VOICE_PACK_FILES, BUILDER_DISK_SHA256, BUILDER_DISK_BASE_URL, DEFAULT_BASE_IMAGE } from './chunk-WX2HW2G2.js';
7
+ import { runExec, execCapture, waitForAgent } from './chunk-PHIQHIRJ.js';
8
+ import { GUEST_CID, linkVsockSockets } from './chunk-G4SOMWXL.js';
9
+ import { retrySend, describeCallFailure, keepStagedContext, controlPlaneTokenFailure, refusalCode, resolveGoverningSource, prefetchGovernedContext, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, shimScript, WORKFLOW_PERMISSION_REASON } from './chunk-PPQTTJSW.js';
10
+ import { runnerImageVersion } from './chunk-LBKCYEJT.js';
11
+ import { hasStoredCredential, AGENT_COMMANDS, storeClaudeCredential, credentialFromStdin, isAgentName } from './chunk-6LS62EO4.js';
12
+ import { optionalEgress, runnerCredentialProblem, builtinKind, allowHostProblem, systemClock, emptyEgressCounts, hostAllowed } from './chunk-GXMMILQ4.js';
13
+ import { formatBytes, allocatedBytes } from './chunk-EGJY6MBC.js';
14
+ import { NETWORK_HELPER_MEMORY, createDockerHost, builderSpec, runnerLabelValue, RUNNER_LABEL, BUILD_LABEL, prepareRunArgs, networkHelperName, containerRunArgs, HASH_ARGV, parseProgramHash, JUDGE_PROGRAM, mountableHome, homeCopyRunArgs, containerExecArgs, childEnvironment, readDu, JUDGE_DIR, MAX_ITEMS_BYTES, JUDGE_ITEMS, MAX_REPORT_BYTES, JUDGE_REPORT, NETWORK_READY_FILE, spawnRun, identityRunArgs, parseIdentity, networkHelperRunArgs } from './chunk-AHWMY3MS.js';
15
+ import { RecipeError, DOCKER_FEATURE, universalImagePending, writeSanitizedRecipe, classifyProperties } from './chunk-CM4J53WZ.js';
16
+ import { firecrackerArch, MICROVM_ARCHES, FIRECRACKER_VERSION, hostHelperPinned, CLAUDE_CODE_VERSION, builderDiskPinned, guestAssetsPinned, GUEST_HELPER_SHA256, GUEST_ASSETS_BASE_URL, GUEST_KERNEL_SHA256, JAILER_BINARY_SHA256, FIRECRACKER_BINARY_SHA256, FIRECRACKER_SHA256, GUEST_ASSETS_VERSION, BUILDER_DISK_VERSION, networkHelperPinned, NETWORK_HELPER_SHA256, universalImagePinned, UNIVERSAL_IMAGE, UNIVERSAL_IMAGE_DIGEST, UNIVERSAL_IMAGE_REPOSITORY, UNIVERSAL_IMAGE_SOURCE, FFMPEG_STATIC, FFMPEG_BUILD_TAG, GH_SHA256, GH_VERSION, TINI_SHA256, TINI_VERSION, HEADLESS_SHELL, HEADLESS_SHELL_BASE_URL, PLAYWRIGHT_FFMPEG, PLAYWRIGHT_FFMPEG_BASE_URL, VOICE_PACK_FILES, BUILDER_DISK_SHA256, BUILDER_DISK_BASE_URL, DEFAULT_BASE_IMAGE } from './chunk-D3CT6XQ4.js';
17
17
  import { startTimeOf, isSameProcess } from './chunk-JBJTC3UU.js';
18
- import { postJson, WorkCommandError, getJson } from './chunk-6IMQXBTZ.js';
18
+ import { postJson, WorkCommandError, getJson } from './chunk-GJYGOFF3.js';
19
19
  import { sanitizeTerminal } from './chunk-IXPH4EXK.js';
20
- import { signerFor } from './chunk-RJZZFAXS.js';
20
+ import { signerFor } from './chunk-VKYU4HHW.js';
21
21
  import { sharedSkillNames, skillConflictMessage } from './chunk-FGF52V4V.js';
22
22
  import { versionAtLeast, MINIMUM_CLAUDE_VERSION } from './chunk-HCVLP7XA.js';
23
23
  import { MIN_SCRUBBED_LITERAL, setCustomScrubbers, setLocalIdentity, setRepoRoot, parseTranscript, scrubDeep, scrubText } from './chunk-A6PJSNP6.js';
24
24
  import { orderSessions, extractFacts, sessionsToTimeline } from './chunk-XFJ7YOPD.js';
25
25
  import { downconvertSession } from './chunk-DINRXUQA.js';
26
- import { vmAssetsDir, RUNNER_DIR_MODE, rootfsPathFor, diskTemplatesDir, RUNNER_FILE_MODE, buildsDir, buildDir, runnerDir, deliveryDir, ghConfigDir, runnerDirOfBuild, spoolDir, mirrorDir, SHIM_DIR, vsockPath, builderCacheDiskPath, builderConsolePath } from './chunk-3VJYDWFV.js';
27
- import { claudeCredential, parseIsolation, proxyEnvironment, withProxyWarningHidden, containerLocalAddress, destinationEnvironment, CLAUDE_CREDENTIAL_VARIABLES, builtInEnvironment, withHooksPath, startBuildServices, BUILT_IN_NAMES, repositoriesOf, primaryOf, RELAY_PORT, repositoryPath, CHECKOUT_DIR, lifecycleWorkdir, buildEnvironment, writeBuildMavenSettings, checkEnvironment, AGENT_CREDENTIAL_MISSING, mavenSettingsXml, namesGlobalSettings, MAVEN_NO_PROXY_NOTE, mavenArgs, MAVEN_SPACE_NOTE, writeMavenSettings, checkoutPath, nodeAcceptsProxyWarningFlag, PROXY_WARNING_FLAG, JOB_MOUNT, realFdStorePort } from './chunk-GMKDAF37.js';
26
+ import { vmAssetsDir, RUNNER_DIR_MODE, rootfsPathFor, diskTemplatesDir, RUNNER_FILE_MODE, buildsDir, buildDir, runnerDir, deliveryDir, ghConfigDir, runnerDirOfBuild, spoolDir, mirrorDir, SHIM_DIR, vsockPath, builderCacheDiskPath, builderConsolePath } from './chunk-AJTGTSNA.js';
27
+ import { claudeCredential, parseIsolation, proxyEnvironment, withProxyWarningHidden, containerLocalAddress, destinationEnvironment, CLAUDE_CREDENTIAL_VARIABLES, builtInEnvironment, withHooksPath, startBuildServices, BUILT_IN_NAMES, repositoriesOf, primaryOf, RELAY_PORT, repositoryPath, CHECKOUT_DIR, lifecycleWorkdir, buildEnvironment, checkEnvironment, AGENT_CREDENTIAL_MISSING, checkoutPath, JOB_MOUNT, realFdStorePort } from './chunk-L2OARQKP.js';
28
28
  import { RELAY_USER, RELAY_ID, UNKNOWN_TRANSPORT_REASON, DOCKER_DESKTOP_REASON, MAX_MALFORMED_SESSIONS, MALFORMED_REASON, JOIN_WAIT_MS, MAX_OPEN_STREAMS, STREAM_RESET_RATE, STREAM_RESET_BURST, STREAM_WINDOW, SESSION_WINDOW, targetOfPath } from './chunk-MESOOLF4.js';
29
29
  import { spawn, spawnSync } from 'child_process';
30
30
  import { mkdirSync, existsSync, readFileSync, mkdtempSync, rmSync, chmodSync, truncateSync, statSync, accessSync, constants, readdirSync, writeFileSync, lstatSync, copyFileSync, renameSync, rmdirSync, unlinkSync, linkSync, openSync, closeSync, cpSync, writeSync, appendFileSync, createWriteStream, createReadStream } from 'fs';
@@ -166,9 +166,10 @@ function builderDiskPin(arch) {
166
166
  return { url: `${BUILDER_DISK_BASE_URL}/builder-rootfs-${arch}.ext4`, sha256: BUILDER_DISK_SHA256[arch] };
167
167
  }
168
168
  var sha256Of = (bytes) => createHash("sha256").update(bytes).digest("hex");
169
- function pinProblem(file, expected, actual, where) {
169
+ var MICROVM_STOPS = "no microVM build starts";
170
+ function pinProblem(file, expected, actual, where, stops = MICROVM_STOPS) {
170
171
  const release = file.startsWith("vmlinux-") || file.startsWith("outerlayer-guest-") ? ` (guest assets release ${GUEST_ASSETS_VERSION})` : file.startsWith("builder-rootfs-") ? ` (builder root disk release ${BUILDER_DISK_VERSION})` : "";
171
- return new AssetError(file, `${file} ${where} has sha256 ${actual}, not the ${expected} this release pins${release}, so no microVM build starts`);
172
+ return new AssetError(file, `${file} ${where} has sha256 ${actual}, not the ${expected} this release pins${release}, so ${stops}`);
172
173
  }
173
174
  function writeAtomic(path, bytes, mode) {
174
175
  const temp = `${path}.${process.pid}.tmp`;
@@ -189,16 +190,16 @@ function keptPath(dir, sha256, name) {
189
190
  mkdirSync(join(dir, sha256), { recursive: true, mode: RUNNER_DIR_MODE });
190
191
  return join(dir, sha256, name);
191
192
  }
192
- async function ensureFile(dir, file, pin, fetchImpl, mode) {
193
+ async function ensureFile(dir, file, pin, fetchImpl, mode, stops = MICROVM_STOPS) {
193
194
  const path = keptPath(dir, pin.sha256, file);
194
195
  if (existsSync(path)) {
195
196
  const actual2 = sha256Of(readFileSync(path));
196
- if (actual2 !== pin.sha256) throw pinProblem(file, pin.sha256, actual2, `at ${path}`);
197
+ if (actual2 !== pin.sha256) throw pinProblem(file, pin.sha256, actual2, `at ${path}`, stops);
197
198
  return path;
198
199
  }
199
200
  const bytes = await download(file, pin.url, fetchImpl);
200
201
  const actual = sha256Of(bytes);
201
- if (actual !== pin.sha256) throw pinProblem(file, pin.sha256, actual, `downloaded from ${pin.url}`);
202
+ if (actual !== pin.sha256) throw pinProblem(file, pin.sha256, actual, `downloaded from ${pin.url}`, stops);
202
203
  writeAtomic(path, bytes, mode);
203
204
  return path;
204
205
  }
@@ -282,6 +283,17 @@ async function ensureJailer(options) {
282
283
  }
283
284
  return jailer;
284
285
  }
286
+ async function ensureNetworkHelper(options) {
287
+ const arch = options.arch ?? firecrackerArch(process.arch);
288
+ const file = `outerlayer-guest-${arch}`;
289
+ if (options.pin === void 0 && !networkHelperPinned(arch)) {
290
+ throw new AssetError(file, `no network helper is pinned for ${arch} in this release of the CLI, so container builds cannot start on this host`);
291
+ }
292
+ const pin = options.pin ?? { url: `${GUEST_ASSETS_BASE_URL}/${file}`, sha256: NETWORK_HELPER_SHA256[arch] };
293
+ const dir = vmAssetsDir(options.runnerDir);
294
+ mkdirSync(dir, { recursive: true, mode: RUNNER_DIR_MODE });
295
+ return { path: await ensureFile(dir, file, pin, options.fetchImpl ?? fetch, 493, "no container build starts"), sha256: pin.sha256 };
296
+ }
285
297
  async function ensureBuilderDisk(options) {
286
298
  const arch = options.arch ?? firecrackerArch(process.arch);
287
299
  if (!MICROVM_ARCHES.includes(arch)) throw new AssetError("builder-rootfs", `no builder root disk is pinned for ${arch}, so microVM image builds run on ${MICROVM_ARCHES.join(" or ")} hosts only`);
@@ -315,6 +327,10 @@ function createContainerHost(deps = {}) {
315
327
  const result = await run("docker", ["info", "--format", "{{.OperatingSystem}}"]);
316
328
  return result.status === 0 && result.stdout.trim() !== "" ? result.stdout.trim() : null;
317
329
  },
330
+ async architecture() {
331
+ const result = await run("docker", ["version", "--format", "{{.Server.Arch}}"]);
332
+ return result.status === 0 && result.stdout.trim() !== "" ? result.stdout.trim() : null;
333
+ },
318
334
  async imageConfig(imageId) {
319
335
  const result = await run("docker", ["image", "inspect", "--format", "{{json .Config}}", imageId]);
320
336
  return result.status === 0 ? parseImageConfig(result.stdout) : { user: "", env: {} };
@@ -369,6 +385,13 @@ function createContainerHost(deps = {}) {
369
385
  },
370
386
  remove(container) {
371
387
  return run("docker", ["rm", "--force", "--volumes", container]);
388
+ },
389
+ logs(container, lines) {
390
+ return run("docker", ["logs", "--tail", String(lines), container]);
391
+ },
392
+ async oomKilled(container) {
393
+ const result = await run("docker", ["inspect", "--format", "{{.State.OOMKilled}}", container]);
394
+ return result.status === 0 && result.stdout.trim() === "true";
372
395
  }
373
396
  };
374
397
  }
@@ -1279,6 +1302,7 @@ async function startTunnel(socketPath, opts = {}) {
1279
1302
  } else {
1280
1303
  refusalKeys.add(key);
1281
1304
  refusals.push({ host, address, range });
1305
+ if (range !== CONNECTION_RATE_RANGE && range !== OPEN_CONNECTIONS_RANGE) opts.log?.(`tunnel refused ${host} (${range === NOT_ALLOWED_RANGE ? "not in runner.build.allowHosts" : range})`);
1282
1306
  }
1283
1307
  persist();
1284
1308
  };
@@ -1604,6 +1628,55 @@ ${body}`);
1604
1628
  })
1605
1629
  };
1606
1630
  }
1631
+ var MAVEN_DIR = "maven";
1632
+ var MAVEN_SETTINGS_FILE = "settings.xml";
1633
+ var MAVEN_NO_PROXY_NOTE = "MAVEN_ARGS names its own global settings file, so the build's Maven gets no proxy from the runner";
1634
+ var MAVEN_SPACE_NOTE = "the build's directory has whitespace in its path, which Maven cannot read from MAVEN_ARGS, so its Maven gets no proxy from the runner";
1635
+ function namesGlobalSettings(args) {
1636
+ return args.split(/\s+/).some((token) => token === "--global-settings" || token.startsWith("--global-settings=") || token === "-gs" || token.startsWith("-gs="));
1637
+ }
1638
+ function escapeXml(text) {
1639
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
1640
+ }
1641
+ function mavenSettingsXml(proxyUrl, noProxy) {
1642
+ const url = new URL(proxyUrl);
1643
+ const host = escapeXml(url.hostname.replace(/^\[|\]$/g, ""));
1644
+ const nonProxyHosts = escapeXml(noProxy.split(",").filter((entry) => entry !== "").join("|"));
1645
+ const proxy = (protocol) => [
1646
+ " <proxy>",
1647
+ ` <id>outerlayer-${protocol}</id>`,
1648
+ " <active>true</active>",
1649
+ ` <protocol>${protocol}</protocol>`,
1650
+ ` <host>${host}</host>`,
1651
+ ` <port>${url.port}</port>`,
1652
+ ` <nonProxyHosts>${nonProxyHosts}</nonProxyHosts>`,
1653
+ " </proxy>"
1654
+ ].join("\n");
1655
+ return [
1656
+ '<?xml version="1.0" encoding="UTF-8"?>',
1657
+ '<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0">',
1658
+ " <proxies>",
1659
+ proxy("http"),
1660
+ proxy("https"),
1661
+ " </proxies>",
1662
+ "</settings>",
1663
+ ""
1664
+ ].join("\n");
1665
+ }
1666
+ function writeMavenSettings(buildDir2, proxyUrl, noProxy) {
1667
+ const dir = join(buildDir2, MAVEN_DIR);
1668
+ mkdirSync(dir, { recursive: true });
1669
+ const file = join(dir, MAVEN_SETTINGS_FILE);
1670
+ writeFileSync(file, mavenSettingsXml(proxyUrl, noProxy));
1671
+ return file;
1672
+ }
1673
+ function mavenArgs(settingsFile, team) {
1674
+ const own = team?.trim() ?? "";
1675
+ if (own !== "" && namesGlobalSettings(own)) return { value: team, skipped: true };
1676
+ return { value: own === "" ? `--global-settings ${settingsFile}` : `--global-settings ${settingsFile} ${own}`, skipped: false };
1677
+ }
1678
+
1679
+ // src/runner/host-hooks.ts
1607
1680
  function provisionEnvironment(base, input) {
1608
1681
  return {
1609
1682
  ...base,
@@ -1764,8 +1837,8 @@ async function deliverMavenSettings(build, workdir, base, run, timeoutMs = MAVEN
1764
1837
  const env = { ...base, ...execProxyEnvironment(build) };
1765
1838
  const ran = await run(build.exec, execArgv(workdir, ["/bin/sh", "-c", WRITE_MAVEN_SETTINGS, "sh", mavenSettingsXml(env.HTTPS_PROXY, env.NO_PROXY)]), env, timeoutMs);
1766
1839
  if (ran.error !== void 0) return { reason: describeCallFailure(ran.error) };
1767
- const said = ran.stderr.trim().split("\n")[0];
1768
- if (ran.status !== 0) return { reason: `the write exited ${ran.status ?? ran.signal}${said === "" ? "" : `: ${said}`}` };
1840
+ const said2 = ran.stderr.trim().split("\n")[0];
1841
+ if (ran.status !== 0) return { reason: `the write exited ${ran.status ?? ran.signal}${said2 === "" ? "" : `: ${said2}`}` };
1769
1842
  const lines = ran.stdout.trim().split("\n");
1770
1843
  const path = lines[lines.length - 1].trim();
1771
1844
  if (!isAbsolute(path)) return { reason: "the write did not report an absolute path" };
@@ -2894,6 +2967,15 @@ function lifecycleFailureReason(step, exitCode) {
2894
2967
  return `lifecycle command ${step.name} (${step.source}) exited ${exitCode}`;
2895
2968
  }
2896
2969
 
2970
+ // src/runner/command-output.ts
2971
+ function firstLine4(text) {
2972
+ return text.trim().split("\n")[0] ?? "";
2973
+ }
2974
+ function said(output) {
2975
+ const line2 = firstLine4(output);
2976
+ return line2 === "" ? "" : `: ${line2}`;
2977
+ }
2978
+
2897
2979
  // src/runner/runtimes.ts
2898
2980
  var RUNTIMES = ["node", "python", "go", "rust", "ruby", "java"];
2899
2981
  var MANIFESTS = {
@@ -2910,10 +2992,6 @@ var MANIFESTS = {
2910
2992
  var IMAGE_CONFIG = "/etc/mise/config.toml";
2911
2993
  var RUST_PIN_FILES = ["rust-toolchain.toml", "rust-toolchain"];
2912
2994
  var REFUSALS_NAMED2 = 3;
2913
- var PLAIN = { withoutProxyWarning: true };
2914
- function firstLine4(text) {
2915
- return text.trim().split("\n")[0] ?? "";
2916
- }
2917
2995
  function toolFailure(stderr) {
2918
2996
  for (const l of stderr.split("\n")) {
2919
2997
  if (/^\S+@\S+: /.test(l)) return l;
@@ -2939,7 +3017,7 @@ function parseListing(stdout) {
2939
3017
  }
2940
3018
  }
2941
3019
  async function listing(context) {
2942
- const ran = await context.input.exec(["mise", "ls", "--current", "--json"], context.path, { quiet: true, ...PLAIN });
3020
+ const ran = await context.input.exec(["mise", "ls", "--current", "--json"], context.path, { quiet: true });
2943
3021
  return ran.status === 0 ? parseListing(ran.stdout) : void 0;
2944
3022
  }
2945
3023
  function refusalNote(context) {
@@ -2952,10 +3030,10 @@ function line(context, text) {
2952
3030
  var installWithMise = async (context) => {
2953
3031
  const { input, entry, path } = context;
2954
3032
  context.before = await listing(context) ?? [];
2955
- const installed = await input.exec(["mise", "install"], path, PLAIN);
3033
+ const installed = await input.exec(["mise", "install"], path);
2956
3034
  if (installed.status !== 0) {
2957
3035
  const missing = context.before.filter((r) => !r.installed).map((r) => `${r.tool} ${r.version} (from ${describeSource(r.source, path)})`);
2958
- const what = missing.length === 0 ? `mise install failed in ${entry.repository} (exit ${installed.status})${firstLine4(installed.stderr) === "" ? "" : `: ${firstLine4(installed.stderr)}`}` : `mise could not install ${missing.join(", ")} in ${entry.repository} (exit ${installed.status})${toolFailure(installed.stderr) === "" ? "" : `: ${toolFailure(installed.stderr)}`}`;
3036
+ const what = missing.length === 0 ? `mise install failed in ${entry.repository} (exit ${installed.status})${said(installed.stderr)}` : `mise could not install ${missing.join(", ")} in ${entry.repository} (exit ${installed.status})${toolFailure(installed.stderr) === "" ? "" : `: ${toolFailure(installed.stderr)}`}`;
2959
3037
  return `runtime_install_failed: ${what}${refusalNote(context)}`;
2960
3038
  }
2961
3039
  const after = await listing(context);
@@ -2967,7 +3045,7 @@ var installWithMise = async (context) => {
2967
3045
  var goToolchain = async (context) => {
2968
3046
  if (!context.files.has("go.mod")) return void 0;
2969
3047
  const ran = await context.input.exec(["go", "version"], context.path);
2970
- if (ran.status !== 0) return `runtime_install_failed: go version failed in ${context.entry.repository} (exit ${ran.status})${firstLine4(ran.stderr) === "" ? "" : `: ${firstLine4(ran.stderr)}`}${refusalNote(context)}`;
3048
+ if (ran.status !== 0) return `runtime_install_failed: go version failed in ${context.entry.repository} (exit ${ran.status})${said(ran.stderr)}${refusalNote(context)}`;
2971
3049
  const version = /\bgo(\d+\.\d+(?:\.\d+)?\S*)/.exec(ran.stdout)?.[1];
2972
3050
  line(context, `go ${version ?? firstLine4(ran.stdout)} from go.mod`);
2973
3051
  return void 0;
@@ -2976,7 +3054,7 @@ var rustToolchain = async (context) => {
2976
3054
  const pin = RUST_PIN_FILES.find((file) => context.files.has(file));
2977
3055
  if (pin === void 0) return void 0;
2978
3056
  const ran = await context.input.exec(["rustc", "--version"], context.path);
2979
- if (ran.status !== 0) return `runtime_install_failed: rustc --version failed in ${context.entry.repository} (exit ${ran.status})${firstLine4(ran.stderr) === "" ? "" : `: ${firstLine4(ran.stderr)}`}${refusalNote(context)}`;
3057
+ if (ran.status !== 0) return `runtime_install_failed: rustc --version failed in ${context.entry.repository} (exit ${ran.status})${said(ran.stderr)}${refusalNote(context)}`;
2980
3058
  const version = /\brustc (\S+)/.exec(ran.stdout)?.[1];
2981
3059
  line(context, `rust ${version ?? firstLine4(ran.stdout)} from ${pin}`);
2982
3060
  return void 0;
@@ -2991,7 +3069,6 @@ function unpinnedIn(context) {
2991
3069
  }
2992
3070
  async function provisionRuntimes(input) {
2993
3071
  const unpinned = {};
2994
- let dropProxyWarning = false;
2995
3072
  for (const entry of input.repositories) {
2996
3073
  if (input.aborted?.() === true) return { ok: false, reason: "", aborted: true };
2997
3074
  const path = checkoutPath(entry);
@@ -3010,13 +3087,8 @@ async function provisionRuntimes(input) {
3010
3087
  if (reason !== void 0) return { ok: false, reason };
3011
3088
  }
3012
3089
  unpinned[entry.repository] = unpinnedIn(context);
3013
- const old = context.resolved.find((r) => r.tool === "node" && !nodeAcceptsProxyWarningFlag(r.version));
3014
- if (old !== void 0) {
3015
- dropProxyWarning = true;
3016
- line(context, `leaving ${PROXY_WARNING_FLAG} out of NODE_OPTIONS because node ${old.version} does not accept it`);
3017
- }
3018
3090
  }
3019
- return { ok: true, unpinned, dropProxyWarning };
3091
+ return { ok: true, unpinned };
3020
3092
  }
3021
3093
  function runtimeStepInput(report, services) {
3022
3094
  return report.base === void 0 ? {} : { runtimes: { refusals: () => services.record().refusals } };
@@ -3027,20 +3099,6 @@ function keepUnpinnedRuntimes(state, steps) {
3027
3099
 
3028
3100
  // src/runner/build-steps.ts
3029
3101
  var aborted = () => ({ ok: false, reason: "", aborted: true });
3030
- function firstLine5(text) {
3031
- return text.trim().split("\n")[0] ?? "";
3032
- }
3033
- async function nodeRejectsProxyWarningFlag(repositories, exec, log, tag) {
3034
- for (const entry of repositories) {
3035
- const ran = await exec(["node", "--version"], checkoutPath(entry), { quiet: true, withoutProxyWarning: true });
3036
- if (ran.status !== 0) continue;
3037
- const version = firstLine5(ran.stdout);
3038
- if (nodeAcceptsProxyWarningFlag(version)) continue;
3039
- log.line(`${tag} ${entry.repository}: leaving ${PROXY_WARNING_FLAG} out of NODE_OPTIONS because node ${version} does not accept it`);
3040
- return true;
3041
- }
3042
- return false;
3043
- }
3044
3102
  function gitErrorLine(text) {
3045
3103
  const lines = text.split("\n").map((line2) => line2.trim()).filter((line2) => line2 !== "");
3046
3104
  return lines.find((line2) => /^(fatal|error):/.test(line2)) ?? lines.at(-1) ?? "";
@@ -3059,7 +3117,7 @@ var DELIVER_SCRIPT = [
3059
3117
  var RECORD_SCRIPT = 'd="$(git rev-parse --git-common-dir)" && mkdir -p "$d/outerlayer" && printf "%s" "$1" > "$d/outerlayer/delivery.json"';
3060
3118
  var WRITE_SHIM_SCRIPT = 'mkdir -p "$1" && printf "%s" "$2" > "$1/claude" && chmod 755 "$1/claude"';
3061
3119
  function failure(what, result) {
3062
- return `context_delivery_failed: ${what} (exit ${result.status})${firstLine5(result.stderr) === "" ? "" : `: ${firstLine5(result.stderr)}`}`;
3120
+ return `context_delivery_failed: ${what} (exit ${result.status})${said(result.stderr)}`;
3063
3121
  }
3064
3122
  async function repositorySkills(input, folder) {
3065
3123
  const listed = await input.exec(["ls", "-1", folder], CHECKOUT_DIR, { quiet: true });
@@ -3162,14 +3220,11 @@ async function runBuildSteps(input) {
3162
3220
  }
3163
3221
  if (input.governing !== void 0) await noteIgnoredDevcontainers(input, repositories, input.governing.repository);
3164
3222
  let unpinnedRuntimes;
3165
- const ordered = [{ ...primary, primary: true }, ...repositories.filter((candidate) => candidate.repository !== primary.repository).map((entry) => ({ ...entry, primary: false }))];
3166
3223
  if (input.runtimes !== void 0) {
3224
+ const ordered = [{ ...primary, primary: true }, ...repositories.filter((candidate) => candidate.repository !== primary.repository).map((entry) => ({ ...entry, primary: false }))];
3167
3225
  const chosen = await provisionRuntimes({ repositories: ordered, exec, log, tag, refusals: input.runtimes.refusals, aborted: input.aborted });
3168
3226
  if (!chosen.ok) return chosen.aborted === true ? aborted() : { ok: false, reason: chosen.reason };
3169
3227
  unpinnedRuntimes = chosen.unpinned;
3170
- if (chosen.dropProxyWarning) input.dropProxyWarning?.();
3171
- } else if (input.dropProxyWarning !== void 0 && await nodeRejectsProxyWarningFlag(ordered, exec, log, tag)) {
3172
- input.dropProxyWarning();
3173
3228
  }
3174
3229
  const lifecycleDir = lifecycleWorkdir(repositories, input.governing?.repository);
3175
3230
  for (const step of lifecycleSteps(input.lifecycle)) {
@@ -3224,7 +3279,7 @@ var MAX_TRANSCRIPTS = 500;
3224
3279
  var MAX_TOTAL_TRANSCRIPT_BYTES = 64 * 1024 * 1024;
3225
3280
  var TRANSCRIPT_COPY_MS = 2 * 60 * 1e3;
3226
3281
  var BUILD_HOME = "/build/home";
3227
- function firstLine6(text) {
3282
+ function firstLine5(text) {
3228
3283
  return text.trim().split("\n")[0] ?? "";
3229
3284
  }
3230
3285
  async function copyTranscripts(run, now = Date.now) {
@@ -3236,7 +3291,7 @@ async function copyTranscripts(run, now = Date.now) {
3236
3291
  return { ok: false, reason: describeCallFailure(err) };
3237
3292
  }
3238
3293
  if (listed.status !== 0 && !/No such file or directory/.test(listed.stderr)) {
3239
- return { ok: false, reason: `listing the transcripts failed (exit ${listed.status})${firstLine6(listed.stderr) === "" ? "" : `: ${firstLine6(listed.stderr)}`}` };
3294
+ return { ok: false, reason: `listing the transcripts failed (exit ${listed.status})${firstLine5(listed.stderr) === "" ? "" : `: ${firstLine5(listed.stderr)}`}` };
3240
3295
  }
3241
3296
  const paths = listed.stdout.split("\0").filter((entry) => entry.startsWith(`${TRANSCRIPT_ROOT}/`) && !entry.includes("\n") && !entry.slice(TRANSCRIPT_ROOT.length + 1).split("/").includes("..")).map((entry) => entry.slice(TRANSCRIPT_ROOT.length + 1)).sort();
3242
3297
  const copied = [];
@@ -3253,7 +3308,7 @@ async function copyTranscripts(run, now = Date.now) {
3253
3308
  }
3254
3309
  try {
3255
3310
  const read = await run(["head", "-c", String(MAX_TRANSCRIPT_BYTES + 1), `${TRANSCRIPT_ROOT}/${path}`]);
3256
- if (read.status !== 0) missed.push({ path, reason: `reading it failed (exit ${read.status})${firstLine6(read.stderr) === "" ? "" : `: ${firstLine6(read.stderr)}`}` });
3311
+ if (read.status !== 0) missed.push({ path, reason: `reading it failed (exit ${read.status})${firstLine5(read.stderr) === "" ? "" : `: ${firstLine5(read.stderr)}`}` });
3257
3312
  else if (Buffer.byteLength(read.stdout) > MAX_TRANSCRIPT_BYTES) missed.push({ path, reason: `it is larger than ${MAX_TRANSCRIPT_BYTES / (1024 * 1024)} MiB` });
3258
3313
  else if (total + Buffer.byteLength(read.stdout) > MAX_TOTAL_TRANSCRIPT_BYTES) missed.push({ path, reason: `copying it would take the transcripts past ${MAX_TOTAL_TRANSCRIPT_BYTES / (1024 * 1024)} MiB` });
3259
3314
  else {
@@ -3708,7 +3763,6 @@ var RECEIVE_ARGV = ["/opt/outerlayer/bin/node", "/opt/outerlayer/cli/dist/index.
3708
3763
  var REASON_LINE_MAX = 240;
3709
3764
  var STEPS = {
3710
3765
  gh: "the build's gh configuration",
3711
- maven: "the build's Maven settings",
3712
3766
  "git-hooks": "the commit hooks",
3713
3767
  context: "the staged context",
3714
3768
  "eval-input": "the checks' input"
@@ -4359,6 +4413,67 @@ function createCpuAllocator(cores) {
4359
4413
  }
4360
4414
  };
4361
4415
  }
4416
+ var NETWORK_READY_ATTEMPTS = 60;
4417
+ var NETWORK_READY_PAUSE_MS = 500;
4418
+ var LOG_LINES = 20;
4419
+ async function helperReason(runtime, name) {
4420
+ const logs = await runtime.host.logs(name, LOG_LINES);
4421
+ const lines = `${logs.stdout}
4422
+ ${logs.stderr}`.split("\n").map((line2) => line2.trim());
4423
+ return lines.filter((line2) => line2.startsWith("net: ")).at(-1) ?? lines.filter((line2) => line2 !== "").at(-1) ?? "";
4424
+ }
4425
+ async function waitForNetwork(runtime, name) {
4426
+ for (let attempt = 0; attempt < NETWORK_READY_ATTEMPTS; attempt++) {
4427
+ const probe = await runtime.host.exec({ container: name, user: "0:0", env: { literals: {}, passed: {} }, argv: ["cat", NETWORK_READY_FILE] });
4428
+ if (probe.status === 0) return void 0;
4429
+ const state = await runtime.host.state(name);
4430
+ if (state === "stopped" || state === "missing") {
4431
+ return `the build's network helper container stopped before its network was ready${said(await helperReason(runtime, name))}`;
4432
+ }
4433
+ await runtime.sleep(NETWORK_READY_PAUSE_MS);
4434
+ }
4435
+ return `the build's network helper container was not ready within ${NETWORK_READY_ATTEMPTS * NETWORK_READY_PAUSE_MS / 1e3} seconds${said(await helperReason(runtime, name))}`;
4436
+ }
4437
+ async function startNetworkHelper(runtime, input, logPath) {
4438
+ const started = await runtime.host.run(networkHelperRunArgs(input), { logPath });
4439
+ if (started.status !== 0) {
4440
+ return `starting the build's network helper container failed (exit ${started.status})${said(started.stderr)}`;
4441
+ }
4442
+ return waitForNetwork(runtime, input.name);
4443
+ }
4444
+ async function ensureNetworkReady(runtime, state) {
4445
+ if (state.network === void 0) return void 0;
4446
+ const current = await runtime.host.state(state.network);
4447
+ if (current === "running") return void 0;
4448
+ if (current === "missing") return `the build's network helper container ${state.network} is gone`;
4449
+ const started = await runtime.host.start(state.network);
4450
+ if (started.status !== 0) {
4451
+ return `starting the build's network helper container again failed (exit ${started.status})${said(started.stderr)}`;
4452
+ }
4453
+ return waitForNetwork(runtime, state.network);
4454
+ }
4455
+ async function stoppedHelperReason(runtime, name) {
4456
+ if (await runtime.host.oomKilled(name)) return `the build's network helper container ran out of memory (${NETWORK_HELPER_MEMORY})`;
4457
+ return `the build's network helper container stopped${said(await helperReason(runtime, name))}`;
4458
+ }
4459
+ async function removeNetworkHelper(runtime, state) {
4460
+ if (state.network === void 0) return void 0;
4461
+ const removed = await runtime.host.remove(state.network);
4462
+ if (removed.status !== 0 && !/no such container/i.test(removed.stderr)) return `container ${state.network} was not removed: ${removed.stderr.trim()}`;
4463
+ return void 0;
4464
+ }
4465
+ function kernelHasIpv6(exists = existsSync, platform = process.platform) {
4466
+ return platform !== "linux" || exists("/proc/sys/net/ipv6");
4467
+ }
4468
+ function helperArchOf(engineArch) {
4469
+ if (engineArch === "amd64") return "x86_64";
4470
+ if (engineArch === "arm64") return "aarch64";
4471
+ return engineArch;
4472
+ }
4473
+ async function engineNetworkHelper(host, runnerDir2, ensure = ensureNetworkHelper) {
4474
+ const engine = await host.architecture();
4475
+ return ensure({ runnerDir: runnerDir2, ...engine === null ? {} : { arch: helperArchOf(engine) } });
4476
+ }
4362
4477
 
4363
4478
  // src/runner/container/lease-channel.ts
4364
4479
  var LEASE_SECONDS = 900;
@@ -4409,8 +4524,9 @@ function createContainerRuntime(opts = {}) {
4409
4524
  const { cli, remoteFor } = opts;
4410
4525
  const vm = createMicroVmPorts(opts.vm);
4411
4526
  const sleep = opts.sleep ?? ((ms) => new Promise((resolve2) => setTimeout(resolve2, ms)));
4527
+ const host = opts.host ?? createContainerHost();
4412
4528
  return {
4413
- host: opts.host ?? createContainerHost(),
4529
+ host,
4414
4530
  cpus: opts.cpus ?? createCpuAllocator(usableCpus()),
4415
4531
  tunnels: opts.tunnels ?? /* @__PURE__ */ new Map(),
4416
4532
  relays: opts.relays ?? /* @__PURE__ */ new Map(),
@@ -4446,7 +4562,9 @@ function createContainerRuntime(opts = {}) {
4446
4562
  destinationOptions: opts.destinationOptions,
4447
4563
  claudeUpstream: opts.claudeUpstream,
4448
4564
  vm,
4449
- cliBuild: () => cli ?? currentCliBuild()
4565
+ cliBuild: () => cli ?? currentCliBuild(),
4566
+ networkHelper: opts.networkHelper ?? ((dir) => engineNetworkHelper(host, dir)),
4567
+ ipv6: opts.ipv6 ?? kernelHasIpv6()
4450
4568
  };
4451
4569
  }
4452
4570
  var REPORT_READ_TIMEOUT_MS = 6e4;
@@ -4509,9 +4627,6 @@ function gitRemoteFor(runtime, input) {
4509
4627
  ...input.readOnly === true ? { readOnly: true } : {}
4510
4628
  });
4511
4629
  }
4512
- function firstLine7(text) {
4513
- return text.trim().split("\n")[0] ?? "";
4514
- }
4515
4630
  var NO_ENV = { literals: {}, passed: {} };
4516
4631
  function transportOf(state) {
4517
4632
  const recorded = state.transport;
@@ -4640,6 +4755,12 @@ async function provisionContainer(input) {
4640
4755
  if (unfetched !== void 0) return fail(unfetched);
4641
4756
  }
4642
4757
  const imageRepository = governingSource.kind === "governed" ? governingSource.repository : repository;
4758
+ let networkHelper;
4759
+ try {
4760
+ networkHelper = await runtime.networkHelper(runnerDir(config.configPath));
4761
+ } catch (err) {
4762
+ return fail(err instanceof AssetError ? err.message : `the network helper could not be had: ${describeCallFailure(err)}`);
4763
+ }
4643
4764
  const obtained = await obtainImage({
4644
4765
  config,
4645
4766
  runtime,
@@ -4651,7 +4772,8 @@ async function provisionContainer(input) {
4651
4772
  log,
4652
4773
  aborted: input.aborted,
4653
4774
  deadlineMs: input.deadlineMs,
4654
- now: input.now
4775
+ now: input.now,
4776
+ guestHelper: networkHelper
4655
4777
  });
4656
4778
  if (!obtained.ok) return obtained.aborted === true ? { ok: false, reason: obtained.reason, aborted: true } : fail(obtained.reason);
4657
4779
  const built = obtained.built;
@@ -4711,7 +4833,7 @@ async function provisionContainer(input) {
4711
4833
  }
4712
4834
  return aborted2 ? { ok: false, reason: "ended before provision finished", aborted: true } : fail(reason);
4713
4835
  };
4714
- const dockerFailed = (what, result) => bail(`${what} failed (exit ${result.status})${firstLine7(result.stderr) === "" ? "" : `: ${firstLine7(result.stderr)}`}`);
4836
+ const dockerFailed = (what, result) => bail(`${what} failed (exit ${result.status})${said(result.stderr)}`);
4715
4837
  if (input.aborted()) return bail("", true);
4716
4838
  mkdirSync(buildDir2, { recursive: true });
4717
4839
  const ghDir = ghConfigDir(buildDir2);
@@ -4724,11 +4846,6 @@ async function provisionContainer(input) {
4724
4846
  err instanceof WorkCommandError ? `the build's read token could not be had: ${refusalCode(err)}` : `the build's gh configuration could not be written: ${describeCallFailure(err)}`
4725
4847
  );
4726
4848
  }
4727
- try {
4728
- writeBuildMavenSettings(buildDir2);
4729
- } catch (err) {
4730
- return bail(`the build's Maven settings could not be written: ${describeCallFailure(err)}`);
4731
- }
4732
4849
  for (const entry of repositories) {
4733
4850
  if (entry.repository === primary.repository) continue;
4734
4851
  try {
@@ -4768,12 +4885,23 @@ async function provisionContainer(input) {
4768
4885
  };
4769
4886
  const prepared = await host.run(prepareRunArgs(runInput), { logPath });
4770
4887
  if (prepared.status !== 0) return dockerFailed("preparing the build's volume", prepared);
4771
- const started = await host.run(containerRunArgs(runInput), { logPath });
4888
+ const imageConfig = await host.imageConfig(report.imageId);
4889
+ const resolved = await resolveBuildUser(runtime, runInput, { remoteUser: report.apply.remoteUser, imageUser: imageConfig.user }, logPath);
4890
+ if (!resolved.ok) return bail(resolved.reason);
4891
+ state.agentUser = resolved.user;
4892
+ if (resolved.home !== void 0) state.home = resolved.home;
4893
+ const agentUser = resolved.user;
4894
+ state.network = networkHelperName(name);
4895
+ input.save(state, environment);
4896
+ const notReady = await startNetworkHelper(runtime, { name: state.network, buildId, runnerId, image: report.imageId, limits: limits2, ipv6: runtime.ipv6 }, logPath);
4897
+ if (notReady !== void 0) return bail(notReady);
4898
+ if (input.aborted()) return bail("", true);
4899
+ const started = await host.run(containerRunArgs({ ...runInput, network: state.network, home: state.home }), { logPath });
4772
4900
  if (started.status !== 0) return dockerFailed("starting the build's container", started);
4773
4901
  joinBuild(runtime, state, services, (line2) => log.line(`${tag} ${line2}`));
4774
4902
  if (input.aborted()) return bail("", true);
4775
4903
  if (!await waitForRelay(runtime, state)) return bail("the relay in the build's container did not start");
4776
- const ghDelivered = await deliverJobFiles(runtime, state, ["gh", "maven"], secrets);
4904
+ const ghDelivered = await deliverJobFiles(runtime, state, ["gh"], secrets);
4777
4905
  if (!ghDelivered.ok) return bail(ghDelivered.reason);
4778
4906
  keepGhConfigCurrent(tokens, buildDir2, (err) => log.error(`${tag} the read token could not be written for gh: ${describeCallFailure(err)}`), {
4779
4907
  runtime,
@@ -4782,24 +4910,6 @@ async function provisionContainer(input) {
4782
4910
  delivered: readToken,
4783
4911
  onFailure: (reason) => log.error(`${tag} ${reason}`)
4784
4912
  });
4785
- const imageConfig = await host.imageConfig(report.imageId);
4786
- state.imageEnv = imageConfig.env;
4787
- let agentUser;
4788
- try {
4789
- agentUser = await resolveAgentUser({
4790
- remoteUser: report.apply.remoteUser,
4791
- imageUser: imageConfig.user,
4792
- probe: async (user) => {
4793
- const probe = await host.exec({ container: name, user: ADDED_USER, env: NO_ENV, argv: ["id", "-u", user] });
4794
- const uid = Number(probe.stdout);
4795
- return probe.status === 0 && Number.isInteger(uid) ? uid : null;
4796
- }
4797
- });
4798
- } catch (err) {
4799
- if (err instanceof AgentUserError) return bail(err.message);
4800
- throw err;
4801
- }
4802
- state.agentUser = agentUser;
4803
4913
  const tools = await host.exec({ container: name, user: ADDED_USER, env: NO_ENV, argv: ["cat", "/opt/outerlayer/tools.json"] });
4804
4914
  const agentVersion = agentVersionOf(tools.status === 0 ? tools.stdout : "");
4805
4915
  environment.agentVersion = agentVersion;
@@ -4807,10 +4917,7 @@ async function provisionContainer(input) {
4807
4917
  const hashed = program.status === 0 ? parseProgramHash(program.stdout) : void 0;
4808
4918
  if (hashed !== void 0) state.judgeProgram = { path: JUDGE_PROGRAM, sha256: hashed };
4809
4919
  input.save(state, environment);
4810
- let execEnv = buildEnvironment({ ...envInput, imageEnv: state.imageEnv });
4811
- for (const notice of execEnv.notices) log.line(`${tag} ${notice}`);
4812
- const plainEnv = buildEnvironment({ ...envInput, imageEnv: state.imageEnv, proxyWarning: false });
4813
- const exec = (argv, workdir, opts) => host.exec({ container: name, user: agentUser, workdir, env: opts?.withoutProxyWarning === true ? plainEnv : execEnv, argv }, opts?.quiet === true ? void 0 : { logPath });
4920
+ const exec = (argv, workdir, opts) => host.exec({ container: name, user: agentUser, workdir, env, argv }, opts?.quiet === true ? void 0 : { logPath });
4814
4921
  const steps = await runBuildSteps({
4815
4922
  repository,
4816
4923
  branch: primary.branch,
@@ -4843,11 +4950,7 @@ async function provisionContainer(input) {
4843
4950
  keepIn: jobDir,
4844
4951
  ...input.requireBuildSkill === true ? { requireBuildSkill: true } : {},
4845
4952
  // A repository with no devcontainer file builds on the universal image, whose runtimes the build chooses and installs.
4846
- ...runtimeStepInput(report, services),
4847
- dropProxyWarning: () => {
4848
- state.proxyWarningDropped = true;
4849
- execEnv = plainEnv;
4850
- }
4953
+ ...runtimeStepInput(report, services)
4851
4954
  });
4852
4955
  if (!steps.ok) return bail(steps.reason, steps.aborted === true);
4853
4956
  state.startCommit = steps.startCommit;
@@ -4855,6 +4958,37 @@ async function provisionContainer(input) {
4855
4958
  if (steps.controlPlane !== void 0) environment.controlPlane = steps.controlPlane;
4856
4959
  return { ok: true, workdir: CHECKOUT_DIR, state, environment };
4857
4960
  }
4961
+ async function resolveBuildUser(runtime, runInput, named, logPath) {
4962
+ const lookups = /* @__PURE__ */ new Map();
4963
+ const lookup2 = async (user2) => {
4964
+ const known = lookups.get(user2);
4965
+ if (known !== void 0) return known;
4966
+ const ran = await runtime.host.run(identityRunArgs({ ...runInput, user: ADDED_USER }, user2));
4967
+ const found = parseIdentity(ran.stdout);
4968
+ if (ran.status !== 0 || found === void 0) {
4969
+ throw new AgentUserError(`reading the build's user from the image failed (exit ${ran.status})${said(ran.stderr)}`);
4970
+ }
4971
+ lookups.set(user2, found);
4972
+ return found;
4973
+ };
4974
+ let user;
4975
+ let home;
4976
+ try {
4977
+ user = await resolveAgentUser({ ...named, probe: async (name) => (await lookup2(name))?.uid ?? null });
4978
+ home = user === ADDED_USER ? void 0 : mountableHome((await lookup2(user))?.home);
4979
+ } catch (err) {
4980
+ if (err instanceof AgentUserError) return { ok: false, reason: err.message };
4981
+ throw err;
4982
+ }
4983
+ if (home === void 0) return { ok: true, user };
4984
+ const copied = await copyBuildHome(runtime, { ...runInput, user }, home, logPath);
4985
+ return copied === void 0 ? { ok: true, user, home } : { ok: false, reason: copied };
4986
+ }
4987
+ async function copyBuildHome(runtime, runInput, home, logPath) {
4988
+ const copied = await runtime.host.run(homeCopyRunArgs(runInput, home), { logPath });
4989
+ if (copied.status === 0) return void 0;
4990
+ return `copying ${home} into the build's home failed (exit ${copied.status})${said(copied.stderr)}`;
4991
+ }
4858
4992
  function agentVersionOf(toolsJson) {
4859
4993
  try {
4860
4994
  const version = JSON.parse(toolsJson).claudeCodeVersion;
@@ -4879,9 +5013,7 @@ function containerCommandExec(input) {
4879
5013
  containerEnv: state.containerEnv ?? {},
4880
5014
  unpinnedRuntimes: state.unpinnedRuntimes,
4881
5015
  builtIns: state.builtIns === true,
4882
- identity: input.job.commitIdentity,
4883
- imageEnv: state.imageEnv,
4884
- proxyWarning: state.proxyWarningDropped !== true
5016
+ identity: input.job.commitIdentity
4885
5017
  });
4886
5018
  return {
4887
5019
  container: state.container,
@@ -4905,9 +5037,7 @@ function containerSenderCommand(input) {
4905
5037
  containerEnv: state.containerEnv ?? {},
4906
5038
  unpinnedRuntimes: state.unpinnedRuntimes,
4907
5039
  builtIns: state.builtIns === true,
4908
- identity: input.job.commitIdentity,
4909
- imageEnv: state.imageEnv,
4910
- proxyWarning: state.proxyWarningDropped !== true
5040
+ identity: input.job.commitIdentity
4911
5041
  });
4912
5042
  const args = containerExecArgs({
4913
5043
  container: state.container,
@@ -5007,7 +5137,7 @@ async function ensureTunnel(runtime, state, jobDir, config, itemKey, branch, rep
5007
5137
  }
5008
5138
  async function redeliver(runtime, state, jobDir) {
5009
5139
  if (!filesAreCopied(state)) return { ok: true };
5010
- const parts = ["gh", "maven", "git-hooks", "context"];
5140
+ const parts = ["gh", "git-hooks", "context"];
5011
5141
  return deliverJobFiles(runtime, state, parts, secretsOf(runtime, jobDir));
5012
5142
  }
5013
5143
  async function deliverContainerHooks(runtime, state, jobDir) {
@@ -5020,6 +5150,8 @@ async function syncInContainer(input) {
5020
5150
  try {
5021
5151
  await ensureTunnel(runtime, state, input.jobDir, input.config, job.itemKey, job.branch, job.repositories, input.log, () => leaseExpiresAtMs(job));
5022
5152
  if (state.stopped) {
5153
+ const network = await ensureNetworkReady(runtime, state);
5154
+ if (network !== void 0) return { ok: false, reason: network };
5023
5155
  await runtime.host.start(state.container);
5024
5156
  state.stopped = false;
5025
5157
  if (!await waitForRelay(runtime, state)) return { ok: false, reason: "the relay did not start again" };
@@ -5038,9 +5170,7 @@ async function syncInContainer(input) {
5038
5170
  containerEnv: state.containerEnv ?? {},
5039
5171
  unpinnedRuntimes: state.unpinnedRuntimes,
5040
5172
  builtIns: state.builtIns === true,
5041
- identity: job.commitIdentity,
5042
- imageEnv: state.imageEnv,
5043
- proxyWarning: state.proxyWarningDropped !== true
5173
+ identity: job.commitIdentity
5044
5174
  });
5045
5175
  const result = await runtime.host.exec(
5046
5176
  { container: state.container, user: state.agentUser ?? ADDED_USER, workdir: job.workdir ?? CHECKOUT_DIR, env, argv: ["outerlayer", "sync"] },
@@ -5054,6 +5184,8 @@ async function syncInContainer(input) {
5054
5184
  async function copyTranscriptsFromContainer(runtime, state) {
5055
5185
  try {
5056
5186
  if (state.stopped) {
5187
+ const network = await ensureNetworkReady(runtime, state);
5188
+ if (network !== void 0) return { ok: false, reason: network };
5057
5189
  const started = await runtime.host.start(state.container);
5058
5190
  if (started.status !== 0) return { ok: false, reason: `the build's container could not be started again (exit ${started.status})` };
5059
5191
  state.stopped = false;
@@ -5067,6 +5199,7 @@ var HOOK_ERRORS_IN_CONTAINER = "/build/home/.outerlayer/spool/hook-errors.log";
5067
5199
  async function copyHookErrors(runtime, state, jobDir) {
5068
5200
  try {
5069
5201
  if (state.stopped) {
5202
+ if (await ensureNetworkReady(runtime, state) !== void 0) return;
5070
5203
  const started = await runtime.host.start(state.container);
5071
5204
  if (started.status !== 0) return;
5072
5205
  }
@@ -5086,6 +5219,8 @@ async function cleanupContainer(runtime, state, jobDir) {
5086
5219
  if (removedContainer.status !== 0 && !/no such container/i.test(removedContainer.stderr)) {
5087
5220
  failures.push(`container ${state.container} was not removed: ${removedContainer.stderr.trim()}`);
5088
5221
  }
5222
+ const helperLeft = await removeNetworkHelper(runtime, state);
5223
+ if (helperLeft !== void 0) failures.push(helperLeft);
5089
5224
  let volumeGone = false;
5090
5225
  for (let attempt = 0; attempt < VOLUME_REMOVE_ATTEMPTS && !volumeGone; attempt++) {
5091
5226
  const removed = await runtime.host.removeVolume(state.volume);
@@ -5115,13 +5250,15 @@ function containerJudgeEnvironment(input) {
5115
5250
  env: NO_ENV,
5116
5251
  argv: ["/bin/sh", "-c", `[ -f ${file} ] && [ ! -L ${file} ] && head -c ${maxBytes + 1} ${file}`]
5117
5252
  }, { timeoutMs: REPORT_READ_TIMEOUT_MS });
5118
- if (read.status > 1) throw new Error(`reading the judge's ${name} exited ${read.status}: ${firstLine7(read.stderr)}`);
5253
+ if (read.status > 1) throw new Error(`reading the judge's ${name} exited ${read.status}: ${firstLine4(read.stderr)}`);
5119
5254
  return read.status === 0 && Buffer.byteLength(read.stdout) <= maxBytes ? read.stdout : void 0;
5120
5255
  };
5121
5256
  return {
5122
5257
  stop: async () => {
5123
5258
  if (input.config !== void 0) await ensureTunnel(runtime, state, input.jobDir, input.config, job.itemKey, job.branch, job.repositories, input.log);
5124
5259
  await stopContainer(runtime, state);
5260
+ const network = await ensureNetworkReady(runtime, state);
5261
+ if (network !== void 0) throw new Error(network);
5125
5262
  const started = await runtime.host.start(state.container);
5126
5263
  if (started.status !== 0) throw new Error(`the build's container could not be started again (exit ${started.status})`);
5127
5264
  state.stopped = false;
@@ -5133,7 +5270,7 @@ function containerJudgeEnvironment(input) {
5133
5270
  hashProgram: async () => {
5134
5271
  const ran = await runtime.host.exec({ container: state.container, user: ADDED_USER, env: NO_ENV, argv: [...HASH_ARGV] });
5135
5272
  const sha256 = ran.status === 0 ? parseProgramHash(ran.stdout) : void 0;
5136
- return sha256 === void 0 ? { ok: false, reason: firstLine7(ran.stderr) || `the hash could not be taken (exit ${ran.status})` } : { ok: true, sha256 };
5273
+ return sha256 === void 0 ? { ok: false, reason: firstLine4(ran.stderr) || `the hash could not be taken (exit ${ran.status})` } : { ok: true, sha256 };
5137
5274
  },
5138
5275
  prepare: async (files, tree) => {
5139
5276
  if (filesAreCopied(state)) {
@@ -5166,7 +5303,7 @@ function containerJudgeEnvironment(input) {
5166
5303
  // host. Every capability is dropped in the container, so root there could not either; the build's user removes its own, and the runner removes the rest.
5167
5304
  clear: async () => {
5168
5305
  const removed = await runtime.host.exec({ container: state.container, user, env: NO_ENV, argv: ["find", JUDGE_DIR, "-mindepth", "1", "-user", user, "-delete"] });
5169
- if (removed.status !== 0) throw new Error(`find exited ${removed.status}: ${firstLine7(removed.stderr)}`);
5306
+ if (removed.status !== 0) throw new Error(`find exited ${removed.status}: ${firstLine4(removed.stderr)}`);
5170
5307
  if (!filesAreCopied(state)) return;
5171
5308
  const emptied = await clearJudgeFolder(runtime, state, secretsOf(runtime, input.jobDir));
5172
5309
  if (!emptied.ok) throw new Error(emptied.reason);
@@ -5204,11 +5341,12 @@ async function startCheckContainer(input) {
5204
5341
  buildDir: buildDir2,
5205
5342
  repository,
5206
5343
  imageId: built.imageId,
5207
- imageEnv: built.imageEnv,
5208
5344
  agentUser,
5209
5345
  cpuset,
5210
5346
  transport,
5211
- ...transport === "exec" ? { jobFiles: "copied" } : {}
5347
+ ...transport === "exec" ? { jobFiles: "copied" } : {},
5348
+ ...built.network === void 0 ? {} : { network: networkHelperName(name) },
5349
+ ...built.home === void 0 ? {} : { home: built.home }
5212
5350
  };
5213
5351
  const checksDir = join(jobDir, "checks");
5214
5352
  mkdirSync(checksDir, { recursive: true });
@@ -5222,7 +5360,7 @@ async function startCheckContainer(input) {
5222
5360
  }
5223
5361
  return { ok: false, reason };
5224
5362
  };
5225
- const dockerFailed = (what, result) => fail(`${what} failed (exit ${result.status})${firstLine7(result.stderr) === "" ? "" : `: ${firstLine7(result.stderr)}`}`);
5363
+ const dockerFailed = (what, result) => fail(`${what} failed (exit ${result.status})${said(result.stderr)}`);
5226
5364
  mkdirSync(buildDir2, { recursive: true });
5227
5365
  if (!filesAreCopied(state)) chmodSync(buildDir2, 493);
5228
5366
  let services;
@@ -5258,11 +5396,19 @@ async function startCheckContainer(input) {
5258
5396
  };
5259
5397
  const prepared = await host.run(prepareRunArgs(runInput), { logPath });
5260
5398
  if (prepared.status !== 0) return dockerFailed("preparing the check environment's volume", prepared);
5261
- const started = await host.run(containerRunArgs(runInput), { logPath });
5399
+ if (state.home !== void 0) {
5400
+ const copied = await copyBuildHome(runtime, { ...runInput, user: agentUser }, state.home, logPath);
5401
+ if (copied !== void 0) return fail(copied);
5402
+ }
5403
+ if (state.network !== void 0) {
5404
+ const notReady = await startNetworkHelper(runtime, { name: state.network, buildId, runnerId, image: built.imageId, limits: limits2, ipv6: runtime.ipv6 }, logPath);
5405
+ if (notReady !== void 0) return fail(notReady);
5406
+ }
5407
+ const started = await host.run(containerRunArgs({ ...runInput, network: state.network, home: state.home }), { logPath });
5262
5408
  if (started.status !== 0) return dockerFailed("starting the check environment's container", started);
5263
5409
  if (transport === "exec") joinBuild(runtime, state, services, (line2) => log.line(`${tag} ${line2}`));
5264
5410
  if (!await waitForRelay(runtime, state)) return fail("the relay in the check environment's container did not start");
5265
- const env = checkEnvironment({ config, item: job.item, repository, hostEnv: runtime.hostEnv, containerEnv: built.containerEnv ?? {}, imageEnv: built.imageEnv });
5411
+ const env = checkEnvironment({ config, item: job.item, repository, hostEnv: runtime.hostEnv, containerEnv: built.containerEnv ?? {} });
5266
5412
  const secrets = () => tokens.issuedTokens();
5267
5413
  let delivered = false;
5268
5414
  const deliverInput = async () => {
@@ -5287,6 +5433,11 @@ async function startCheckContainer(input) {
5287
5433
  restart: async () => {
5288
5434
  await leaveBuild(runtime, state);
5289
5435
  await host.stop(name);
5436
+ const network = await ensureNetworkReady(runtime, state);
5437
+ if (network !== void 0) {
5438
+ log.error(`${tag} ${network}`);
5439
+ return false;
5440
+ }
5290
5441
  const again = await host.start(name);
5291
5442
  if (again.status !== 0 || !await waitForRelay(runtime, state)) return false;
5292
5443
  rejoinBuild(runtime, state, (line2) => log.line(`${tag} ${line2}`));
@@ -5402,4 +5553,4 @@ function describeMachineDocker(machine) {
5402
5553
  return `Docker Engine ${version ?? "of no known version"}, older than the ${MIN_ENGINE_MAJOR} that container builds need`;
5403
5554
  }
5404
5555
 
5405
- export { ADDED_USER, ADOPTED_FETCH_RETRY_WINDOW_MS, AgentUserError, AssetError, DeliveryFailure, EVAL_INPUT_NAME, GH_CONFIG_YML, HELPER_ENV, LEASE_SECONDS, MANAGED_UNJAILED_REASON, MIN_ENGINE_MAJOR, PLACEHOLDER_MARKER, ROOT_DISK_ID_PREFIX, RunnerInitError, attemptNote, claimPermissionProblem, claudeCredentialCheck, cleanupContainer, closeHostBuild, containerCommandExec, containerJudgeEnvironment, containerSenderCommand, copyJudgeTree, copyTranscripts, copyTranscriptsFromContainer, createBuildDisk, createContainerRuntime, createLeaseChannel, currentSkillCommand, decideHostBuildSkill, deleteBuildDisk, deliverContainerHooks, deliverExecMaven, describeMachineDocker, detectMachine, dropManagedBuildSettings, dropManagedClaudeKey, ensureFirecrackerAndJailer, ensureRootfs, ensureTunnel, execArgv, execCommandLine, fetchManagedBuildSettings, fetchManagedClaudeKey, filesAreCopied, formerSkillProblem, formerSkillQueues, ghHostsYml, gitRemoteFor, hasClaudeCredential, helperFirecrackerNote, helperSocketPath, holdManagedBuildSettings, holdManagedClaudeKey, hostCommandEnvironment, hostEnvironment, isPlaceholderCommand, keepGhConfigCurrent, keepUnpinnedRuntimes, leaseExpiresAtMs, leaseTimeLeftMs, lifecycleFailureReason, lifecycleSteps, listenOnBroker, machineConfig, makeBuildsDirPrivate, managedBuildSettingValues, managedBuildSettingsFor, managedClaudeKeyFor, managedClaudeKeyValues, managedMachineLimits, measureDisk, microVmArchSupported, microVmAssetsPinned, missingPermissionFix, missingPermissionOf, needsBuildSkill, needsClaudeCredential, obtainImage, outOfMemoryReason, parseCpuList, permissionModeProblem, permissionModeProblems, placeholderProblem, placeholderQueues, prepareBranch, prepareRunnerInit, probeHelper, provisionContainer, provisionEnvironment, reachDockerStep, readConfigObject, resolveAgentUser, resolveHostBuild, runBuildSteps, runRunnerInit, runWithSpawn, runtimeStepInput, senderAliveScript, senderSignalScript, setUpRunnerCgroup, shellQuote, signalInContainer, startCheckContainer, startHostServices, startJailedInto, startServicesFor, stopContainer, stopJailed, supportsContainerBuilds, supportsMicroVmBuilds, sweepImageBuilders, syncInContainer, withFactoryHosts, withTunnelLog, writeEvalInput, writeRunnerInit };
5556
+ export { ADDED_USER, ADOPTED_FETCH_RETRY_WINDOW_MS, AgentUserError, AssetError, DeliveryFailure, EVAL_INPUT_NAME, GH_CONFIG_YML, HELPER_ENV, LEASE_SECONDS, MANAGED_UNJAILED_REASON, MIN_ENGINE_MAJOR, PLACEHOLDER_MARKER, ROOT_DISK_ID_PREFIX, RunnerInitError, attemptNote, claimPermissionProblem, claudeCredentialCheck, cleanupContainer, closeHostBuild, containerCommandExec, containerJudgeEnvironment, containerSenderCommand, copyJudgeTree, copyTranscripts, copyTranscriptsFromContainer, createBuildDisk, createContainerRuntime, createLeaseChannel, currentSkillCommand, decideHostBuildSkill, deleteBuildDisk, deliverContainerHooks, deliverExecMaven, describeMachineDocker, detectMachine, dropManagedBuildSettings, dropManagedClaudeKey, ensureFirecrackerAndJailer, ensureNetworkReady, ensureRootfs, ensureTunnel, execArgv, execCommandLine, fetchManagedBuildSettings, fetchManagedClaudeKey, filesAreCopied, firstLine4 as firstLine, formerSkillProblem, formerSkillQueues, ghHostsYml, gitRemoteFor, hasClaudeCredential, helperFirecrackerNote, helperSocketPath, holdManagedBuildSettings, holdManagedClaudeKey, hostCommandEnvironment, hostEnvironment, isPlaceholderCommand, keepGhConfigCurrent, keepUnpinnedRuntimes, leaseExpiresAtMs, leaseTimeLeftMs, lifecycleFailureReason, lifecycleSteps, listenOnBroker, machineConfig, makeBuildsDirPrivate, managedBuildSettingValues, managedBuildSettingsFor, managedClaudeKeyFor, managedClaudeKeyValues, managedMachineLimits, measureDisk, microVmArchSupported, microVmAssetsPinned, missingPermissionFix, missingPermissionOf, needsBuildSkill, needsClaudeCredential, obtainImage, outOfMemoryReason, parseCpuList, permissionModeProblem, permissionModeProblems, placeholderProblem, placeholderQueues, prepareBranch, prepareRunnerInit, probeHelper, provisionContainer, provisionEnvironment, reachDockerStep, readConfigObject, resolveAgentUser, resolveHostBuild, runBuildSteps, runRunnerInit, runWithSpawn, runtimeStepInput, said, senderAliveScript, senderSignalScript, setUpRunnerCgroup, shellQuote, signalInContainer, startCheckContainer, startHostServices, startJailedInto, startServicesFor, stopContainer, stopJailed, stoppedHelperReason, supportsContainerBuilds, supportsMicroVmBuilds, sweepImageBuilders, syncInContainer, withFactoryHosts, withTunnelLog, writeEvalInput, writeRunnerInit };