@outerlayer/cli 0.26.1 → 0.26.2

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 (62) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +3 -1
  3. package/dist/{build-JK2DLT6X.js → build-AW4A2QPK.js} +2 -2
  4. package/dist/build-info.json +1 -1
  5. package/dist/{builder-TMA25KRR.js → builder-TDCBQ2RD.js} +2 -2
  6. package/dist/{check-3CBJVXZD.js → check-KL3LDAI3.js} +19 -19
  7. package/dist/{chunk-QIIMZC7W.js → chunk-2EAVBJMO.js} +1 -1
  8. package/dist/{chunk-DYEFPYME.js → chunk-2O5KA67H.js} +1 -1
  9. package/dist/{chunk-TBJ7KO2A.js → chunk-6OYAW5SF.js} +15 -10
  10. package/dist/{chunk-AINUN2TT.js → chunk-DJILFADE.js} +1 -1
  11. package/dist/{chunk-D7V33CAH.js → chunk-DXHISLCI.js} +1 -1
  12. package/dist/{chunk-4R24DSL2.js → chunk-FI66JNLT.js} +4 -4
  13. package/dist/{chunk-XPKI5OMT.js → chunk-GMPXOQTH.js} +1 -1
  14. package/dist/{chunk-ILL2CWOU.js → chunk-GUT4IU7K.js} +16 -12
  15. package/dist/{chunk-DXDF43YG.js → chunk-I7RZHMXW.js} +1 -1
  16. package/dist/{chunk-7I6GZSN3.js → chunk-KZLLLARE.js} +1 -1
  17. package/dist/{chunk-2N72GPS2.js → chunk-MWPBF2XG.js} +1 -1
  18. package/dist/{chunk-HPOEVC2V.js → chunk-MXTN35XN.js} +3 -3
  19. package/dist/{chunk-GAWZ7ATV.js → chunk-OL2O5PEI.js} +61 -16
  20. package/dist/{chunk-JUTN2HUP.js → chunk-PCY7IGSL.js} +2 -2
  21. package/dist/{chunk-7NKVMAP6.js → chunk-RO3BRAO6.js} +2 -2
  22. package/dist/{chunk-BMWIUSTZ.js → chunk-TODY3MTS.js} +3 -3
  23. package/dist/{chunk-PNHNKMA3.js → chunk-U2FSJBNI.js} +2 -2
  24. package/dist/{chunk-GNPTU4BM.js → chunk-URIZRCRY.js} +2 -1
  25. package/dist/{chunk-IIFMFX6J.js → chunk-V5LUWRCV.js} +2 -2
  26. package/dist/{chunk-GQOT37HL.js → chunk-WA7R6U2F.js} +5 -5
  27. package/dist/{chunk-XGJUNNXL.js → chunk-XLC7KEUV.js} +3 -1
  28. package/dist/{cli-7HVTFJZO.js → cli-UH2YQA5M.js} +63 -61
  29. package/dist/{command-2Q5UDZUO.js → command-ZECJJNLY.js} +9 -9
  30. package/dist/{container-start-SCCR2PRD.js → container-start-GFH5LLSG.js} +10 -10
  31. package/dist/{docker-4X2A5HDY.js → docker-Q7QJMX7I.js} +2 -2
  32. package/dist/{doctor-3QA5Y5HG.js → doctor-3LCCPBX6.js} +11 -11
  33. package/dist/{emit-artifact-cmd-SFUSDWZM.js → emit-artifact-cmd-AIBDDJGW.js} +4 -4
  34. package/dist/{emit-result-cmd-NEICBIDU.js → emit-result-cmd-LQN6AGGP.js} +4 -4
  35. package/dist/{exec-client-KH33DICR.js → exec-client-J6L5FDRR.js} +2 -2
  36. package/dist/{governing-source-J5DF65X5.js → governing-source-5OU235UP.js} +2 -2
  37. package/dist/{guest-init-TOSKPGPF.js → guest-init-CXIHA5VI.js} +2 -2
  38. package/dist/{hook-fast-REXH5P6R.js → hook-fast-LZSHEKUA.js} +1 -1
  39. package/dist/{hook-wrap-fast-NOOGDNSW.js → hook-wrap-fast-7VYYAAH4.js} +2 -2
  40. package/dist/index.js +5 -5
  41. package/dist/{init-UMON3HZK.js → init-ARB2JUPA.js} +10 -10
  42. package/dist/{init-NEUTUGEQ.js → init-C2RROWQU.js} +10 -10
  43. package/dist/{init-cmd-54DMRBNO.js → init-cmd-SLXPX44L.js} +5 -5
  44. package/dist/{loop-6JKW5QR5.js → loop-QQV4PYNX.js} +19 -19
  45. package/dist/{machine-XF55O56X.js → machine-OVXDPPFK.js} +9 -9
  46. package/dist/{runner-identity-NH6RLVMI.js → runner-identity-QQU6BUUO.js} +2 -2
  47. package/dist/{runner-key-FUNSJ564.js → runner-key-WIEESRA5.js} +10 -10
  48. package/dist/{session-sender-P5GVOIUY.js → session-sender-DFB2N3DO.js} +5 -5
  49. package/dist/settings-3DBYKYQD.js +7 -0
  50. package/dist/{spec-cmd-HMFW552G.js → spec-cmd-FBA4BJPZ.js} +1 -1
  51. package/dist/{status-ULZVKQ7G.js → status-V2DWSLL3.js} +15 -15
  52. package/dist/{statusline-fast-GVRSBHAF.js → statusline-fast-YVHG6ZLX.js} +2 -2
  53. package/dist/{sync-cmd-VCLCOME6.js → sync-cmd-KU567KX6.js} +4 -4
  54. package/dist/{watch-SVGL24OX.js → watch-LBPCO6GR.js} +4 -4
  55. package/dist/{work-claim-cmd-WQF5RTCT.js → work-claim-cmd-IT7R7G3E.js} +3 -3
  56. package/dist/{work-cmd-TGSNYPSG.js → work-cmd-SJB6N6FZ.js} +1 -1
  57. package/dist/{work-comment-cmd-O3FVX6M4.js → work-comment-cmd-FGUQM2F3.js} +1 -1
  58. package/dist/{work-logs-cmd-2RMJFVNZ.js → work-logs-cmd-74GRYFTW.js} +1 -1
  59. package/dist/{work-open-pr-cmd-5EP7BKRE.js → work-open-pr-cmd-CX7A2BE5.js} +1 -1
  60. package/dist/{work-stop-cmd-TNJYBLMN.js → work-stop-cmd-W6EKY5Y3.js} +1 -1
  61. package/package.json +1 -1
  62. package/dist/settings-AKYEOCC2.js +0 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @outerlayer/cli
2
2
 
3
+ ## 0.26.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 7c8012c: The hooks that `outerlayer init --org` prints, and the hooks and status line that `outerlayer init --project` and `outerlayer hooks wrap --project` write, run `outerlayer` from the PATH. They work on every machine, instead of naming the install path of the machine that wrote them. The `--org` snippet also names the Windows registry value, `Settings`, and says to install the CLI on each machine.
8
+ - 3c1d9ee: A microVM build powers off when its lease runs out with no runner renewing it. A build started through the root helper ends at `runner.timeLimitMinutes` plus 10 minutes, even when no runner stops it.
9
+
3
10
  ## 0.26.1
4
11
 
5
12
  ### Patch Changes
package/README.md CHANGED
@@ -234,7 +234,9 @@ content:
234
234
  With the root helper installed, the runner asks it over a Unix socket that only
235
235
  the runner's account can open to start each microVM build under Firecracker's
236
236
  jailer. That socket is local, and nothing about the host leaves the machine
237
- through it.
237
+ through it. The runner also serves a lease socket in each build's directory,
238
+ which the guest reaches over vsock. The runner writes only the time left on
239
+ the build's lease to it, and the guest powers off when that time runs out.
238
240
  - **`outerlayer runner install --service` with `builtin:vm` hooks** downloads the
239
241
  root helper from github.com on each install, from the same public guest assets
240
242
  repository, and checks it against a sha256 pinned in the CLI. The request
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { buildRepositoryImage } from './chunk-AINUN2TT.js';
3
+ export { buildRepositoryImage } from './chunk-DJILFADE.js';
4
4
  import './chunk-PYSKSROG.js';
5
5
  import './chunk-JBJTC3UU.js';
6
- export { RecipeError } from './chunk-4R24DSL2.js';
6
+ export { RecipeError } from './chunk-FI66JNLT.js';
7
7
  import './chunk-L4CW6LZQ.js';
8
8
  import './chunk-2K3TCQHW.js';
9
9
  import './chunk-JGD5TWQ2.js';
@@ -1 +1 @@
1
- {"id":"2026-10-16T15:29:16.974Z+c2e9a47","root":"/home/runner/_work/outerlayer/outerlayer","pkg":"outerlayer"}
1
+ {"id":"2026-10-16T18:16:32.915Z+7b81ff6","root":"/home/runner/_work/outerlayer/outerlayer","pkg":"outerlayer"}
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { MIN_BUILDX_VERSION, builderName, builderSpec, buildxState, ensureBuilder, ensureFailureCount, isOutOfMemory, proxyEnvironment, trackImageBuild } from './chunk-7I6GZSN3.js';
4
- import './chunk-4R24DSL2.js';
3
+ export { MIN_BUILDX_VERSION, builderName, builderSpec, buildxState, ensureBuilder, ensureFailureCount, isOutOfMemory, proxyEnvironment, trackImageBuild } from './chunk-KZLLLARE.js';
4
+ import './chunk-FI66JNLT.js';
5
5
  import './chunk-7RQ73DLO.js';
6
6
  import './chunk-QE3UQAHK.js';
7
7
  import './chunk-QZBXLLTV.js';
@@ -1,41 +1,41 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { probeCredentials } from './chunk-TBJ7KO2A.js';
4
- import './chunk-GAWZ7ATV.js';
3
+ import { probeCredentials } from './chunk-6OYAW5SF.js';
4
+ import './chunk-OL2O5PEI.js';
5
5
  import './chunk-TKL74NLB.js';
6
6
  import './chunk-ZVB57WI6.js';
7
7
  import './chunk-6FAP657M.js';
8
8
  import './chunk-3JVYMD4G.js';
9
9
  import './chunk-YETTWTAY.js';
10
10
  import './chunk-TPKYTORP.js';
11
- import './chunk-IIFMFX6J.js';
12
- import './chunk-2N72GPS2.js';
11
+ import './chunk-V5LUWRCV.js';
12
+ import './chunk-MWPBF2XG.js';
13
13
  import './chunk-UNF7MWEL.js';
14
- import './chunk-PNHNKMA3.js';
14
+ import './chunk-U2FSJBNI.js';
15
15
  import './chunk-EORWWFPA.js';
16
16
  import './chunk-ESVW4MJY.js';
17
- import { placeholderQueues, placeholderProblem, permissionModeProblems, permissionModeProblem, needsClaudeCredential, claudeCredentialCheck, claimPermissionProblem, formerSkillQueues, formerSkillProblem } from './chunk-BMWIUSTZ.js';
17
+ import { placeholderQueues, placeholderProblem, permissionModeProblems, permissionModeProblem, needsClaudeCredential, claudeCredentialCheck, claimPermissionProblem, formerSkillQueues, formerSkillProblem } from './chunk-TODY3MTS.js';
18
18
  import './chunk-4IFKLYMM.js';
19
19
  import './chunk-YYYRBYWG.js';
20
20
  import './chunk-TBT347UY.js';
21
- import './chunk-JUTN2HUP.js';
22
- import './chunk-7NKVMAP6.js';
23
- import './chunk-ILL2CWOU.js';
21
+ import './chunk-PCY7IGSL.js';
22
+ import './chunk-RO3BRAO6.js';
23
+ import './chunk-GUT4IU7K.js';
24
24
  import './chunk-665QWBNW.js';
25
25
  import './chunk-TQMI335S.js';
26
26
  import './chunk-5PMQDQFV.js';
27
27
  import './chunk-MLD2NA7N.js';
28
28
  import { parseRunnerEnv } from './chunk-6MZSX4M7.js';
29
- import './chunk-AINUN2TT.js';
29
+ import './chunk-DJILFADE.js';
30
30
  import './chunk-PYSKSROG.js';
31
31
  import './chunk-JBJTC3UU.js';
32
32
  import './chunk-OGFGZQA3.js';
33
- import './chunk-7I6GZSN3.js';
34
- import './chunk-4R24DSL2.js';
35
- import './chunk-HPOEVC2V.js';
36
- import './chunk-XGJUNNXL.js';
37
- import './chunk-D7V33CAH.js';
38
- import './chunk-XPKI5OMT.js';
33
+ import './chunk-KZLLLARE.js';
34
+ import './chunk-FI66JNLT.js';
35
+ import './chunk-MXTN35XN.js';
36
+ import './chunk-XLC7KEUV.js';
37
+ import './chunk-DXHISLCI.js';
38
+ import './chunk-GMPXOQTH.js';
39
39
  import './chunk-HXFRJKMU.js';
40
40
  import './chunk-TEVO3RUV.js';
41
41
  import './chunk-BUP5N3X6.js';
@@ -47,9 +47,9 @@ import './chunk-7RQ73DLO.js';
47
47
  import './chunk-W3NVHOCS.js';
48
48
  import './chunk-MQ743JX3.js';
49
49
  import './chunk-QRZLUUNN.js';
50
- import './chunk-QIIMZC7W.js';
50
+ import './chunk-2EAVBJMO.js';
51
51
  import './chunk-ZJSNLVCE.js';
52
- import './chunk-DYEFPYME.js';
52
+ import './chunk-2O5KA67H.js';
53
53
  import './chunk-BKO6JEZI.js';
54
54
  import './chunk-VPEGE3QZ.js';
55
55
  import './chunk-HCVLP7XA.js';
@@ -62,7 +62,7 @@ import './chunk-HBISTTG3.js';
62
62
  import './chunk-T2Q7ISPE.js';
63
63
  import './chunk-WZBHBH3J.js';
64
64
  import './chunk-CRB3POP4.js';
65
- import './chunk-GNPTU4BM.js';
65
+ import './chunk-URIZRCRY.js';
66
66
  import './chunk-YQR6E6OV.js';
67
67
  import './chunk-TUSYOL2O.js';
68
68
  import './chunk-RKOTJQVG.js';
@@ -429,7 +429,7 @@ async function handleWorkLaunch(sessionId, home, env, spawnImpl = spawnDetached,
429
429
  }
430
430
  async function missingRenewalHookContext(home, cwd) {
431
431
  try {
432
- const { settingsPath, readSettings, isOurHookCommand } = await import('./settings-AKYEOCC2.js');
432
+ const { settingsPath, readSettings, isOurHookCommand } = await import('./settings-3DBYKYQD.js');
433
433
  const userSettings = readSettings(settingsPath("user", { home }));
434
434
  const projectSettings = readSettings(settingsPath("project", { cwd }));
435
435
  if (userSettings === null && projectSettings === null) return void 0;
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { decodeWrappedCommand } from './chunk-GNPTU4BM.js';
3
+ import { decodeWrappedCommand } from './chunk-URIZRCRY.js';
4
4
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
5
5
  import { readFileSync, mkdirSync, appendFileSync, writeFileSync } from 'fs';
6
6
  import { spawn } from 'child_process';
@@ -1,25 +1,25 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { releaseLease, isUnfinished, setStage, jobEnv, runHook, describeHookEnd, provisionMicroVm, deliverCommitHooks, provisionProcess, provisionEnvironment, readProvisionOut, resolveHostBuild, workdirProblem, listenOnBroker, hostEnvironment, hostCommandEnvironment, execArgv, microVmCommandLine, runCommand, commandLogOffset, execCommandLine, startSender, startHostServices, finishJob, isContainerTracked, probeCommand, appendCommandLog, judgeProbe, EXIT_CODE_FILE, isGroupAlive, outcomeFromExitCode, isTimedOut, readCpuUsec, isIdle, stopOrphanedMicroVms, unfinishedJobs, listUnreadableJobs, listAdoptableJobs, retryFailedReleases, recoverLostJobs, hookLimitsFor, AttemptLogBook, needsRenew, renewLease, RENEW_INTERVAL_SECONDS, listTrackedJobs, restartSender, ALREADY_RELEASED, inTeardown } from './chunk-GAWZ7ATV.js';
3
+ import { releaseLease, isUnfinished, setStage, jobEnv, runHook, describeHookEnd, provisionMicroVm, deliverCommitHooks, provisionProcess, provisionEnvironment, readProvisionOut, resolveHostBuild, workdirProblem, listenOnBroker, hostEnvironment, hostCommandEnvironment, execArgv, microVmCommandLine, runCommand, commandLogOffset, execCommandLine, startSender, startHostServices, finishJob, isContainerTracked, probeCommand, appendCommandLog, judgeProbe, EXIT_CODE_FILE, isGroupAlive, outcomeFromExitCode, isTimedOut, readCpuUsec, isIdle, stopOrphanedMicroVms, unfinishedJobs, listUnreadableJobs, listAdoptableJobs, retryFailedReleases, recoverLostJobs, hookLimitsFor, AttemptLogBook, needsRenew, renewLease, RENEW_INTERVAL_SECONDS, listTrackedJobs, restartSender, ALREADY_RELEASED, inTeardown } from './chunk-OL2O5PEI.js';
4
4
  import { writePendingUpdate } from './chunk-TKL74NLB.js';
5
5
  import { JOB_STATE_FORMAT, readsJobState, jobStateFormatOf } from './chunk-ZVB57WI6.js';
6
6
  import { readHousekeepingRecord, writeHousekeepingRecord } from './chunk-6FAP657M.js';
7
7
  import { decideInstalledSwitch } from './chunk-3JVYMD4G.js';
8
8
  import { fetchVersionMeta, npmVersion, npmSupportsProvenance, fetchTarballDigest, fetchProvenance, installVersion, auditSignatures } from './chunk-YETTWTAY.js';
9
9
  import { RUNNER_PROTOCOL } from './chunk-TPKYTORP.js';
10
- import { currentSkillCommand, formerSkillProblem, placeholderQueues, placeholderProblem } from './chunk-BMWIUSTZ.js';
10
+ import { currentSkillCommand, formerSkillProblem, placeholderQueues, placeholderProblem } from './chunk-TODY3MTS.js';
11
11
  import { writeMarker, readMarker, currentVersion, removeMarker, entryIn, versionDir, startedThroughCurrent, switchCurrent, isInLayout, cleanVersions, stagingDir } from './chunk-4IFKLYMM.js';
12
12
  import { freeBytes, formatBytes } from './chunk-YYYRBYWG.js';
13
13
  import { RepoFilter } from './chunk-TBT347UY.js';
14
- import { LEASE_SECONDS, provisionContainer, leaseExpiresAtMs, deliverContainerHooks, lifecycleSteps, lifecycleFailureReason, prepareBranch, containerCommandExec, measureDisk, setUpRunnerCgroup, createContainerRuntime, parseCpuList, ensureTunnel, keepGhConfigCurrent, filesAreCopied } from './chunk-ILL2CWOU.js';
14
+ import { leaseTimeLeftMs, LEASE_SECONDS, provisionContainer, leaseExpiresAtMs, deliverContainerHooks, lifecycleSteps, lifecycleFailureReason, prepareBranch, containerCommandExec, measureDisk, setUpRunnerCgroup, createContainerRuntime, parseCpuList, ensureTunnel, keepGhConfigCurrent, filesAreCopied } from './chunk-GUT4IU7K.js';
15
15
  import { tagToPull, pullInstruction, imageTag, writeUpdateStatus } from './chunk-665QWBNW.js';
16
16
  import { isVersion, compareVersions, satisfiesRange } from './chunk-TQMI335S.js';
17
17
  import { checkFit } from './chunk-MLD2NA7N.js';
18
18
  import { claimPidFile, readPidFile, releasePidFile } from './chunk-PYSKSROG.js';
19
19
  import { startTimeOf, isSameProcess } from './chunk-JBJTC3UU.js';
20
- import { writeJobFile, ensureRunnerIdentity, readJobFile, builderName, runnerLabelValue, ensureFailureCount, builderSpec, ensureBuilder, spawnRun, BUILD_LABEL, RUNNER_LABEL, readJobFileChecked } from './chunk-7I6GZSN3.js';
21
- import { describeCallFailure, retrySend, shortClaim, relativeToRunner, formatDuration, BuildTokens, classifyRefusal, refusalCode, createRunnerLog, formatClock } from './chunk-D7V33CAH.js';
22
- import { isSignatureRefusal, WorkCommandError, getJson, postJson } from './chunk-XPKI5OMT.js';
20
+ import { writeJobFile, ensureRunnerIdentity, readJobFile, builderName, runnerLabelValue, ensureFailureCount, builderSpec, ensureBuilder, spawnRun, BUILD_LABEL, RUNNER_LABEL, readJobFileChecked } from './chunk-KZLLLARE.js';
21
+ import { describeCallFailure, retrySend, shortClaim, relativeToRunner, formatDuration, BuildTokens, classifyRefusal, refusalCode, createRunnerLog, formatClock } from './chunk-DXHISLCI.js';
22
+ import { isSignatureRefusal, WorkCommandError, getJson, postJson } from './chunk-GMPXOQTH.js';
23
23
  import { isBuiltinContainer, isBuiltinVm, isBuiltinProcess, loadRunnerConfig, checkHooks, builtinKind, DEFAULT_UPDATE_MAX_WAIT_HOURS } from './chunk-JWRX5ZTT.js';
24
24
  import { exceedsDisk } from './chunk-7RQ73DLO.js';
25
25
  import { resolveVersion } from './chunk-RA3O54FC.js';
@@ -1057,6 +1057,9 @@ function attemptLogsOf(state) {
1057
1057
  function nowOf(state) {
1058
1058
  return (state.deps.now ?? (() => /* @__PURE__ */ new Date()))();
1059
1059
  }
1060
+ function leaseTimeLeftFor(state, active) {
1061
+ return () => (state.deps.leaseTimeLeftMs ?? leaseTimeLeftMs)(active.job, nowOf(state).getTime());
1062
+ }
1060
1063
  function runtimeOf(state) {
1061
1064
  state.containerRuntime ??= createContainerRuntime(state.deps.container);
1062
1065
  return state.containerRuntime;
@@ -1746,7 +1749,7 @@ var CLAIM_REFUSAL_CODES = new Set(
1746
1749
  "pull_request_from_fork pull_request_on_default_branch pull_request_ambiguous pull_request_repository_not_connected repository_not_reachable branch_claimed_elsewhere".split(" ")
1747
1750
  );
1748
1751
  async function tryClaimAndStart(state, item, queue) {
1749
- const { postJson: postJson2 } = await import('./work-cmd-TGSNYPSG.js');
1752
+ const { postJson: postJson2 } = await import('./work-cmd-SJB6N6FZ.js');
1750
1753
  const log = logOf(state);
1751
1754
  const hostKey = await loadHostKey(state.config.configPath);
1752
1755
  const claim = await retrySend(
@@ -2030,7 +2033,8 @@ async function startJob(state, item, queue, claimId, itemKey, branch, identity,
2030
2033
  aborted: () => active.ending,
2031
2034
  deadlineMs: startedAt.getTime() + state.config.timeLimitMinutes * 6e4,
2032
2035
  fetchImpl: state.deps.fetchImpl,
2033
- now: state.deps.now
2036
+ now: state.deps.now,
2037
+ leaseTimeLeftMs: leaseTimeLeftFor(state, active)
2034
2038
  }).catch((err) => ({ ok: false, reason: `provision failed: ${describeCallFailure(err)}`, aborted: false }));
2035
2039
  const provisionTook = formatDuration(nowOf(state).getTime() - provisionStartedMs);
2036
2040
  if (active.ending) return;
@@ -2430,6 +2434,7 @@ async function renewLeaseIfDue(state, active, nowMs) {
2430
2434
  writeJobFile(join(active.dirPath, "job.json"), active.job);
2431
2435
  log.line(`${tag} lease renewed \xB7 expires ${formatClock(new Date(nowMs + LEASE_SECONDS * 1e3), new Date(nowMs))}`);
2432
2436
  if (active.job.container !== void 0) state.containerRuntime?.leases.get(active.job.container.buildId)?.publish();
2437
+ if (active.job.microvm !== void 0) state.containerRuntime?.leases.get(active.job.microvm.buildId)?.publish();
2433
2438
  } else {
2434
2439
  log.error(`${tag} renew did not land \xB7 retrying in ${RENEW_INTERVAL_SECONDS / 60}m`);
2435
2440
  }
@@ -2730,7 +2735,7 @@ async function start(configPath, deps = { fetchImpl: fetch }) {
2730
2735
  const outcome = await onStartUnderMarker({
2731
2736
  configPath,
2732
2737
  own: ownVersionOf(deps),
2733
- check: update.check ? () => update.check(configPath) : async () => (await import('./check-3CBJVXZD.js')).runRunnerCheck(configPath, { fetchImpl: deps.fetchImpl }),
2738
+ check: update.check ? () => update.check(configPath) : async () => (await import('./check-KL3LDAI3.js')).runRunnerCheck(configPath, { fetchImpl: deps.fetchImpl }),
2734
2739
  now: () => (deps.now ?? (() => /* @__PURE__ */ new Date()))().getTime(),
2735
2740
  log
2736
2741
  });
@@ -3015,4 +3020,4 @@ function runnerProcessState(configPath) {
3015
3020
  return isSameProcess(entry.pid, entry.start) ? { state: "running", pid: entry.pid } : { state: "stale", pid: entry.pid };
3016
3021
  }
3017
3022
 
3018
- export { RunnerStartError, listJobFiles, logUnusableHelper, probeBuild, probeCredentials, requestStop, runnerProcessState, start, tick, watchTick };
3023
+ export { RunnerStartError, leaseTimeLeftFor, listJobFiles, logUnusableHelper, probeBuild, probeCredentials, requestStop, runnerProcessState, start, tick, watchTick };
@@ -2,7 +2,7 @@
2
2
  import { createRequire } from 'node:module';
3
3
  import { claimPidFile, RunnerAlreadyRunningError, releasePidFile } from './chunk-PYSKSROG.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-4R24DSL2.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-FI66JNLT.js';
6
6
  import { RUNNER_DIR_MODE, repoCacheDir, imagesDir, attemptStamp, runnerDir, rootfsPathFor, RUNNER_FILE_MODE } from './chunk-L4CW6LZQ.js';
7
7
  import { withGitConfig, tokenHeader, PROXY_WARNING_FLAG } from './chunk-2K3TCQHW.js';
8
8
  import { RELAY_ID, RELAY_USER } from './chunk-JGD5TWQ2.js';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { WorkCommandError, postJson } from './chunk-XPKI5OMT.js';
3
+ import { WorkCommandError, postJson } from './chunk-GMPXOQTH.js';
4
4
  import { defaultGitRunner, materializeContext, isStagingWriteFault, lookupGoverningSource } from './chunk-W3NVHOCS.js';
5
5
  import { signingFetchFor } from './chunk-QRZLUUNN.js';
6
6
  import { unsupportedLayout, layoutRefusalReason, composeDelivery } from './chunk-VPEGE3QZ.js';
@@ -249,13 +249,13 @@ var FIRECRACKER_SHA256 = {
249
249
  var FIRECRACKER_BINARY_SHA256 = {
250
250
  x86_64: "99ad0f5cd0514a88aad0e9ae8cfdb3cc3b4ab9d190e1194602406c786b5de7a5"
251
251
  };
252
- var GUEST_ASSETS_VERSION = "1";
252
+ var GUEST_ASSETS_VERSION = "6";
253
253
  var GUEST_ASSETS_BASE_URL = `https://github.com/outerlayerai/guest-assets/releases/download/guest-${GUEST_ASSETS_VERSION}`;
254
254
  var GUEST_KERNEL_SHA256 = {
255
255
  x86_64: "5a2d716d301615c69fefc2f9574954e838269f14d5e8b0d1bad88b680cd372ee"
256
256
  };
257
257
  var GUEST_HELPER_SHA256 = {
258
- x86_64: "4175e89ae8cb633113b5f69ef8b6e206093954411fe53edf86357bc1b7e822f9"
258
+ x86_64: "0ae934d3ad3f2a94abffcc3f044ba633b1a523dc17ff0c2bc322ed7d7fc505ea"
259
259
  };
260
260
  function guestAssetsPinned(arch) {
261
261
  const zero = "0".repeat(64);
@@ -264,10 +264,10 @@ function guestAssetsPinned(arch) {
264
264
  var JAILER_BINARY_SHA256 = {
265
265
  x86_64: "65ef226e96f0ceda55ba643f445801ef2cc0ea667ef67cad8ac4f406c9c8434f"
266
266
  };
267
- var HOST_HELPER_ASSETS_VERSION = "4";
267
+ var HOST_HELPER_ASSETS_VERSION = "5";
268
268
  var HOST_HELPER_BASE_URL = `https://github.com/outerlayerai/guest-assets/releases/download/guest-${HOST_HELPER_ASSETS_VERSION}`;
269
269
  var HOST_HELPER_SHA256 = {
270
- x86_64: "5c9d9e46daf165411ebe594fa28f4adc6b363989d77673c7651ab6dccb808684"
270
+ x86_64: "f2ec1c6a7ff29353045fad617ac1a6bf0155d6f3eb6a6259272a15342feaf957"
271
271
  };
272
272
  function hostHelperPinned(arch = "x86_64", hashes = HOST_HELPER_SHA256) {
273
273
  return hashes[arch] !== "0".repeat(64);
@@ -428,7 +428,7 @@ async function runWorkLinkSession(opts) {
428
428
  return await linkSession(opts);
429
429
  } catch (err) {
430
430
  if (opts.logFailures) {
431
- const { logHookError } = await import('./hook-fast-REXH5P6R.js');
431
+ const { logHookError } = await import('./hook-fast-LZSHEKUA.js');
432
432
  const reason = err instanceof Error ? err.message : String(err);
433
433
  logHookError(opts.home ?? homeFromEnv(opts.env ?? process.env), new Error(`work link-session #${opts.number} failed: ${reason}`));
434
434
  }
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { runnerImageVersion } from './chunk-665QWBNW.js';
4
- import { readDefaultBranchHead, cloneRepository, buildRepositoryImage } from './chunk-AINUN2TT.js';
4
+ import { readDefaultBranchHead, cloneRepository, buildRepositoryImage } from './chunk-DJILFADE.js';
5
5
  import { startTimeOf, isSameProcess } from './chunk-JBJTC3UU.js';
6
6
  import { currentCliBuild } from './chunk-OGFGZQA3.js';
7
- import { createDockerHost, builderSpec, runnerLabelValue, RUNNER_LABEL, BUILD_LABEL, prepareRunArgs, containerRunArgs, HASH_ARGV, parseProgramHash, JUDGE_PROGRAM, containerExecArgs, childEnvironment, JUDGE_DIR, JUDGE_REPORT, MAX_REPORT_BYTES, spawnRun } from './chunk-7I6GZSN3.js';
8
- import { FIRECRACKER_VERSION, hostHelperPinned, firecrackerArch, MICROVM_ARCHES, RecipeError, DOCKER_FEATURE, CLAUDE_CODE_VERSION, GUEST_HELPER_SHA256, GUEST_ASSETS_BASE_URL, GUEST_KERNEL_SHA256, JAILER_BINARY_SHA256, FIRECRACKER_BINARY_SHA256, FIRECRACKER_SHA256, GUEST_ASSETS_VERSION, DEFAULT_BASE_IMAGE } from './chunk-4R24DSL2.js';
9
- import { execCapture } from './chunk-HPOEVC2V.js';
10
- import { GUEST_CID } from './chunk-XGJUNNXL.js';
11
- import { describeCallFailure, controlPlaneTokenFailure, refusalCode, resolveGoverningSource, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, shimScript } from './chunk-D7V33CAH.js';
12
- import { WorkCommandError } from './chunk-XPKI5OMT.js';
7
+ import { createDockerHost, builderSpec, runnerLabelValue, RUNNER_LABEL, BUILD_LABEL, prepareRunArgs, containerRunArgs, HASH_ARGV, parseProgramHash, JUDGE_PROGRAM, containerExecArgs, childEnvironment, JUDGE_DIR, JUDGE_REPORT, MAX_REPORT_BYTES, spawnRun } from './chunk-KZLLLARE.js';
8
+ import { FIRECRACKER_VERSION, hostHelperPinned, firecrackerArch, MICROVM_ARCHES, RecipeError, DOCKER_FEATURE, CLAUDE_CODE_VERSION, GUEST_HELPER_SHA256, GUEST_ASSETS_BASE_URL, GUEST_KERNEL_SHA256, JAILER_BINARY_SHA256, FIRECRACKER_BINARY_SHA256, FIRECRACKER_SHA256, GUEST_ASSETS_VERSION, DEFAULT_BASE_IMAGE } from './chunk-FI66JNLT.js';
9
+ import { execCapture } from './chunk-MXTN35XN.js';
10
+ import { GUEST_CID } from './chunk-XLC7KEUV.js';
11
+ import { describeCallFailure, controlPlaneTokenFailure, refusalCode, resolveGoverningSource, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, shimScript } from './chunk-DXHISLCI.js';
12
+ import { WorkCommandError } from './chunk-GMPXOQTH.js';
13
13
  import { hostAllowed } from './chunk-UXYLWVTQ.js';
14
14
  import { parseDuKilobytes } from './chunk-7RQ73DLO.js';
15
15
  import { sharedSkillNames, skillConflictMessage } from './chunk-VPEGE3QZ.js';
@@ -196,8 +196,8 @@ function ask(socketPath, request, timeoutMs) {
196
196
  function helperClient(socketPath, options = {}) {
197
197
  const REQUEST_TIMEOUT_MS = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
198
198
  return {
199
- async start({ build, kind }) {
200
- const reply = await ask(socketPath, { v: 1, op: "start", build, kind }, START_TIMEOUT_MS);
199
+ async start({ build, kind, timeLimitMinutes }) {
200
+ const reply = await ask(socketPath, { v: 1, op: "start", build, kind, timeLimitMinutes }, START_TIMEOUT_MS);
201
201
  return { unit: String(reply.unit), chroot: String(reply.chroot), vsock: String(reply.vsock) };
202
202
  },
203
203
  async stop(build) {
@@ -412,11 +412,14 @@ function leaseExpiresAtMs(job) {
412
412
  const base = Date.parse(job.lastRenewAt ?? job.startedAt);
413
413
  return (Number.isFinite(base) ? base : Date.now()) + LEASE_SECONDS * 1e3;
414
414
  }
415
- function createLeaseChannel(expiryMs) {
415
+ function leaseTimeLeftMs(job, nowMs) {
416
+ return Math.max(0, leaseExpiresAtMs(job) - nowMs);
417
+ }
418
+ function createLeaseChannel(valueMs) {
416
419
  const open = /* @__PURE__ */ new Set();
417
420
  let stopped = false;
418
421
  const write = (stream) => {
419
- if (!stopped && !stream.destroyed && stream.writable) stream.write(`${Math.floor(expiryMs())}
422
+ if (!stopped && !stream.destroyed && stream.writable) stream.write(`${Math.floor(valueMs())}
420
423
  `);
421
424
  };
422
425
  return {
@@ -829,6 +832,7 @@ function machineConfig(limits2, paths) {
829
832
  "rootfstype=ext4",
830
833
  `init=${INIT}`,
831
834
  ...paths.relayPorts.length === 0 ? [] : [`outerlayer.relay=${paths.relayPorts.join(",")}`],
835
+ ...paths.leasePort === void 0 ? [] : [`outerlayer.lease=${paths.leasePort}`],
832
836
  ...paths.docker === true ? ["outerlayer.docker=1"] : []
833
837
  ];
834
838
  return {
@@ -3311,4 +3315,4 @@ async function startCheckContainer(input) {
3311
3315
  };
3312
3316
  }
3313
3317
 
3314
- export { ADDED_USER, AgentUserError, AssetError, DeliveryFailure, EVAL_INPUT_NAME, GH_CONFIG_YML, HelperRefusal, LEASE_SECONDS, MIN_ENGINE_MAJOR, cleanupContainer, containerCommandExec, containerJudgeEnvironment, containerSenderCommand, copyJudgeTree, copyTranscripts, copyTranscriptsFromContainer, createBuildDisk, createContainerRuntime, deleteBuildDisk, deliverContainerHooks, ensureFirecrackerAndJailer, ensureRootfs, ensureTunnel, filesAreCopied, ghHostsYml, gitRemoteFor, helperFirecrackerNote, helperSocketPath, isLiteralAddress, keepGhConfigCurrent, leaseExpiresAtMs, lifecycleFailureReason, lifecycleSteps, machineConfig, measureDisk, obtainImage, outOfMemoryReason, parseCpuList, prepareBranch, probeHelper, provisionContainer, resolveAgentUser, runBuildSteps, senderAliveScript, senderSignalScript, setUpRunnerCgroup, shellQuote, signalInContainer, startCheckContainer, startServicesFor, stopContainer, syncInContainer, writeEvalInput };
3318
+ export { ADDED_USER, AgentUserError, AssetError, DeliveryFailure, EVAL_INPUT_NAME, GH_CONFIG_YML, HelperRefusal, LEASE_SECONDS, MIN_ENGINE_MAJOR, cleanupContainer, containerCommandExec, containerJudgeEnvironment, containerSenderCommand, copyJudgeTree, copyTranscripts, copyTranscriptsFromContainer, createBuildDisk, createContainerRuntime, createLeaseChannel, deleteBuildDisk, deliverContainerHooks, ensureFirecrackerAndJailer, ensureRootfs, ensureTunnel, filesAreCopied, ghHostsYml, gitRemoteFor, helperFirecrackerNote, helperSocketPath, isLiteralAddress, keepGhConfigCurrent, leaseExpiresAtMs, leaseTimeLeftMs, lifecycleFailureReason, lifecycleSteps, machineConfig, measureDisk, obtainImage, outOfMemoryReason, parseCpuList, prepareBranch, probeHelper, provisionContainer, resolveAgentUser, runBuildSteps, senderAliveScript, senderSignalScript, setUpRunnerCgroup, shellQuote, signalInContainer, startCheckContainer, startServicesFor, stopContainer, syncInContainer, writeEvalInput };
@@ -2,7 +2,7 @@
2
2
  import { createRequire } from 'node:module';
3
3
  import { recordReportedCost } from './chunk-BKO6JEZI.js';
4
4
  import { cliInvocation } from './chunk-CRB3POP4.js';
5
- import { decodeWrappedCommand } from './chunk-GNPTU4BM.js';
5
+ import { decodeWrappedCommand } from './chunk-URIZRCRY.js';
6
6
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
7
7
  import { readFileSync } from 'fs';
8
8
  import { spawn } from 'child_process';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { RecipeError, BUILDKIT_IMAGE } from './chunk-4R24DSL2.js';
3
+ import { RecipeError, BUILDKIT_IMAGE } from './chunk-FI66JNLT.js';
4
4
  import { parseSize } from './chunk-7RQ73DLO.js';
5
5
  import { compareVersions } from './chunk-QE3UQAHK.js';
6
6
  import { ensureHostKey } from './chunk-F6DIHHBS.js';
@@ -2,7 +2,7 @@
2
2
  import { createRequire } from 'node:module';
3
3
  import { BRIDGE_ADDRESS, TUNNEL_PORT, BRIDGE_CIDR } from './chunk-UNF7MWEL.js';
4
4
  import { startTimeOf } from './chunk-JBJTC3UU.js';
5
- import { EXEC_PORT } from './chunk-XGJUNNXL.js';
5
+ import { EXEC_PORT } from './chunk-XLC7KEUV.js';
6
6
  import { RELAY_PORT } from './chunk-2K3TCQHW.js';
7
7
  import { spawn, spawnSync } from 'child_process';
8
8
  import { writeFileSync, chmodSync, mkdirSync } from 'fs';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { EXEC_PORT } from './chunk-XGJUNNXL.js';
3
+ import { EXEC_PORT } from './chunk-XLC7KEUV.js';
4
4
  import { createConnection } from 'net';
5
5
 
6
6
  createRequire(import.meta.url);
@@ -41,8 +41,8 @@ var FrameDecoder = class {
41
41
  }
42
42
  };
43
43
  function encodeRequest(request) {
44
- const { argv, user, cwd, env } = request;
45
- return Buffer.from(JSON.stringify({ argv, user, cwd, env }), "utf8");
44
+ const { argv, user, cwd, env, detach } = request;
45
+ return Buffer.from(JSON.stringify({ argv, user, cwd, env, ...detach === void 0 ? {} : { detach } }), "utf8");
46
46
  }
47
47
  function decodeExit(payload) {
48
48
  if (payload.length !== 4) throw new ProtocolError(`an exit frame holds ${payload.length} bytes, not 4`);
@@ -1,19 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { readsJobState, READ_JOB_STATE_FORMATS, jobStateFormatOf } from './chunk-ZVB57WI6.js';
4
- import { senderPidfile } from './chunk-IIFMFX6J.js';
5
- import { DOCKERD_LOG, HELPER_PATH, HELPER_RECORD } from './chunk-2N72GPS2.js';
4
+ import { senderPidfile } from './chunk-V5LUWRCV.js';
5
+ import { DOCKERD_LOG, HELPER_PATH, HELPER_RECORD } from './chunk-MWPBF2XG.js';
6
6
  import { writeDockerClientConfig } from './chunk-UNF7MWEL.js';
7
- import { installScrubContext } from './chunk-PNHNKMA3.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, helperFirecrackerNote, HelperRefusal, GH_CONFIG_YML, ghHostsYml, isLiteralAddress, deleteBuildDisk, startCheckContainer, lifecycleSteps, lifecycleFailureReason, writeEvalInput, DeliveryFailure, EVAL_INPUT_NAME, copyTranscripts, senderSignalScript, containerJudgeEnvironment, copyJudgeTree } from './chunk-ILL2CWOU.js';
9
- import { readBranchHead, fetchCommit, diffBetween } from './chunk-AINUN2TT.js';
7
+ import { installScrubContext } from './chunk-U2FSJBNI.js';
8
+ import { ADDED_USER, AssetError, obtainImage, ensureRootfs, gitRemoteFor, startServicesFor, createLeaseChannel, createBuildDisk, machineConfig, resolveAgentUser, AgentUserError, runBuildSteps, shellQuote, LEASE_SECONDS, createContainerRuntime, stopContainer, cleanupContainer, outOfMemoryReason, containerSenderCommand, signalInContainer, syncInContainer, copyTranscriptsFromContainer, senderAliveScript, helperFirecrackerNote, HelperRefusal, GH_CONFIG_YML, ghHostsYml, isLiteralAddress, deleteBuildDisk, startCheckContainer, lifecycleSteps, lifecycleFailureReason, writeEvalInput, DeliveryFailure, EVAL_INPUT_NAME, copyTranscripts, senderSignalScript, containerJudgeEnvironment, copyJudgeTree } from './chunk-GUT4IU7K.js';
9
+ import { readBranchHead, fetchCommit, diffBetween } from './chunk-DJILFADE.js';
10
10
  import { isSameProcess, startTimeOf } from './chunk-JBJTC3UU.js';
11
- import { HASH_ARGV, parseProgramHash, JUDGE_PROGRAM, writeJobFile, readJobFile, COMMAND_DIR, childEnvironment, judgeCommand, JUDGE_MAX_TURNS, MAX_REPORT_BYTES, JUDGE_DIR } from './chunk-7I6GZSN3.js';
12
- import { CLAUDE_CODE_VERSION, FIRECRACKER_VERSION } from './chunk-4R24DSL2.js';
13
- import { waitForAgent, vmExecArgs } from './chunk-HPOEVC2V.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-D7V33CAH.js';
16
- import { WorkCommandError, postJson, isSignatureRefusal, getJson } from './chunk-XPKI5OMT.js';
11
+ import { HASH_ARGV, parseProgramHash, JUDGE_PROGRAM, writeJobFile, readJobFile, COMMAND_DIR, childEnvironment, judgeCommand, JUDGE_MAX_TURNS, MAX_REPORT_BYTES, JUDGE_DIR } from './chunk-KZLLLARE.js';
12
+ import { CLAUDE_CODE_VERSION, FIRECRACKER_VERSION } from './chunk-FI66JNLT.js';
13
+ import { waitForAgent, vmExecArgs } from './chunk-MXTN35XN.js';
14
+ import { socketPathProblem, vsockLinks, LEASE_LINK, linkVsockSockets } from './chunk-XLC7KEUV.js';
15
+ import { describeCallFailure, resolveGoverningSource, refusalCode, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, logStamp, createRunnerLog, formatDuration, retrySend, formatClock } from './chunk-DXHISLCI.js';
16
+ import { WorkCommandError, postJson, isSignatureRefusal, getJson } from './chunk-GMPXOQTH.js';
17
17
  import { planArtifactUpload } from './chunk-BUP5N3X6.js';
18
18
  import { isBuiltinContainer, isBuiltinProcess, isBuiltinVm, DEFAULT_CHECK_TIME_LIMIT_MINUTES } from './chunk-JWRX5ZTT.js';
19
19
  import { parseSize } from './chunk-7RQ73DLO.js';
@@ -31,6 +31,8 @@ import { existsSync, statSync, appendFileSync, mkdirSync, chmodSync, writeFileSy
31
31
  import { join, isAbsolute, dirname, delimiter, sep } from 'path';
32
32
  import { spawn, spawnSync } from 'child_process';
33
33
  import { randomBytes, createHash } from 'crypto';
34
+ import { once } from 'events';
35
+ import { createServer } from 'net';
34
36
  import { pathToFileURL } from 'url';
35
37
 
36
38
  createRequire(import.meta.url);
@@ -95,6 +97,21 @@ function judgeProbe(probe, missedBefore) {
95
97
  if (probe.alive) return { kind: "running" };
96
98
  return missedBefore ? { kind: "lost" } : { kind: "recheck" };
97
99
  }
100
+ async function serveLease(socketPath, channel, makeServer = createServer) {
101
+ const server = makeServer((socket) => channel.accept(socket));
102
+ rmSync(socketPath, { force: true });
103
+ server.listen(socketPath);
104
+ await once(server, "listening");
105
+ server.on("error", () => void 0);
106
+ return {
107
+ ...channel,
108
+ close() {
109
+ channel.close();
110
+ server.close();
111
+ rmSync(socketPath, { force: true });
112
+ }
113
+ };
114
+ }
98
115
  function unitNameFor(buildId) {
99
116
  return `outerlayer-build-${buildId}`;
100
117
  }
@@ -121,7 +138,7 @@ async function startJailed(input) {
121
138
  if (err.code !== "ENOENT") throw err;
122
139
  }
123
140
  }
124
- return input.client.start({ build: input.buildId, kind: input.kind });
141
+ return input.client.start({ build: input.buildId, kind: input.kind, ...input.timeLimitMinutes === void 0 ? {} : { timeLimitMinutes: input.timeLimitMinutes } });
125
142
  }
126
143
  async function startJailedInto(state, input, save) {
127
144
  state.jailed = { unit: unitNameFor(state.buildId), chroot: "" };
@@ -358,15 +375,33 @@ async function provisionMicroVm(input) {
358
375
  diskBytes: parseSize(config.build?.disk ?? DEFAULT_DISK) ?? parseSize(DEFAULT_DISK)
359
376
  };
360
377
  const links = vsockLinks({ destinations: config.build?.destinations?.length ?? 0, builtIns: true });
378
+ const served = input.leaseTimeLeftMs === void 0 ? links : [...links, LEASE_LINK];
379
+ if (input.leaseTimeLeftMs !== void 0) {
380
+ try {
381
+ const channel = createLeaseChannel(input.leaseTimeLeftMs);
382
+ const served2 = await serveLease(join(buildDir2, LEASE_LINK.socket), { ...channel, accept: (stream) => runtime.leases.get(buildId)?.accept(stream) });
383
+ runtime.leases.set(buildId, { ...channel, close: served2.close });
384
+ } catch (err) {
385
+ return bail(`the lease stream could not start: ${describeCallFailure(err)}`);
386
+ }
387
+ }
361
388
  const configPath = join(buildDir2, "vm.json");
362
389
  const helper = await helperFor(runtime, (line) => log.line(`${tag} ${line}`));
363
390
  try {
364
- if (helper === void 0) linkVsockSockets({ buildDir: buildDir2, vsockPath: state.vsockPath, links });
391
+ if (helper === void 0) linkVsockSockets({ buildDir: buildDir2, vsockPath: state.vsockPath, links: served });
365
392
  await createBuildDisk({ host: vm.rootfs, runnerDir: runnerDirPath, bytes: limits.diskBytes, dest: state.buildDisk, memoryBytes: limits.memoryBytes });
366
393
  writeFileSync(
367
394
  configPath,
368
395
  JSON.stringify(
369
- machineConfig(limits, { kernel: assets.kernel, rootfs: state.rootfs, buildDisk: state.buildDisk, vsock: state.vsockPath, relayPorts: links.map((link) => link.port), docker: report.docker }),
396
+ machineConfig(limits, {
397
+ kernel: assets.kernel,
398
+ rootfs: state.rootfs,
399
+ buildDisk: state.buildDisk,
400
+ vsock: state.vsockPath,
401
+ relayPorts: links.map((link) => link.port),
402
+ ...input.leaseTimeLeftMs === void 0 ? {} : { leasePort: LEASE_LINK.port },
403
+ docker: report.docker
404
+ }),
370
405
  null,
371
406
  2
372
407
  ),
@@ -387,7 +422,11 @@ async function provisionMicroVm(input) {
387
422
  const consolePath = join(jobDir, "vm-console.log");
388
423
  if (helper !== void 0) {
389
424
  try {
390
- await startJailedInto(state, { client: helper, kind: "build", kernel: assets.kernel, rootfs: state.rootfs, sockets: links.map((link) => link.socket) }, () => input.save(state, environment));
425
+ await startJailedInto(
426
+ state,
427
+ { client: helper, kind: "build", kernel: assets.kernel, rootfs: state.rootfs, sockets: served.map((link) => link.socket), timeLimitMinutes: config.timeLimitMinutes },
428
+ () => input.save(state, environment)
429
+ );
391
430
  } catch (err) {
392
431
  return bail(`the microVM did not start under the jailer: ${describeCallFailure(err)}`);
393
432
  }
@@ -813,7 +852,11 @@ async function startCheckMicroVm(input) {
813
852
  const boot = async () => {
814
853
  if (helper !== void 0) {
815
854
  try {
816
- await startJailedInto(state, { client: helper, kind: "check", kernel: assets.kernel, rootfs: state.rootfs, sockets: links.map((link) => link.socket) }, () => input.save(state));
855
+ await startJailedInto(
856
+ state,
857
+ { client: helper, kind: "check", kernel: assets.kernel, rootfs: state.rootfs, sockets: links.map((link) => link.socket), timeLimitMinutes: config.timeLimitMinutes },
858
+ () => input.save(state)
859
+ );
817
860
  } catch (err) {
818
861
  return `the microVM did not start under the jailer: ${describeCallFailure(err)}`;
819
862
  }
@@ -903,6 +946,8 @@ async function cleanupMicroVm(runtime, state, jobDir) {
903
946
  }
904
947
  }
905
948
  if (state.buildDisk !== void 0) deleteBuildDisk(state.buildDisk);
949
+ runtime.leases.get(state.buildId)?.close();
950
+ runtime.leases.delete(state.buildId);
906
951
  const tunnel = runtime.tunnels.get(state.buildId);
907
952
  if (tunnel !== void 0) {
908
953
  runtime.tunnels.delete(state.buildId);
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { detectMachine, supportsContainerBuilds, reachDockerStep, describeMachineDocker, supportsMicroVmBuilds } from './chunk-7NKVMAP6.js';
4
- import { MIN_ENGINE_MAJOR } from './chunk-ILL2CWOU.js';
3
+ import { detectMachine, supportsContainerBuilds, reachDockerStep, describeMachineDocker, supportsMicroVmBuilds } from './chunk-RO3BRAO6.js';
4
+ import { MIN_ENGINE_MAJOR } from './chunk-GUT4IU7K.js';
5
5
  import { hasStoredCredential, AGENT_COMMANDS, storeClaudeCredential, credentialFromStdin, isAgentName } from './chunk-5PMQDQFV.js';
6
6
  import { runnerCredentialProblem } from './chunk-JWRX5ZTT.js';
7
7
  import { runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-L4CW6LZQ.js';
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { MIN_ENGINE_MAJOR } from './chunk-ILL2CWOU.js';
3
+ import { MIN_ENGINE_MAJOR } from './chunk-GUT4IU7K.js';
4
4
  import { runnerImageVersion } from './chunk-665QWBNW.js';
5
- import { firecrackerArch, MICROVM_ARCHES, guestAssetsPinned } from './chunk-4R24DSL2.js';
5
+ import { firecrackerArch, MICROVM_ARCHES, guestAssetsPinned } from './chunk-FI66JNLT.js';
6
6
  import { spawnSync } from 'child_process';
7
7
  import { existsSync, accessSync, constants, statSync, readFileSync } from 'fs';
8
8
 
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { isPlaceholderCommand } from './chunk-JUTN2HUP.js';
4
- import { describeCallFailure } from './chunk-D7V33CAH.js';
5
- import { WorkCommandError, getJson } from './chunk-XPKI5OMT.js';
3
+ import { isPlaceholderCommand } from './chunk-PCY7IGSL.js';
4
+ import { describeCallFailure } from './chunk-DXHISLCI.js';
5
+ import { WorkCommandError, getJson } from './chunk-GMPXOQTH.js';
6
6
  import { sanitizeTerminal } from './chunk-BUP5N3X6.js';
7
7
  import { builtinKind } from './chunk-JWRX5ZTT.js';
8
8
  import { signerFor } from './chunk-F6DIHHBS.js';
@@ -5,9 +5,9 @@ import { LaunchFilter } from './chunk-ESVW4MJY.js';
5
5
  import { RepoFilter } from './chunk-TBT347UY.js';
6
6
  import { migrateLegacyArtifactSidecars, planArtifactUpload, artifactsStatePath, sanitizeTerminal, acquireArtifactSpoolLock, artifactBlobsDir, resolveArtifactTurnIndex, isArtifactTombstoned, ARTIFACT_RETRY_MAX_AGE_MS, writeArtifactSpoolState, reclaimUnneededArtifactBlobs, neededArtifactShas } from './chunk-BUP5N3X6.js';
7
7
  import { cliFetch, resolveGatewayCredentials, defaultFetch, unauthorizedMessage } from './chunk-QRZLUUNN.js';
8
- import { writeSyncStatus, spoolDir } from './chunk-QIIMZC7W.js';
8
+ import { writeSyncStatus, spoolDir } from './chunk-2EAVBJMO.js';
9
9
  import { readLatestProvenanceForSession, readContextProvenance } from './chunk-ZJSNLVCE.js';
10
- import { hookExecSpoolPath } from './chunk-DYEFPYME.js';
10
+ import { hookExecSpoolPath } from './chunk-2O5KA67H.js';
11
11
  import { applyReportedCost } from './chunk-BKO6JEZI.js';
12
12
  import { readRepoConnection, findGitDirs } from './chunk-BJ3KTMDH.js';
13
13
  import { setCustomScrubbers, setLocalIdentity, tailTranscript, enrichSessionRepo, scanAll, setRepoRoot, resolveRepoIdentity, sessionIdFromPath, scrubDeep, SOURCE_ADAPTERS } from './chunk-QE3UQAHK.js';