@outerlayer/cli 0.26.3 → 0.27.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 (129) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +12 -9
  3. package/dist/{agent-setup-PZYQWN4H.js → agent-setup-UW36TAQM.js} +13 -13
  4. package/dist/{bridge-5KZ36YDG.js → bridge-B5VJVECY.js} +2 -2
  5. package/dist/build-TNM7HYCA.js +12 -0
  6. package/dist/build-info.json +1 -1
  7. package/dist/{builder-WEGLC2F2.js → builder-LDJGS2JC.js} +6 -6
  8. package/dist/{check-WJJ325EQ.js → check-JVBAWIN6.js} +44 -43
  9. package/dist/{chunk-7LVF4E5V.js → chunk-24ID7EQ2.js} +7 -4
  10. package/dist/{chunk-HXFRJKMU.js → chunk-2F762IXY.js} +2 -2
  11. package/dist/{chunk-2K3TCQHW.js → chunk-2I3LIRZP.js} +26 -8
  12. package/dist/{chunk-UKCNOAO6.js → chunk-55GNQPO6.js} +17 -6
  13. package/dist/{chunk-XSPA5ODY.js → chunk-6BLXUD56.js} +4 -3
  14. package/dist/{chunk-MWPBF2XG.js → chunk-6KKM7VGZ.js} +32 -4
  15. package/dist/{chunk-VPEGE3QZ.js → chunk-6TRNCUM4.js} +1 -1
  16. package/dist/{chunk-MLD2NA7N.js → chunk-7AQ5AM7U.js} +12 -5
  17. package/dist/{chunk-HBISTTG3.js → chunk-7OUOLGUV.js} +20 -5
  18. package/dist/{chunk-6FAP657M.js → chunk-ABXQBEYK.js} +1 -1
  19. package/dist/{chunk-TSW4DGV2.js → chunk-B6K7R5UY.js} +2 -2
  20. package/dist/chunk-BM7EC3OZ.js +181 -0
  21. package/dist/{chunk-W3NVHOCS.js → chunk-BPKO76QR.js} +4 -4
  22. package/dist/{chunk-QRZLUUNN.js → chunk-BWH36FOC.js} +8 -3
  23. package/dist/{chunk-PYSKSROG.js → chunk-D7ECMB7B.js} +4 -4
  24. package/dist/{chunk-FO7F6QSV.js → chunk-DJHNEGNM.js} +27 -3
  25. package/dist/{chunk-TPAF24PK.js → chunk-E5IJ5533.js} +2 -2
  26. package/dist/{chunk-JWRX5ZTT.js → chunk-EPPIISRD.js} +2 -2
  27. package/dist/{chunk-6M4LNO22.js → chunk-FP23SVDD.js} +6 -6
  28. package/dist/{chunk-GOSFARMS.js → chunk-G2JWZDFA.js} +9 -2
  29. package/dist/{chunk-XFGL53GU.js → chunk-G3EZA6MK.js} +56 -8
  30. package/dist/{chunk-5PMQDQFV.js → chunk-GFUE5TKO.js} +3 -3
  31. package/dist/{chunk-XLC7KEUV.js → chunk-GLUKDQS4.js} +1 -1
  32. package/dist/{chunk-ZLEXMZFW.js → chunk-JH2GQU5T.js} +5 -5
  33. package/dist/{chunk-YVZJ6GKF.js → chunk-KT4CN6OU.js} +1 -1
  34. package/dist/{chunk-JKNYTNYD.js → chunk-LOKSLO25.js} +1 -1
  35. package/dist/{chunk-665QWBNW.js → chunk-M3MHHIUW.js} +1 -1
  36. package/dist/{chunk-4IFKLYMM.js → chunk-MATUHHN4.js} +1 -1
  37. package/dist/{chunk-MQ743JX3.js → chunk-MHX7YX7Y.js} +1 -1
  38. package/dist/{chunk-TEVO3RUV.js → chunk-N4D5TMVU.js} +4 -4
  39. package/dist/{chunk-EORWWFPA.js → chunk-O2IJTY7L.js} +2 -2
  40. package/dist/{chunk-EABW6AJQ.js → chunk-PJDQPF5N.js} +18 -5
  41. package/dist/{chunk-KDDFI5MR.js → chunk-QHH4OSD4.js} +1 -1
  42. package/dist/{chunk-W7LGHNXT.js → chunk-QIVOTQOQ.js} +5 -5
  43. package/dist/{chunk-JF572PM5.js → chunk-QKIQ2R7F.js} +3 -3
  44. package/dist/{chunk-L4CW6LZQ.js → chunk-RHAGBUL5.js} +5 -2
  45. package/dist/{chunk-TKL74NLB.js → chunk-RHGF73IU.js} +1 -1
  46. package/dist/{chunk-SKZG7SAN.js → chunk-RK7FWC6B.js} +206 -42
  47. package/dist/{chunk-6MZSX4M7.js → chunk-STSLH5EJ.js} +3 -1
  48. package/dist/{chunk-K7FCZCLQ.js → chunk-TXHJ7BGR.js} +13 -13
  49. package/dist/{chunk-364XDGOK.js → chunk-UQYBCJ2L.js} +3 -3
  50. package/dist/{chunk-2AKDF6C2.js → chunk-VS27BP3E.js} +5 -5
  51. package/dist/{chunk-J7BXZLSO.js → chunk-WSYXLLA5.js} +29 -8
  52. package/dist/{chunk-WX2WEERU.js → chunk-WUL2OP5A.js} +3 -3
  53. package/dist/{chunk-ZPXI7LMG.js → chunk-WVDP6HVZ.js} +6 -6
  54. package/dist/{chunk-MXTN35XN.js → chunk-XBPUTQ7E.js} +1 -1
  55. package/dist/{chunk-UNF7MWEL.js → chunk-XS3FDWSZ.js} +1 -1
  56. package/dist/{chunk-VJBFQP3H.js → chunk-XZ6Q6ZNR.js} +9 -5
  57. package/dist/{chunk-F6DIHHBS.js → chunk-Y4OKEFAX.js} +1 -1
  58. package/dist/{chunk-XDHYZWEK.js → chunk-Y7ZCHBYB.js} +2 -2
  59. package/dist/chunk-YB3CSYXX.js +95 -0
  60. package/dist/{chunk-VHVFU6QU.js → chunk-YF56R4DV.js} +86 -31
  61. package/dist/chunk-YJLHUKYS.js +38 -0
  62. package/dist/{chunk-XF77SNB4.js → chunk-ZXRWMOJ3.js} +287 -51
  63. package/dist/{claude-launcher-O2U6P6ZD.js → claude-launcher-TKX4WCUN.js} +8 -4
  64. package/dist/{cli-2UUJM3AE.js → cli-XVXQDKZT.js} +141 -135
  65. package/dist/{command-GQBHC53U.js → command-B2T7VR77.js} +33 -32
  66. package/dist/{config-JJ3EO7SB.js → config-TWS5VZEN.js} +3 -3
  67. package/dist/{connect-cmd-2JHSLBXK.js → connect-cmd-HGS7YPA2.js} +10 -10
  68. package/dist/{container-start-AUJHF2BC.js → container-start-JE7HTKZG.js} +32 -31
  69. package/dist/{control-plane-launch-654RV5PO.js → control-plane-launch-DBQA3KLJ.js} +9 -9
  70. package/dist/{docker-NYAIIX2F.js → docker-MJEEHUUA.js} +6 -6
  71. package/dist/{doctor-NV2PUERZ.js → doctor-6ZIF2BRZ.js} +184 -37
  72. package/dist/{emit-artifact-cmd-XXTCHP6V.js → emit-artifact-cmd-ALDK55Y2.js} +14 -14
  73. package/dist/{emit-cmd-WQH2NK7H.js → emit-cmd-VAQHRWJR.js} +4 -4
  74. package/dist/{emit-criteria-cmd-VMZIRJCQ.js → emit-criteria-cmd-Q7SM6VP2.js} +11 -11
  75. package/dist/{emit-finding-cmd-KMJNYQI7.js → emit-finding-cmd-2NBAPDSV.js} +11 -11
  76. package/dist/{emit-result-cmd-HRTXGZLK.js → emit-result-cmd-KUSL56RI.js} +14 -14
  77. package/dist/{emit-step-cmd-AUHA3EXY.js → emit-step-cmd-KD4AKEAT.js} +12 -12
  78. package/dist/{exec-client-J6L5FDRR.js → exec-client-6WVS7DRZ.js} +3 -3
  79. package/dist/{governing-source-PTJ6EAA3.js → governing-source-VVUA5TKB.js} +16 -16
  80. package/dist/{guest-init-CXIHA5VI.js → guest-init-H5K2RW3P.js} +4 -4
  81. package/dist/{hook-fast-SDFXJEAW.js → hook-fast-3SUJM765.js} +1 -1
  82. package/dist/{host-key-5TKBNUZ4.js → host-key-XNKZCWTS.js} +3 -3
  83. package/dist/{image-tag-5SJ6ZKT7.js → image-tag-R34J4O3F.js} +3 -3
  84. package/dist/index.js +4 -4
  85. package/dist/init-ETKGFCXR.js +55 -0
  86. package/dist/{init-UZWRJMPZ.js → init-Q2RPUUVP.js} +33 -32
  87. package/dist/{init-cmd-SQKWPACS.js → init-cmd-M6MQRGOU.js} +19 -18
  88. package/dist/{init-update-FJDKY4SJ.js → init-update-N4HTZGVS.js} +59 -30
  89. package/dist/{inspect-6UYAAXH7.js → inspect-IPFA7AAT.js} +1 -1
  90. package/dist/{install-QSTTBUHX.js → install-6OIY3KHZ.js} +6 -5
  91. package/dist/{install-cmd-3DXJJUAA.js → install-cmd-JMT67P35.js} +5 -5
  92. package/dist/{layout-UOJQGEPW.js → layout-XNFDTOET.js} +2 -2
  93. package/dist/{login-browser-4OMZFP3U.js → login-browser-EWXSGHM7.js} +3 -3
  94. package/dist/{logout-cmd-5V5MMBSY.js → logout-cmd-5WE2N5B5.js} +2 -2
  95. package/dist/{logs-VN2HKDSH.js → logs-XHAS6LMZ.js} +2 -2
  96. package/dist/loop-2Y4CUFNP.js +79 -0
  97. package/dist/machine-Z2S47JW7.js +50 -0
  98. package/dist/machine-skills-RRF4HLAD.js +11 -0
  99. package/dist/{mcp-install-cmd-GGWB3JJ2.js → mcp-install-cmd-LD7KYAOP.js} +2 -2
  100. package/dist/{mcp-serve-cmd-U5N5DK3H.js → mcp-serve-cmd-LY5A3CE7.js} +5 -5
  101. package/dist/{paths-ZC6BMWMT.js → paths-LHSPNORF.js} +2 -2
  102. package/dist/{pending-54HC7MM3.js → pending-3YZCSKON.js} +3 -3
  103. package/dist/{pidfile-BY5Z6YH7.js → pidfile-DKMYYXLH.js} +3 -3
  104. package/dist/{record-K23IN6QN.js → record-3LPTY3G5.js} +3 -3
  105. package/dist/{runner-env-2D7MPOIJ.js → runner-env-YRRNRKF4.js} +8 -7
  106. package/dist/{runner-identity-YYENYKDH.js → runner-identity-EX7HXPUE.js} +6 -6
  107. package/dist/{runner-key-AZVXBQIB.js → runner-key-GO277GW2.js} +32 -31
  108. package/dist/{session-sender-VH2EKAT5.js → session-sender-SC5PSU2G.js} +15 -15
  109. package/dist/{spec-cmd-BOUPLX7X.js → spec-cmd-JGYHHJ4P.js} +12 -12
  110. package/dist/{starter-pack-55EFILC5.js → starter-pack-GPU4X6B7.js} +2 -2
  111. package/dist/{status-3WC2IGVI.js → status-CJCE2FHD.js} +34 -33
  112. package/dist/{sync-cmd-GT2WTQRA.js → sync-cmd-ATXJVS7S.js} +14 -14
  113. package/dist/{watch-JED7SYAA.js → watch-M7NR3DOW.js} +14 -14
  114. package/dist/{work-claim-cmd-MY4N74HA.js → work-claim-cmd-DNUDZKJA.js} +16 -16
  115. package/dist/{work-cmd-UQ45HDM4.js → work-cmd-VECTYST6.js} +12 -12
  116. package/dist/{work-comment-cmd-I7NNSNDP.js → work-comment-cmd-F3NRWKPZ.js} +12 -12
  117. package/dist/{work-logs-cmd-YIQJVENH.js → work-logs-cmd-QF6P32FE.js} +12 -12
  118. package/dist/{work-open-pr-cmd-VP5NNTCW.js → work-open-pr-cmd-XE23JA3R.js} +13 -13
  119. package/dist/{work-pr-cmd-DKTBEFHO.js → work-pr-cmd-BH56GUKN.js} +12 -12
  120. package/dist/{work-stop-cmd-GN2WX73C.js → work-stop-cmd-C3F5HNUO.js} +12 -12
  121. package/package.json +1 -1
  122. package/skill-pack/maintained/outerlayer-cli/SKILL.md +6 -5
  123. package/skill-pack/shipped.json +1 -0
  124. package/skill-pack/template/build/SKILL.md +1 -1
  125. package/dist/build-EBQYXL7Y.js +0 -12
  126. package/dist/chunk-7RQ73DLO.js +0 -23
  127. package/dist/init-KIGYMLDM.js +0 -54
  128. package/dist/loop-OE32U2IZ.js +0 -78
  129. package/dist/machine-L7INJ4JN.js +0 -49
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { WorkCommandError, postJson } from './chunk-UKCNOAO6.js';
4
- import { defaultGitRunner, materializeContext, isStagingWriteFault, lookupGoverningSource } from './chunk-W3NVHOCS.js';
5
- import { signingFetchFor } from './chunk-QRZLUUNN.js';
6
- import { unsupportedLayout, layoutRefusalReason, composeDelivery } from './chunk-VPEGE3QZ.js';
3
+ import { WorkCommandError, postJson } from './chunk-55GNQPO6.js';
4
+ import { defaultGitRunner, materializeContext, isStagingWriteFault, lookupGoverningSource } from './chunk-BPKO76QR.js';
5
+ import { signingFetchFor } from './chunk-BWH36FOC.js';
6
+ import { unsupportedLayout, layoutRefusalReason, composeDelivery } from './chunk-6TRNCUM4.js';
7
7
  import { SHIM_SCRIPT, GOVERNANCE_VARIABLE } from './chunk-HCVLP7XA.js';
8
8
  import { readDegraded, readContextManifest, readSourceCache } from './chunk-YQR6E6OV.js';
9
- import { signerFor } from './chunk-F6DIHHBS.js';
10
- import { SHIM_DIR, stagedContextDir, contextHomeDir, deliveryDir } from './chunk-L4CW6LZQ.js';
11
- import { fstatSync, mkdirSync, writeFileSync, chmodSync, rmSync, lstatSync } from 'fs';
9
+ import { signerFor } from './chunk-Y4OKEFAX.js';
10
+ import { SHIM_DIR, stagedContextDir, contextHomeDir, deliveryDir, keptContextDir } from './chunk-RHAGBUL5.js';
11
+ import { fstatSync, mkdirSync, writeFileSync, chmodSync, rmSync, cpSync, readFileSync, existsSync, lstatSync } from 'fs';
12
12
  import { relative, join, dirname } from 'path';
13
13
 
14
14
  createRequire(import.meta.url);
@@ -464,6 +464,27 @@ async function controlPlaneAccess(ask, candidates, repository, log, tag) {
464
464
  function removeStagedContext(buildDir) {
465
465
  rmSync(stagedContextDir(buildDir), { recursive: true, force: true });
466
466
  }
467
+ function keepStagedContext(staged, jobDir) {
468
+ const kept = keptContextDir(jobDir);
469
+ rmSync(kept, { recursive: true, force: true });
470
+ const tree = join(staged.dir, "tree");
471
+ cpSync(tree, join(kept, "tree"), { recursive: true, verbatimSymlinks: true, filter: (source) => source !== join(tree, ".git") });
472
+ writeFileSync(join(kept, "kept.json"), JSON.stringify({ schemaVersion: 1, repository: staged.repository, sha: staged.sha }) + "\n");
473
+ }
474
+ function keptContextTree(jobDir, governing) {
475
+ const kept = keptContextDir(jobDir);
476
+ let record;
477
+ try {
478
+ record = JSON.parse(readFileSync(join(kept, "kept.json"), "utf8"));
479
+ } catch {
480
+ return void 0;
481
+ }
482
+ if (governing === void 0 || record.sha !== governing.commit || String(record.repository).toLowerCase() !== governing.repository.toLowerCase()) return void 0;
483
+ return existsSync(join(kept, "tree")) ? join(kept, "tree") : void 0;
484
+ }
485
+ function removeKeptContext(jobDir) {
486
+ rmSync(keptContextDir(jobDir), { recursive: true, force: true });
487
+ }
467
488
 
468
489
  // src/runner/governing-source.ts
469
490
  var unavailable2 = (why) => ({ ok: false, reason: `context_unavailable: ${why}` });
@@ -494,4 +515,4 @@ async function imageTargetFor(input) {
494
515
  return { ok: true, repository: resolved.source.repository, pinned: { commit: resolved.source.sha, ref: resolved.source.ref } };
495
516
  }
496
517
 
497
- export { BuildTokens, classifyRefusal, commandWithShim, controlPlaneTokenFailure, createRunnerLog, describeCallFailure, formatClock, formatDuration, imageTargetFor, logStamp, pinnedSourceOf, refusalCode, relativeToRunner, removeStagedContext, resolveGoverningSource, retrySend, shimScript, shortClaim, stageGovernedContext };
518
+ export { BuildTokens, classifyRefusal, commandWithShim, controlPlaneTokenFailure, createRunnerLog, describeCallFailure, formatClock, formatDuration, imageTargetFor, keepStagedContext, keptContextTree, logStamp, pinnedSourceOf, refusalCode, relativeToRunner, removeKeptContext, removeStagedContext, resolveGoverningSource, retrySend, shimScript, shortClaim, stageGovernedContext };
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { retiredSkillPaths, removeRetiredSkills } from './chunk-MQ743JX3.js';
3
+ import { isAgentsMdLayout, discoverOuterlayerPaths, isForeignTree, toRepoRelative } from './chunk-LOKSLO25.js';
4
+ import { retiredSkillPaths, removeRetiredSkills } from './chunk-MHX7YX7Y.js';
5
+ import { maintainedFilesForExistingSkills, loadMaintainedFiles, writeMaintainedFiles } from './chunk-7OUOLGUV.js';
4
6
  import { C } from './chunk-ANPNT6PM.js';
5
- import { isAgentsMdLayout, discoverOuterlayerPaths, isForeignTree, toRepoRelative } from './chunk-JKNYTNYD.js';
6
- import { maintainedFilesForExistingSkills, loadMaintainedFiles, writeMaintainedFiles } from './chunk-HBISTTG3.js';
7
7
  import { cliInvocation } from './chunk-CRB3POP4.js';
8
8
  import { emitTree, generatedHeaderSource, parseOuterlayerConfig, classifyTree } from './chunk-RKOTJQVG.js';
9
9
  import { existsSync, readFileSync, mkdirSync, writeFileSync, copyFileSync, unlinkSync, rmdirSync, readdirSync } from 'fs';
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { isPlaceholderCommand } from './chunk-W7LGHNXT.js';
4
- import { describeCallFailure } from './chunk-J7BXZLSO.js';
5
- import { WorkCommandError, getJson } from './chunk-UKCNOAO6.js';
3
+ import { isPlaceholderCommand } from './chunk-QIVOTQOQ.js';
4
+ import { describeCallFailure } from './chunk-WSYXLLA5.js';
5
+ import { WorkCommandError, getJson } from './chunk-55GNQPO6.js';
6
6
  import { sanitizeTerminal } from './chunk-BUP5N3X6.js';
7
- import { builtinKind } from './chunk-JWRX5ZTT.js';
8
- import { signerFor } from './chunk-F6DIHHBS.js';
9
- import { CLAUDE_CREDENTIAL_VARIABLES, claudeCredential } from './chunk-2K3TCQHW.js';
7
+ import { builtinKind } from './chunk-EPPIISRD.js';
8
+ import { signerFor } from './chunk-Y4OKEFAX.js';
9
+ import { CLAUDE_CREDENTIAL_VARIABLES, claudeCredential } from './chunk-2I3LIRZP.js';
10
10
 
11
11
  createRequire(import.meta.url);
12
12
 
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { EXEC_PORT } from './chunk-XLC7KEUV.js';
3
+ import { EXEC_PORT } from './chunk-GLUKDQS4.js';
4
4
  import { createConnection } from 'net';
5
5
 
6
6
  createRequire(import.meta.url);
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { RELAY_PORT, BUILD_HOME } from './chunk-2K3TCQHW.js';
3
+ import { RELAY_PORT, BUILD_HOME } from './chunk-2I3LIRZP.js';
4
4
  import { createServer, connect } from 'net';
5
5
 
6
6
  createRequire(import.meta.url);
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
+ import { resolvePackRoot, OUTERLAYER_SKILLS_BASE, loadTemplateFiles, AGENTS_SKILLS_BASE, loadMaintainedFiles, rewriteSkillPaths, TEMPLATE_SKILLS, skillDir, writeMaintainedFiles, MAINTAINED_SKILLS, MACHINE_SKILL_PATH } from './chunk-7OUOLGUV.js';
3
4
  import { C } from './chunk-ANPNT6PM.js';
4
- import { resolvePackRoot, OUTERLAYER_SKILLS_BASE, loadTemplateFiles, loadMaintainedFiles, rewriteSkillPaths, TEMPLATE_SKILLS, skillDir, writeMaintainedFiles, MAINTAINED_SKILLS } from './chunk-HBISTTG3.js';
5
5
  import { cliInvocation } from './chunk-CRB3POP4.js';
6
6
  import { linkedAgentsPath } from './chunk-VWFOKRYS.js';
7
7
  import { resolvePackageVersion } from './chunk-RA3O54FC.js';
@@ -31,7 +31,7 @@ function installStarterPack(opts) {
31
31
  const linked = base.startsWith(".agents/") ? linkedAgentsPath(opts.repoRoot) : void 0;
32
32
  if (linked !== void 0) throw new StarterPackError(`${linked} is a link, and a write there would land outside the repository; replace it with a folder and run this again`);
33
33
  const templateFiles = loadTemplateFiles(packRoot, version, base);
34
- const maintainedFiles = loadMaintainedFiles(packRoot, version, base);
34
+ const maintainedFiles = base === AGENTS_SKILLS_BASE ? [] : loadMaintainedFiles(packRoot, version, base);
35
35
  const validatorFiles = VALIDATOR_FILES.map(({ name }) => ({
36
36
  path: `${VALIDATORS_DIR}/${name}`,
37
37
  content: rewriteSkillPaths(readFileSync(join(packRoot, "validators", name), "utf8"), base)
@@ -94,9 +94,13 @@ function formatStarterPackOutput(result) {
94
94
  result.kept.includes(skill) ? ` ${C.dim}kept${C.reset} ${skillDir(skill, base)}/ ${C.dim}(already exists, left exactly as it is)${C.reset}` : ` ${skillFile(skill, base)}`
95
95
  );
96
96
  }
97
- const rewriter = base === OUTERLAYER_SKILLS_BASE ? "emit" : "`init --update`";
98
- lines.push("", `Rewritten on every ${rewriter} \u2014 edits are overwritten by the installed CLI:`);
99
- for (const skill of MAINTAINED_SKILLS) lines.push(` ${skillFile(skill, base)}`);
97
+ if (base === OUTERLAYER_SKILLS_BASE) {
98
+ lines.push("", "Rewritten on every emit \u2014 edits are overwritten by the installed CLI:");
99
+ for (const skill of MAINTAINED_SKILLS) lines.push(` ${skillFile(skill, base)}`);
100
+ } else {
101
+ lines.push("", `Kept once per machine, not in this repository. \`${cliInvocation()} init\` installs them, and every later command keeps them at its own version:`);
102
+ for (const skill of MAINTAINED_SKILLS) lines.push(` ${skillFile(skill, MACHINE_SKILL_PATH)}`);
103
+ }
100
104
  lines.push(
101
105
  "",
102
106
  result.policy === "written" ? `${C.green}\u2713${C.reset} Wrote ${POLICY_PATH} (review required)` : `${C.dim}${POLICY_PATH} already exists \u2014 left as it is${C.reset}`,
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { hostKeyPath, runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-L4CW6LZQ.js';
3
+ import { hostKeyPath, runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-RHAGBUL5.js';
4
4
  import { generateKeyPairSync, createPrivateKey, createPublicKey, sign } from 'crypto';
5
5
  import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
6
6
 
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { LiveUploader } from './chunk-2AKDF6C2.js';
4
- import { spoolDir } from './chunk-FO7F6QSV.js';
3
+ import { LiveUploader } from './chunk-VS27BP3E.js';
4
+ import { spoolDir } from './chunk-DJHNEGNM.js';
5
5
  import { CaptureDaemon } from './chunk-QE3UQAHK.js';
6
6
  import { parseWorkItemEnv } from './chunk-T2Q7ISPE.js';
7
7
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from 'node:module';
3
+ import { spawn } from 'child_process';
4
+
5
+ createRequire(import.meta.url);
6
+ var FD_STORE_ENV = "OUTERLAYER_FD_STORE";
7
+ var MIN_SYSTEMD = 254;
8
+ var LISTEN_FDS_START = 3;
9
+ var FD_SLOTS_PER_BUILD = 64;
10
+ function fdName(buildId, socket) {
11
+ return `ol-${buildId}-${socket}`;
12
+ }
13
+ function listenFdOf(server) {
14
+ const handle = server._handle;
15
+ return typeof handle?.fd === "number" && handle.fd >= 0 ? handle.fd : void 0;
16
+ }
17
+ function parseListenFds(env, pid) {
18
+ const found = /* @__PURE__ */ new Map();
19
+ if (env.LISTEN_PID !== String(pid)) return found;
20
+ const count = Number(env.LISTEN_FDS);
21
+ if (!Number.isInteger(count) || count <= 0) return found;
22
+ const names = (env.LISTEN_FDNAMES ?? "").split(":");
23
+ for (let index = 0; index < count; index++) {
24
+ const name = names[index];
25
+ if (name !== void 0 && name !== "" && name !== "stored") found.set(name, LISTEN_FDS_START + index);
26
+ }
27
+ return found;
28
+ }
29
+ function listenOnFd(server, fd) {
30
+ return new Promise((resolve, reject) => {
31
+ server.once("error", reject);
32
+ server.listen({ fd }, () => {
33
+ server.off("error", reject);
34
+ resolve();
35
+ });
36
+ });
37
+ }
38
+ function run(spawnFn, command, args, fd) {
39
+ return new Promise((resolve) => {
40
+ let stdout = "";
41
+ let stderr = "";
42
+ let child;
43
+ try {
44
+ child = spawnFn(command, args, { stdio: ["ignore", "pipe", "pipe", ...fd === void 0 ? [] : [fd]] });
45
+ } catch (err) {
46
+ resolve({ status: null, stdout, stderr: err instanceof Error ? err.message : String(err) });
47
+ return;
48
+ }
49
+ child.stdout?.on("data", (chunk) => stdout += chunk.toString("utf8"));
50
+ child.stderr?.on("data", (chunk) => stderr += chunk.toString("utf8"));
51
+ child.on("error", (err) => resolve({ status: null, stdout, stderr: err.message }));
52
+ child.on("close", (status) => resolve({ status, stdout, stderr }));
53
+ });
54
+ }
55
+ function systemdVersion(ran) {
56
+ const match = /^systemd (\d+)/.exec(ran.stdout);
57
+ return ran.status === 0 && match !== null ? Number(match[1]) : void 0;
58
+ }
59
+ function realFdStorePort(options = {}) {
60
+ const env = options.env ?? process.env;
61
+ const pid = options.pid ?? process.pid;
62
+ const command = options.command ?? "systemd-notify";
63
+ const spawnFn = options.spawn ?? spawn;
64
+ let inherited;
65
+ let version;
66
+ return {
67
+ async status() {
68
+ if (env.NOTIFY_SOCKET === void 0 || env.NOTIFY_SOCKET === "") return { ok: false, reason: "NOTIFY_SOCKET is not set, so this runner was not started by a service that accepts descriptors" };
69
+ const size = Number(env[FD_STORE_ENV]);
70
+ if (!Number.isInteger(size) || size <= 0) return { ok: false, reason: `${FD_STORE_ENV} is not set, so the service's unit keeps no descriptor store` };
71
+ version ??= run(spawnFn, command, ["--version"]).then(systemdVersion);
72
+ const found = await version;
73
+ if (found === void 0) return { ok: false, reason: `${command} could not be run, so no descriptor can be stored` };
74
+ if (found < MIN_SYSTEMD) return { ok: false, reason: `systemd ${found} cannot store a descriptor sent from a child process: it needs systemd ${MIN_SYSTEMD} or later` };
75
+ return { ok: true };
76
+ },
77
+ async push(name, server) {
78
+ const fd = listenFdOf(server);
79
+ if (fd === void 0) throw new Error(`${name} has no descriptor to store`);
80
+ const ran = await run(spawnFn, command, [`--fd=${LISTEN_FDS_START}`, `--fdname=${name}`, "FDSTORE=1"], fd);
81
+ if (ran.status !== 0) throw new Error(`storing ${name} failed${ran.status === null ? "" : ` (exit ${ran.status})`}: ${ran.stderr.trim().split("\n")[0] ?? ""}`);
82
+ },
83
+ async remove(name) {
84
+ const ran = await run(spawnFn, command, [`--fdname=${name}`, "FDSTOREREMOVE=1"]);
85
+ if (ran.status !== 0) throw new Error(`removing ${name} from the store failed${ran.status === null ? "" : ` (exit ${ran.status})`}: ${ran.stderr.trim().split("\n")[0] ?? ""}`);
86
+ },
87
+ inherited() {
88
+ inherited ??= parseListenFds(env, pid);
89
+ return inherited;
90
+ },
91
+ listenOn: listenOnFd
92
+ };
93
+ }
94
+
95
+ export { FD_SLOTS_PER_BUILD, FD_STORE_ENV, fdName, realFdStorePort };
@@ -1,24 +1,25 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { runnerImageVersion } from './chunk-665QWBNW.js';
4
- import { readDefaultBranchHead, cloneRepository, buildRepositoryImage } from './chunk-7LVF4E5V.js';
3
+ import { keepStagedContext, describeCallFailure, controlPlaneTokenFailure, refusalCode, resolveGoverningSource, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, shimScript } from './chunk-WSYXLLA5.js';
4
+ import { runnerImageVersion } from './chunk-M3MHHIUW.js';
5
+ import { realFdStorePort } from './chunk-YB3CSYXX.js';
6
+ import { readDefaultBranchHead, cloneRepository, buildRepositoryImage } from './chunk-24ID7EQ2.js';
5
7
  import { startTimeOf, isSameProcess } from './chunk-JBJTC3UU.js';
6
8
  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-ZLEXMZFW.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-TSW4DGV2.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-J7BXZLSO.js';
12
- import { WorkCommandError } from './chunk-UKCNOAO6.js';
9
+ 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-JH2GQU5T.js';
10
+ 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-B6K7R5UY.js';
11
+ import { execCapture } from './chunk-XBPUTQ7E.js';
12
+ import { GUEST_CID } from './chunk-GLUKDQS4.js';
13
+ import { WorkCommandError } from './chunk-55GNQPO6.js';
13
14
  import { hostAllowed } from './chunk-UXYLWVTQ.js';
14
- import { parseDuKilobytes } from './chunk-7RQ73DLO.js';
15
- import { sharedSkillNames, skillConflictMessage } from './chunk-VPEGE3QZ.js';
15
+ import { readDu } from './chunk-YJLHUKYS.js';
16
+ import { sharedSkillNames, skillConflictMessage } from './chunk-6TRNCUM4.js';
16
17
  import { versionAtLeast, MINIMUM_CLAUDE_VERSION } from './chunk-HCVLP7XA.js';
17
18
  import { setCustomScrubbers, setLocalIdentity, setRepoRoot, parseTranscript, scrubDeep, scrubText } from './chunk-QE3UQAHK.js';
18
19
  import { orderSessions, extractFacts, sessionsToTimeline } from './chunk-RKOTJQVG.js';
19
20
  import { downconvertSession } from './chunk-QZBXLLTV.js';
20
- import { vmAssetsDir, RUNNER_DIR_MODE, rootfsPathFor, diskTemplatesDir, RUNNER_FILE_MODE, deliveryDir, ghConfigDir, runnerDirOfBuild, spoolDir, mirrorDir, buildDir, SHIM_DIR } from './chunk-L4CW6LZQ.js';
21
- import { repositoriesOf, primaryOf, RELAY_PORT, repositoryPath, CHECKOUT_DIR, lifecycleWorkdir, claudeCredential, buildEnvironment, startBuildServices, checkEnvironment, AGENT_CREDENTIAL_MISSING, checkoutPath, JOB_MOUNT } from './chunk-2K3TCQHW.js';
21
+ import { vmAssetsDir, RUNNER_DIR_MODE, rootfsPathFor, diskTemplatesDir, RUNNER_FILE_MODE, deliveryDir, ghConfigDir, runnerDirOfBuild, spoolDir, mirrorDir, buildDir, SHIM_DIR } from './chunk-RHAGBUL5.js';
22
+ import { repositoriesOf, primaryOf, RELAY_PORT, repositoryPath, CHECKOUT_DIR, lifecycleWorkdir, claudeCredential, buildEnvironment, startBuildServices, checkEnvironment, AGENT_CREDENTIAL_MISSING, checkoutPath, JOB_MOUNT } from './chunk-2I3LIRZP.js';
22
23
  import { RELAY_USER, RELAY_ID, UNKNOWN_TRANSPORT_REASON, DOCKER_DESKTOP_REASON, MAX_MALFORMED_SESSIONS, MALFORMED_REASON, MAX_OPEN_STREAMS, STREAM_WINDOW, SESSION_WINDOW, targetOfPath } from './chunk-JGD5TWQ2.js';
23
24
  import { readFileSync, mkdirSync, existsSync, mkdtempSync, rmSync, chmodSync, truncateSync, writeFileSync, readdirSync, lstatSync, copyFileSync, accessSync, constants, statSync, rmdirSync, renameSync, unlinkSync, openSync, closeSync, createWriteStream, createReadStream } from 'fs';
24
25
  import { join, dirname, basename } from 'path';
@@ -210,6 +211,9 @@ function helperClient(socketPath, options = {}) {
210
211
  async list() {
211
212
  const reply = await ask(socketPath, { v: 1, op: "list" }, REQUEST_TIMEOUT_MS);
212
213
  return Array.isArray(reply.builds) ? reply.builds.map(String) : [];
214
+ },
215
+ async relink(build) {
216
+ await ask(socketPath, { v: 1, op: "relink", build }, REQUEST_TIMEOUT_MS);
213
217
  }
214
218
  };
215
219
  }
@@ -815,6 +819,13 @@ async function createBuildDisk(input) {
815
819
  function deleteBuildDisk(path) {
816
820
  rmSync(path, { force: true });
817
821
  }
822
+ var clearBit = (bit) => `0b${"x".repeat(31 - bit)}0${"x".repeat(bit)}`;
823
+ var CPU_TEMPLATE = {
824
+ cpuid_modifiers: [
825
+ { leaf: "0x1", subleaf: "0x0", flags: 0, modifiers: [{ register: "ecx", bitmap: clearBit(5) }] },
826
+ { leaf: "0x80000001", subleaf: "0x0", flags: 0, modifiers: [{ register: "ecx", bitmap: clearBit(2) }] }
827
+ ]
828
+ };
818
829
  var MIB = 1024 ** 2;
819
830
  var INIT = "/opt/outerlayer/bin/outerlayer-guest";
820
831
  function machineConfig(limits2, paths) {
@@ -842,7 +853,8 @@ function machineConfig(limits2, paths) {
842
853
  { drive_id: "build", path_on_host: paths.buildDisk, is_root_device: false, is_read_only: false }
843
854
  ],
844
855
  "machine-config": { vcpu_count: limits2.cpus, mem_size_mib: Math.max(1, Math.floor(limits2.memoryBytes / MIB)), smt: false },
845
- vsock: { guest_cid: GUEST_CID, uds_path: paths.vsock }
856
+ vsock: { guest_cid: GUEST_CID, uds_path: paths.vsock },
857
+ "cpu-config": CPU_TEMPLATE
846
858
  };
847
859
  }
848
860
  function firecrackerCommand(input) {
@@ -907,6 +919,7 @@ function createMicroVmPorts(over = {}) {
907
919
  firecracker: over.firecracker ?? createFirecrackerHost(),
908
920
  cgroup: over.cgroup ?? realCgroupPort(),
909
921
  helper: over.helper ?? realHelperPort(),
922
+ fdStore: over.fdStore ?? realFdStorePort(),
910
923
  exec: over.exec ?? execCapture
911
924
  };
912
925
  }
@@ -1048,6 +1061,11 @@ async function runBuildSteps(input) {
1048
1061
  const delivered = await deliver(input, staged);
1049
1062
  if (!delivered.ok) return delivered;
1050
1063
  controlPlane = { repository: staged.repository, commit: staged.sha };
1064
+ try {
1065
+ if (input.keepIn !== void 0) keepStagedContext(staged, input.keepIn);
1066
+ } catch (err) {
1067
+ log.error(`${tag} the governed context could not be kept for the host's checks: ${describeCallFailure(err)} \xB7 they fetch it again`);
1068
+ }
1051
1069
  log.line(`${tag} governed context ${staged.sha.slice(0, 7)} delivered to ${deliveryDir(staged.repository, staged.sha)} (${staged.files.length} files)`);
1052
1070
  } finally {
1053
1071
  input.removeStagedContext();
@@ -2090,6 +2108,9 @@ var V4 = [
2090
2108
  ["private", "10.0.0.0/8"],
2091
2109
  ["private", "172.16.0.0/12"],
2092
2110
  ["private", "192.168.0.0/16"],
2111
+ ["protocol-assignments", "192.0.0.0/24"],
2112
+ ["benchmarking", "198.18.0.0/15"],
2113
+ ["azure-wireserver", "168.63.129.16/32"],
2093
2114
  ["link-local", "169.254.0.0/16"],
2094
2115
  ["shared-address", "100.64.0.0/10"],
2095
2116
  ["multicast", "224.0.0.0/4"],
@@ -2100,6 +2121,8 @@ var V6 = [
2100
2121
  ["loopback", "::1/128"],
2101
2122
  ["ipv4-mapped", "::ffff:0:0/96"],
2102
2123
  ["nat64", "64:ff9b::/96"],
2124
+ // The location of an embedded IPv4 address depends on the translator's prefix length, so the whole prefix is refused.
2125
+ ["nat64-local", "64:ff9b:1::/48"],
2103
2126
  ["ipv4-compatible", "::/96"],
2104
2127
  ["link-local", "fe80::/10"],
2105
2128
  ["unique-local", "fc00::/7"],
@@ -2164,6 +2187,12 @@ function build6() {
2164
2187
  var RANGES_4 = build4();
2165
2188
  var RANGES_6 = build6();
2166
2189
  [...RANGES_4, ...RANGES_6].map(({ name, cidr }) => ({ name, cidr }));
2190
+ function carried6to4(address) {
2191
+ const v6 = parseV6(address);
2192
+ if (v6 === void 0 || v6 >> BigInt(112) !== BigInt(8194)) return void 0;
2193
+ const v4 = Number(v6 >> BigInt(80) & BigInt(4294967295));
2194
+ return [v4 >>> 24, v4 >>> 16 & 255, v4 >>> 8 & 255, v4 & 255].join(".");
2195
+ }
2167
2196
  function classifyAddress(address) {
2168
2197
  const v4 = parseV4(address);
2169
2198
  if (v4 !== void 0) {
@@ -2175,6 +2204,11 @@ function classifyAddress(address) {
2175
2204
  }
2176
2205
  const v6 = parseV6(address);
2177
2206
  if (v6 === void 0) return UNPARSEABLE;
2207
+ const carries = carried6to4(address);
2208
+ if (carries !== void 0) {
2209
+ const inner = classifyAddress(carries);
2210
+ return inner === void 0 ? void 0 : { ...inner, carries };
2211
+ }
2178
2212
  for (const range of RANGES_6) {
2179
2213
  const shift = BigInt(128 - range.bits);
2180
2214
  if (v6 >> shift === range.base >> shift) return { name: range.name, cidr: range.cidr };
@@ -2309,13 +2343,15 @@ async function startTunnel(socketPath, opts = {}) {
2309
2343
  const own = new Set(ownAddresses().map(normalize));
2310
2344
  let firstRefusal;
2311
2345
  for (const { address: address2 } of addresses) {
2312
- const range = own.has(normalize(address2)) ? { name: "host-address", cidr: address2 } : classifyAddress(address2);
2346
+ const carried = carried6to4(address2);
2347
+ const range = own.has(normalize(address2)) || carried !== void 0 && own.has(carried) ? { name: "host-address", cidr: address2, ...carried === void 0 ? {} : { carries: carried } } : classifyAddress(address2);
2313
2348
  if (range === void 0) return { ok: true, address: address2 };
2314
- firstRefusal ??= { address: address2, name: range.name, cidr: range.cidr };
2349
+ firstRefusal ??= { address: address2, name: range.name, cidr: range.cidr, carries: range.carries };
2315
2350
  }
2316
- const { address, name, cidr } = firstRefusal;
2351
+ const { address, name, cidr, carries } = firstRefusal;
2317
2352
  refused2(host, address, name);
2318
- return { ok: false, status: 403, body: `refused: ${host} is ${address}, in the ${name} range ${cidr}
2353
+ const via = carries === void 0 ? "" : `, which carries ${carries}`;
2354
+ return { ok: false, status: 403, body: `refused: ${host} is ${address}${via}, in the ${name} range ${cidr}
2319
2355
  ` };
2320
2356
  }
2321
2357
  const sockets = /* @__PURE__ */ new Set();
@@ -2432,12 +2468,16 @@ ${body}`);
2432
2468
  req.pipe(upstream);
2433
2469
  }
2434
2470
  if (opts.socket !== false) {
2435
- if (existsSync(socketPath)) unlinkSync(socketPath);
2436
- await new Promise((resolveListen, reject) => {
2437
- server.once("error", reject);
2438
- server.listen(socketPath, () => resolveListen());
2439
- });
2440
- chmodSync(socketPath, 438);
2471
+ if (opts.listenOn !== void 0) {
2472
+ await opts.listenOn(server);
2473
+ } else {
2474
+ if (existsSync(socketPath)) unlinkSync(socketPath);
2475
+ await new Promise((resolveListen, reject) => {
2476
+ server.once("error", reject);
2477
+ server.listen(socketPath, () => resolveListen());
2478
+ });
2479
+ chmodSync(socketPath, 438);
2480
+ }
2441
2481
  }
2442
2482
  const tcpServers = [];
2443
2483
  return {
@@ -2445,6 +2485,7 @@ ${body}`);
2445
2485
  record,
2446
2486
  destinationUsed,
2447
2487
  acceptStream: (stream) => void server.emit("connection", stream),
2488
+ listener: () => opts.socket === false ? void 0 : server,
2448
2489
  async listenTcp(address) {
2449
2490
  const tcp = createServer$1((socket) => server.emit("connection", socket));
2450
2491
  await new Promise((resolveListen, reject) => {
@@ -2883,7 +2924,8 @@ async function provisionContainer(input) {
2883
2924
  const delivered = await deliverJobFiles(runtime, state, ["context"], secrets);
2884
2925
  return delivered.ok ? delivered : { ok: false, reason: `context_unavailable: ${delivered.reason}` };
2885
2926
  },
2886
- removeStagedContext: () => removeStagedContext(buildDir2)
2927
+ removeStagedContext: () => removeStagedContext(buildDir2),
2928
+ keepIn: jobDir
2887
2929
  });
2888
2930
  if (!steps.ok) return bail(steps.reason, steps.aborted === true);
2889
2931
  state.startCommit = steps.startCommit;
@@ -2972,16 +3014,28 @@ async function stopContainer(runtime, state) {
2972
3014
  await runtime.host.stop(state.container);
2973
3015
  state.stopped = true;
2974
3016
  }
3017
+ var DISK_CHECK_MS = 12e4;
2975
3018
  async function measureDisk(runtime, state) {
2976
- const result = await runtime.host.exec({
2977
- container: state.container,
2978
- user: state.agentUser ?? ADDED_USER,
2979
- env: NO_ENV,
2980
- argv: ["du", "-skx", "/build"]
3019
+ let timer;
3020
+ const late = new Promise((resolve) => {
3021
+ timer = setTimeout(() => resolve({ failure: "du ran past 2 minutes" }), DISK_CHECK_MS);
2981
3022
  });
2982
- return result.status === 0 ? parseDuKilobytes(result.stdout) : void 0;
3023
+ try {
3024
+ const run = runtime.host.exec(
3025
+ {
3026
+ container: state.container,
3027
+ user: state.agentUser ?? ADDED_USER,
3028
+ env: { literals: { LC_ALL: "C" }, passed: {} },
3029
+ argv: ["du", "-skx", "/build"]
3030
+ },
3031
+ { timeoutMs: DISK_CHECK_MS + 1e4 }
3032
+ ).then(readDu, (err) => ({ failure: `docker exec did not run: ${err instanceof Error ? err.message.slice(0, 200) : "unknown error"}` }));
3033
+ return await Promise.race([run, late]);
3034
+ } finally {
3035
+ clearTimeout(timer);
3036
+ }
2983
3037
  }
2984
- async function startServicesFor(runtime, config, buildDir2, jobDir, itemKey, builtIns, gitRemote, serve = "socket", lease) {
3038
+ async function startServicesFor(runtime, config, buildDir2, jobDir, itemKey, builtIns, gitRemote, serve = "socket", lease, inherit) {
2985
3039
  return startBuildServices({
2986
3040
  startTunnel: runtime.startTunnel,
2987
3041
  tunnelOptions: { ...runtime.tunnelOptions, ...gitRemote === void 0 ? {} : { gitRemote } },
@@ -2991,6 +3045,7 @@ async function startServicesFor(runtime, config, buildDir2, jobDir, itemKey, bui
2991
3045
  allowHosts: config.build?.allowHosts,
2992
3046
  serve,
2993
3047
  ...lease === void 0 ? {} : { lease },
3048
+ ...inherit === void 0 ? {} : { inherit },
2994
3049
  ...builtIns ? { builtIns: { gatewayUrl: config.url, itemKey, claudeUpstream: runtime.claudeUpstream } } : {},
2995
3050
  hostEnv: runtime.hostEnv,
2996
3051
  destinationOptions: runtime.destinationOptions
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from 'node:module';
3
+
4
+ createRequire(import.meta.url);
5
+
6
+ // src/runner/container/disk.ts
7
+ var UNITS = { "": 1, k: 1024, m: 1024 ** 2, g: 1024 ** 3 };
8
+ function parseSize(text) {
9
+ const match = /^(\d+(?:\.\d+)?)([kKmMgG]?)$/.exec(text);
10
+ if (match === null) return void 0;
11
+ const bytes = Number(match[1]) * UNITS[match[2].toLowerCase()];
12
+ return bytes > 0 ? bytes : void 0;
13
+ }
14
+ function exceedsDisk(usedKilobytes, limit) {
15
+ const bytes = parseSize(limit);
16
+ return usedKilobytes * 1024 > (bytes ?? Number.POSITIVE_INFINITY);
17
+ }
18
+ var TOTAL = /^(\d+)\t\/build$/;
19
+ var GONE = /: No such file or directory$/;
20
+ var LINE_MAX = 200;
21
+ function readDu(result) {
22
+ const stdoutLines = result.stdout.split("\n");
23
+ const totalAt = stdoutLines.map((line) => TOTAL.test(line)).lastIndexOf(true);
24
+ const kib = totalAt === -1 ? void 0 : Number(TOTAL.exec(stdoutLines[totalAt])[1]);
25
+ const lines = [...result.stderr.split("\n"), ...stdoutLines.filter((_, index) => index !== totalAt)].map((line) => line.trim()).filter((line) => line !== "");
26
+ const other = lines.find((line) => !GONE.test(line));
27
+ if (kib !== void 0 && result.status === 0) return { kib };
28
+ if (kib !== void 0 && other === void 0 && lines.length > 0) return { kib };
29
+ const detail = other === void 0 ? "" : `: ${cut(other.replace(/[\u0000-\u001f\u007f]/g, " "))}`;
30
+ return { ...kib === void 0 ? {} : { kib }, failure: `docker exec exited ${result.status}${detail}` };
31
+ }
32
+ function cut(line) {
33
+ const head = line.slice(0, LINE_MAX);
34
+ const last = head.charCodeAt(head.length - 1);
35
+ return last >= 55296 && last <= 56319 ? head.slice(0, -1) : head;
36
+ }
37
+
38
+ export { exceedsDisk, parseSize, readDu };