@outerlayer/cli 0.10.2 → 0.11.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 (44) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/build-info.json +1 -1
  3. package/dist/{builder-EVO6F2NO.js → builder-PP436VGZ.js} +2 -2
  4. package/dist/{check-NQYQHITZ.js → check-YDXOLVJ5.js} +16 -15
  5. package/dist/{chunk-VVIRHTH4.js → chunk-2GBCTEN4.js} +1 -1
  6. package/dist/{chunk-ERHJETKP.js → chunk-3YFCWYBU.js} +128 -30
  7. package/dist/{chunk-M6G7TJVF.js → chunk-4Q7OMKAT.js} +44 -4
  8. package/dist/{chunk-MC6J453K.js → chunk-7C4T5BGN.js} +2 -2
  9. package/dist/{chunk-472KC6JV.js → chunk-BEZSECPA.js} +1 -1
  10. package/dist/{chunk-KZ5M4QOB.js → chunk-BHOBM3IZ.js} +32 -14
  11. package/dist/{chunk-JSUUXA5W.js → chunk-CJGQQZWB.js} +1 -1
  12. package/dist/{chunk-BREEX2Z7.js → chunk-E5DC4VZL.js} +115 -58
  13. package/dist/{chunk-R2UYH4QV.js → chunk-EOWWTFUU.js} +3 -3
  14. package/dist/{chunk-PDTSUOVT.js → chunk-FI5UYJMQ.js} +1 -1
  15. package/dist/{chunk-V42JY4F6.js → chunk-HYZRY4KZ.js} +2 -2
  16. package/dist/chunk-O765JR4W.js +35 -0
  17. package/dist/{chunk-6CXYORUS.js → chunk-QKFB4K7X.js} +1 -1
  18. package/dist/{chunk-ESZJ5QIC.js → chunk-R7BJYFD2.js} +4 -4
  19. package/dist/{chunk-S6IUUNCD.js → chunk-RSNSZ2LJ.js} +1 -1
  20. package/dist/{chunk-NTLGWCWK.js → chunk-TFIOXPZT.js} +1 -1
  21. package/dist/{chunk-M2PBLRB7.js → chunk-XR3BJN33.js} +23 -3
  22. package/dist/{cli-ZCWMJCEK.js → cli-RQZXTOEI.js} +39 -35
  23. package/dist/{command-LNEFKIVC.js → command-U6UGIBVT.js} +9 -9
  24. package/dist/config-MKBX2ZQD.js +11 -0
  25. package/dist/{docker-GM526LGX.js → docker-WVRRMK6R.js} +3 -3
  26. package/dist/{doctor-QSV4DYT2.js → doctor-ZF4PYWVN.js} +10 -10
  27. package/dist/{exec-client-QTUO6TZT.js → exec-client-CQV746UF.js} +3 -3
  28. package/dist/{guest-init-4UW4HM6N.js → guest-init-LJP5GPZF.js} +3 -3
  29. package/dist/index.js +1 -1
  30. package/dist/{init-MJ2PO2VQ.js → init-M5IBAGVE.js} +9 -9
  31. package/dist/{init-OKCDXEOG.js → init-PUY2BUHH.js} +8 -8
  32. package/dist/{init-cmd-5TEM2QNH.js → init-cmd-NPNR23UL.js} +1 -1
  33. package/dist/{install-PYNCWSTV.js → install-HKOVISUP.js} +3 -3
  34. package/dist/{loop-DBF3UJAD.js → loop-3FNROLW7.js} +16 -15
  35. package/dist/{machine-TBJKZ6TN.js → machine-RWDDJRWB.js} +7 -7
  36. package/dist/pending-MXLSRYMO.js +7 -0
  37. package/dist/{status-KPDVZMJ6.js → status-2OW5AKWL.js} +17 -9
  38. package/dist/{work-claim-cmd-DYD6II56.js → work-claim-cmd-LXXSNEGF.js} +3 -3
  39. package/dist/{work-open-pr-cmd-N2RBDKZ4.js → work-open-pr-cmd-YZAENDP6.js} +5 -4
  40. package/package.json +1 -1
  41. package/skill-pack/maintained/amend/SKILL.md +10 -1
  42. package/skill-pack/maintained/outerlayer/SKILL.md +19 -3
  43. package/skill-pack/maintained/outerlayer/references/open-pull-request.md +11 -0
  44. package/dist/config-X45X7AS4.js +0 -11
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @outerlayer/cli
2
2
 
3
+ ## 0.11.0
4
+
5
+ ### Minor Changes
6
+
7
+ - b248d4f: A container or microVM build now checks out every repository connected to the factory. The primary stays at `/build/work/checkout`, and each other repository is cloned to `/build/work/repos/<owner>/<repo>` on its claim branch. `OUTERLAYER_REPOSITORIES` lists each repository with its path, branch and whether it is primary. `outerlayer work open-pr --repository <owner/name>` opens a pull request in any repository the claim names. The runner protocol is now 16: a gateway refuses an older runner a claim over more than one repository.
8
+ - 4b30f06: A runner with an update pending now keeps taking work while a build runs, and updates the first time no build is running. It holds new work only when the gateway refuses its version or the update has waited longer than `runner.update.maxWaitHours` (default 6, `0` holds at once). The runner logs when an update is pending and when it starts holding work, and `outerlayer runner status` shows the pending version and the builds the runner waits for.
9
+
3
10
  ## 0.10.2
4
11
 
5
12
  ### Patch Changes
@@ -1 +1 @@
1
- {"id":"2026-10-07T19:14:32.738Z+adc613b","root":"/home/runner/_work/outerlayer/outerlayer","pkg":"outerlayer"}
1
+ {"id":"2026-10-07T20:56:19.457Z+b4e50a8","root":"/home/runner/_work/outerlayer/outerlayer","pkg":"outerlayer"}
@@ -1,10 +1,10 @@
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-JSUUXA5W.js';
3
+ export { MIN_BUILDX_VERSION, builderName, builderSpec, buildxState, ensureBuilder, ensureFailureCount, isOutOfMemory, proxyEnvironment, trackImageBuild } from './chunk-CJGQQZWB.js';
4
4
  import './chunk-CX22S5BA.js';
5
5
  import './chunk-IU4NZROR.js';
6
6
  import './chunk-7RQ73DLO.js';
7
- import './chunk-M6G7TJVF.js';
7
+ import './chunk-4Q7OMKAT.js';
8
8
  import './chunk-YT35WGIP.js';
9
9
  import './chunk-BYT5O5RV.js';
10
10
  import './chunk-ZM2IMMYN.js';
@@ -1,35 +1,36 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { probeCredentials } from './chunk-ERHJETKP.js';
3
+ import { probeCredentials } from './chunk-3YFCWYBU.js';
4
+ import './chunk-UGP76IZ5.js';
4
5
  import './chunk-3JVYMD4G.js';
5
6
  import './chunk-I2UOAV7X.js';
6
7
  import './chunk-YETTWTAY.js';
7
- import './chunk-KZ5M4QOB.js';
8
+ import './chunk-BHOBM3IZ.js';
8
9
  import './chunk-T6OIJQRT.js';
9
- import './chunk-PDTSUOVT.js';
10
- import './chunk-UGP76IZ5.js';
10
+ import './chunk-FI5UYJMQ.js';
11
+ import './chunk-O765JR4W.js';
11
12
  import './chunk-HKUH5AR2.js';
12
- import './chunk-V42JY4F6.js';
13
+ import './chunk-HYZRY4KZ.js';
13
14
  import './chunk-Y6P5XX2B.js';
14
15
  import './chunk-HHJDN6AU.js';
15
- import { placeholderQueues, placeholderProblem, permissionModeProblems, permissionModeProblem, needsClaudeCredential, claudeCredentialCheck, claimPermissionProblem } from './chunk-ESZJ5QIC.js';
16
+ import { placeholderQueues, placeholderProblem, permissionModeProblems, permissionModeProblem, needsClaudeCredential, claudeCredentialCheck, claimPermissionProblem } from './chunk-R7BJYFD2.js';
16
17
  import './chunk-TI7B7UEO.js';
17
18
  import './chunk-YYYRBYWG.js';
18
19
  import './chunk-TBT347UY.js';
19
- import './chunk-MC6J453K.js';
20
- import './chunk-472KC6JV.js';
21
- import './chunk-BREEX2Z7.js';
20
+ import './chunk-7C4T5BGN.js';
21
+ import './chunk-BEZSECPA.js';
22
+ import './chunk-E5DC4VZL.js';
22
23
  import { parseRunnerEnv } from './chunk-6MZSX4M7.js';
23
24
  import './chunk-JKIWMRFH.js';
24
25
  import './chunk-3FMPZPJQ.js';
25
26
  import './chunk-N5FOE5PS.js';
26
27
  import './chunk-OGFGZQA3.js';
27
- import './chunk-VVIRHTH4.js';
28
+ import './chunk-2GBCTEN4.js';
28
29
  import './chunk-QOZKPLVJ.js';
29
- import './chunk-JSUUXA5W.js';
30
+ import './chunk-CJGQQZWB.js';
30
31
  import './chunk-CX22S5BA.js';
31
- import './chunk-6CXYORUS.js';
32
- import './chunk-S6IUUNCD.js';
32
+ import './chunk-QKFB4K7X.js';
33
+ import './chunk-RSNSZ2LJ.js';
33
34
  import './chunk-F7CU5ABH.js';
34
35
  import './chunk-BKO6JEZI.js';
35
36
  import './chunk-DTDZXDQ3.js';
@@ -41,10 +42,10 @@ import './chunk-IU4NZROR.js';
41
42
  import './chunk-USO2DKBD.js';
42
43
  import './chunk-N6LURUEF.js';
43
44
  import './chunk-YRYMNBGQ.js';
44
- import { loadRunnerConfig, RunnerConfigError, checkHooks } from './chunk-M2PBLRB7.js';
45
+ import { loadRunnerConfig, RunnerConfigError, checkHooks } from './chunk-XR3BJN33.js';
45
46
  import './chunk-UXYLWVTQ.js';
46
47
  import './chunk-7RQ73DLO.js';
47
- import './chunk-M6G7TJVF.js';
48
+ import './chunk-4Q7OMKAT.js';
48
49
  import './chunk-GQD22KKN.js';
49
50
  import './chunk-WZBHBH3J.js';
50
51
  import './chunk-5QRP3MVS.js';
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { RecipeError } from './chunk-QOZKPLVJ.js';
4
- import { trackImageBuild, isOutOfMemory, ensureBuilder } from './chunk-JSUUXA5W.js';
4
+ import { trackImageBuild, isOutOfMemory, ensureBuilder } from './chunk-CJGQQZWB.js';
5
5
  import { spawn } from 'child_process';
6
6
  import { existsSync, mkdirSync, createWriteStream, rmSync, readFileSync } from 'fs';
7
7
  import { join, dirname } from 'path';
@@ -1,25 +1,26 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
+ import { readHousekeepingRecord, writeHousekeepingRecord } from './chunk-UGP76IZ5.js';
3
4
  import { decideInstalledSwitch } from './chunk-3JVYMD4G.js';
4
5
  import { compareVersions, satisfiesRange } from './chunk-I2UOAV7X.js';
5
6
  import { fetchVersionMeta, npmVersion, npmSupportsProvenance, fetchTarballDigest, fetchProvenance, installVersion, auditSignatures } from './chunk-YETTWTAY.js';
6
- import { LEASE_SECONDS, releaseLease, isUnfinished, setStage, jobEnv, runHook, describeHookEnd, provisionMicroVm, deliverCommitHooks, provisionProcess, provisionEnvironment, readProvisionOut, resolveHostBuild, workdirProblem, listenOnBroker, hostEnvironment, hostCommandEnvironment, execArgv, microVmCommandLine, runCommand, execCommandLine, startSender, startHostServices, finishJob, isGroupAlive, outcomeFromExitCode, isTimedOut, readCpuUsec, isIdle, stopOrphanedMicroVms, unfinishedJobs, listAdoptableJobs, retryFailedReleases, recoverLostJobs, hookLimitsFor, needsRenew, renewLease, RENEW_INTERVAL_SECONDS, ALREADY_RELEASED } from './chunk-KZ5M4QOB.js';
7
+ import { LEASE_SECONDS, releaseLease, isUnfinished, setStage, jobEnv, runHook, describeHookEnd, provisionMicroVm, deliverCommitHooks, provisionProcess, provisionEnvironment, readProvisionOut, resolveHostBuild, workdirProblem, listenOnBroker, hostEnvironment, hostCommandEnvironment, execArgv, microVmCommandLine, runCommand, execCommandLine, startSender, startHostServices, finishJob, isGroupAlive, outcomeFromExitCode, isTimedOut, readCpuUsec, isIdle, stopOrphanedMicroVms, unfinishedJobs, listAdoptableJobs, retryFailedReleases, recoverLostJobs, hookLimitsFor, needsRenew, renewLease, RENEW_INTERVAL_SECONDS, ALREADY_RELEASED } from './chunk-BHOBM3IZ.js';
7
8
  import { writeJobFile, readJobFile, readJobFileChecked } from './chunk-T6OIJQRT.js';
8
- import { RUNNER_PROTOCOL } from './chunk-PDTSUOVT.js';
9
- import { readHousekeepingRecord, writeHousekeepingRecord } from './chunk-UGP76IZ5.js';
10
- import { placeholderQueues, placeholderProblem } from './chunk-ESZJ5QIC.js';
9
+ import { RUNNER_PROTOCOL } from './chunk-FI5UYJMQ.js';
10
+ import { writePendingUpdate } from './chunk-O765JR4W.js';
11
+ import { placeholderQueues, placeholderProblem } from './chunk-R7BJYFD2.js';
11
12
  import { writeMarker, readMarker, currentVersion, removeMarker, entryIn, versionDir, startedThroughCurrent, switchCurrent, cleanVersions, isInLayout, stagingDir } from './chunk-TI7B7UEO.js';
12
13
  import { freeBytes, formatBytes } from './chunk-YYYRBYWG.js';
13
14
  import { RepoFilter } from './chunk-TBT347UY.js';
14
- import { describeCallFailure, retrySend, shortClaim, relativeToRunner, formatDuration, provisionContainer, lifecycleSteps, lifecycleFailureReason, prepareBranch, containerCommandLine, BuildTokens, classifyRefusal, refusalCode, measureDisk, createRunnerLog, setUpRunnerCgroup, parseCpuList, ensureTunnel, keepGhConfigCurrent, createContainerRuntime, formatClock } from './chunk-BREEX2Z7.js';
15
+ import { describeCallFailure, retrySend, shortClaim, relativeToRunner, formatDuration, provisionContainer, lifecycleSteps, lifecycleFailureReason, prepareBranch, containerCommandLine, BuildTokens, classifyRefusal, refusalCode, measureDisk, createRunnerLog, setUpRunnerCgroup, parseCpuList, ensureTunnel, keepGhConfigCurrent, createContainerRuntime, formatClock } from './chunk-E5DC4VZL.js';
15
16
  import { checkFit } from './chunk-JKIWMRFH.js';
16
17
  import { startTimeOf, claimPidFile, readPidFile, isSameProcess, releasePidFile } from './chunk-N5FOE5PS.js';
17
- import { spawnRun } from './chunk-VVIRHTH4.js';
18
- import { builderName, runnerLabelValue, ensureFailureCount, builderSpec, ensureBuilder, BUILD_LABEL, RUNNER_LABEL } from './chunk-JSUUXA5W.js';
18
+ import { spawnRun } from './chunk-2GBCTEN4.js';
19
+ import { builderName, runnerLabelValue, ensureFailureCount, builderSpec, ensureBuilder, BUILD_LABEL, RUNNER_LABEL } from './chunk-CJGQQZWB.js';
19
20
  import { isSignatureRefusal, WorkCommandError, getJson, postJson } from './chunk-DTDZXDQ3.js';
20
- import { isBuiltinContainer, isBuiltinVm, isBuiltinProcess, loadRunnerConfig, checkHooks, builtinKind } from './chunk-M2PBLRB7.js';
21
+ import { isBuiltinContainer, isBuiltinVm, isBuiltinProcess, loadRunnerConfig, checkHooks, builtinKind, DEFAULT_UPDATE_MAX_WAIT_HOURS } from './chunk-XR3BJN33.js';
21
22
  import { exceedsDisk } from './chunk-7RQ73DLO.js';
22
- import { sharedUserEnvironment, JOB_MOUNT, claudeCredential } from './chunk-M6G7TJVF.js';
23
+ import { parseClaimedRepositories, repositoriesOf, primaryOf, sharedUserEnvironment, JOB_MOUNT, claudeCredential } from './chunk-4Q7OMKAT.js';
23
24
  import { parseClaimIdentity } from './chunk-BYT5O5RV.js';
24
25
  import { resolveVersion } from './chunk-RA3O54FC.js';
25
26
  import { loadHostKey, ensureHostKey, signerFor } from './chunk-V7NIVOFD.js';
@@ -950,12 +951,19 @@ function considerNamedVersion(state, named) {
950
951
  });
951
952
  const updating = decision === "update" && !retryHeld(state, named);
952
953
  state.pendingUpdate = updating ? named : void 0;
954
+ if (!updating) clearUpdateWait(state);
953
955
  if (!updating || state.preflightedUpdate !== named) state.preflightedUpdate = void 0;
954
956
  if (decision === "cannot_self_update" && !state.cannotSelfUpdateLogged && installedSwitchOf(state, update).kind !== "restart") {
955
957
  state.cannotSelfUpdateLogged = true;
956
958
  logOf(state).line(`this runner cannot update itself to ${named}: ${blocker}`);
957
959
  }
958
960
  }
961
+ function adoptUpdateWait(state, version) {
962
+ const previous = state.updateWait;
963
+ const wait = { version, sinceMs: previous?.sinceMs ?? nowOf(state).getTime(), holdSinceMs: previous?.holdSinceMs };
964
+ state.updateWait = wait;
965
+ return wait;
966
+ }
959
967
  function retryHeld(state, version) {
960
968
  return state.updateRetry?.version === version && nowOf(state).getTime() < state.updateRetry.retryAtMs;
961
969
  }
@@ -972,6 +980,68 @@ function updateArgsOf(state, update, version) {
972
980
  function dropPendingUpdate(state) {
973
981
  state.pendingUpdate = void 0;
974
982
  state.preflightedUpdate = void 0;
983
+ clearUpdateWait(state);
984
+ }
985
+ function clearUpdateWait(state) {
986
+ state.updateWait = void 0;
987
+ state.updateLogged = void 0;
988
+ state.upgradeRefused = false;
989
+ recordPendingUpdate(state, void 0);
990
+ }
991
+ function recordPendingUpdate(state, record) {
992
+ const text = record === void 0 ? "none" : JSON.stringify(record);
993
+ if (state.updateRecord === text) return;
994
+ try {
995
+ writePendingUpdate(runnerDir(state.config.configPath), record);
996
+ state.updateRecord = text;
997
+ reportRepeating(state, "the update-pending.json record", void 0);
998
+ } catch (err) {
999
+ const code = err.code;
1000
+ const cause = code?.replace(/^ERR_FS_/, "") ?? (err instanceof Error ? err.name : "unknown error");
1001
+ reportRepeating(
1002
+ state,
1003
+ "the update-pending.json record",
1004
+ `could not write update-pending.json (${cause}): \`runner status\` will not show the pending update`
1005
+ );
1006
+ }
1007
+ }
1008
+ function runningItems(state) {
1009
+ const numbers = [...state.jobs.values()].map((entry) => Number(entry.job.item)).filter((n) => Number.isFinite(n));
1010
+ return numbers.sort((a, b) => a - b);
1011
+ }
1012
+ function holdForUpdate(state, version, mayHold = true) {
1013
+ const log = logOf(state);
1014
+ const nowMs = nowOf(state).getTime();
1015
+ const wait = adoptUpdateWait(state, version);
1016
+ const failed2 = readLastUpdate(state.config.configPath);
1017
+ const failedAtMs = failed2?.to === version && failed2.outcome === "retrying" ? new Date(failed2.at ?? Number.NaN).getTime() : Number.NaN;
1018
+ if (failedAtMs < wait.sinceMs) wait.sinceMs = failedAtMs;
1019
+ const logged = state.updateLogged ??= {};
1020
+ if (logged.pending !== version) {
1021
+ logged.pending = version;
1022
+ log.line(`update to ${version} pending \xB7 updating when no build is running`);
1023
+ }
1024
+ const maxWaitMs = (state.config.update?.maxWaitHours ?? DEFAULT_UPDATE_MAX_WAIT_HOURS) * 60 * 6e4;
1025
+ const holding = mayHold && (state.upgradeRefused === true || nowMs - wait.sinceMs >= maxWaitMs);
1026
+ const record = { version, since: new Date(wait.sinceMs).toISOString() };
1027
+ if (holding) {
1028
+ wait.holdSinceMs ??= nowMs;
1029
+ const builds = runningItems(state);
1030
+ const key = `${version}:${builds.join(",")}`;
1031
+ if (logged.hold !== key) {
1032
+ logged.hold = key;
1033
+ log.line(`claiming nothing: update to ${version} waits for ${buildsPhrase(builds)} to finish`);
1034
+ }
1035
+ record.holding = { builds, since: new Date(wait.holdSinceMs).toISOString() };
1036
+ } else {
1037
+ wait.holdSinceMs = void 0;
1038
+ logged.hold = void 0;
1039
+ }
1040
+ recordPendingUpdate(state, record);
1041
+ return holding;
1042
+ }
1043
+ function buildsPhrase(builds) {
1044
+ return builds.length === 0 ? "the running builds" : builds.map((n) => `#${n}`).join(", ");
975
1045
  }
976
1046
  function reportUpdateResult(state, version, result) {
977
1047
  if (result.kind === "retrying") state.updateRetry = { version, retryAtMs: result.retryAtMs };
@@ -1031,7 +1101,10 @@ function restartOntoInstalled(state) {
1031
1101
  async function updateWhenIdle(state) {
1032
1102
  const update = state.deps.update;
1033
1103
  const version = state.pendingUpdate;
1034
- if (update === void 0 || version === void 0) return false;
1104
+ if (update === void 0 || version === void 0) {
1105
+ recordPendingUpdate(state, void 0);
1106
+ return false;
1107
+ }
1035
1108
  if (!state.config.autoUpdate || retryHeld(state, version)) {
1036
1109
  dropPendingUpdate(state);
1037
1110
  return false;
@@ -1039,18 +1112,22 @@ async function updateWhenIdle(state) {
1039
1112
  if (state.jobs.size > 0) {
1040
1113
  const record = readLastUpdate(state.config.configPath);
1041
1114
  if (record?.to === version && record.outcome === "retrying") {
1042
- const failedAtMs = record.at === void 0 ? Number.NaN : Date.parse(record.at);
1043
- if (!(nowOf(state).getTime() >= failedAtMs + RETRY_MAX_WAIT_MS)) return false;
1044
- }
1045
- if (state.preflightedUpdate === version) return true;
1046
- const early = await preflightUpdate(updateArgsOf(state, update, version));
1047
- if (early !== void 0) {
1048
- dropPendingUpdate(state);
1049
- reportUpdateResult(state, version, early);
1050
- return false;
1115
+ const failedAtMs = new Date(record.at ?? Number.NaN).getTime();
1116
+ if (!(nowOf(state).getTime() >= failedAtMs + RETRY_MAX_WAIT_MS)) {
1117
+ holdForUpdate(state, version, false);
1118
+ return false;
1119
+ }
1051
1120
  }
1052
- state.preflightedUpdate = version;
1053
- return true;
1121
+ if (state.preflightedUpdate !== version) {
1122
+ const early = await preflightUpdate(updateArgsOf(state, update, version));
1123
+ if (early !== void 0) {
1124
+ dropPendingUpdate(state);
1125
+ reportUpdateResult(state, version, early);
1126
+ return false;
1127
+ }
1128
+ state.preflightedUpdate = version;
1129
+ }
1130
+ return holdForUpdate(state, version);
1054
1131
  }
1055
1132
  dropPendingUpdate(state);
1056
1133
  const result = await performUpdate(updateArgsOf(state, update, version));
@@ -1215,7 +1292,7 @@ async function runTick(state) {
1215
1292
  claimed = true;
1216
1293
  break;
1217
1294
  }
1218
- if (attempt.kind === "outdated" || attempt.kind === "signature" || attempt.kind === "no_item_key" || attempt.kind === "no_branch") {
1295
+ if (attempt.kind === "outdated" || attempt.kind === "signature" || attempt.kind === "no_item_key" || attempt.kind === "no_branch" || attempt.kind === "unreadable_repositories") {
1219
1296
  return;
1220
1297
  }
1221
1298
  if (attempt.kind === "error") {
@@ -1235,7 +1312,7 @@ async function runTick(state) {
1235
1312
  );
1236
1313
  }
1237
1314
  var CLAIM_REFUSAL_CODES = new Set(
1238
- "pull_request_from_fork pull_request_on_default_branch pull_request_ambiguous branch_claimed_elsewhere".split(" ")
1315
+ "pull_request_from_fork pull_request_on_default_branch pull_request_ambiguous pull_request_repository_not_connected branch_claimed_elsewhere".split(" ")
1239
1316
  );
1240
1317
  async function tryClaimAndStart(state, item, queue) {
1241
1318
  const { postJson: postJson2 } = await import('./work-cmd-ZJY3NA2G.js');
@@ -1276,11 +1353,13 @@ async function tryClaimAndStart(state, item, queue) {
1276
1353
  }
1277
1354
  if (claim.code === "runner_upgrade_required") {
1278
1355
  reportRepeating(state, "the runner protocol", claim.message ?? claim.reason);
1356
+ state.upgradeRefused = true;
1279
1357
  return { kind: "outdated" };
1280
1358
  }
1281
1359
  return { kind: "error", reason: `${claim.reason} (${claim.attempts} attempt(s))` };
1282
1360
  }
1283
1361
  reportRepeating(state, "the runner protocol", void 0);
1362
+ state.upgradeRefused = false;
1284
1363
  reportRepeating(state, "the request signature", void 0);
1285
1364
  const { data } = claim.value;
1286
1365
  const claimId = data.id === void 0 || data.id === null ? "" : String(data.id);
@@ -1326,8 +1405,22 @@ async function tryClaimAndStart(state, item, queue) {
1326
1405
  }
1327
1406
  reportRepeating(state, "the branch", void 0);
1328
1407
  const identity = parseClaimIdentity(data);
1408
+ const repositories = parseClaimedRepositories(data.repositories);
1409
+ if (repositories === null) {
1410
+ const released = await retrySend(
1411
+ () => releaseLease(state.config, item.number, void 0, {}, state.deps.fetchImpl),
1412
+ { now: state.deps.now, sleep: state.deps.sleep }
1413
+ );
1414
+ reportRepeating(
1415
+ state,
1416
+ "the repositories",
1417
+ `the gateway named repositories for #${item.number} that this runner cannot read; upgrade the runner or the gateway. ` + (released.ok ? "The claim was released and no build started" : `No build started, but releasing the claim failed (${released.reason}), so it stays held until its lease lapses`)
1418
+ );
1419
+ return { kind: "unreadable_repositories" };
1420
+ }
1421
+ reportRepeating(state, "the repositories", void 0);
1329
1422
  try {
1330
- await startJob(state, item, queue, claimId, itemKey, branch, identity);
1423
+ await startJob(state, item, queue, claimId, itemKey, branch, identity, repositories);
1331
1424
  } catch (err) {
1332
1425
  const stranded = [...state.jobs.values()].find((active) => active.job.claimId === claimId);
1333
1426
  if (stranded === void 0) throw err;
@@ -1352,9 +1445,11 @@ function wasExtended(claim) {
1352
1445
  if (!Number.isFinite(createdAtMs) || !Number.isFinite(expiresAtMs)) return false;
1353
1446
  return expiresAtMs - createdAtMs > LEASE_SECONDS * 1e3 + 2e3;
1354
1447
  }
1355
- async function startJob(state, item, queue, claimId, itemKey, branch, identity) {
1448
+ async function startJob(state, item, queue, claimId, itemKey, branch, identity, claimed) {
1356
1449
  const log = logOf(state);
1357
1450
  const startedAt = nowOf(state);
1451
+ const repositories = repositoriesOf({ repositories: claimed, repository: item.specRepository, branch });
1452
+ const primary = primaryOf(repositories);
1358
1453
  const dirPath = freeJobDir(state.config.configPath, queue, item.number, claimId, startedAt);
1359
1454
  mkdirSync(dirPath, { recursive: true, mode: RUNNER_DIR_MODE });
1360
1455
  const runnerRoot = runnerDir(state.config.configPath);
@@ -1366,7 +1461,7 @@ async function startJob(state, item, queue, claimId, itemKey, branch, identity)
1366
1461
  itemKey,
1367
1462
  branch,
1368
1463
  commitIdentity: identity,
1369
- ...item.specRepository === void 0 || item.specRepository === null || item.specRepository === "" ? {} : { repository: item.specRepository },
1464
+ ...primary === void 0 ? {} : { repository: primary.repository, repositories },
1370
1465
  startedAt: startedAt.toISOString()
1371
1466
  };
1372
1467
  writeJobFile(jobFilePath, job);
@@ -1440,7 +1535,8 @@ async function startJob(state, item, queue, claimId, itemKey, branch, identity)
1440
1535
  item,
1441
1536
  itemKey,
1442
1537
  tokens,
1443
- branch,
1538
+ branch: primary?.branch ?? branch,
1539
+ repositories,
1444
1540
  jobDir: dirPath,
1445
1541
  cliVersion,
1446
1542
  log,
@@ -1472,7 +1568,8 @@ async function startJob(state, item, queue, claimId, itemKey, branch, identity)
1472
1568
  item,
1473
1569
  itemKey,
1474
1570
  tokens,
1475
- branch,
1571
+ branch: primary?.branch ?? branch,
1572
+ repositories,
1476
1573
  jobDir: dirPath,
1477
1574
  cliVersion,
1478
1575
  log,
@@ -1749,6 +1846,7 @@ function buildTokensFor(state, active, item) {
1749
1846
  return new BuildTokens({
1750
1847
  config: state.config,
1751
1848
  item,
1849
+ primary: primaryOf(repositoriesOf({ repositories: active.job.repositories, repository: active.job.repository, branch: active.job.branch }))?.repository,
1752
1850
  fetchImpl: state.deps.fetchImpl,
1753
1851
  now: state.deps.now,
1754
1852
  sleep: state.deps.sleep,
@@ -1974,7 +2072,7 @@ async function start(configPath, deps = { fetchImpl: fetch }) {
1974
2072
  const outcome = await onStartUnderMarker({
1975
2073
  configPath,
1976
2074
  own: ownVersionOf(deps),
1977
- check: update.check ? () => update.check(configPath) : async () => (await import('./check-NQYQHITZ.js')).runRunnerCheck(configPath, { fetchImpl: deps.fetchImpl }),
2075
+ check: update.check ? () => update.check(configPath) : async () => (await import('./check-YDXOLVJ5.js')).runRunnerCheck(configPath, { fetchImpl: deps.fetchImpl }),
1978
2076
  now: () => (deps.now ?? (() => /* @__PURE__ */ new Date()))().getTime(),
1979
2077
  log
1980
2078
  });
@@ -2020,7 +2118,7 @@ async function start(configPath, deps = { fetchImpl: fetch }) {
2020
2118
  if (cores !== void 0) runtimeOf(state).cpus.hold(job.container.buildId, cores);
2021
2119
  const tokens = buildTokensFor(state, adopted, job.item);
2022
2120
  runtimeOf(state).credentials.set(dirPath, tokens);
2023
- await ensureTunnel(runtimeOf(state), job.container, dirPath, config, job.itemKey, job.branch);
2121
+ await ensureTunnel(runtimeOf(state), job.container, dirPath, config, job.itemKey, job.branch, job.repositories);
2024
2122
  try {
2025
2123
  await tokens.token("read");
2026
2124
  keepGhConfigCurrent(
@@ -345,11 +345,38 @@ async function startBuildServices(input) {
345
345
  }
346
346
  }
347
347
 
348
+ // src/runner/repositories.ts
349
+ function parseClaimedRepositories(value) {
350
+ if (!Array.isArray(value) || value.length === 0) return void 0;
351
+ const parsed = [];
352
+ for (const entry of value) {
353
+ if (typeof entry !== "object" || entry === null) return null;
354
+ const { repository, branch, primary } = entry;
355
+ if (typeof repository !== "string" || repository === "" || typeof branch !== "string" || branch === "") return null;
356
+ parsed.push({ repository, branch, primary: primary === true });
357
+ }
358
+ const primaryAt = parsed.findIndex((entry) => entry.primary);
359
+ const at = primaryAt === -1 ? 0 : primaryAt;
360
+ return [{ ...parsed[at], primary: true }, ...parsed.filter((_, index) => index !== at).map((entry) => ({ ...entry, primary: false }))];
361
+ }
362
+ function repositoriesOf(input) {
363
+ if (input.repositories !== void 0 && input.repositories.length > 0) return input.repositories;
364
+ if (input.repository === void 0 || input.repository === null || input.repository === "" || input.branch === void 0) return [];
365
+ return [{ repository: input.repository, branch: input.branch, primary: true }];
366
+ }
367
+ function primaryOf(repositories) {
368
+ return repositories.find((entry) => entry.primary) ?? repositories[0];
369
+ }
370
+
348
371
  // src/runner/container/environment.ts
349
372
  var RELAY_PORT = 3128;
350
373
  var JOB_MOUNT = "/outerlayer/job";
351
374
  var EVAL_INPUT_DIR = `${JOB_MOUNT}/eval-input`;
352
375
  var CHECKOUT_DIR = "/build/work/checkout";
376
+ var REPOS_DIR = "/build/work/repos";
377
+ function checkoutPath(entry) {
378
+ return entry.primary ? CHECKOUT_DIR : `${REPOS_DIR}/${entry.repository}`;
379
+ }
353
380
  var MAX_HOSTS = 200;
354
381
  function tokenVariables() {
355
382
  return ["GH_TOKEN", "GITHUB_TOKEN", "GH_ENTERPRISE_TOKEN", "GITHUB_ENTERPRISE_TOKEN"];
@@ -377,7 +404,7 @@ function proxyEnvironment(proxyUrl, alsoNoProxy) {
377
404
  YARN_HTTP_PROXY: proxyUrl
378
405
  };
379
406
  }
380
- function runnerLiterals(repository) {
407
+ function runnerLiterals(repository, repositories = []) {
381
408
  return {
382
409
  OUTERLAYER_JOB_DIR: JOB_MOUNT,
383
410
  HOME: "/build/home",
@@ -386,7 +413,13 @@ function runnerLiterals(repository) {
386
413
  GIT_TERMINAL_PROMPT: "0",
387
414
  GH_CONFIG_DIR: `${JOB_MOUNT}/gh`,
388
415
  GH_NO_UPDATE_NOTIFIER: "1",
389
- ...repository === void 0 ? {} : { GH_REPO: repository }
416
+ ...repository === void 0 ? {} : { GH_REPO: repository },
417
+ // What the build's command reads to find every repository it holds: its path, its branch, and whether it is the primary.
418
+ ...repositories.length === 0 ? {} : {
419
+ OUTERLAYER_REPOSITORIES: JSON.stringify(
420
+ repositories.map((entry) => ({ repository: entry.repository, path: checkoutPath(entry), branch: entry.branch, primary: entry.primary }))
421
+ )
422
+ }
390
423
  };
391
424
  }
392
425
  function containerBuiltInAddress(name) {
@@ -448,7 +481,14 @@ function buildEnvironment(input) {
448
481
  delete passed.GIT_CONFIG_COUNT;
449
482
  }
450
483
  return {
451
- literals: { ...recipe, ...destinations, ...runnerLiterals(input.repository), ...builtInLiterals, ...authored, ...hooks },
484
+ literals: {
485
+ ...recipe,
486
+ ...destinations,
487
+ ...runnerLiterals(input.repository, repositoriesOf({ repositories: input.repositories, repository: input.repository, branch: input.branch })),
488
+ ...builtInLiterals,
489
+ ...authored,
490
+ ...hooks
491
+ },
452
492
  passed,
453
493
  variables,
454
494
  skippedTokenVariables
@@ -504,4 +544,4 @@ function withTunnelRecord(environment, record, onlyWhenUsed = false) {
504
544
  };
505
545
  }
506
546
 
507
- export { AGENT_CREDENTIAL_MISSING, BUILT_IN_NAMES, CHECKOUT_DIR, CLAUDE_CREDENTIAL_VARIABLES, CLAUDE_PORT, CLAUDE_SOCKET, DESTINATION_BASE_PORT, EVAL_INPUT_DIR, GATEWAY_PORT, GATEWAY_SOCKET, JOB_MOUNT, RELAY_PORT, buildEnvironment, builtInEnvironment, checkEnvironment, claudeCredential, containerLocalAddress, destinationEnvironment, headerVariables, isRefusedInConfig, isReservedVariable, parseIsolation, proxyEnvironment, resolveDestinations, sharedUserEnvironment, startBuildServices, withTunnelRecord };
547
+ export { AGENT_CREDENTIAL_MISSING, BUILT_IN_NAMES, CHECKOUT_DIR, CLAUDE_CREDENTIAL_VARIABLES, CLAUDE_PORT, CLAUDE_SOCKET, DESTINATION_BASE_PORT, EVAL_INPUT_DIR, GATEWAY_PORT, GATEWAY_SOCKET, JOB_MOUNT, RELAY_PORT, buildEnvironment, builtInEnvironment, checkEnvironment, checkoutPath, claudeCredential, containerLocalAddress, destinationEnvironment, headerVariables, isRefusedInConfig, isReservedVariable, parseClaimedRepositories, parseIsolation, primaryOf, proxyEnvironment, repositoriesOf, resolveDestinations, sharedUserEnvironment, startBuildServices, withTunnelRecord };
@@ -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-472KC6JV.js';
4
- import { MIN_ENGINE_MAJOR } from './chunk-BREEX2Z7.js';
3
+ import { detectMachine, supportsContainerBuilds, reachDockerStep, describeMachineDocker, supportsMicroVmBuilds } from './chunk-BEZSECPA.js';
4
+ import { MIN_ENGINE_MAJOR } from './chunk-E5DC4VZL.js';
5
5
  import { RUNNER_DIR_MODE, runnerDir, RUNNER_FILE_MODE } from './chunk-ZM2IMMYN.js';
6
6
  import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
7
7
  import { dirname } from 'path';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { MIN_ENGINE_MAJOR } from './chunk-BREEX2Z7.js';
3
+ import { MIN_ENGINE_MAJOR } from './chunk-E5DC4VZL.js';
4
4
  import { firecrackerArch, MICROVM_ARCHES, guestAssetsPinned } from './chunk-CX22S5BA.js';
5
5
  import { spawnSync } from 'child_process';
6
6
  import { existsSync, accessSync, constants, statSync, readFileSync } from 'fs';
@@ -2,21 +2,21 @@
2
2
  import { createRequire } from 'node:module';
3
3
  import { writeJobFile, readJobFile } from './chunk-T6OIJQRT.js';
4
4
  import { senderPidfile } from './chunk-HKUH5AR2.js';
5
- import { DOCKERD_LOG } from './chunk-V42JY4F6.js';
5
+ import { DOCKERD_LOG } from './chunk-HYZRY4KZ.js';
6
6
  import { installScrubContext } from './chunk-Y6P5XX2B.js';
7
- import { AssetError, describeCallFailure, obtainImage, ensureRootfs, gitRemoteFor, startServicesFor, createBuildDisk, machineConfig, refusalCode, resolveAgentUser, AgentUserError, runBuildSteps, removeStagedContext, stageGovernedContext, shellQuote, createRunnerLog, createContainerRuntime, stopContainer, cleanupContainer, outOfMemoryReason, formatDuration, retrySend, formatClock, containerSenderCommand, syncInContainer, copyTranscriptsFromContainer, GH_CONFIG_YML, ghHostsYml, ADDED_USER, isLiteralAddress, signalInContainer, deleteBuildDisk, startCheckContainer, lifecycleSteps, lifecycleFailureReason, writeEvalInput, EVAL_INPUT_NAME, copyTranscripts, senderSignalScript } from './chunk-BREEX2Z7.js';
7
+ import { AssetError, describeCallFailure, obtainImage, ensureRootfs, gitRemoteFor, startServicesFor, createBuildDisk, machineConfig, refusalCode, resolveAgentUser, AgentUserError, runBuildSteps, removeStagedContext, stageGovernedContext, shellQuote, createRunnerLog, createContainerRuntime, stopContainer, cleanupContainer, outOfMemoryReason, formatDuration, retrySend, formatClock, containerSenderCommand, syncInContainer, copyTranscriptsFromContainer, GH_CONFIG_YML, ghHostsYml, ADDED_USER, isLiteralAddress, signalInContainer, deleteBuildDisk, startCheckContainer, lifecycleSteps, lifecycleFailureReason, writeEvalInput, EVAL_INPUT_NAME, copyTranscripts, senderSignalScript } from './chunk-E5DC4VZL.js';
8
8
  import { readBranchHead, diffBetween, fetchCommit } from './chunk-3FMPZPJQ.js';
9
9
  import { isSameProcess, startTimeOf } from './chunk-N5FOE5PS.js';
10
- import { childEnvironment } from './chunk-VVIRHTH4.js';
10
+ import { childEnvironment } from './chunk-2GBCTEN4.js';
11
11
  import { CLAUDE_CODE_VERSION } from './chunk-CX22S5BA.js';
12
- import { waitForAgent, vmExecArgs } from './chunk-6CXYORUS.js';
13
- import { socketPathProblem, vsockLinks, linkVsockSockets } from './chunk-S6IUUNCD.js';
12
+ import { waitForAgent, vmExecArgs } from './chunk-QKFB4K7X.js';
13
+ import { socketPathProblem, vsockLinks, linkVsockSockets } from './chunk-RSNSZ2LJ.js';
14
14
  import { WorkCommandError, postJson, isSignatureRefusal, getJson } from './chunk-DTDZXDQ3.js';
15
15
  import { planArtifactUpload } from './chunk-VDI5POCC.js';
16
16
  import { scrubText } from './chunk-IU4NZROR.js';
17
- import { isBuiltinContainer, isBuiltinProcess, isBuiltinVm, DEFAULT_CHECK_TIME_LIMIT_MINUTES } from './chunk-M2PBLRB7.js';
17
+ import { isBuiltinContainer, isBuiltinProcess, isBuiltinVm, DEFAULT_CHECK_TIME_LIMIT_MINUTES } from './chunk-XR3BJN33.js';
18
18
  import { parseSize } from './chunk-7RQ73DLO.js';
19
- import { claudeCredential, buildEnvironment, JOB_MOUNT, CHECKOUT_DIR, parseIsolation, proxyEnvironment, containerLocalAddress, destinationEnvironment, CLAUDE_CREDENTIAL_VARIABLES, builtInEnvironment, startBuildServices, BUILT_IN_NAMES, AGENT_CREDENTIAL_MISSING, sharedUserEnvironment, headerVariables, withTunnelRecord, RELAY_PORT, checkEnvironment, EVAL_INPUT_DIR } from './chunk-M6G7TJVF.js';
19
+ import { claudeCredential, repositoriesOf, primaryOf, buildEnvironment, JOB_MOUNT, CHECKOUT_DIR, parseIsolation, proxyEnvironment, containerLocalAddress, destinationEnvironment, CLAUDE_CREDENTIAL_VARIABLES, builtInEnvironment, startBuildServices, BUILT_IN_NAMES, AGENT_CREDENTIAL_MISSING, sharedUserEnvironment, headerVariables, withTunnelRecord, RELAY_PORT, checkEnvironment, EVAL_INPUT_DIR } from './chunk-4Q7OMKAT.js';
20
20
  import { parsePolicy } from './chunk-TB7EP24C.js';
21
21
  import { readCloudConfig } from './chunk-EABW6AJQ.js';
22
22
  import { withHooksPath, authorEnvironment, commitIdentityRecord } from './chunk-BYT5O5RV.js';
@@ -90,10 +90,10 @@ async function provisionMicroVm(input) {
90
90
  const logPath = join(jobDir, "provision.log");
91
91
  const fail = (reason) => ({ ok: false, reason });
92
92
  if (claudeCredential(runtime.hostEnv) === void 0) return fail(AGENT_CREDENTIAL_MISSING);
93
- const repository = item.specRepository;
94
- if (repository === void 0 || repository === null || repository === "") {
95
- return fail("the work item names no repository to clone");
96
- }
93
+ const repositories = repositoriesOf({ repositories: input.repositories, repository: item.specRepository, branch: input.branch });
94
+ const primary = primaryOf(repositories);
95
+ if (primary === void 0) return fail("the work item names no repository to clone");
96
+ const repository = primary.repository;
97
97
  const runnerDirPath = runnerDir(config.configPath);
98
98
  const tooDeep = socketPathProblem(buildDir(config.configPath, "0".repeat(12)));
99
99
  if (tooDeep !== void 0) return fail(tooDeep);
@@ -134,6 +134,7 @@ async function provisionMicroVm(input) {
134
134
  item: item.number,
135
135
  itemKey,
136
136
  repository,
137
+ repositories,
137
138
  hostEnv: runtime.hostEnv,
138
139
  containerEnv: report.apply.containerEnv,
139
140
  builtIns: true
@@ -182,7 +183,7 @@ async function provisionMicroVm(input) {
182
183
  mkdirSync(buildDir2, { recursive: true, mode: 448 });
183
184
  chmodSync(buildDir2, 448);
184
185
  try {
185
- const gitRemote = gitRemoteFor(runtime, { repository, branch: input.branch, tokens, buildDir: buildDir2, log: (line) => log.line(`${tag} ${line}`) });
186
+ const gitRemote = gitRemoteFor(runtime, { repositories, tokens, buildDir: buildDir2, log: (line) => log.line(`${tag} ${line}`) });
186
187
  runtime.tunnels.set(buildId, await startServicesFor(runtime, config, buildDir2, jobDir, itemKey, true, gitRemote));
187
188
  } catch (err) {
188
189
  return bail(`the tunnel could not start: ${describeCallFailure(err)}`);
@@ -243,6 +244,14 @@ async function provisionMicroVm(input) {
243
244
  err instanceof WorkCommandError ? `the build's read token could not be had: ${refusalCode(err)}` : `the build's gh configuration could not be written: ${describeCallFailure(err)}`
244
245
  );
245
246
  }
247
+ for (const entry of repositories) {
248
+ if (entry.repository === primary.repository) continue;
249
+ try {
250
+ await tokens.token("read", entry.repository);
251
+ } catch (err) {
252
+ return bail(`the build's read token for ${entry.repository} could not be had: ${refusalCode(err)}`);
253
+ }
254
+ }
246
255
  tokens.onRead((token) => {
247
256
  pushes = pushes.then(async () => {
248
257
  if (state.firecracker === void 0 || !vm.firecracker.alive(state.firecracker)) return;
@@ -277,7 +286,8 @@ async function provisionMicroVm(input) {
277
286
  const request = (argv, workdir) => ({ argv, user: agentUser, cwd: workdir, env: execEnvironment(state.imageEnv, env) });
278
287
  const steps = await runBuildSteps({
279
288
  repository,
280
- branch: input.branch,
289
+ branch: primary.branch,
290
+ repositories,
281
291
  lifecycle: report.apply.lifecycle,
282
292
  exec: async (argv, workdir, opts) => {
283
293
  const ran = await vm.exec(state.vsockPath, request(argv, workdir));
@@ -351,6 +361,7 @@ function vmExecFor(input, argv) {
351
361
  itemKey: input.job.itemKey,
352
362
  branch: input.job.branch,
353
363
  repository: state.repository,
364
+ repositories: input.job.repositories,
354
365
  hostEnv: input.runtime.hostEnv,
355
366
  containerEnv: state.containerEnv ?? {},
356
367
  builtIns: state.builtIns === true,
@@ -388,6 +399,7 @@ async function syncInMicroVm(input) {
388
399
  itemKey: job.itemKey,
389
400
  branch: job.branch,
390
401
  repository: state.repository,
402
+ repositories: job.repositories,
391
403
  hostEnv: runtime.hostEnv,
392
404
  containerEnv: state.containerEnv ?? {},
393
405
  builtIns: state.builtIns === true,
@@ -476,7 +488,13 @@ async function startCheckMicroVm(input) {
476
488
  input.save(state);
477
489
  mkdirSync(buildDir2, { recursive: true, mode: 448 });
478
490
  try {
479
- const gitRemote = gitRemoteFor(runtime, { repository, branch, tokens, buildDir: buildDir2, log: (line) => log.line(`${tag} ${line}`), readOnly: true });
491
+ const gitRemote = gitRemoteFor(runtime, {
492
+ repositories: repositoriesOf({ repositories: job.repositories, repository, branch }),
493
+ tokens,
494
+ buildDir: buildDir2,
495
+ log: (line) => log.line(`${tag} ${line}`),
496
+ readOnly: true
497
+ });
480
498
  runtime.tunnels.set(buildId, await startServicesFor(runtime, config, buildDir2, checksDir, void 0, false, gitRemote));
481
499
  } catch (err) {
482
500
  return fail(`the tunnel could not start: ${describeCallFailure(err)}`);
@@ -3,7 +3,7 @@ import { createRequire } from 'node:module';
3
3
  import { BUILDKIT_IMAGE } from './chunk-CX22S5BA.js';
4
4
  import { compareVersions } from './chunk-IU4NZROR.js';
5
5
  import { parseSize } from './chunk-7RQ73DLO.js';
6
- import { JOB_MOUNT, GATEWAY_PORT, GATEWAY_SOCKET, CLAUDE_PORT, CLAUDE_SOCKET, RELAY_PORT, DESTINATION_BASE_PORT } from './chunk-M6G7TJVF.js';
6
+ import { JOB_MOUNT, GATEWAY_PORT, GATEWAY_SOCKET, CLAUDE_PORT, CLAUDE_SOCKET, RELAY_PORT, DESTINATION_BASE_PORT } from './chunk-4Q7OMKAT.js';
7
7
  import { runnerDir } from './chunk-ZM2IMMYN.js';
8
8
  import { createHash } from 'crypto';
9
9
  import { realpathSync } from 'fs';