@outerlayer/cli 0.17.0 → 0.19.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 (160) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/README.md +36 -2
  3. package/dist/agent-setup-TPR4BBFV.js +27 -0
  4. package/dist/{artifact-link-cmd-2F47LT7F.js → artifact-link-cmd-W7XF5BFB.js} +4 -3
  5. package/dist/{build-BG2YENGK.js → build-TQ6X5PYN.js} +5 -4
  6. package/dist/build-info.json +1 -1
  7. package/dist/{builder-2D3WSOOY.js → builder-C4QNTYMS.js} +5 -6
  8. package/dist/{check-5XE7XMC4.js → check-UWQAL2MN.js} +56 -52
  9. package/dist/{chunk-R7PF5OOU.js → chunk-3CWUOFV6.js} +21 -14
  10. package/dist/{chunk-4NPZVMJU.js → chunk-3UZTIRLF.js} +60 -4
  11. package/dist/chunk-452TM7J4.js +502 -0
  12. package/dist/{chunk-NNRTPG7X.js → chunk-5GHGAF6P.js} +4 -4
  13. package/dist/{chunk-WVUIRTWA.js → chunk-5MYFOW5V.js} +196 -37
  14. package/dist/{chunk-HGECYFEI.js → chunk-5TN7GLYX.js} +138 -109
  15. package/dist/{chunk-VQYBXPI7.js → chunk-6D7GT22T.js} +5 -5
  16. package/dist/{chunk-G5NPRL2K.js → chunk-6U3MV7TZ.js} +687 -76
  17. package/dist/{chunk-42ZI52JW.js → chunk-6X4SQ5MY.js} +4 -3
  18. package/dist/{chunk-MAK5LYRF.js → chunk-7KSSBQTS.js} +278 -535
  19. package/dist/{chunk-NWQTTSBB.js → chunk-7SJPQWBM.js} +41 -16
  20. package/dist/{chunk-J5M7BSJQ.js → chunk-7VUK5RFS.js} +23 -4
  21. package/dist/{chunk-OZGHL5Y5.js → chunk-7YP7T6GV.js} +2 -2
  22. package/dist/{chunk-TI7B7UEO.js → chunk-AMFWYESY.js} +1 -1
  23. package/dist/{chunk-YRYMNBGQ.js → chunk-ANPNT6PM.js} +2 -1
  24. package/dist/{chunk-4KSQKQXE.js → chunk-BM63HB2M.js} +20 -16
  25. package/dist/{chunk-4Q7OMKAT.js → chunk-BQXFBI7T.js} +81 -5
  26. package/dist/{chunk-ADJRGVZC.js → chunk-BWSUPRDK.js} +1 -1
  27. package/dist/{chunk-3NSNIIBE.js → chunk-CG36IONK.js} +18 -17
  28. package/dist/chunk-CJJDJ7AT.js +56 -0
  29. package/dist/chunk-CRB3POP4.js +34 -0
  30. package/dist/{chunk-LWSJQJC6.js → chunk-DADWEUH3.js} +7 -7
  31. package/dist/{chunk-KG5ECZGJ.js → chunk-DJ3ZUSC3.js} +11 -11
  32. package/dist/{chunk-F47JBIAW.js → chunk-DSF2FWAZ.js} +2 -1
  33. package/dist/{chunk-N5FOE5PS.js → chunk-ECODQ7II.js} +4 -33
  34. package/dist/{chunk-HHJDN6AU.js → chunk-ESVW4MJY.js} +1 -1
  35. package/dist/{chunk-YO4PSLVB.js → chunk-FVMYKL6L.js} +1 -1
  36. package/dist/chunk-G2YNJIGF.js +44 -0
  37. package/dist/{chunk-WUYTWNMA.js → chunk-G3IJ3N6F.js} +5 -3
  38. package/dist/{chunk-QKFB4K7X.js → chunk-GGOMT6KF.js} +1 -1
  39. package/dist/{chunk-N6LURUEF.js → chunk-GOSFARMS.js} +1 -1
  40. package/dist/{chunk-S3NYLI2P.js → chunk-HPJNLETG.js} +93 -38
  41. package/dist/{chunk-IP7BIBXJ.js → chunk-IF2OSI5T.js} +35 -1
  42. package/dist/{chunk-C5Y5ZJJZ.js → chunk-IXYZUUYQ.js} +5 -4
  43. package/dist/chunk-JBJTC3UU.js +35 -0
  44. package/dist/chunk-KYS3TQAG.js +296 -0
  45. package/dist/chunk-LLM3I5YU.js +89 -0
  46. package/dist/{chunk-YU3VKZ5F.js → chunk-LRG3ZMZD.js} +6 -7
  47. package/dist/{chunk-V7NIVOFD.js → chunk-M2ZWWTWZ.js} +1 -1
  48. package/dist/{chunk-ERI5GBNI.js → chunk-MLAAT4S6.js} +3 -3
  49. package/dist/{chunk-O765JR4W.js → chunk-MTP2QEVO.js} +1 -1
  50. package/dist/{chunk-ZM2IMMYN.js → chunk-N2PXGQRL.js} +9 -1
  51. package/dist/{chunk-BWQ66M6N.js → chunk-NFIR3GEE.js} +98 -24
  52. package/dist/{chunk-POJMEEJJ.js → chunk-NNLA7LLQ.js} +1 -1
  53. package/dist/{chunk-PLMTLGYH.js → chunk-NTRCK4NH.js} +5 -4
  54. package/dist/{chunk-22RMZBGW.js → chunk-P53VEAOF.js} +1 -1
  55. package/dist/{chunk-RLYZLUQ7.js → chunk-QEFKA2QD.js} +2 -2
  56. package/dist/{chunk-JXYVA45C.js → chunk-QNLX477Q.js} +1200 -322
  57. package/dist/{chunk-UGP76IZ5.js → chunk-S5PCA3SN.js} +1 -1
  58. package/dist/{chunk-RMWLBUCJ.js → chunk-SADUQSO4.js} +1 -1
  59. package/dist/{chunk-GQD22KKN.js → chunk-T2Q7ISPE.js} +2 -1
  60. package/dist/chunk-TUSYOL2O.js +113 -0
  61. package/dist/{chunk-NBGDBTO2.js → chunk-TWF3RICI.js} +9 -8
  62. package/dist/{chunk-ONKJUM6R.js → chunk-UVG35MWF.js} +1 -1
  63. package/dist/{chunk-KMDLFI4P.js → chunk-VMJPFQNE.js} +1 -1
  64. package/dist/chunk-VRRGENS4.js +144 -0
  65. package/dist/{chunk-PTW6W5NR.js → chunk-VYAL7PUE.js} +1 -1
  66. package/dist/{chunk-OHVJA253.js → chunk-WFSUUUAN.js} +47 -30
  67. package/dist/{chunk-RSNSZ2LJ.js → chunk-X5H2WYMB.js} +1 -1
  68. package/dist/{chunk-HYZRY4KZ.js → chunk-XNGMQ27R.js} +16 -6
  69. package/dist/chunk-XSZD4AZ6.js +490 -0
  70. package/dist/chunk-YQR6E6OV.js +109 -0
  71. package/dist/{chunk-XCK2YAY5.js → chunk-YVZJ6GKF.js} +3 -2
  72. package/dist/{chunk-2MNPHL23.js → chunk-ZHAUSEEN.js} +38 -15
  73. package/dist/claude-launcher-FPPHZPMR.js +115 -0
  74. package/dist/{cli-A76AXELQ.js → cli-HROW5T7X.js} +567 -285
  75. package/dist/{command-R2QCVX55.js → command-OEAV7BVX.js} +42 -40
  76. package/dist/{config-N3C6DFQA.js → config-CLSGABD5.js} +2 -3
  77. package/dist/{connect-cmd-JBKAQNSF.js → connect-cmd-UNYKGDAL.js} +10 -9
  78. package/dist/context-cleanup-HSVYDGMI.js +9 -0
  79. package/dist/control-plane-launch-NYVDJESK.js +216 -0
  80. package/dist/{dist-LKDWQWZ7.js → dist-WO7NOJNG.js} +2 -2
  81. package/dist/{docker-4J77Q2BF.js → docker-BFU3AQGY.js} +7 -8
  82. package/dist/{doctor-4TAIARIG.js → doctor-23BBJWBX.js} +48 -42
  83. package/dist/{emit-artifact-cmd-MPZVR56N.js → emit-artifact-cmd-O6SCM7TV.js} +27 -24
  84. package/dist/emit-cmd-7SP3I6UZ.js +14 -0
  85. package/dist/{emit-criteria-cmd-EFGYI23V.js → emit-criteria-cmd-LQNERZRV.js} +17 -16
  86. package/dist/{emit-finding-cmd-5GF3V4LR.js → emit-finding-cmd-AJPKHIOV.js} +18 -17
  87. package/dist/{emit-result-cmd-I4OADKMD.js → emit-result-cmd-RUICOKWQ.js} +22 -19
  88. package/dist/emit-step-cmd-347XNGPQ.js +26 -0
  89. package/dist/{exec-client-CQV746UF.js → exec-client-7UMESIE2.js} +3 -4
  90. package/dist/governing-source-V5EEGPTA.js +34 -0
  91. package/dist/guest-init-KPBQOFE5.js +9 -0
  92. package/dist/{hook-fast-R4FVSZ2H.js → hook-fast-YAZG5MDX.js} +5 -2
  93. package/dist/host-key-U4B5QETR.js +8 -0
  94. package/dist/{import-capture-cmd-EQ35EARA.js → import-capture-cmd-KKFFOGWP.js} +7 -5
  95. package/dist/{import-ruler-cmd-BGAZXCQM.js → import-ruler-cmd-5P6JOXQN.js} +5 -3
  96. package/dist/index.js +8 -4
  97. package/dist/{init-PWU5YVL7.js → init-LWHDMZQG.js} +40 -38
  98. package/dist/init-MOINY2DD.js +53 -0
  99. package/dist/{init-cmd-XAVO7HYZ.js → init-cmd-HSMRID6A.js} +75 -30
  100. package/dist/{init-update-CVCWD6VS.js → init-update-LWX5MPPR.js} +29 -29
  101. package/dist/{install-HDBIPHTX.js → install-4SEFIIW2.js} +4 -5
  102. package/dist/{install-cmd-5HYMXLEW.js → install-cmd-QDOTR4OM.js} +5 -4
  103. package/dist/{login-browser-QZCS3WW6.js → login-browser-DX35MARZ.js} +5 -4
  104. package/dist/{logout-cmd-QAUFDJ6J.js → logout-cmd-5V5MMBSY.js} +3 -2
  105. package/dist/{logs-H55NWW4H.js → logs-AMLKC3VP.js} +3 -1
  106. package/dist/loop-SYYPVFYW.js +77 -0
  107. package/dist/machine-6X63G2KH.js +48 -0
  108. package/dist/{mcp-install-cmd-FDTPQQS6.js → mcp-install-cmd-GGWB3JJ2.js} +3 -2
  109. package/dist/{mcp-serve-cmd-3KVYEUXG.js → mcp-serve-cmd-N3UTY6EE.js} +11 -9
  110. package/dist/paths-7XP63OAX.js +7 -0
  111. package/dist/pending-532ABZYC.js +8 -0
  112. package/dist/{pidfile-UZRH774M.js → pidfile-3DM4OBKO.js} +4 -2
  113. package/dist/{record-C43U4PKS.js → record-3WP6V2K5.js} +3 -2
  114. package/dist/{runner-env-EN7YE7QX.js → runner-env-FRZFFHDF.js} +5 -6
  115. package/dist/{runner-key-6SLBI7PP.js → runner-key-276SJU5R.js} +40 -38
  116. package/dist/session-sender-GGIY5OAX.js +36 -0
  117. package/dist/{pending-MXLSRYMO.js → shell-function-NRD4KVUK.js} +1 -2
  118. package/dist/spec-cmd-SIZBRN7D.js +115 -0
  119. package/dist/{starter-pack-KF66HGZR.js → starter-pack-6LQVLBIA.js} +7 -5
  120. package/dist/{status-7VNQN5PW.js → status-NAK6DYSF.js} +46 -42
  121. package/dist/{statusline-fast-SVTMBMD7.js → statusline-fast-KN3BX67H.js} +2 -1
  122. package/dist/sync-cmd-G7GF4UTW.js +35 -0
  123. package/dist/{watch-23HSAEI6.js → watch-EVM5GSMP.js} +22 -15
  124. package/dist/{work-claim-cmd-LKL3GHFQ.js → work-claim-cmd-3J3QW56U.js} +26 -29
  125. package/dist/work-cmd-5EPPD33Y.js +24 -0
  126. package/dist/{work-comment-cmd-AWHP56M2.js → work-comment-cmd-2ACOZQAE.js} +16 -15
  127. package/dist/{work-launch-R5HTAP6X.js → work-launch-LEQ2MPM3.js} +3 -1
  128. package/dist/work-logs-cmd-QDD2NMJL.js +60 -0
  129. package/dist/{work-open-pr-cmd-IOM4AVQQ.js → work-open-pr-cmd-XNCEI4ZM.js} +18 -17
  130. package/dist/work-pr-cmd-H4OQR26N.js +25 -0
  131. package/package.json +3 -2
  132. package/skill-pack/maintained/outerlayer-amend/SKILL.md +4 -2
  133. package/skill-pack/maintained/outerlayer-cli/SKILL.md +9 -2
  134. package/skill-pack/maintained/outerlayer-cli/references/find-out-why-a-build-ended.md +76 -0
  135. package/skill-pack/shipped.json +18 -2
  136. package/skill-pack/template/build/SKILL.md +23 -10
  137. package/skill-pack/template/build/references/agent-briefs.md +3 -1
  138. package/skill-pack/template/build/references/criteria-judge.md +27 -0
  139. package/skill-pack/template/build/references/release.md +22 -29
  140. package/skill-pack/template/spec/SKILL.md +35 -10
  141. package/skill-pack/validators/acceptance-criteria.yaml +25 -26
  142. package/dist/agent-setup-T624CWPD.js +0 -27
  143. package/dist/chunk-6Y5RUTHO.js +0 -39
  144. package/dist/chunk-BYT5O5RV.js +0 -61
  145. package/dist/chunk-WTE3MQML.js +0 -133
  146. package/dist/chunk-XCCLFVXM.js +0 -401
  147. package/dist/chunk-YZ5F4PIS.js +0 -797
  148. package/dist/context-adopt-NFHCLVUB.js +0 -108
  149. package/dist/context-materialize-IV2TUUFO.js +0 -22
  150. package/dist/emit-cmd-IJ3GVRFD.js +0 -12
  151. package/dist/guest-init-LJP5GPZF.js +0 -9
  152. package/dist/host-key-YMLXY6QB.js +0 -7
  153. package/dist/init-6XPDRDTC.js +0 -51
  154. package/dist/loop-FK3LPMMZ.js +0 -73
  155. package/dist/machine-SQXEBAM2.js +0 -46
  156. package/dist/paths-OYKMVYJP.js +0 -6
  157. package/dist/session-sender-FO3LCREV.js +0 -29
  158. package/dist/sync-cmd-GVPPFZ3G.js +0 -28
  159. package/dist/work-cmd-Z2WXLZPH.js +0 -23
  160. package/dist/work-pr-cmd-HNEUIEN7.js +0 -24
@@ -1,35 +1,35 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- 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-G5NPRL2K.js';
4
- import { writeJobFile, readJobFile, readJobFileChecked } from './chunk-RMWLBUCJ.js';
5
- import { writePendingUpdate } from './chunk-O765JR4W.js';
6
- import { readHousekeepingRecord, writeHousekeepingRecord } from './chunk-UGP76IZ5.js';
3
+ 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, AttemptLogBook, needsRenew, renewLease, RENEW_INTERVAL_SECONDS, ALREADY_RELEASED } from './chunk-6U3MV7TZ.js';
4
+ import { writePendingUpdate } from './chunk-MTP2QEVO.js';
5
+ import { readHousekeepingRecord, writeHousekeepingRecord } from './chunk-S5PCA3SN.js';
7
6
  import { decideInstalledSwitch } from './chunk-3JVYMD4G.js';
8
7
  import { fetchVersionMeta, npmVersion, npmSupportsProvenance, fetchTarballDigest, fetchProvenance, installVersion, auditSignatures } from './chunk-YETTWTAY.js';
8
+ import { writeJobFile, readJobFile, readJobFileChecked } from './chunk-SADUQSO4.js';
9
9
  import { compareVersions, satisfiesRange } from './chunk-I2UOAV7X.js';
10
- import { RUNNER_PROTOCOL } from './chunk-ADJRGVZC.js';
11
- import { currentSkillCommand, formerSkillProblem, placeholderQueues, placeholderProblem } from './chunk-LWSJQJC6.js';
10
+ import { RUNNER_PROTOCOL } from './chunk-BWSUPRDK.js';
11
+ import { currentSkillCommand, formerSkillProblem, placeholderQueues, placeholderProblem } from './chunk-DADWEUH3.js';
12
12
  import { freeBytes, formatBytes } from './chunk-YYYRBYWG.js';
13
- import { writeMarker, readMarker, currentVersion, removeMarker, entryIn, versionDir, startedThroughCurrent, switchCurrent, cleanVersions, isInLayout, stagingDir } from './chunk-TI7B7UEO.js';
13
+ import { writeMarker, readMarker, currentVersion, removeMarker, entryIn, versionDir, startedThroughCurrent, switchCurrent, cleanVersions, isInLayout, stagingDir } from './chunk-AMFWYESY.js';
14
14
  import { RepoFilter } from './chunk-TBT347UY.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-MAK5LYRF.js';
16
- import { spawnRun } from './chunk-KMDLFI4P.js';
17
- import { checkFit } from './chunk-RLYZLUQ7.js';
18
- import { isSignatureRefusal, WorkCommandError, getJson, postJson } from './chunk-S3NYLI2P.js';
19
- import { isBuiltinContainer, isBuiltinVm, isBuiltinProcess, loadRunnerConfig, checkHooks, builtinKind, DEFAULT_UPDATE_MAX_WAIT_HOURS } from './chunk-22RMZBGW.js';
20
- import { startTimeOf, claimPidFile, readPidFile, isSameProcess, releasePidFile } from './chunk-N5FOE5PS.js';
21
- import { builderName, runnerLabelValue, ensureFailureCount, builderSpec, ensureBuilder, BUILD_LABEL, RUNNER_LABEL } from './chunk-4NPZVMJU.js';
15
+ import { provisionContainer, lifecycleSteps, lifecycleFailureReason, prepareBranch, containerCommandLine, measureDisk, setUpRunnerCgroup, parseCpuList, ensureTunnel, keepGhConfigCurrent, createContainerRuntime } from './chunk-7KSSBQTS.js';
16
+ import { spawnRun } from './chunk-VMJPFQNE.js';
17
+ import { builderName, runnerLabelValue, ensureFailureCount, builderSpec, ensureBuilder, BUILD_LABEL, RUNNER_LABEL } from './chunk-3UZTIRLF.js';
18
+ import { describeCallFailure, retrySend, shortClaim, relativeToRunner, formatDuration, BuildTokens, classifyRefusal, refusalCode, createRunnerLog, formatClock } from './chunk-XSZD4AZ6.js';
19
+ import { checkFit } from './chunk-QEFKA2QD.js';
20
+ import { isSignatureRefusal, WorkCommandError, getJson, postJson } from './chunk-HPJNLETG.js';
21
+ import { isBuiltinContainer, isBuiltinVm, isBuiltinProcess, loadRunnerConfig, checkHooks, builtinKind, DEFAULT_UPDATE_MAX_WAIT_HOURS } from './chunk-P53VEAOF.js';
22
22
  import { exceedsDisk } from './chunk-7RQ73DLO.js';
23
- import { parseClaimedRepositories, repositoriesOf, primaryOf, sharedUserEnvironment, JOB_MOUNT, claudeCredential } from './chunk-4Q7OMKAT.js';
24
- import { parseClaimIdentity } from './chunk-BYT5O5RV.js';
23
+ import { claimPidFile, readPidFile, releasePidFile } from './chunk-ECODQ7II.js';
24
+ import { startTimeOf, isSameProcess } from './chunk-JBJTC3UU.js';
25
25
  import { resolveVersion } from './chunk-RA3O54FC.js';
26
- import { loadHostKey, ensureHostKey, signerFor } from './chunk-V7NIVOFD.js';
27
- import { RUNNER_DIR_MODE, runnerDir, buildDir, attemptStamp, jobDir, jobsDir, pidFilePath, spoolDir, RUNNER_FILE_MODE, rootfsDir } from './chunk-ZM2IMMYN.js';
28
- import { HOOKS_DIR_NAME, writeCommitHooks } from './chunk-XCCLFVXM.js';
26
+ import { loadHostKey, ensureHostKey, signerFor } from './chunk-M2ZWWTWZ.js';
27
+ import { RUNNER_DIR_MODE, runnerDir, buildDir, attemptStamp, jobDir, jobsDir, pidFilePath, spoolDir, RUNNER_FILE_MODE, rootfsDir } from './chunk-N2PXGQRL.js';
28
+ import { parseClaimIdentity, parseClaimedRepositories, repositoriesOf, primaryOf, sharedUserEnvironment, JOB_MOUNT, claudeCredential } from './chunk-BQXFBI7T.js';
29
29
  import { randomBytes } from 'crypto';
30
- import { mkdirSync, existsSync, chmodSync, statSync, readdirSync, readFileSync, rmSync, renameSync, writeFileSync, closeSync, openSync, constants, lstatSync } from 'fs';
30
+ import { mkdirSync, existsSync, chmodSync, statSync, readdirSync, writeFileSync, readFileSync, rmSync, renameSync, closeSync, openSync, constants, lstatSync } from 'fs';
31
31
  import { join, dirname } from 'path';
32
- import { totalmem } from 'os';
32
+ import { totalmem, constants as constants$1 } from 'os';
33
33
 
34
34
  createRequire(import.meta.url);
35
35
  function openKvm() {
@@ -785,6 +785,145 @@ async function removeStaleRootDisks(root, unfinished, options) {
785
785
  }
786
786
  return freed;
787
787
  }
788
+ var HOOKS_DIR_NAME = "git-hooks";
789
+ var CO_AUTHOR_FILE = "co-author";
790
+ var HOOKS = [
791
+ "applypatch-msg",
792
+ "pre-applypatch",
793
+ "post-applypatch",
794
+ "pre-commit",
795
+ "pre-merge-commit",
796
+ "prepare-commit-msg",
797
+ "commit-msg",
798
+ "post-commit",
799
+ "pre-rebase",
800
+ "post-checkout",
801
+ "post-merge",
802
+ "pre-push",
803
+ "pre-receive",
804
+ "update",
805
+ "post-receive",
806
+ "post-update",
807
+ "reference-transaction",
808
+ "pre-auto-gc",
809
+ "post-rewrite",
810
+ "sendemail-validate",
811
+ "post-index-change"
812
+ ];
813
+ var READS_STDIN = /* @__PURE__ */ new Set(["pre-push", "pre-receive", "post-receive", "reference-transaction", "post-rewrite"]);
814
+ var ADD_TRAILER = `
815
+ # Every commit of the build names the requester once: a trailer already there is left alone.
816
+ file=\${1-}
817
+ if [ -n "$file" ] && [ -f "$file" ]; then
818
+ git interpret-trailers --in-place --if-exists addIfDifferent --trailer "Co-authored-by: $(cat "$here/${CO_AUTHOR_FILE}")" "$file" ||
819
+ echo "outerlayer: could not add the co-author line to the commit message" >&2
820
+ fi
821
+ `;
822
+ var HOOK_WRAPPER_MARKER = "# Written by the OuterLayer runner.";
823
+ function script(name) {
824
+ const adds = name === "prepare-commit-msg";
825
+ return `#!/bin/sh
826
+ ${HOOK_WRAPPER_MARKER} Runs the repository's own ${name} hook, then
827
+ # ${adds ? "adds the co-author line to the commit message" : "hands its status on"}.
828
+ here=$(dirname "$0")
829
+
830
+ # The hooks path git would use without this directory: cut the list of configuration
831
+ # entries the runner passes just before its own core.hooksPath entry, then ask git.
832
+ n=\${GIT_CONFIG_COUNT-0}
833
+ case $n in '' | *[!0-9]*) n=0 ;; esac
834
+ cut=$n
835
+ i=$n
836
+ while [ "$i" -gt 0 ]; do
837
+ i=$((i - 1))
838
+ eval "key=\\\${GIT_CONFIG_KEY_$i-}"
839
+ eval "value=\\\${GIT_CONFIG_VALUE_$i-}"
840
+ if [ "$key" = core.hooksPath ] && { [ "$value" = "$here" ] || [ "$value" -ef "$here" ]; }; then
841
+ cut=$i
842
+ break
843
+ fi
844
+ done
845
+ path=$(GIT_CONFIG_COUNT=$cut git config --type=path core.hooksPath 2>/dev/null) || path=
846
+ if [ -z "$path" ]; then
847
+ path=$(git rev-parse --git-common-dir 2>/dev/null)/hooks
848
+ fi
849
+
850
+ hook=$path/${name}
851
+ status=0
852
+ if [ "$path" -ef "$here" ] || [ ! -f "$hook" ] || [ ! -x "$hook" ]; then
853
+ ${READS_STDIN.has(name) ? " cat >/dev/null\n" : ""} :
854
+ else
855
+ ${adds ? ` "$hook" "$@" || status=$?` : ` exec "$hook" "$@"`}
856
+ fi
857
+ ${adds ? `[ "$status" -eq 0 ] || exit "$status"
858
+ ${ADD_TRAILER}` : ""}exit 0
859
+ `;
860
+ }
861
+ function writeCommitHooks(buildDir2, coAuthor) {
862
+ const dir = join(buildDir2, HOOKS_DIR_NAME);
863
+ mkdirSync(dir, { recursive: true });
864
+ chmodSync(dir, 493);
865
+ for (const name of HOOKS) {
866
+ const path = join(dir, name);
867
+ writeFileSync(path, script(name));
868
+ chmodSync(path, 493);
869
+ }
870
+ const data = join(dir, CO_AUTHOR_FILE);
871
+ writeFileSync(data, `${coAuthor.name} <${coAuthor.email}>
872
+ `);
873
+ chmodSync(data, 420);
874
+ return dir;
875
+ }
876
+ function linuxSignalName(number) {
877
+ const names = {
878
+ 1: "SIGHUP",
879
+ 2: "SIGINT",
880
+ 3: "SIGQUIT",
881
+ 4: "SIGILL",
882
+ 5: "SIGTRAP",
883
+ 6: "SIGABRT",
884
+ 7: "SIGBUS",
885
+ 8: "SIGFPE",
886
+ 9: "SIGKILL",
887
+ 10: "SIGUSR1",
888
+ 11: "SIGSEGV",
889
+ 12: "SIGUSR2",
890
+ 13: "SIGPIPE",
891
+ 14: "SIGALRM",
892
+ 15: "SIGTERM",
893
+ 16: "SIGSTKFLT",
894
+ 17: "SIGCHLD",
895
+ 18: "SIGCONT",
896
+ 19: "SIGSTOP",
897
+ 20: "SIGTSTP",
898
+ 21: "SIGTTIN",
899
+ 22: "SIGTTOU",
900
+ 23: "SIGURG",
901
+ 24: "SIGXCPU",
902
+ 25: "SIGXFSZ",
903
+ 26: "SIGVTALRM",
904
+ 27: "SIGPROF",
905
+ 28: "SIGWINCH",
906
+ 29: "SIGIO",
907
+ 30: "SIGPWR",
908
+ 31: "SIGSYS"
909
+ };
910
+ return names[number];
911
+ }
912
+ function hostSignalName(number) {
913
+ return Object.entries(constants$1.signals).find(([, value]) => value === number)?.[0];
914
+ }
915
+ function notEndedByRunnerReason(exit, isolated) {
916
+ if (exit.signal !== null) {
917
+ return `the command was killed by ${exit.signal} on the host; the runner did not end it`;
918
+ }
919
+ const number = exit.code - 128;
920
+ const name = isolated ? linuxSignalName(number) : hostSignalName(number);
921
+ if (name === void 0) return void 0;
922
+ return `the command exited ${exit.code}, the status of a process killed by ${name}; the runner did not end it`;
923
+ }
924
+ function jobNotEndedByRunnerReason(exit, job) {
925
+ return notEndedByRunnerReason(exit, job.container !== void 0 || job.microvm !== void 0);
926
+ }
788
927
 
789
928
  // src/runner/loop.ts
790
929
  var QUEUE_ORDER = ["amend", "implement"];
@@ -794,7 +933,12 @@ var TRACKER_REPOSITORY_HOSTS = {
794
933
  var HOUSEKEEPING_INTERVAL_MS = 36e5;
795
934
  function logOf(state) {
796
935
  state.deps.log ??= createRunnerLog(state.deps.now ?? (() => /* @__PURE__ */ new Date()));
797
- return state.deps.log;
936
+ state.attemptLog ??= attemptLogsOf(state).wrap(state.deps.log);
937
+ return state.attemptLog;
938
+ }
939
+ function attemptLogsOf(state) {
940
+ state.attemptLogs ??= new AttemptLogBook(state.deps.now);
941
+ return state.attemptLogs;
798
942
  }
799
943
  function nowOf(state) {
800
944
  return (state.deps.now ?? (() => /* @__PURE__ */ new Date()))();
@@ -810,6 +954,7 @@ function finishDepsOf(state) {
810
954
  now: state.deps.now,
811
955
  sleep: state.deps.sleep,
812
956
  log: logOf(state),
957
+ attemptLogs: attemptLogsOf(state),
813
958
  cliVersion: state.deps.cliVersion,
814
959
  // Any job that has a container needs the runtime to stop and remove it, including one a config change left behind.
815
960
  container: runtimeOf(state)
@@ -839,8 +984,11 @@ function reportRepeating(state, key, message, level = "error") {
839
984
  }
840
985
  }
841
986
  function deriveRepo(item) {
842
- const host = item.tracker === void 0 ? void 0 : TRACKER_REPOSITORY_HOSTS[item.tracker];
843
- if (host === void 0) return void 0;
987
+ if (item.tracker === void 0) return void 0;
988
+ const host = TRACKER_REPOSITORY_HOSTS[item.tracker];
989
+ if (host === void 0) {
990
+ return item.specRepository ? `${TRACKER_REPOSITORY_HOSTS.github}/${item.specRepository}` : void 0;
991
+ }
844
992
  const hash = item.trackerKey.lastIndexOf("#");
845
993
  const repoPart = hash === -1 ? item.trackerKey : item.trackerKey.slice(0, hash);
846
994
  return repoPart === "" ? void 0 : `${host}/${repoPart}`;
@@ -1315,7 +1463,7 @@ var CLAIM_REFUSAL_CODES = new Set(
1315
1463
  "pull_request_from_fork pull_request_on_default_branch pull_request_ambiguous pull_request_repository_not_connected branch_claimed_elsewhere".split(" ")
1316
1464
  );
1317
1465
  async function tryClaimAndStart(state, item, queue) {
1318
- const { postJson: postJson2 } = await import('./work-cmd-Z2WXLZPH.js');
1466
+ const { postJson: postJson2 } = await import('./work-cmd-5EPPD33Y.js');
1319
1467
  const log = logOf(state);
1320
1468
  const hostKey = await loadHostKey(state.config.configPath);
1321
1469
  const claim = await retrySend(
@@ -1474,9 +1622,10 @@ async function startJob(state, item, queue, claimId, itemKey, branch, identity,
1474
1622
  ending: false
1475
1623
  };
1476
1624
  state.jobs.set(dirPath, active);
1477
- log.line(
1478
- `claimed ${queue} #${item.number} ${item.trackerKey} (claim ${shortClaim(claimId)}) \u2192 ${relativeToRunner(runnerRoot, dirPath)}`
1479
- );
1625
+ attemptLogsOf(state).open(item.number, dirPath);
1626
+ const claimLine = `claimed ${queue} #${item.number} ${item.trackerKey} (claim ${shortClaim(claimId)}) \u2192 ${relativeToRunner(runnerRoot, dirPath)}`;
1627
+ log.line(claimLine);
1628
+ attemptLogsOf(state).note(item.number, claimLine);
1480
1629
  const hookLimits = () => hookLimitsFor(state.config, startedAt.getTime(), state.deps.now);
1481
1630
  const tag = `#${item.number}`;
1482
1631
  const containerMode = isBuiltinContainer(state.config.hooks.provision);
@@ -1610,6 +1759,7 @@ async function startJob(state, item, queue, claimId, itemKey, branch, identity,
1610
1759
  config: state.config,
1611
1760
  runtime: runtimeOf(state),
1612
1761
  item,
1762
+ repository: primary?.repository,
1613
1763
  itemKey,
1614
1764
  jobDir: dirPath,
1615
1765
  cliVersion,
@@ -1635,10 +1785,10 @@ async function startJob(state, item, queue, claimId, itemKey, branch, identity,
1635
1785
  installCommitHooks(active.job, log, tag);
1636
1786
  } else {
1637
1787
  const runtime = runtimeOf(state);
1638
- const build = await startHostBuild(state, active, item.specRepository ?? void 0);
1788
+ const build = await startHostBuild(state, active, primary?.repository);
1639
1789
  const provisionEnv = provisionEnvironment(jobEnv(state.config, item.number, itemKey, dirPath, process.env, branch, identity?.author), {
1640
1790
  buildDir: build.state.buildDir,
1641
- repository: item.specRepository,
1791
+ repository: primary?.repository ?? null,
1642
1792
  recipeCommit: build.recipeCommit,
1643
1793
  limits: {
1644
1794
  memory: state.config.build?.memory ?? "8g",
@@ -1836,11 +1986,13 @@ async function startJob(state, item, queue, claimId, itemKey, branch, identity,
1836
1986
  const took = formatDuration(nowOf(state).getTime() - commandStartedMs);
1837
1987
  if (signal !== null) {
1838
1988
  log.error(`${tag} command killed by ${signal} (${took})`);
1989
+ active.job.commandEndReason = jobNotEndedByRunnerReason({ code: null, signal }, active.job);
1839
1990
  void endJob(state, active, "failed");
1840
1991
  return;
1841
1992
  }
1842
1993
  log.line(`${tag} command exited ${code ?? 0} (${took})`);
1843
1994
  if (code !== null) active.job.exitCode = code;
1995
+ active.job.commandEndReason = jobNotEndedByRunnerReason({ code, signal }, active.job);
1844
1996
  void endJob(state, active, code === 0 ? "ok" : "failed");
1845
1997
  });
1846
1998
  }
@@ -1978,7 +2130,7 @@ async function renewLeaseIfDue(state, active, nowMs) {
1978
2130
  }
1979
2131
  async function watchTick(state, active, nowMs, logMtimeMs) {
1980
2132
  if (active.ending) {
1981
- if (active.job.stage === "checks") await renewLeaseIfDue(state, active, nowMs);
2133
+ if (active.job.stage === "checks" || active.job.stage === "judge") await renewLeaseIfDue(state, active, nowMs);
1982
2134
  return;
1983
2135
  }
1984
2136
  const log = logOf(state);
@@ -2074,7 +2226,7 @@ async function start(configPath, deps = { fetchImpl: fetch }) {
2074
2226
  const outcome = await onStartUnderMarker({
2075
2227
  configPath,
2076
2228
  own: ownVersionOf(deps),
2077
- check: update.check ? () => update.check(configPath) : async () => (await import('./check-5XE7XMC4.js')).runRunnerCheck(configPath, { fetchImpl: deps.fetchImpl }),
2229
+ check: update.check ? () => update.check(configPath) : async () => (await import('./check-UWQAL2MN.js')).runRunnerCheck(configPath, { fetchImpl: deps.fetchImpl }),
2078
2230
  now: () => (deps.now ?? (() => /* @__PURE__ */ new Date()))().getTime(),
2079
2231
  log
2080
2232
  });
@@ -2112,9 +2264,11 @@ async function start(configPath, deps = { fetchImpl: fetch }) {
2112
2264
  return [];
2113
2265
  });
2114
2266
  for (const buildId of runningMicroVms) log.line(`stopped microVM build ${buildId}, left running by an earlier runner`);
2267
+ const attemptLogs = attemptLogsOf(state);
2115
2268
  for (const { dirPath, job } of listAdoptableJobs(jobsDir(configPath))) {
2116
2269
  const adopted = { job, dirPath, lastRenewAtMs: nowMs(), cmd: null, cpuSample: null, ending: false };
2117
2270
  state.jobs.set(dirPath, adopted);
2271
+ attemptLogs.open(job.item, dirPath);
2118
2272
  if (job.container !== void 0) {
2119
2273
  const cores = job.container.cpuset === void 0 ? void 0 : parseCpuList(job.container.cpuset);
2120
2274
  if (cores !== void 0) runtimeOf(state).cpus.hold(job.container.buildId, cores);
@@ -2126,18 +2280,20 @@ async function start(configPath, deps = { fetchImpl: fetch }) {
2126
2280
  keepGhConfigCurrent(
2127
2281
  tokens,
2128
2282
  job.container.buildDir,
2129
- (err) => log.error(`#${job.item} the read token could not be written for gh: ${describeCallFailure(err)}`)
2283
+ (err) => logOf(state).error(`#${job.item} the read token could not be written for gh: ${describeCallFailure(err)}`)
2130
2284
  );
2131
2285
  } catch (err) {
2132
- log.error(`#${job.item} could not give the adopted build a read token: ${describeCallFailure(err)}`);
2286
+ logOf(state).error(`#${job.item} could not give the adopted build a read token: ${describeCallFailure(err)}`);
2133
2287
  }
2134
2288
  }
2135
2289
  if (job.build !== void 0 && !runtimeOf(state).tunnels.has(job.build.buildId)) {
2136
2290
  await startHostServices({ runtime: runtimeOf(state), config, build: job.build, jobDir: dirPath, itemKey: job.itemKey, process: job.build.workDir !== void 0 }).catch((err) => {
2137
- log.error(`the tunnel of #${job.item} could not start again: ${describeCallFailure(err)}`);
2291
+ logOf(state).error(`the tunnel of #${job.item} could not start again: ${describeCallFailure(err)}`);
2138
2292
  });
2139
2293
  }
2140
- log.line(`adopted job ${job.queue} #${job.item} (claim ${shortClaim(job.claimId)}) \xB7 pid ${job.pid} still running`);
2294
+ const adoptedLine = `adopted job ${job.queue} #${job.item} (claim ${shortClaim(job.claimId)}) \xB7 pid ${job.pid} still running`;
2295
+ log.line(adoptedLine);
2296
+ attemptLogs.note(job.item, adoptedLine);
2141
2297
  }
2142
2298
  for (const { job, released } of await retryFailedReleases(jobsDir(configPath), config, {
2143
2299
  fetchImpl: deps.fetchImpl,
@@ -2177,7 +2333,7 @@ async function start(configPath, deps = { fetchImpl: fetch }) {
2177
2333
  } catch {
2178
2334
  }
2179
2335
  void watchTick(state, active, now, mtime).catch((err) => {
2180
- log.error(`#${active.job.item} health check failed: ${describeCallFailure(err)}`);
2336
+ logOf(state).error(`#${active.job.item} health check failed: ${describeCallFailure(err)}`);
2181
2337
  });
2182
2338
  }
2183
2339
  }, deps.watchIntervalMs ?? 3e4);
@@ -2224,6 +2380,9 @@ async function start(configPath, deps = { fetchImpl: fetch }) {
2224
2380
  let passes = 0;
2225
2381
  while (state.jobs.size > 0 && !exited) {
2226
2382
  onWaiting?.([...state.jobs.keys()]);
2383
+ for (const active of state.jobs.values()) {
2384
+ attemptLogs.noteChanged(active.job.item, "drain", `stopping: draining, waiting on #${active.job.item} (${active.job.stage ?? "starting"})`);
2385
+ }
2227
2386
  if (passes % DRAIN_LOG_EVERY_PASSES === 0) {
2228
2387
  log.line(
2229
2388
  `stopping: draining, waiting on ${[...state.jobs.values()].map((a) => describeWaiting(a, nowMs())).join(", ")}`