@outerlayer/cli 0.24.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +9 -0
  3. package/dist/{agent-setup-QQYRBPK2.js → agent-setup-PDIIGMKE.js} +7 -7
  4. package/dist/{bridge-4ZARDVGS.js → bridge-5KZ36YDG.js} +3 -3
  5. package/dist/build-Q2OBF77R.js +12 -0
  6. package/dist/build-info.json +1 -1
  7. package/dist/{builder-MECDEKXX.js → builder-PRSCX5AH.js} +6 -6
  8. package/dist/{check-YYKNYFNI.js → check-EPYRTE3R.js} +38 -37
  9. package/dist/{chunk-BN3CSI7S.js → chunk-2K3TCQHW.js} +1 -1
  10. package/dist/{chunk-A62QFN2M.js → chunk-2N72GPS2.js} +3 -3
  11. package/dist/{chunk-W7O4LA4E.js → chunk-34ANPNVB.js} +2 -2
  12. package/dist/{chunk-6GSA2SKT.js → chunk-3I44PQ26.js} +205 -56
  13. package/dist/{chunk-WH2QV3UL.js → chunk-4S4VBDSO.js} +1 -1
  14. package/dist/{chunk-IDSHLKQA.js → chunk-5222PA6S.js} +1 -1
  15. package/dist/{chunk-V5Q3S4NM.js → chunk-6CNHXHI2.js} +1 -1
  16. package/dist/{chunk-LY2L3O2O.js → chunk-7OWPLRJR.js} +1 -1
  17. package/dist/{chunk-HHXBOTRO.js → chunk-ATGHVEU4.js} +1 -1
  18. package/dist/{chunk-TTLVQZSH.js → chunk-AXPCGD46.js} +5 -5
  19. package/dist/{chunk-FWEWFW3F.js → chunk-DEBOL6ON.js} +1 -1
  20. package/dist/{chunk-E4OUL7ZP.js → chunk-FXUVXSY2.js} +2 -2
  21. package/dist/{chunk-BUBCPP3F.js → chunk-HBLLZLOH.js} +2 -2
  22. package/dist/{chunk-F2W2IYNP.js → chunk-HWEIFHSW.js} +2 -2
  23. package/dist/{chunk-F7Y2USIM.js → chunk-IDJIWKTY.js} +2 -2
  24. package/dist/{chunk-DG2ULWM6.js → chunk-IGRRD7PX.js} +11 -7
  25. package/dist/{chunk-GISNHSYL.js → chunk-JGD5TWQ2.js} +4 -2
  26. package/dist/{chunk-BOQY756V.js → chunk-JKILLWZF.js} +8 -7
  27. package/dist/{chunk-D7X5ITVT.js → chunk-JWRX5ZTT.js} +6 -2
  28. package/dist/{chunk-755WXDBI.js → chunk-K5WVK7IC.js} +1 -1
  29. package/dist/{chunk-H6IUKXXI.js → chunk-L2FZLBF7.js} +207 -35
  30. package/dist/{chunk-FKXGQOF5.js → chunk-M4B6QKNZ.js} +1 -1
  31. package/dist/{chunk-NTQTDCYR.js → chunk-O2WYUIK7.js} +1 -1
  32. package/dist/{chunk-VV7ZD5LR.js → chunk-QMQC6JCO.js} +1 -1
  33. package/dist/{chunk-5XCAPBE2.js → chunk-QUGYGO6L.js} +5 -5
  34. package/dist/{chunk-FQPN5S4Q.js → chunk-QXNJWSTM.js} +4 -4
  35. package/dist/{chunk-3W333NFO.js → chunk-RGW7ERF3.js} +15 -4
  36. package/dist/{chunk-CZUH2SLQ.js → chunk-UNF7MWEL.js} +1 -1
  37. package/dist/{chunk-ZFLOFAUG.js → chunk-VMF5LK3D.js} +7 -7
  38. package/dist/{chunk-VBEXKEBV.js → chunk-VNGENFOG.js} +19 -6
  39. package/dist/{chunk-5ECUMU53.js → chunk-VPUNOGXO.js} +6 -6
  40. package/dist/{chunk-RVYOOYOA.js → chunk-X5LNCIZT.js} +18 -9
  41. package/dist/{chunk-PDIM5T65.js → chunk-XGJUNNXL.js} +1 -1
  42. package/dist/{chunk-GU4PKXN7.js → chunk-XHXDCYSK.js} +184 -37
  43. package/dist/{chunk-NGZID7UI.js → chunk-XRYUJTAT.js} +8 -1
  44. package/dist/{chunk-TQ6Y7YV6.js → chunk-YMKQVCKC.js} +5 -5
  45. package/dist/{chunk-D7K446H6.js → chunk-YTTHDPWF.js} +4 -4
  46. package/dist/{chunk-LBCZXXOX.js → chunk-ZGMQQWCV.js} +2 -2
  47. package/dist/{chunk-KF37SUDM.js → chunk-ZI2ZVWKT.js} +1 -1
  48. package/dist/{chunk-PVRBE7S4.js → chunk-ZODVSFI4.js} +1 -1
  49. package/dist/chunk-ZVB57WI6.js +19 -0
  50. package/dist/{claude-launcher-JCPSHDZQ.js → claude-launcher-WGOCLTG6.js} +1 -1
  51. package/dist/{cli-ZTBH3FBG.js → cli-2LGSPAYZ.js} +105 -100
  52. package/dist/command-ITLPJ5XU.js +533 -0
  53. package/dist/{config-7Z5DHSGY.js → config-JJ3EO7SB.js} +3 -3
  54. package/dist/{connect-cmd-NY5LIKVC.js → connect-cmd-JFDZKPND.js} +6 -6
  55. package/dist/{container-start-OHBUZEJJ.js → container-start-X22OXY6E.js} +44 -35
  56. package/dist/{control-plane-launch-GKGI6HJA.js → control-plane-launch-ZFT6SI4N.js} +6 -6
  57. package/dist/{docker-RKGBJESN.js → docker-PQHWAY5J.js} +6 -6
  58. package/dist/{doctor-DOAFZV4O.js → doctor-73GNT4VV.js} +78 -32
  59. package/dist/{emit-artifact-cmd-VZHIDPXQ.js → emit-artifact-cmd-AIOTX6YT.js} +10 -10
  60. package/dist/{emit-criteria-cmd-SYLBCWHW.js → emit-criteria-cmd-7PJINOHA.js} +7 -7
  61. package/dist/{emit-finding-cmd-52M43NPC.js → emit-finding-cmd-JRDSZ4DR.js} +7 -7
  62. package/dist/{emit-result-cmd-BTMTGDAV.js → emit-result-cmd-ZGF6Q6OP.js} +10 -10
  63. package/dist/{emit-step-cmd-6XTJITZT.js → emit-step-cmd-DUR34STQ.js} +8 -8
  64. package/dist/{exec-client-CKPK62K2.js → exec-client-S5IA7JRG.js} +4 -4
  65. package/dist/{governing-source-GWN7GVEN.js → governing-source-DKJABQAT.js} +10 -10
  66. package/dist/{guest-init-ZBL5CN7Y.js → guest-init-TOSKPGPF.js} +5 -5
  67. package/dist/{hook-fast-3JL4PXLG.js → hook-fast-NEELST6G.js} +1 -1
  68. package/dist/host-key-ICJEQBWH.js +9 -0
  69. package/dist/{image-tag-AO4RBAKW.js → image-tag-6KJOGBQK.js} +4 -4
  70. package/dist/index.js +4 -4
  71. package/dist/{init-EQTR7AEF.js → init-NE3VR3EY.js} +24 -22
  72. package/dist/{init-TSQ3EOQW.js → init-SKOXNJND.js} +24 -22
  73. package/dist/{init-cmd-AF2MH36A.js → init-cmd-UEDOJ7LG.js} +10 -10
  74. package/dist/{init-update-SHISHMXV.js → init-update-VKZ4S6HH.js} +8 -8
  75. package/dist/{install-ORQC26ZE.js → install-MPEJJ7X6.js} +5 -5
  76. package/dist/{install-cmd-4LA3UJZ4.js → install-cmd-SE6NCTJK.js} +6 -6
  77. package/dist/job-state-format-WJQGQB6F.js +6 -0
  78. package/dist/{logs-5EPHIPZB.js → logs-T4ERSOQ4.js} +3 -3
  79. package/dist/{loop-4WUCS5JP.js → loop-BPVEA5OC.js} +37 -36
  80. package/dist/{machine-6UNLIPLE.js → machine-G3GICXQN.js} +20 -18
  81. package/dist/{mcp-serve-cmd-KMWEKM7C.js → mcp-serve-cmd-7M4VLNI4.js} +5 -5
  82. package/dist/{paths-XY5ADO32.js → paths-2KGM2LZV.js} +3 -3
  83. package/dist/pending-BGLMTB5Q.js +9 -0
  84. package/dist/{pidfile-OJ7RP4Q2.js → pidfile-VYBH3IMN.js} +4 -4
  85. package/dist/{record-BEJB4J7N.js → record-GNOHDJ2O.js} +4 -4
  86. package/dist/{relay-PSZ4LGMW.js → relay-GFPPD6GF.js} +1 -1
  87. package/dist/relay-protocol-HELO5SNH.js +6 -0
  88. package/dist/{runner-env-ZJWJOJKQ.js → runner-env-GUFV544G.js} +6 -6
  89. package/dist/{runner-identity-2OOUJSFJ.js → runner-identity-J6DXJ6MF.js} +6 -6
  90. package/dist/{runner-key-WDFBSJRX.js → runner-key-L55O7Y7W.js} +24 -22
  91. package/dist/{session-sender-X3BBQZMF.js → session-sender-LXTASWBY.js} +11 -11
  92. package/dist/{spec-cmd-QRF5YXKK.js → spec-cmd-G2JNXKD7.js} +8 -8
  93. package/dist/{status-ZCAAF6MD.js → status-U6DXOR6C.js} +34 -28
  94. package/dist/{sync-cmd-UQK3RYAC.js → sync-cmd-VPNS5ITY.js} +10 -10
  95. package/dist/{watch-MOQ3GQTE.js → watch-ZOCYD2NE.js} +10 -10
  96. package/dist/{work-claim-cmd-RT343CLA.js → work-claim-cmd-BUMIPJNF.js} +11 -11
  97. package/dist/{work-cmd-APXSER2D.js → work-cmd-LRAXUOJV.js} +8 -8
  98. package/dist/{work-comment-cmd-AT5NUYUU.js → work-comment-cmd-4RDIBUYO.js} +8 -8
  99. package/dist/{work-logs-cmd-Z5DMNEJP.js → work-logs-cmd-YYN2CPJQ.js} +8 -8
  100. package/dist/{work-open-pr-cmd-ZTS6MJHL.js → work-open-pr-cmd-3MCND2LZ.js} +9 -9
  101. package/dist/{work-pr-cmd-IWZCC3WH.js → work-pr-cmd-BODEZAXN.js} +8 -8
  102. package/dist/{work-stop-cmd-DCAWFDZC.js → work-stop-cmd-P7HXVKEG.js} +8 -8
  103. package/package.json +2 -2
  104. package/skill-pack/maintained/outerlayer-build/SKILL.md +1 -1
  105. package/skill-pack/maintained/outerlayer-build/references/agent-briefs.md +3 -2
  106. package/skill-pack/maintained/outerlayer-build/references/review-briefs.md +3 -1
  107. package/dist/build-OVZIT2G2.js +0 -12
  108. package/dist/command-DO4TERRT.js +0 -208
  109. package/dist/host-key-W2DLZGZ7.js +0 -9
  110. package/dist/pending-35J3ZPLR.js +0 -9
  111. package/dist/relay-protocol-K7KP2SPI.js +0 -6
@@ -1,20 +1,21 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { senderPidfile } from './chunk-W7O4LA4E.js';
4
- import { DOCKERD_LOG, HELPER_PATH, HELPER_RECORD } from './chunk-A62QFN2M.js';
5
- import { writeDockerClientConfig } from './chunk-CZUH2SLQ.js';
6
- import { installScrubContext } from './chunk-D7K446H6.js';
7
- import { ADDED_USER, AssetError, obtainImage, ensureRootfs, gitRemoteFor, startServicesFor, createBuildDisk, machineConfig, resolveAgentUser, AgentUserError, runBuildSteps, shellQuote, LEASE_SECONDS, createContainerRuntime, stopContainer, cleanupContainer, outOfMemoryReason, containerSenderCommand, signalInContainer, syncInContainer, copyTranscriptsFromContainer, senderAliveScript, GH_CONFIG_YML, ghHostsYml, isLiteralAddress, deleteBuildDisk, startCheckContainer, lifecycleSteps, lifecycleFailureReason, writeEvalInput, DeliveryFailure, EVAL_INPUT_NAME, copyTranscripts, senderSignalScript, containerJudgeEnvironment, copyJudgeTree } from './chunk-GU4PKXN7.js';
8
- import { readBranchHead, fetchCommit, diffBetween } from './chunk-TTLVQZSH.js';
3
+ import { readsJobState, READ_JOB_STATE_FORMATS, jobStateFormatOf } from './chunk-ZVB57WI6.js';
4
+ import { senderPidfile } from './chunk-34ANPNVB.js';
5
+ import { DOCKERD_LOG, HELPER_PATH, HELPER_RECORD } from './chunk-2N72GPS2.js';
6
+ import { writeDockerClientConfig } from './chunk-UNF7MWEL.js';
7
+ import { installScrubContext } from './chunk-YTTHDPWF.js';
8
+ import { ADDED_USER, AssetError, obtainImage, ensureRootfs, gitRemoteFor, startServicesFor, createBuildDisk, machineConfig, resolveAgentUser, AgentUserError, runBuildSteps, shellQuote, LEASE_SECONDS, createContainerRuntime, stopContainer, cleanupContainer, outOfMemoryReason, containerSenderCommand, signalInContainer, syncInContainer, copyTranscriptsFromContainer, senderAliveScript, HelperRefusal, GH_CONFIG_YML, ghHostsYml, isLiteralAddress, deleteBuildDisk, startCheckContainer, lifecycleSteps, lifecycleFailureReason, writeEvalInput, DeliveryFailure, EVAL_INPUT_NAME, copyTranscripts, senderSignalScript, containerJudgeEnvironment, copyJudgeTree } from './chunk-XHXDCYSK.js';
9
+ import { readBranchHead, fetchCommit, diffBetween } from './chunk-AXPCGD46.js';
9
10
  import { isSameProcess, startTimeOf } from './chunk-JBJTC3UU.js';
10
- import { HASH_ARGV, parseProgramHash, JUDGE_PROGRAM, writeJobFile, readJobFile, COMMAND_DIR, childEnvironment, judgeCommand, JUDGE_MAX_TURNS, MAX_REPORT_BYTES, JUDGE_DIR } from './chunk-5XCAPBE2.js';
11
- import { CLAUDE_CODE_VERSION } from './chunk-3W333NFO.js';
12
- import { waitForAgent, vmExecArgs } from './chunk-LY2L3O2O.js';
13
- import { socketPathProblem, vsockLinks, linkVsockSockets } from './chunk-PDIM5T65.js';
14
- import { describeCallFailure, resolveGoverningSource, refusalCode, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, logStamp, createRunnerLog, formatDuration, retrySend, formatClock } from './chunk-TQ6Y7YV6.js';
15
- import { WorkCommandError, postJson, isSignatureRefusal, getJson } from './chunk-RVYOOYOA.js';
11
+ import { HASH_ARGV, parseProgramHash, JUDGE_PROGRAM, writeJobFile, readJobFile, COMMAND_DIR, childEnvironment, judgeCommand, JUDGE_MAX_TURNS, MAX_REPORT_BYTES, JUDGE_DIR } from './chunk-QUGYGO6L.js';
12
+ import { CLAUDE_CODE_VERSION } from './chunk-RGW7ERF3.js';
13
+ import { waitForAgent, vmExecArgs } from './chunk-7OWPLRJR.js';
14
+ import { socketPathProblem, vsockLinks, linkVsockSockets } from './chunk-XGJUNNXL.js';
15
+ import { describeCallFailure, resolveGoverningSource, refusalCode, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, logStamp, createRunnerLog, formatDuration, retrySend, formatClock } from './chunk-YMKQVCKC.js';
16
+ import { WorkCommandError, postJson, isSignatureRefusal, getJson } from './chunk-X5LNCIZT.js';
16
17
  import { planArtifactUpload } from './chunk-BUP5N3X6.js';
17
- import { isBuiltinContainer, isBuiltinProcess, isBuiltinVm, DEFAULT_CHECK_TIME_LIMIT_MINUTES } from './chunk-D7X5ITVT.js';
18
+ import { isBuiltinContainer, isBuiltinProcess, isBuiltinVm, DEFAULT_CHECK_TIME_LIMIT_MINUTES } from './chunk-JWRX5ZTT.js';
18
19
  import { parseSize } from './chunk-7RQ73DLO.js';
19
20
  import { scrubText } from './chunk-D4AMAEZ7.js';
20
21
  import { readCloudConfig } from './chunk-EABW6AJQ.js';
@@ -22,11 +23,11 @@ import { resolvePackRoot } from './chunk-HBISTTG3.js';
22
23
  import { parsePolicy } from './chunk-RKOTJQVG.js';
23
24
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
24
25
  import { resolveVersion } from './chunk-RA3O54FC.js';
25
- import { signerFor } from './chunk-PVRBE7S4.js';
26
- import { RUNNER_FILE_MODE, runnerDir, buildDir, vsockPath } from './chunk-KF37SUDM.js';
27
- import { claudeCredential, repositoriesOf, primaryOf, buildEnvironment, JOB_MOUNT, CHECKOUT_DIR, parseIsolation, proxyEnvironment, withProxyWarningHidden, containerLocalAddress, destinationEnvironment, CLAUDE_CREDENTIAL_VARIABLES, builtInEnvironment, withHooksPath, startBuildServices, BUILT_IN_NAMES, AGENT_CREDENTIAL_MISSING, sharedUserEnvironment, headerVariables, authorEnvironment, withTunnelRecord, commitIdentityRecord, RELAY_PORT, repositoryPath, lifecycleWorkdir, checkEnvironment, EVAL_INPUT_DIR } from './chunk-BN3CSI7S.js';
28
- import { RUNNER_WORDED_REASONS, UNKNOWN_TRACKING_REASON } from './chunk-GISNHSYL.js';
29
- import { existsSync, statSync, appendFileSync, mkdirSync, chmodSync, writeFileSync, accessSync, constants, openSync, readFileSync, closeSync, rmSync, readdirSync, lstatSync, fstatSync, readSync, realpathSync } from 'fs';
26
+ import { signerFor } from './chunk-ZODVSFI4.js';
27
+ import { RUNNER_FILE_MODE, runnerDir, buildDir, vsockPath } from './chunk-ZI2ZVWKT.js';
28
+ import { claudeCredential, repositoriesOf, primaryOf, buildEnvironment, JOB_MOUNT, CHECKOUT_DIR, parseIsolation, proxyEnvironment, withProxyWarningHidden, containerLocalAddress, destinationEnvironment, CLAUDE_CREDENTIAL_VARIABLES, builtInEnvironment, withHooksPath, startBuildServices, BUILT_IN_NAMES, AGENT_CREDENTIAL_MISSING, sharedUserEnvironment, headerVariables, authorEnvironment, withTunnelRecord, commitIdentityRecord, RELAY_PORT, repositoryPath, lifecycleWorkdir, checkEnvironment, EVAL_INPUT_DIR } from './chunk-2K3TCQHW.js';
29
+ import { RUNNER_WORDED_REASONS, UNKNOWN_TRACKING_REASON } from './chunk-JGD5TWQ2.js';
30
+ import { existsSync, statSync, appendFileSync, mkdirSync, chmodSync, writeFileSync, accessSync, constants, openSync, readFileSync, closeSync, rmSync, readdirSync, linkSync, lstatSync, fstatSync, readSync, realpathSync } from 'fs';
30
31
  import { join, isAbsolute, dirname, delimiter, sep } from 'path';
31
32
  import { spawn, spawnSync } from 'child_process';
32
33
  import { randomBytes, createHash } from 'crypto';
@@ -94,6 +95,61 @@ function judgeProbe(probe, missedBefore) {
94
95
  if (probe.alive) return { kind: "running" };
95
96
  return missedBefore ? { kind: "lost" } : { kind: "recheck" };
96
97
  }
98
+ function unitNameFor(buildId) {
99
+ return `outerlayer-build-${buildId}`;
100
+ }
101
+ function linkIn(buildDir2, name, source) {
102
+ const target = join(buildDir2, name);
103
+ rmSync(target, { force: true });
104
+ try {
105
+ linkSync(source, target);
106
+ } catch (err) {
107
+ if (err.code === "EXDEV") {
108
+ throw new Error(`${source} and ${buildDir2} are on different file systems, so the build's files cannot be linked into its jail`);
109
+ }
110
+ throw err;
111
+ }
112
+ chmodSync(source, 292);
113
+ }
114
+ async function startJailed(input) {
115
+ linkIn(input.buildDir, "kernel", input.kernel);
116
+ linkIn(input.buildDir, "rootfs.ext4", input.rootfs);
117
+ for (const name of input.sockets) {
118
+ try {
119
+ chmodSync(join(input.buildDir, name), 438);
120
+ } catch (err) {
121
+ if (err.code !== "ENOENT") throw err;
122
+ }
123
+ }
124
+ return input.client.start({ build: input.buildId, kind: input.kind });
125
+ }
126
+ async function startJailedInto(state, input, save) {
127
+ state.jailed = { unit: unitNameFor(state.buildId), chroot: "" };
128
+ save();
129
+ try {
130
+ const started = await startJailed({ ...input, buildId: state.buildId, buildDir: state.buildDir });
131
+ state.jailed = { unit: started.unit, chroot: started.chroot };
132
+ state.vsockPath = started.vsock;
133
+ } catch (err) {
134
+ if (err instanceof HelperRefusal) {
135
+ delete state.jailed;
136
+ save();
137
+ }
138
+ throw err;
139
+ }
140
+ save();
141
+ }
142
+ async function stopJailed(helper, state) {
143
+ const probe = await helper.probe();
144
+ if (!probe.ok) throw new Error(`the build's unit ${state.jailed?.unit ?? unitNameFor(state.buildId)} could not be stopped, because there is no helper to ask: ${probe.detail}`);
145
+ try {
146
+ await probe.client.stop(state.buildId);
147
+ } catch (err) {
148
+ throw new Error(`the build's unit ${state.jailed?.unit ?? unitNameFor(state.buildId)} was not stopped: ${describeCallFailure(err)}`);
149
+ }
150
+ }
151
+
152
+ // src/runner/microvm/hooks.ts
97
153
  var DEFAULT_MEMORY = "8g";
98
154
  var DEFAULT_DISK = "40g";
99
155
  var DEFAULT_CPUS = 4;
@@ -147,6 +203,29 @@ async function unpackIntoGuest(runtime, state, dir, target, opts = {}) {
147
203
  async function deliverCommitHooks(input) {
148
204
  await unpackIntoGuest(input.runtime, input.state, input.hooksDir, GUEST_HOOKS_DIR);
149
205
  }
206
+ function vmAlive(runtime, state) {
207
+ if (state.jailed !== void 0) return runtime.vm.helper.alive(state.jailed.unit);
208
+ return state.firecracker !== void 0 && runtime.vm.firecracker.alive(state.firecracker);
209
+ }
210
+ async function helperFor(runtime, log) {
211
+ const probe = await runtime.vm.helper.probe();
212
+ if (probe.ok) return probe.client;
213
+ if (probe.reason === "unsupported") log(probe.detail);
214
+ else if (probe.unreachable === true) log(`${probe.detail}, so this build runs without the jailer`);
215
+ return void 0;
216
+ }
217
+ function consoleNote(state, consolePath) {
218
+ return state.jailed === void 0 ? `its console is in ${consolePath}` : `its console output is in the journal of the unit ${state.jailed.unit}`;
219
+ }
220
+ async function helperKills(runtime, state) {
221
+ const probe = await runtime.vm.helper.probe();
222
+ return probe.ok ? (await probe.client.state(state.buildId)).oomKills : 0;
223
+ }
224
+ async function microVmOomKills(runtime, state) {
225
+ if (state.cgroup !== void 0 && runtime.vm.cgroup.oomKills(state.cgroup) > 0) return 1;
226
+ if (state.jailed !== void 0) return helperKills(runtime, state);
227
+ return 0;
228
+ }
150
229
  async function provisionMicroVm(input) {
151
230
  const { config, runtime, item, itemKey, jobDir, log, tokens } = input;
152
231
  const { vm } = runtime;
@@ -224,9 +303,9 @@ async function provisionMicroVm(input) {
224
303
  input.save(state, environment);
225
304
  const bail = async (reason, aborted = false) => {
226
305
  let why = reason;
227
- if (!aborted && state.cgroup !== void 0) {
306
+ if (!aborted && (state.cgroup !== void 0 || state.jailed !== void 0)) {
228
307
  try {
229
- if (runtime.vm.cgroup.oomKills(state.cgroup) > 0) why = outOfMemoryReason(config.build?.memory);
308
+ if (await microVmOomKills(runtime, state) > 0) why = outOfMemoryReason(config.build?.memory);
230
309
  } catch (err) {
231
310
  log.error(`${tag} could not read the build's memory events: ${describeCallFailure(err)} \xB7 continuing`);
232
311
  }
@@ -266,8 +345,9 @@ async function provisionMicroVm(input) {
266
345
  };
267
346
  const links = vsockLinks({ destinations: config.build?.destinations?.length ?? 0, builtIns: true });
268
347
  const configPath = join(buildDir2, "vm.json");
348
+ const helper = await helperFor(runtime, (line) => log.line(`${tag} ${line}`));
269
349
  try {
270
- linkVsockSockets({ buildDir: buildDir2, vsockPath: state.vsockPath, links });
350
+ if (helper === void 0) linkVsockSockets({ buildDir: buildDir2, vsockPath: state.vsockPath, links });
271
351
  await createBuildDisk({ host: vm.rootfs, runnerDir: runnerDirPath, bytes: limits.diskBytes, dest: state.buildDisk, memoryBytes: limits.memoryBytes });
272
352
  writeFileSync(
273
353
  configPath,
@@ -282,24 +362,34 @@ async function provisionMicroVm(input) {
282
362
  return bail(`the build's disk and machine could not be made: ${describeCallFailure(err)}`);
283
363
  }
284
364
  if (input.aborted()) return bail("", true);
285
- try {
286
- state.cgroup = vm.cgroup.create(buildId, limits.memoryBytes);
287
- } catch (err) {
288
- return bail(`the build's memory limit could not be set: ${describeCallFailure(err)}`);
365
+ if (helper === void 0) {
366
+ try {
367
+ state.cgroup = vm.cgroup.create(buildId, limits.memoryBytes);
368
+ } catch (err) {
369
+ return bail(`the build's memory limit could not be set: ${describeCallFailure(err)}`);
370
+ }
371
+ if (state.cgroup !== void 0) input.save(state, environment);
289
372
  }
290
- if (state.cgroup !== void 0) input.save(state, environment);
291
373
  const consolePath = join(jobDir, "vm-console.log");
292
- try {
293
- state.firecracker = await vm.firecracker.spawn({ binary: assets.firecracker, configPath, consolePath, cgroup: state.cgroup });
294
- } catch (err) {
295
- return bail(`Firecracker did not start: ${describeCallFailure(err)}`);
374
+ if (helper !== void 0) {
375
+ try {
376
+ await startJailedInto(state, { client: helper, kind: "build", kernel: assets.kernel, rootfs: state.rootfs, sockets: links.map((link) => link.socket) }, () => input.save(state, environment));
377
+ } catch (err) {
378
+ return bail(`the microVM did not start under the jailer: ${describeCallFailure(err)}`);
379
+ }
380
+ } else {
381
+ try {
382
+ state.firecracker = await vm.firecracker.spawn({ binary: assets.firecracker, configPath, consolePath, cgroup: state.cgroup });
383
+ } catch (err) {
384
+ return bail(`Firecracker did not start: ${describeCallFailure(err)}`);
385
+ }
386
+ input.save(state, environment);
296
387
  }
297
- input.save(state, environment);
298
388
  if (input.aborted()) return bail("", true);
299
389
  const ready = await waitForAgent(state.vsockPath, { attempts: BOOT_ATTEMPTS, delayMs: BOOT_POLL_MS, sleep: runtime.sleep });
300
390
  if (!ready) {
301
- const why = vm.firecracker.alive(state.firecracker) ? "its exec agent did not answer" : "it exited before its exec agent answered";
302
- return bail(`the microVM did not start: ${why}; its console is in ${consolePath}`);
391
+ const why = vmAlive(runtime, state) ? "its exec agent did not answer" : "it exited before its exec agent answered";
392
+ return bail(`the microVM did not start: ${why}; ${consoleNote(state, consolePath)}`);
303
393
  }
304
394
  let pushes = Promise.resolve();
305
395
  let firstWriteFailure;
@@ -325,7 +415,7 @@ async function provisionMicroVm(input) {
325
415
  }
326
416
  tokens.onRead((token) => {
327
417
  pushes = pushes.then(async () => {
328
- if (state.firecracker === void 0 || !vm.firecracker.alive(state.firecracker)) return;
418
+ if (!vmAlive(runtime, state)) return;
329
419
  await writeGuestGhConfig(runtime, state, token);
330
420
  }, void 0).catch(reportWrite);
331
421
  });
@@ -467,7 +557,7 @@ function microVmSenderCommand(input) {
467
557
  return { command: process.execPath, args: [input.cli, "vm-exec", ...vmExecArgs(options)], env };
468
558
  }
469
559
  function isRunning(runtime, state) {
470
- return state.firecracker !== void 0 && runtime.vm.firecracker.alive(state.firecracker);
560
+ return vmAlive(runtime, state);
471
561
  }
472
562
  async function syncInMicroVm(input) {
473
563
  const { runtime, job } = input;
@@ -549,7 +639,7 @@ function microVmJudgeEnvironment(input) {
549
639
  const state = job.microvm;
550
640
  const agentUser = state.agentUser ?? ADDED_USER;
551
641
  const needsVm = () => {
552
- if (state.firecracker !== void 0 && !isRunning(runtime, state)) throw new Error("the build's microVM is gone");
642
+ if ((state.firecracker !== void 0 || state.jailed !== void 0) && !isRunning(runtime, state)) throw new Error("the build's microVM is gone");
553
643
  };
554
644
  return {
555
645
  stop: async () => {
@@ -681,8 +771,9 @@ async function startCheckMicroVm(input) {
681
771
  };
682
772
  const links = vsockLinks({ destinations: config.build?.destinations?.length ?? 0, builtIns: false });
683
773
  const configPath = join(buildDir2, "vm.json");
774
+ const helper = await helperFor(runtime, (line) => log.line(`${tag} ${line}`));
684
775
  try {
685
- linkVsockSockets({ buildDir: buildDir2, vsockPath: state.vsockPath, links });
776
+ if (helper === void 0) linkVsockSockets({ buildDir: buildDir2, vsockPath: state.vsockPath, links });
686
777
  await createBuildDisk({ host: vm.rootfs, runnerDir: runnerDirPath, bytes: limits.diskBytes, dest: state.buildDisk, memoryBytes: limits.memoryBytes });
687
778
  writeFileSync(
688
779
  configPath,
@@ -697,24 +788,34 @@ async function startCheckMicroVm(input) {
697
788
  return fail(`the check environment's disk and machine could not be made: ${describeCallFailure(err)}`);
698
789
  }
699
790
  if (abandoned()) return fail(ABANDONED);
700
- try {
701
- state.cgroup = vm.cgroup.create(buildId, limits.memoryBytes);
702
- } catch (err) {
703
- return fail(`the check environment's memory limit could not be set: ${describeCallFailure(err)}`);
704
- }
705
- if (state.cgroup !== void 0) input.save(state);
706
- const boot = async () => {
791
+ if (helper === void 0) {
707
792
  try {
708
- state.firecracker = await vm.firecracker.spawn({ binary: assets.firecracker, configPath, consolePath, cgroup: state.cgroup });
793
+ state.cgroup = vm.cgroup.create(buildId, limits.memoryBytes);
709
794
  } catch (err) {
710
- return `Firecracker did not start: ${describeCallFailure(err)}`;
795
+ return fail(`the check environment's memory limit could not be set: ${describeCallFailure(err)}`);
796
+ }
797
+ if (state.cgroup !== void 0) input.save(state);
798
+ }
799
+ const boot = async () => {
800
+ if (helper !== void 0) {
801
+ try {
802
+ await startJailedInto(state, { client: helper, kind: "check", kernel: assets.kernel, rootfs: state.rootfs, sockets: links.map((link) => link.socket) }, () => input.save(state));
803
+ } catch (err) {
804
+ return `the microVM did not start under the jailer: ${describeCallFailure(err)}`;
805
+ }
806
+ } else {
807
+ try {
808
+ state.firecracker = await vm.firecracker.spawn({ binary: assets.firecracker, configPath, consolePath, cgroup: state.cgroup });
809
+ } catch (err) {
810
+ return `Firecracker did not start: ${describeCallFailure(err)}`;
811
+ }
812
+ input.save(state);
711
813
  }
712
- input.save(state);
713
814
  if (abandoned()) return ABANDONED;
714
815
  const ready = await waitForAgent(state.vsockPath, { attempts: BOOT_ATTEMPTS, delayMs: BOOT_POLL_MS, sleep: runtime.sleep });
715
816
  if (!ready) {
716
- const why = vm.firecracker.alive(state.firecracker) ? "its exec agent did not answer" : "it exited before its exec agent answered";
717
- return `the microVM did not start: ${why}; its console is in ${consolePath}`;
817
+ const why = vmAlive(runtime, state) ? "its exec agent did not answer" : "it exited before its exec agent answered";
818
+ return `the microVM did not start: ${why}; ${consoleNote(state, consolePath)}`;
718
819
  }
719
820
  if (built.docker === true) return waitForDocker(runtime, state, agentUser, () => /* @__PURE__ */ new Date());
720
821
  return void 0;
@@ -740,7 +841,8 @@ async function startCheckMicroVm(input) {
740
841
  },
741
842
  restart: async () => {
742
843
  try {
743
- await vm.firecracker.stop(state.firecracker);
844
+ if (state.jailed !== void 0) await stopJailed(vm.helper, state);
845
+ else await vm.firecracker.stop(state.firecracker);
744
846
  rmSync(state.vsockPath, { force: true });
745
847
  if (await boot() !== void 0) return false;
746
848
  if (evalInput.delivered) await deliverEvalInput();
@@ -754,6 +856,10 @@ async function startCheckMicroVm(input) {
754
856
  }
755
857
  async function stopBuildMicroVm(runtime, state, jobDir) {
756
858
  await copyHookErrors(runtime, state, jobDir);
859
+ if (state.jailed !== void 0) {
860
+ await stopJailed(runtime.vm.helper, state);
861
+ return;
862
+ }
757
863
  if (state.firecracker === void 0) return;
758
864
  await runtime.vm.firecracker.stop(state.firecracker);
759
865
  if (runtime.vm.firecracker.alive(state.firecracker)) throw new Error(`the microVM (pid ${state.firecracker.pid}) is still running after it was stopped`);
@@ -761,6 +867,13 @@ async function stopBuildMicroVm(runtime, state, jobDir) {
761
867
  async function cleanupMicroVm(runtime, state, jobDir) {
762
868
  const failures = [];
763
869
  if (jobDir !== void 0) await copyHookErrors(runtime, state, jobDir);
870
+ if (state.jailed !== void 0) {
871
+ try {
872
+ await stopJailed(runtime.vm.helper, state);
873
+ } catch (err) {
874
+ failures.push(describeCallFailure(err));
875
+ }
876
+ }
764
877
  if (state.firecracker !== void 0) {
765
878
  try {
766
879
  await runtime.vm.firecracker.stop(state.firecracker);
@@ -786,6 +899,8 @@ async function cleanupMicroVm(runtime, state, jobDir) {
786
899
  }
787
900
  async function stopOrphanedMicroVms(input) {
788
901
  const stopped = [];
902
+ const report = (line) => input.onError?.(line);
903
+ const jailedByJobs = [];
789
904
  for (const { job } of input.jobs) {
790
905
  const states = [job.microvm, job.checkMicrovm].filter((state) => state !== void 0);
791
906
  if (states.length === 0) continue;
@@ -798,12 +913,38 @@ async function stopOrphanedMicroVms(input) {
798
913
  while (isSameProcess(job.pid, job.start) && Date.now() < deadline) await new Promise((resolve) => setTimeout(resolve, 10));
799
914
  }
800
915
  for (const state of states) {
916
+ if (state.jailed !== void 0) jailedByJobs.push(state.jailed.unit);
801
917
  if (state.firecracker !== void 0 && input.runtime.vm.firecracker.alive(state.firecracker)) {
802
- await input.runtime.vm.firecracker.stop(state.firecracker);
803
- stopped.push(state.buildId);
918
+ try {
919
+ await input.runtime.vm.firecracker.stop(state.firecracker);
920
+ stopped.push(state.buildId);
921
+ } catch (err) {
922
+ report(`the microVM of build ${state.buildId} (pid ${state.firecracker.pid}) was not stopped: ${describeCallFailure(err)}`);
923
+ }
804
924
  }
805
925
  }
806
926
  }
927
+ const probe = await input.runtime.vm.helper.probe();
928
+ if (!probe.ok) {
929
+ if (jailedByJobs.length > 0) report(`the units ${jailedByJobs.join(", ")} could not be stopped, because there is no helper to ask: ${probe.detail}`);
930
+ return stopped;
931
+ }
932
+ let builds;
933
+ try {
934
+ builds = await probe.client.list();
935
+ } catch (err) {
936
+ report(`the helper's list of builds could not be read: ${describeCallFailure(err)}`);
937
+ return stopped;
938
+ }
939
+ for (const build of builds) {
940
+ try {
941
+ await probe.client.stop(build);
942
+ } catch (err) {
943
+ report(`the unit of build ${build} was not stopped: ${describeCallFailure(err)}`);
944
+ continue;
945
+ }
946
+ if (!stopped.includes(build)) stopped.push(build);
947
+ }
807
948
  return stopped;
808
949
  }
809
950
  function provisionEnvironment(base, input) {
@@ -2468,9 +2609,9 @@ async function finishJob(job, jobDirPath, outcome, config, deps, ending) {
2468
2609
  }
2469
2610
  }
2470
2611
  let outOfMemory;
2471
- if (vmBuild?.state.cgroup !== void 0 && outcome !== void 0 && outcome !== "ok" && ending?.reason === void 0) {
2612
+ if ((vmBuild?.state.cgroup !== void 0 || vmBuild?.state.jailed !== void 0) && outcome !== void 0 && outcome !== "ok" && ending?.reason === void 0) {
2472
2613
  try {
2473
- if (vmBuild.runtime.vm.cgroup.oomKills(vmBuild.state.cgroup) > 0) {
2614
+ if (await microVmOomKills(vmBuild.runtime, vmBuild.state) > 0) {
2474
2615
  outOfMemory = outOfMemoryReason(config.build?.memory);
2475
2616
  }
2476
2617
  } catch (err) {
@@ -2739,8 +2880,15 @@ function unfinishedJobs(jobsDirPath) {
2739
2880
  function isContainerTracked(job) {
2740
2881
  return job.container?.tracking === "container";
2741
2882
  }
2883
+ function isReadable(job) {
2884
+ return readsJobState(job, READ_JOB_STATE_FORMATS);
2885
+ }
2886
+ function listUnreadableJobs(jobsDirPath) {
2887
+ return unfinishedJobs(jobsDirPath).flatMap(({ dirPath, job }) => isReadable(job) ? [] : [{ dirPath, job, format: jobStateFormatOf(job) }]);
2888
+ }
2742
2889
  function listTrackedJobs(jobsDirPath) {
2743
2890
  return unfinishedJobs(jobsDirPath).flatMap(({ dirPath, job }) => {
2891
+ if (!isReadable(job)) return [];
2744
2892
  const tracking = job.container?.tracking;
2745
2893
  if (tracking === void 0) return [];
2746
2894
  if (tracking === "container" && inTeardown(job)) return [];
@@ -2749,12 +2897,13 @@ function listTrackedJobs(jobsDirPath) {
2749
2897
  }
2750
2898
  function listAdoptableJobs(jobsDirPath) {
2751
2899
  return unfinishedJobs(jobsDirPath).filter(
2752
- ({ job }) => job.microvm === void 0 && job.pid !== void 0 && job.start !== void 0 && isSameProcess(job.pid, job.start)
2900
+ ({ job }) => isReadable(job) && job.microvm === void 0 && job.pid !== void 0 && job.start !== void 0 && isSameProcess(job.pid, job.start)
2753
2901
  );
2754
2902
  }
2755
2903
  async function recoverLostJobs(jobsDirPath, config, deps) {
2756
2904
  const recovered = [];
2757
2905
  for (const { dirPath, job } of unfinishedJobs(jobsDirPath)) {
2906
+ if (!isReadable(job)) continue;
2758
2907
  const tracking = job.container?.tracking;
2759
2908
  if (tracking !== void 0 && tracking !== "container") {
2760
2909
  recovered.push(await finishJob(job, dirPath, "interrupted", config, deps, { reason: UNKNOWN_TRACKING_REASON }));
@@ -2928,4 +3077,4 @@ async function stopSender(input) {
2928
3077
  }
2929
3078
  }
2930
3079
 
2931
- export { ALREADY_RELEASED, AttemptLogBook, EXIT_CODE_FILE, RENEW_INTERVAL_SECONDS, appendCommandLog, commandLogOffset, deliverCommitHooks, describeHookEnd, execArgv, execCommandLine, finishJob, hookLimitsFor, hostCommandEnvironment, hostEnvironment, isContainerTracked, isGroupAlive, isIdle, isTimedOut, isUnfinished, jobEnv, judgeProbe, listAdoptableJobs, listTrackedJobs, listenOnBroker, microVmCommandLine, needsRenew, outcomeFromExitCode, probeCommand, provisionEnvironment, provisionMicroVm, provisionProcess, readCpuUsec, readProvisionOut, recoverLostJobs, releaseLease, renewLease, resolveHostBuild, restartSender, retryFailedReleases, runCommand, runHook, setStage, startHostServices, startSender, stopOrphanedMicroVms, unfinishedJobs, workdirProblem };
3080
+ export { ALREADY_RELEASED, AttemptLogBook, EXIT_CODE_FILE, RENEW_INTERVAL_SECONDS, appendCommandLog, commandLogOffset, deliverCommitHooks, describeHookEnd, execArgv, execCommandLine, finishJob, hookLimitsFor, hostCommandEnvironment, hostEnvironment, inTeardown, isContainerTracked, isGroupAlive, isIdle, isReadable, isTimedOut, isUnfinished, jobEnv, judgeProbe, listAdoptableJobs, listTrackedJobs, listUnreadableJobs, listenOnBroker, microVmCommandLine, needsRenew, outcomeFromExitCode, probeCommand, provisionEnvironment, provisionMicroVm, provisionProcess, readCpuUsec, readProvisionOut, recoverLostJobs, releaseLease, renewLease, resolveHostBuild, restartSender, retryFailedReleases, runCommand, runHook, setStage, startHostServices, startSender, stopOrphanedMicroVms, unfinishedJobs, workdirProblem };
@@ -2,7 +2,7 @@
2
2
  import { createRequire } from 'node:module';
3
3
  import { runEmit } from './chunk-WX2WEERU.js';
4
4
  import { installStarterPack } from './chunk-VJBFQP3H.js';
5
- import { resolveGitCommonDir, defaultGitRunner } from './chunk-E4OUL7ZP.js';
5
+ import { resolveGitCommonDir, defaultGitRunner } from './chunk-FXUVXSY2.js';
6
6
  import { addStdioMcpEntryIfAbsent, addDocsMcpEntryIfAbsent, DOCS_MCP_SERVER_NAME } from './chunk-YVZJ6GKF.js';
7
7
  import { C } from './chunk-ANPNT6PM.js';
8
8
  import { AGENTS_MD_LAYOUT, declareAgentsMdLayout, linkClaudeSkills, SKILLS_LINK_PATH, describeSkillsLink, isAgentsMdLayout, holdsTodaysLayoutSources, discoverOuterlayerPaths } from './chunk-JKNYTNYD.js';
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { isVersion, compareVersions } from './chunk-TQMI335S.js';
4
- import { RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-KF37SUDM.js';
4
+ import { RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-ZI2ZVWKT.js';
5
5
  import { readFileSync, mkdirSync, writeFileSync, renameSync } from 'fs';
6
6
  import { join } from 'path';
7
7
 
@@ -2,7 +2,7 @@
2
2
  import { createRequire } from 'node:module';
3
3
  import { sanitizeTerminal } from './chunk-BUP5N3X6.js';
4
4
  import { DEFAULT_DASHBOARD } from './chunk-XSPA5ODY.js';
5
- import { cliFetch, resolveGatewayCredentials } from './chunk-FKXGQOF5.js';
5
+ import { cliFetch, resolveGatewayCredentials } from './chunk-M4B6QKNZ.js';
6
6
  import { writeRepoConnection, findGitDirs, readRepoConnection } from './chunk-BJ3KTMDH.js';
7
7
  import { remoteLookupFailed } from './chunk-D4AMAEZ7.js';
8
8
  import { readCloudConfig } from './chunk-EABW6AJQ.js';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { EXEC_PORT } from './chunk-PDIM5T65.js';
3
+ import { EXEC_PORT } from './chunk-XGJUNNXL.js';
4
4
  import { createConnection } from 'net';
5
5
 
6
6
  createRequire(import.meta.url);
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { currentLink } from './chunk-VV7ZD5LR.js';
3
+ import { currentLink } from './chunk-QMQC6JCO.js';
4
4
  import { readFileSync, statSync, chmodSync, mkdirSync, writeFileSync, renameSync, rmSync, existsSync, lstatSync, accessSync, constants, realpathSync } from 'fs';
5
5
  import { randomBytes } from 'crypto';
6
6
  import { join, dirname, delimiter, resolve } from 'path';
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { claimPidFile, RunnerAlreadyRunningError, releasePidFile } from './chunk-FWEWFW3F.js';
3
+ import { claimPidFile, RunnerAlreadyRunningError, releasePidFile } from './chunk-DEBOL6ON.js';
4
4
  import { startTimeOf } from './chunk-JBJTC3UU.js';
5
- import { CLAUDE_CODE_VERSION, NODE_IMAGE, DEFAULT_BASE_IMAGE, RecipeError, locateRecipe, readRecipe, assertBuildable, TINI_VERSION, GH_VERSION, writeSanitizedRecipe, classifyProperties, GH_SHA256, TINI_SHA256, SANITIZED_NAME } from './chunk-3W333NFO.js';
6
- import { RUNNER_DIR_MODE, repoCacheDir, imagesDir, attemptStamp, runnerDir, rootfsPathFor, RUNNER_FILE_MODE } from './chunk-KF37SUDM.js';
7
- import { withGitConfig, tokenHeader, PROXY_WARNING_FLAG } from './chunk-BN3CSI7S.js';
8
- import { RELAY_ID, RELAY_USER } from './chunk-GISNHSYL.js';
5
+ import { CLAUDE_CODE_VERSION, NODE_IMAGE, DEFAULT_BASE_IMAGE, RecipeError, locateRecipe, readRecipe, assertBuildable, TINI_VERSION, GH_VERSION, writeSanitizedRecipe, classifyProperties, GH_SHA256, TINI_SHA256, SANITIZED_NAME } from './chunk-RGW7ERF3.js';
6
+ import { RUNNER_DIR_MODE, repoCacheDir, imagesDir, attemptStamp, runnerDir, rootfsPathFor, RUNNER_FILE_MODE } from './chunk-ZI2ZVWKT.js';
7
+ import { withGitConfig, tokenHeader, PROXY_WARNING_FLAG } from './chunk-2K3TCQHW.js';
8
+ import { RELAY_ID, RELAY_USER } from './chunk-JGD5TWQ2.js';
9
9
  import { mkdirSync, rmSync, existsSync, mkdtempSync, cpSync, readFileSync, writeFileSync, readdirSync, lstatSync, readlinkSync } from 'fs';
10
10
  import { tmpdir } from 'os';
11
11
  import { dirname, join } from 'path';
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { isSameProcess } from './chunk-JBJTC3UU.js';
4
- import { RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-KF37SUDM.js';
4
+ import { RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-ZI2ZVWKT.js';
5
5
  import { existsSync, readFileSync, rmSync, mkdirSync, writeFileSync } from 'fs';
6
6
  import { dirname } from 'path';
7
7
 
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { removeRetiredSkills } from './chunk-MQ743JX3.js';
4
- import { defaultFetch, resolveGatewayCredentials } from './chunk-FKXGQOF5.js';
4
+ import { defaultFetch, resolveGatewayCredentials } from './chunk-M4B6QKNZ.js';
5
5
  import { appendContextProvenance } from './chunk-ZJSNLVCE.js';
6
6
  import { loadMaintainedFiles, writeMaintainedFiles } from './chunk-HBISTTG3.js';
7
7
  import { cliInvocation } from './chunk-CRB3POP4.js';
8
8
  import { writeDegraded, writeSourceCache, SOURCE_CACHE_TTL_RETRY_MS, writeContextManifest, SOURCE_CACHE_TTL_SUCCESS_MS, readSourceCache, isSourceCacheFresh, clearDegraded } from './chunk-YQR6E6OV.js';
9
9
  import { normalizeRepoName, parseOuterlayerConfig, classifyTree, emitTree } from './chunk-RKOTJQVG.js';
10
10
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
11
- import { withTokenHeader } from './chunk-BN3CSI7S.js';
11
+ import { withTokenHeader } from './chunk-2K3TCQHW.js';
12
12
  import { execFileSync } from 'child_process';
13
13
  import { existsSync, mkdirSync, writeFileSync, chmodSync, lstatSync, readFileSync, copyFileSync } from 'fs';
14
14
  import { isAbsolute, join, dirname } from 'path';
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { autoConnect, detectActiveSession } from './chunk-F2W2IYNP.js';
4
- import { defaultFetch, unauthorizedMessage, resolveGatewayCredentials } from './chunk-FKXGQOF5.js';
3
+ import { autoConnect, detectActiveSession } from './chunk-HWEIFHSW.js';
4
+ import { defaultFetch, unauthorizedMessage, resolveGatewayCredentials } from './chunk-M4B6QKNZ.js';
5
5
  import { resolveRepoIdentity } from './chunk-D4AMAEZ7.js';
6
6
  import { C } from './chunk-ANPNT6PM.js';
7
7
  import { parseWorkItemEnv } from './chunk-T2Q7ISPE.js';
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { fetchFactories, selectFactory, saveFactoryConnection, autoConnectedLine } from './chunk-V5Q3S4NM.js';
4
- import { resolveGatewayCredentials } from './chunk-FKXGQOF5.js';
3
+ import { fetchFactories, selectFactory, saveFactoryConnection, autoConnectedLine } from './chunk-6CNHXHI2.js';
4
+ import { resolveGatewayCredentials } from './chunk-M4B6QKNZ.js';
5
5
  import { findGitDirs, readRepoConnection } from './chunk-BJ3KTMDH.js';
6
6
  import { resolveRepoIdentity } from './chunk-D4AMAEZ7.js';
7
7
  import { cliInvocation } from './chunk-CRB3POP4.js';
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { launchRefusalForSession } from './chunk-ESVW4MJY.js';
4
- import { autoConnect, detectActiveSession } from './chunk-F2W2IYNP.js';
4
+ import { autoConnect, detectActiveSession } from './chunk-HWEIFHSW.js';
5
5
  import { acquireSpoolLockAt } from './chunk-BUP5N3X6.js';
6
- import { resolveGatewayCredentials, defaultFetch, unauthorizedMessage } from './chunk-FKXGQOF5.js';
6
+ import { resolveGatewayCredentials, defaultFetch, unauthorizedMessage } from './chunk-M4B6QKNZ.js';
7
7
  import { resolveRepoIdentity } from './chunk-D4AMAEZ7.js';
8
8
  import { C } from './chunk-ANPNT6PM.js';
9
9
  import { launchedItemForSession } from './chunk-T2Q7ISPE.js';
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { builtinKind } from './chunk-D7X5ITVT.js';
3
+ import { builtinKind } from './chunk-JWRX5ZTT.js';
4
4
  import { parseSize } from './chunk-7RQ73DLO.js';
5
- import { runnerDir } from './chunk-KF37SUDM.js';
5
+ import { runnerDir } from './chunk-ZI2ZVWKT.js';
6
6
  import { dirname } from 'path';
7
7
  import { spawnSync } from 'child_process';
8
8
 
@@ -16,16 +16,19 @@ function escapeUnitPath(path) {
16
16
  return path.replace(/%/g, "%%").replace(/ /g, "\\x20");
17
17
  }
18
18
  function runnerUnit(unit) {
19
+ const helperService = unit.helper === void 0 ? void 0 : `${unit.helper.unit}.service`;
19
20
  return `${UNIT_MARKER}
20
21
  [Unit]
21
22
  Description=OuterLayer runner
22
- After=network-online.target${unit.docker ? " docker.service" : ""}
23
+ After=network-online.target${unit.docker ? " docker.service" : ""}${helperService === void 0 ? "" : ` ${helperService}`}
23
24
  Wants=network-online.target
24
- ${unit.docker ? "Requires=docker.service\n" : ""}
25
+ ${helperService === void 0 ? "" : `Wants=${helperService}
26
+ `}${unit.docker ? "Requires=docker.service\n" : ""}
25
27
  [Service]
26
28
  User=${unit.user}
27
29
  ExecStart=${unit.execStart}
28
- EnvironmentFile=-${escapeUnitPath(`${unit.configDir}/runner.env`)}
30
+ ${unit.helper === void 0 ? "" : `Environment=OUTERLAYER_HELPER_SOCKET=${unit.helper.socket}
31
+ `}EnvironmentFile=-${escapeUnitPath(`${unit.configDir}/runner.env`)}
29
32
  Restart=on-failure
30
33
  RestartForceExitStatus=75
31
34
  RestartSec=30
@@ -143,7 +146,8 @@ function installService(request, deps) {
143
146
  configDir: dirname(request.configPath),
144
147
  execStart: request.execStart,
145
148
  timeLimitMinutes: request.timeLimitMinutes,
146
- docker: kind === "container" || kind === "vm" || builtinKind(request.hooks.cleanup) === "container" || builtinKind(request.hooks.cleanup) === "vm"
149
+ docker: kind === "container" || kind === "vm" || builtinKind(request.hooks.cleanup) === "container" || builtinKind(request.hooks.cleanup) === "vm",
150
+ ...request.helperSocket !== void 0 && request.helperUnit !== void 0 ? { helper: { unit: request.helperUnit, socket: request.helperSocket } } : {}
147
151
  });
148
152
  if (request.print === true) return outcome(true, "printed", [], unit);
149
153
  if (own) return outcome(false, "refused", [OWN_HOOKS]);
@@ -274,4 +278,4 @@ function uninstallService(request, deps) {
274
278
  return outcome(true, "removed", lines);
275
279
  }
276
280
 
277
- export { DEFAULT_UNIT_NAME, RUNNER_RESERVE_BYTES, VM_SERVICE_NAME, checkFit, installService, realTaskScheduler, uninstallService, unitPathFor };
281
+ export { DEFAULT_UNIT_NAME, RUNNER_RESERVE_BYTES, UNIT_MARKER, VM_SERVICE_NAME, checkFit, installService, realTaskScheduler, uninstallService, unitPathFor };
@@ -30,12 +30,14 @@ var UNKNOWN_TRANSPORT_REASON = "the runner cannot tell how this build reaches it
30
30
  var COMMAND_LOST_REASON = "the build's command ended without recording an exit code";
31
31
  var CONTAINER_STOPPED_REASON = "the build's container stopped while no runner was managing it";
32
32
  var UNKNOWN_TRACKING_REASON = "the runner cannot tell how this build is tracked";
33
+ var DOCKER_DESKTOP_REASON = "Docker Desktop is accepted only for a runner in the runner image, so container builds here need Docker Engine: install it (on Windows, inside WSL2), run the runner image, or use builtin:process";
33
34
  var RUNNER_WORDED_REASONS = /* @__PURE__ */ new Set([
34
35
  MALFORMED_REASON,
35
36
  UNKNOWN_TRANSPORT_REASON,
36
37
  COMMAND_LOST_REASON,
37
38
  CONTAINER_STOPPED_REASON,
38
- UNKNOWN_TRACKING_REASON
39
+ UNKNOWN_TRACKING_REASON,
40
+ DOCKER_DESKTOP_REASON
39
41
  ]);
40
42
 
41
- export { COMMAND_LOST_REASON, CONTAINER_STOPPED_REASON, JOIN_DIR, JOIN_SOCKET, JOIN_WAIT_MS, MALFORMED_REASON, MAX_MALFORMED_SESSIONS, MAX_OPEN_STREAMS, RELAY_ID, RELAY_USER, RUNNER_WORDED_REASONS, SESSION_WINDOW, STREAM_WINDOW, TARGET_CLAUDE, TARGET_GATEWAY, TARGET_LEASE, TARGET_TUNNEL, UNKNOWN_TRACKING_REASON, UNKNOWN_TRANSPORT_REASON, destinationTarget, targetOfPath };
43
+ export { COMMAND_LOST_REASON, CONTAINER_STOPPED_REASON, DOCKER_DESKTOP_REASON, JOIN_DIR, JOIN_SOCKET, JOIN_WAIT_MS, MALFORMED_REASON, MAX_MALFORMED_SESSIONS, MAX_OPEN_STREAMS, RELAY_ID, RELAY_USER, RUNNER_WORDED_REASONS, SESSION_WINDOW, STREAM_WINDOW, TARGET_CLAUDE, TARGET_GATEWAY, TARGET_LEASE, TARGET_TUNNEL, UNKNOWN_TRACKING_REASON, UNKNOWN_TRANSPORT_REASON, destinationTarget, targetOfPath };