@outerlayer/cli 0.34.0-next.20261027013606 → 0.34.0-next.20261027121359

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 (117) hide show
  1. package/dist/{agent-setup-2A6P2SYL.js → agent-setup-UPRMGVB7.js} +6 -6
  2. package/dist/{bridge-F5FBQSPZ.js → bridge-GVZUP3NU.js} +2 -2
  3. package/dist/{build-YSOVDTAN.js → build-ZDYL7ZGP.js} +7 -7
  4. package/dist/{build-disk-RZ7AZKTY.js → build-disk-WMIRA4RD.js} +5 -5
  5. package/dist/build-info.json +1 -1
  6. package/dist/{builder-MQIL24HI.js → builder-XTAHDFV5.js} +4 -4
  7. package/dist/{check-JD3GVQFP.js → check-FAG4QKIX.js} +36 -36
  8. package/dist/{chunk-MYLOOVRJ.js → chunk-3NMDGGZS.js} +2 -2
  9. package/dist/{chunk-DM4EEV73.js → chunk-4IB5WUY2.js} +6 -6
  10. package/dist/{chunk-77VBS2RT.js → chunk-66TKWWTX.js} +5 -5
  11. package/dist/{chunk-P3NPTFLF.js → chunk-6SJ3DJDH.js} +3 -3
  12. package/dist/{chunk-AHAYHJNN.js → chunk-ARPPH7VS.js} +164 -26
  13. package/dist/{chunk-QRJIBTNQ.js → chunk-B7LPFCIN.js} +5 -5
  14. package/dist/{chunk-CCHSD7RS.js → chunk-CHDWAWQA.js} +1 -1
  15. package/dist/{chunk-HOUFCUMH.js → chunk-DUG3JXAT.js} +1 -1
  16. package/dist/{chunk-WYR4INK3.js → chunk-FRETDGET.js} +2 -2
  17. package/dist/{chunk-SDELQEG4.js → chunk-HO4XRLAZ.js} +1 -1
  18. package/dist/{chunk-GJ4KBHBD.js → chunk-I2GHZ2VA.js} +1 -1
  19. package/dist/{chunk-YL3RWW7X.js → chunk-J2X5CTYY.js} +1 -1
  20. package/dist/{chunk-FQGC22IP.js → chunk-JKOONI3H.js} +2 -2
  21. package/dist/{chunk-L5VHGRQE.js → chunk-KDSKFXPE.js} +1 -1
  22. package/dist/{chunk-EBVK3QBO.js → chunk-KFXPH7SJ.js} +2 -2
  23. package/dist/{chunk-QWXBWOVV.js → chunk-L4DCIEVT.js} +3 -3
  24. package/dist/{chunk-O7QPHJWN.js → chunk-L7RPNSAA.js} +1 -1
  25. package/dist/{chunk-MN3PP45X.js → chunk-LHUZVM3L.js} +1 -1
  26. package/dist/{chunk-EP3WBNMC.js → chunk-LTMFHECB.js} +20 -20
  27. package/dist/{chunk-7PCA37ZS.js → chunk-LUYTNCMS.js} +3 -3
  28. package/dist/{chunk-25XBOX3K.js → chunk-LXOBWRVC.js} +2 -2
  29. package/dist/{chunk-66LH5QAV.js → chunk-M6YTST7G.js} +2 -2
  30. package/dist/{chunk-72CJOYN6.js → chunk-N752ZNZ5.js} +1 -1
  31. package/dist/{chunk-QABXXQ67.js → chunk-NGZBVN6F.js} +5 -5
  32. package/dist/{chunk-TS3EFB7S.js → chunk-PBZODW5X.js} +1 -1
  33. package/dist/{chunk-RR3VDM7M.js → chunk-Q3ATWA2U.js} +3 -3
  34. package/dist/{chunk-7DK2FOZ4.js → chunk-QBBZGVZJ.js} +2 -2
  35. package/dist/{chunk-JA2ARVY6.js → chunk-QTAADTIO.js} +1 -1
  36. package/dist/{chunk-6KFJIU73.js → chunk-RMJSYOSV.js} +1 -1
  37. package/dist/{chunk-DEJCZ43H.js → chunk-RO2NZJHZ.js} +82 -6
  38. package/dist/{chunk-7X2G463B.js → chunk-SGT7YU3X.js} +5 -5
  39. package/dist/{chunk-FQOUIYBL.js → chunk-SJY6A6EH.js} +24 -18
  40. package/dist/{chunk-7QAJQDHS.js → chunk-T375XV3H.js} +1 -1
  41. package/dist/{chunk-BLSEHKZ4.js → chunk-TS2YACAQ.js} +2 -2
  42. package/dist/{chunk-7GY3DVIL.js → chunk-UC4OSOQS.js} +48 -2
  43. package/dist/{chunk-MPNASRYB.js → chunk-UDRBQI5J.js} +10 -10
  44. package/dist/{chunk-7QF2EXAN.js → chunk-UXGWAAGQ.js} +4 -4
  45. package/dist/{chunk-GR7ZVGNI.js → chunk-UYWGR35C.js} +3 -3
  46. package/dist/{chunk-LQHCNXPK.js → chunk-W5EKMK37.js} +1 -1
  47. package/dist/{chunk-JM3YQ4LC.js → chunk-W774NREK.js} +3 -3
  48. package/dist/{chunk-GK6OYFMU.js → chunk-WS5E73JO.js} +5 -5
  49. package/dist/{chunk-VUJURIPJ.js → chunk-XEJ5USHY.js} +13 -5
  50. package/dist/{chunk-Q2KGDDUX.js → chunk-XSUM3E67.js} +3 -3
  51. package/dist/{chunk-CFFVCI2I.js → chunk-XZGURZHF.js} +1 -1
  52. package/dist/{chunk-WBTPI5MP.js → chunk-YGX72FUQ.js} +2 -2
  53. package/dist/{chunk-OKGHWCSK.js → chunk-YIBHQR3B.js} +2 -2
  54. package/dist/{chunk-SDAEXUIX.js → chunk-Z7THNFUU.js} +1 -0
  55. package/dist/{chunk-3VZTNXK5.js → chunk-ZV6GOXYA.js} +1 -1
  56. package/dist/{claude-launcher-EO3ALKBS.js → claude-launcher-SGZSOGKZ.js} +1 -1
  57. package/dist/{cli-3BAUWQCS.js → cli-6QN7TH6U.js} +110 -110
  58. package/dist/{command-UVGNJILP.js → command-6T6RI5XY.js} +24 -24
  59. package/dist/{config-NGCQD6SN.js → config-CWYMIXTV.js} +6 -6
  60. package/dist/{connect-cmd-65YBQRSY.js → connect-cmd-MY6SR4OK.js} +5 -5
  61. package/dist/{container-start-YBENDAOQ.js → container-start-FDXR4QND.js} +30 -30
  62. package/dist/{context-show-cmd-S5SEBOI2.js → context-show-cmd-WRTV3ACH.js} +6 -6
  63. package/dist/{control-plane-launch-BDSUP4DK.js → control-plane-launch-UM4IHOJQ.js} +5 -5
  64. package/dist/{demo-record-cmd-C2C4P2EQ.js → demo-record-cmd-XBWTORVM.js} +2 -2
  65. package/dist/{demo-voice-cmd-RWTRJUAX.js → demo-voice-cmd-FLU4GDKS.js} +11 -11
  66. package/dist/{docker-TRGA5QRL.js → docker-IUPWQ2RK.js} +4 -4
  67. package/dist/{doctor-QENPDYBD.js → doctor-5VNZ2BLY.js} +28 -26
  68. package/dist/{emit-artifact-cmd-56C6DBUP.js → emit-artifact-cmd-RDXIWRFU.js} +10 -10
  69. package/dist/{emit-criteria-cmd-HRCWXD3W.js → emit-criteria-cmd-EDJOWGKL.js} +7 -7
  70. package/dist/{emit-demo-cmd-QMRDQGB6.js → emit-demo-cmd-W3BXFFU3.js} +11 -11
  71. package/dist/{emit-finding-cmd-6MVFN4BO.js → emit-finding-cmd-TMZIOQIP.js} +7 -7
  72. package/dist/{emit-result-cmd-E3YYBXRY.js → emit-result-cmd-P55JBD2W.js} +9 -9
  73. package/dist/{emit-step-cmd-DM4CRYYI.js → emit-step-cmd-Y7LKI7L3.js} +7 -7
  74. package/dist/{exec-client-LXHTMVIB.js → exec-client-FB3OBHOJ.js} +3 -3
  75. package/dist/{find-unit-IOCVYPNW.js → find-unit-R4I5GJCH.js} +8 -8
  76. package/dist/{findings-cmd-K2OYBTUH.js → findings-cmd-D64BYS7Z.js} +7 -7
  77. package/dist/{fleet-readiness-VIAVQYRP.js → fleet-readiness-75KQEZ6E.js} +5 -5
  78. package/dist/{governing-source-MQA2SDJT.js → governing-source-YYEU46PP.js} +9 -9
  79. package/dist/{guest-init-WWL2WL7R.js → guest-init-SGF6ZVZN.js} +4 -4
  80. package/dist/{hook-fast-KXAQ22LZ.js → hook-fast-XX5HZOCR.js} +1 -1
  81. package/dist/{host-checks-UNEQTQ6L.js → host-checks-VKBAGGWH.js} +28 -28
  82. package/dist/{pending-UWFDVFOA.js → host-key-CNCHVNDC.js} +3 -3
  83. package/dist/{image-tag-BTXKIH73.js → image-tag-MRWNQGXA.js} +3 -3
  84. package/dist/index.js +4 -4
  85. package/dist/{init-6UEOOD2J.js → init-B5S5LMIL.js} +21 -21
  86. package/dist/{init-JR62PVKC.js → init-BB2TLXVB.js} +21 -21
  87. package/dist/{init-cmd-34YWWGQZ.js → init-cmd-I2Z4VZSG.js} +10 -10
  88. package/dist/{init-update-JMVLGBDE.js → init-update-TIZILQXL.js} +8 -8
  89. package/dist/{install-cmd-RGO7NWKP.js → install-cmd-X4OHS36T.js} +5 -5
  90. package/dist/{logs-LEVH6VAI.js → logs-BPEOYWRW.js} +2 -2
  91. package/dist/{loop-WHK6EVUE.js → loop-XULUT5HL.js} +35 -35
  92. package/dist/{machine-ZZOQ7LLV.js → machine-UYFUUSEQ.js} +21 -21
  93. package/dist/{mcp-serve-cmd-4O5INM77.js → mcp-serve-cmd-NCPWJJDZ.js} +4 -4
  94. package/dist/{paths-AQ47ZRHK.js → paths-WXGOFVCF.js} +2 -2
  95. package/dist/{host-key-TSOKVSZX.js → pending-GEDI4K7P.js} +3 -3
  96. package/dist/{pidfile-PCG2H5T4.js → pidfile-MYLBUG2I.js} +3 -3
  97. package/dist/{record-SVCNFCGQ.js → record-Y2JIOP56.js} +3 -3
  98. package/dist/{runner-env-DH7YA4BU.js → runner-env-Y2PBG7TR.js} +8 -8
  99. package/dist/{runner-identity-GLL56XY7.js → runner-identity-PL442M57.js} +4 -4
  100. package/dist/{runner-key-4ASVLQGM.js → runner-key-L6LXC4QA.js} +21 -21
  101. package/dist/{session-sender-KLOMLL7X.js → session-sender-AXROAZSC.js} +10 -10
  102. package/dist/{spec-cmd-MX5QFW32.js → spec-cmd-JG4QLGGJ.js} +8 -8
  103. package/dist/{status-7YP2C2QK.js → status-VOGNQ3NG.js} +28 -28
  104. package/dist/{sync-cmd-CO4DFMHU.js → sync-cmd-B3KQZJZO.js} +9 -9
  105. package/dist/{update-steps-J54P3SBL.js → update-steps-RSYFLNTL.js} +29 -29
  106. package/dist/{watch-GU62YVQY.js → watch-IHZRBUYV.js} +9 -9
  107. package/dist/{work-claim-cmd-JF5GGDFZ.js → work-claim-cmd-YEMHNW3H.js} +12 -12
  108. package/dist/{work-cmd-VR7PPSP6.js → work-cmd-OWZS3ZXL.js} +7 -7
  109. package/dist/{work-comment-cmd-HVZF72B4.js → work-comment-cmd-ESBYAE4K.js} +8 -8
  110. package/dist/{work-demo-cmd-EDGNM5VJ.js → work-demo-cmd-FT3FQWM7.js} +7 -7
  111. package/dist/{work-logs-cmd-ZZVAHX36.js → work-logs-cmd-K6NTURGR.js} +7 -7
  112. package/dist/{work-open-pr-cmd-AQWZRJHZ.js → work-open-pr-cmd-NGD4Z2TO.js} +8 -8
  113. package/dist/{work-pr-cmd-UJ7VWCJN.js → work-pr-cmd-274YUPQB.js} +7 -7
  114. package/dist/{work-proofs-cmd-DTFQ3FSB.js → work-proofs-cmd-JLSQHVKO.js} +8 -8
  115. package/dist/{work-proofs-record-XG544MGV.js → work-proofs-record-AYUWUFBE.js} +14 -14
  116. package/dist/{work-stop-cmd-SAT4XVM2.js → work-stop-cmd-VQLLLJ3H.js} +7 -7
  117. package/package.json +1 -1
@@ -1,16 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { keepHandWritten, runAgentSetup } from './chunk-72CJOYN6.js';
3
+ export { keepHandWritten, runAgentSetup } from './chunk-N752ZNZ5.js';
4
4
  import './chunk-TWFBOZQ5.js';
5
5
  import './chunk-KT4CN6OU.js';
6
6
  import './chunk-J7EJMIDR.js';
7
7
  import './chunk-ANPNT6PM.js';
8
8
  import './chunk-LYCJQOO2.js';
9
- import './chunk-66LH5QAV.js';
9
+ import './chunk-M6YTST7G.js';
10
10
  import './chunk-LMYRR5MO.js';
11
- import './chunk-7QAJQDHS.js';
11
+ import './chunk-T375XV3H.js';
12
12
  import './chunk-PJDQPF5N.js';
13
- import './chunk-L5VHGRQE.js';
13
+ import './chunk-KDSKFXPE.js';
14
14
  import './chunk-ZJSNLVCE.js';
15
15
  import './chunk-BJ3KTMDH.js';
16
16
  import './chunk-OVNF4LLC.js';
@@ -24,8 +24,8 @@ import './chunk-TUSYOL2O.js';
24
24
  import './chunk-XFJ7YOPD.js';
25
25
  import './chunk-DINRXUQA.js';
26
26
  import './chunk-VNVZDWO3.js';
27
- import './chunk-GJ4KBHBD.js';
28
- import './chunk-SDAEXUIX.js';
27
+ import './chunk-I2GHZ2VA.js';
28
+ import './chunk-Z7THNFUU.js';
29
29
  import './chunk-MESOOLF4.js';
30
30
  import './chunk-Z5GEFMRW.js';
31
31
 
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { BRIDGE_ADDRESS, BRIDGE_CIDR, CONTAINER_NO_PROXY, CONTAINER_PROXY, TUNNEL_PORT, dockerClientConfig, startBridgeForward, writeDockerClientConfig } from './chunk-CFFVCI2I.js';
4
- import './chunk-SDAEXUIX.js';
3
+ export { BRIDGE_ADDRESS, BRIDGE_CIDR, CONTAINER_NO_PROXY, CONTAINER_PROXY, TUNNEL_PORT, dockerClientConfig, startBridgeForward, writeDockerClientConfig } from './chunk-XZGURZHF.js';
4
+ import './chunk-Z7THNFUU.js';
5
5
  import './chunk-MESOOLF4.js';
6
6
  import './chunk-Z5GEFMRW.js';
7
7
 
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { KEY_PREFIX, TAG_HOST, buildRepositoryImage, metadataFromLabels, prepareImageBuild, writeRecord } from './chunk-7X2G463B.js';
4
- import './chunk-7GY3DVIL.js';
5
- import './chunk-GR7ZVGNI.js';
3
+ export { KEY_PREFIX, TAG_HOST, buildRepositoryImage, metadataFromLabels, prepareImageBuild, writeRecord } from './chunk-SGT7YU3X.js';
4
+ import './chunk-UC4OSOQS.js';
5
+ import './chunk-UYWGR35C.js';
6
6
  export { RecipeError } from './chunk-HDLON3RJ.js';
7
7
  import './chunk-QUOITPN7.js';
8
- import './chunk-LQHCNXPK.js';
8
+ import './chunk-W5EKMK37.js';
9
9
  import './chunk-JBJTC3UU.js';
10
- import './chunk-L5VHGRQE.js';
10
+ import './chunk-KDSKFXPE.js';
11
11
  import './chunk-OOD5NDQA.js';
12
12
  import './chunk-DINRXUQA.js';
13
- import './chunk-GJ4KBHBD.js';
14
- import './chunk-SDAEXUIX.js';
13
+ import './chunk-I2GHZ2VA.js';
14
+ import './chunk-Z7THNFUU.js';
15
15
  import './chunk-MESOOLF4.js';
16
16
  import './chunk-Z5GEFMRW.js';
17
17
 
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { DEFAULT_BUILD_DISK, DEFAULT_CACHE_DISK, DOCKER_CACHE_MS, allocatedBytes, checkDiskFit, realBuildDiskProbe, runDocker, volumeBytes } from './chunk-BLSEHKZ4.js';
4
- import './chunk-GR7ZVGNI.js';
3
+ export { DEFAULT_BUILD_DISK, DEFAULT_CACHE_DISK, DOCKER_CACHE_MS, allocatedBytes, checkDiskFit, realBuildDiskProbe, runDocker, volumeBytes } from './chunk-TS2YACAQ.js';
4
+ import './chunk-UYWGR35C.js';
5
5
  import './chunk-HDLON3RJ.js';
6
6
  import './chunk-QUOITPN7.js';
7
- import './chunk-L5VHGRQE.js';
7
+ import './chunk-KDSKFXPE.js';
8
8
  import './chunk-OOD5NDQA.js';
9
9
  import './chunk-DINRXUQA.js';
10
- import './chunk-GJ4KBHBD.js';
11
- import './chunk-SDAEXUIX.js';
10
+ import './chunk-I2GHZ2VA.js';
11
+ import './chunk-Z7THNFUU.js';
12
12
  import './chunk-MESOOLF4.js';
13
13
  import './chunk-Z5GEFMRW.js';
14
14
 
@@ -1 +1 @@
1
- {"id":"2026-10-27T01:37:43.355Z+a8ae7a2","root":"/home/runner/_work/outerlayer/outerlayer","pkg":"outerlayer"}
1
+ {"id":"2026-10-27T12:15:21.059Z+364ef72","root":"/home/runner/_work/outerlayer/outerlayer","pkg":"outerlayer"}
@@ -1,13 +1,13 @@
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-GR7ZVGNI.js';
3
+ export { MIN_BUILDX_VERSION, builderName, builderSpec, buildxState, ensureBuilder, ensureFailureCount, isOutOfMemory, proxyEnvironment, trackImageBuild } from './chunk-UYWGR35C.js';
4
4
  import './chunk-HDLON3RJ.js';
5
5
  import './chunk-QUOITPN7.js';
6
- import './chunk-L5VHGRQE.js';
6
+ import './chunk-KDSKFXPE.js';
7
7
  import './chunk-OOD5NDQA.js';
8
8
  import './chunk-DINRXUQA.js';
9
- import './chunk-GJ4KBHBD.js';
10
- import './chunk-SDAEXUIX.js';
9
+ import './chunk-I2GHZ2VA.js';
10
+ import './chunk-Z7THNFUU.js';
11
11
  import './chunk-MESOOLF4.js';
12
12
  import './chunk-Z5GEFMRW.js';
13
13
 
@@ -1,64 +1,64 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { probeCredentials } from './chunk-EP3WBNMC.js';
3
+ import { probeCredentials } from './chunk-LTMFHECB.js';
4
4
  import './chunk-3JVYMD4G.js';
5
- import './chunk-DM4EEV73.js';
5
+ import './chunk-4IB5WUY2.js';
6
6
  import './chunk-E7R2GIAW.js';
7
7
  import './chunk-MH6QLXUO.js';
8
- import './chunk-HOUFCUMH.js';
9
- import './chunk-JM3YQ4LC.js';
10
- import './chunk-TS3EFB7S.js';
11
- import './chunk-FQOUIYBL.js';
8
+ import './chunk-DUG3JXAT.js';
9
+ import './chunk-W774NREK.js';
10
+ import './chunk-PBZODW5X.js';
11
+ import './chunk-SJY6A6EH.js';
12
12
  import './chunk-6CK2OC4Q.js';
13
13
  import './chunk-ZVB57WI6.js';
14
- import './chunk-P3NPTFLF.js';
14
+ import './chunk-6SJ3DJDH.js';
15
15
  import './chunk-I3LTIAOR.js';
16
- import './chunk-WBTPI5MP.js';
17
- import './chunk-QRJIBTNQ.js';
18
- import './chunk-7DK2FOZ4.js';
16
+ import './chunk-YGX72FUQ.js';
17
+ import './chunk-B7LPFCIN.js';
18
+ import './chunk-QBBZGVZJ.js';
19
19
  import './chunk-ESVW4MJY.js';
20
- import './chunk-CFFVCI2I.js';
21
- import { managedProblems, managedFactsOf } from './chunk-VUJURIPJ.js';
22
- import './chunk-YL3RWW7X.js';
20
+ import './chunk-XZGURZHF.js';
21
+ import { managedProblems, managedFactsOf } from './chunk-XEJ5USHY.js';
22
+ import './chunk-J2X5CTYY.js';
23
23
  import './chunk-TBT347UY.js';
24
- import { findServiceUnit } from './chunk-FQGC22IP.js';
24
+ import { findServiceUnit } from './chunk-JKOONI3H.js';
25
25
  import './chunk-TZMDRHWB.js';
26
- import { placeholderQueues, placeholderProblem, permissionModeProblems, permissionModeProblem, HELPER_ENV, helperSocketPath, probeHelper, needsClaudeCredential, claudeCredentialCheck, claimPermissionProblem, formerSkillQueues, formerSkillProblem } from './chunk-AHAYHJNN.js';
26
+ import { placeholderQueues, placeholderProblem, permissionModeProblems, permissionModeProblem, HELPER_ENV, helperSocketPath, probeHelper, needsClaudeCredential, claudeCredentialCheck, claimPermissionProblem, formerSkillQueues, formerSkillProblem } from './chunk-ARPPH7VS.js';
27
27
  import './chunk-2PGI6RDE.js';
28
- import './chunk-7X2G463B.js';
29
- import './chunk-7GY3DVIL.js';
28
+ import './chunk-SGT7YU3X.js';
29
+ import './chunk-UC4OSOQS.js';
30
30
  import './chunk-OGFGZQA3.js';
31
- import './chunk-3VZTNXK5.js';
32
- import './chunk-6KFJIU73.js';
33
- import './chunk-77VBS2RT.js';
34
- import './chunk-SDELQEG4.js';
31
+ import './chunk-ZV6GOXYA.js';
32
+ import './chunk-RMJSYOSV.js';
33
+ import './chunk-66TKWWTX.js';
34
+ import './chunk-HO4XRLAZ.js';
35
35
  import './chunk-TQMI335S.js';
36
- import './chunk-Q2KGDDUX.js';
37
- import './chunk-7QF2EXAN.js';
38
- import { loadRunnerConfig, RunnerConfigError, checkHooks } from './chunk-DEJCZ43H.js';
39
- import './chunk-BLSEHKZ4.js';
40
- import './chunk-GR7ZVGNI.js';
36
+ import './chunk-XSUM3E67.js';
37
+ import './chunk-UXGWAAGQ.js';
38
+ import { loadRunnerConfig, RunnerConfigError, checkHooks } from './chunk-RO2NZJHZ.js';
39
+ import './chunk-TS2YACAQ.js';
40
+ import './chunk-UYWGR35C.js';
41
41
  import './chunk-HDLON3RJ.js';
42
42
  import './chunk-QUOITPN7.js';
43
- import './chunk-LQHCNXPK.js';
43
+ import './chunk-W5EKMK37.js';
44
44
  import './chunk-JBJTC3UU.js';
45
45
  import './chunk-KT4CN6OU.js';
46
46
  import './chunk-J7EJMIDR.js';
47
- import './chunk-QABXXQ67.js';
47
+ import './chunk-NGZBVN6F.js';
48
48
  import './chunk-IP7BIBXJ.js';
49
- import './chunk-OKGHWCSK.js';
50
- import './chunk-O7QPHJWN.js';
49
+ import './chunk-YIBHQR3B.js';
50
+ import './chunk-L7RPNSAA.js';
51
51
  import './chunk-NWHU5G6R.js';
52
52
  import './chunk-G2JWZDFA.js';
53
53
  import './chunk-ANPNT6PM.js';
54
54
  import './chunk-IXPH4EXK.js';
55
55
  import './chunk-LYCJQOO2.js';
56
- import './chunk-66LH5QAV.js';
56
+ import './chunk-M6YTST7G.js';
57
57
  import './chunk-LMYRR5MO.js';
58
- import './chunk-7QAJQDHS.js';
58
+ import './chunk-T375XV3H.js';
59
59
  import './chunk-PJDQPF5N.js';
60
- import './chunk-L5VHGRQE.js';
61
- import './chunk-CCHSD7RS.js';
60
+ import './chunk-KDSKFXPE.js';
61
+ import './chunk-CHDWAWQA.js';
62
62
  import './chunk-ZJSNLVCE.js';
63
63
  import './chunk-2O5KA67H.js';
64
64
  import './chunk-BKO6JEZI.js';
@@ -80,8 +80,8 @@ import './chunk-TUSYOL2O.js';
80
80
  import './chunk-XFJ7YOPD.js';
81
81
  import './chunk-DINRXUQA.js';
82
82
  import './chunk-VNVZDWO3.js';
83
- import './chunk-GJ4KBHBD.js';
84
- import { claudeEnvPath, parseRunnerEnv } from './chunk-SDAEXUIX.js';
83
+ import './chunk-I2GHZ2VA.js';
84
+ import { claudeEnvPath, parseRunnerEnv } from './chunk-Z7THNFUU.js';
85
85
  import './chunk-MESOOLF4.js';
86
86
  import './chunk-Z5GEFMRW.js';
87
87
  import { readFileSync } from 'fs';
@@ -2,9 +2,9 @@
2
2
  import { createRequire } from 'node:module';
3
3
  import { launchRefusalForSession } from './chunk-ESVW4MJY.js';
4
4
  import { detectActiveSession, transcriptPathForSession } from './chunk-IP7BIBXJ.js';
5
- import { autoConnect } from './chunk-OKGHWCSK.js';
5
+ import { autoConnect } from './chunk-YIBHQR3B.js';
6
6
  import { C } from './chunk-ANPNT6PM.js';
7
- import { resolveGatewayCredentials, defaultFetch, unauthorizedMessage } from './chunk-7QAJQDHS.js';
7
+ import { resolveGatewayCredentials, defaultFetch, unauthorizedMessage } from './chunk-T375XV3H.js';
8
8
  import { readLatestProvenanceForSession } from './chunk-ZJSNLVCE.js';
9
9
  import { resolveRepoIdentity, defaultProjectsDir, findTranscripts, sessionIdFromPath, scrubText } from './chunk-OOD5NDQA.js';
10
10
  import { launchedItemForSession } from './chunk-T2Q7ISPE.js';
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { scrubReason, stripTerminalControls } from './chunk-FQOUIYBL.js';
4
- import { checkFit, RUNNER_RESERVE_BYTES } from './chunk-7QF2EXAN.js';
5
- import { RunnerAlreadyRunningError, readPidFile } from './chunk-LQHCNXPK.js';
3
+ import { scrubReason, stripTerminalControls } from './chunk-SJY6A6EH.js';
4
+ import { checkFit, RUNNER_RESERVE_BYTES } from './chunk-UXGWAAGQ.js';
5
+ import { RunnerAlreadyRunningError, readPidFile } from './chunk-W5EKMK37.js';
6
6
  import { isSameProcess } from './chunk-JBJTC3UU.js';
7
- import { isSignatureRefusal, postJson } from './chunk-QABXXQ67.js';
8
- import { signerFor } from './chunk-L5VHGRQE.js';
9
- import { pidFilePath } from './chunk-GJ4KBHBD.js';
7
+ import { isSignatureRefusal, postJson } from './chunk-NGZBVN6F.js';
8
+ import { signerFor } from './chunk-KDSKFXPE.js';
9
+ import { pidFilePath } from './chunk-I2GHZ2VA.js';
10
10
  import { readFileSync } from 'fs';
11
11
 
12
12
  createRequire(import.meta.url);
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { WorkCommandError, postJson } from './chunk-QABXXQ67.js';
4
- import { defaultGitRunner, materializeContext, fetchControlPlaneCommit, lookupGoverningSource } from './chunk-66LH5QAV.js';
5
- import { signingFetchFor } from './chunk-7QAJQDHS.js';
6
- import { signerFor } from './chunk-L5VHGRQE.js';
3
+ import { WorkCommandError, postJson } from './chunk-NGZBVN6F.js';
4
+ import { defaultGitRunner, materializeContext, fetchControlPlaneCommit, lookupGoverningSource } from './chunk-M6YTST7G.js';
5
+ import { signingFetchFor } from './chunk-T375XV3H.js';
6
+ import { signerFor } from './chunk-KDSKFXPE.js';
7
7
  import { unsupportedLayout, layoutRefusalReason, composeDelivery } from './chunk-FGF52V4V.js';
8
8
  import { SHIM_SCRIPT, GOVERNANCE_VARIABLE } from './chunk-HCVLP7XA.js';
9
9
  import { readDegraded, readContextManifest, readSourceCache } from './chunk-YQR6E6OV.js';
10
- import { SHIM_DIR, stagedContextDir, contextHomeDir, deliveryDir, keptContextDir } from './chunk-GJ4KBHBD.js';
10
+ import { SHIM_DIR, stagedContextDir, contextHomeDir, deliveryDir, keptContextDir } from './chunk-I2GHZ2VA.js';
11
11
  import { fstatSync, mkdirSync, writeFileSync, chmodSync, rmSync, cpSync, readFileSync, existsSync, lstatSync } from 'fs';
12
12
  import { relative, join, dirname } from 'path';
13
13
 
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { TUNNEL_PORT, BRIDGE_ADDRESS, BRIDGE_CIDR } from './chunk-CFFVCI2I.js';
4
- import { EXEC_PORT } from './chunk-6KFJIU73.js';
3
+ import { TUNNEL_PORT, BRIDGE_ADDRESS, BRIDGE_CIDR } from './chunk-XZGURZHF.js';
4
+ import { EXEC_PORT } from './chunk-RMJSYOSV.js';
5
5
  import { startTimeOf } from './chunk-JBJTC3UU.js';
6
- import { RELAY_PORT } from './chunk-SDAEXUIX.js';
6
+ import { RELAY_PORT } from './chunk-Z7THNFUU.js';
7
7
  import { spawn, spawnSync } from 'child_process';
8
8
  import { symlinkSync, lstatSync, writeFileSync, chmodSync, mkdirSync, existsSync } from 'fs';
9
9
 
@@ -1,30 +1,30 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { sha256OfFile, downloadPinned, VoiceDownloadError } from './chunk-2PGI6RDE.js';
4
- import { readDefaultBranchHead, cloneRepository, buildRepositoryImage, prepareImageBuild, KEY_PREFIX, TAG_HOST, metadataFromLabels, writeRecord } from './chunk-7X2G463B.js';
5
- import { FETCHED_DIR, toolsDockerfile, FETCHED_FFMPEG, FETCHED_GH, FETCHED_TINI, FETCHED_HEADLESS_SHELL, FETCHED_PLAYWRIGHT_FFMPEG, FETCHED_VOICE_DIR } from './chunk-7GY3DVIL.js';
4
+ import { readDefaultBranchHead, cloneRepository, buildRepositoryImage, prepareImageBuild, KEY_PREFIX, TAG_HOST, metadataFromLabels, writeRecord } from './chunk-SGT7YU3X.js';
5
+ import { FETCHED_DIR, toolsDockerfile, FETCHED_FFMPEG, FETCHED_GH, FETCHED_TINI, FETCHED_HEADLESS_SHELL, FETCHED_PLAYWRIGHT_FFMPEG, FETCHED_VOICE_DIR } from './chunk-UC4OSOQS.js';
6
6
  import { currentCliBuild } from './chunk-OGFGZQA3.js';
7
- import { runExec, execCapture, waitForAgent } from './chunk-3VZTNXK5.js';
8
- import { GUEST_CID, linkVsockSockets } from './chunk-6KFJIU73.js';
9
- import { retrySend, describeCallFailure, keepStagedContext, controlPlaneTokenFailure, refusalCode, resolveGoverningSource, prefetchGovernedContext, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, shimScript, WORKFLOW_PERMISSION_REASON } from './chunk-77VBS2RT.js';
10
- import { runnerImageVersion } from './chunk-SDELQEG4.js';
11
- import { hasStoredCredential, AGENT_COMMANDS, storeClaudeCredential, credentialFromStdin, isAgentName } from './chunk-Q2KGDDUX.js';
12
- import { runnerCredentialProblem, builtinKind, allowHostProblem, hostAllowed } from './chunk-DEJCZ43H.js';
13
- import { formatBytes, allocatedBytes } from './chunk-BLSEHKZ4.js';
14
- import { createDockerHost, builderSpec, runnerLabelValue, RUNNER_LABEL, BUILD_LABEL, prepareRunArgs, containerRunArgs, HASH_ARGV, parseProgramHash, JUDGE_PROGRAM, containerExecArgs, childEnvironment, readDu, JUDGE_DIR, MAX_ITEMS_BYTES, JUDGE_ITEMS, MAX_REPORT_BYTES, JUDGE_REPORT, spawnRun } from './chunk-GR7ZVGNI.js';
7
+ import { runExec, execCapture, waitForAgent } from './chunk-ZV6GOXYA.js';
8
+ import { GUEST_CID, linkVsockSockets } from './chunk-RMJSYOSV.js';
9
+ import { retrySend, describeCallFailure, keepStagedContext, controlPlaneTokenFailure, refusalCode, resolveGoverningSource, prefetchGovernedContext, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, shimScript, WORKFLOW_PERMISSION_REASON } from './chunk-66TKWWTX.js';
10
+ import { runnerImageVersion } from './chunk-HO4XRLAZ.js';
11
+ import { hasStoredCredential, AGENT_COMMANDS, storeClaudeCredential, credentialFromStdin, isAgentName } from './chunk-XSUM3E67.js';
12
+ import { optionalEgress, runnerCredentialProblem, builtinKind, allowHostProblem, systemClock, emptyEgressCounts, hostAllowed } from './chunk-RO2NZJHZ.js';
13
+ import { formatBytes, allocatedBytes } from './chunk-TS2YACAQ.js';
14
+ import { createDockerHost, builderSpec, runnerLabelValue, RUNNER_LABEL, BUILD_LABEL, prepareRunArgs, containerRunArgs, HASH_ARGV, parseProgramHash, JUDGE_PROGRAM, containerExecArgs, childEnvironment, readDu, JUDGE_DIR, MAX_ITEMS_BYTES, JUDGE_ITEMS, MAX_REPORT_BYTES, JUDGE_REPORT, spawnRun } from './chunk-UYWGR35C.js';
15
15
  import { RecipeError, DOCKER_FEATURE, writeSanitizedRecipe, classifyProperties } from './chunk-HDLON3RJ.js';
16
16
  import { firecrackerArch, MICROVM_ARCHES, FIRECRACKER_VERSION, hostHelperPinned, CLAUDE_CODE_VERSION, builderDiskPinned, guestAssetsPinned, GUEST_HELPER_SHA256, GUEST_ASSETS_BASE_URL, GUEST_KERNEL_SHA256, JAILER_BINARY_SHA256, FIRECRACKER_BINARY_SHA256, FIRECRACKER_SHA256, GUEST_ASSETS_VERSION, BUILDER_DISK_VERSION, FFMPEG_STATIC, FFMPEG_BUILD_TAG, GH_SHA256, GH_VERSION, TINI_SHA256, TINI_VERSION, HEADLESS_SHELL, HEADLESS_SHELL_BASE_URL, PLAYWRIGHT_FFMPEG, PLAYWRIGHT_FFMPEG_BASE_URL, VOICE_PACK_FILES, BUILDER_DISK_SHA256, BUILDER_DISK_BASE_URL, DEFAULT_BASE_IMAGE } from './chunk-QUOITPN7.js';
17
17
  import { startTimeOf, isSameProcess } from './chunk-JBJTC3UU.js';
18
- import { postJson, WorkCommandError, getJson } from './chunk-QABXXQ67.js';
18
+ import { postJson, WorkCommandError, getJson } from './chunk-NGZBVN6F.js';
19
19
  import { sanitizeTerminal } from './chunk-IXPH4EXK.js';
20
- import { signerFor } from './chunk-L5VHGRQE.js';
20
+ import { signerFor } from './chunk-KDSKFXPE.js';
21
21
  import { sharedSkillNames, skillConflictMessage } from './chunk-FGF52V4V.js';
22
22
  import { versionAtLeast, MINIMUM_CLAUDE_VERSION } from './chunk-HCVLP7XA.js';
23
23
  import { MIN_SCRUBBED_LITERAL, setCustomScrubbers, setLocalIdentity, setRepoRoot, parseTranscript, scrubDeep, scrubText } from './chunk-OOD5NDQA.js';
24
24
  import { orderSessions, extractFacts, sessionsToTimeline } from './chunk-XFJ7YOPD.js';
25
25
  import { downconvertSession } from './chunk-DINRXUQA.js';
26
- import { vmAssetsDir, RUNNER_DIR_MODE, rootfsPathFor, diskTemplatesDir, RUNNER_FILE_MODE, buildsDir, buildDir, runnerDir, deliveryDir, ghConfigDir, runnerDirOfBuild, spoolDir, mirrorDir, SHIM_DIR, vsockPath, builderCacheDiskPath, builderConsolePath } from './chunk-GJ4KBHBD.js';
27
- import { claudeCredential, parseIsolation, proxyEnvironment, withProxyWarningHidden, containerLocalAddress, destinationEnvironment, CLAUDE_CREDENTIAL_VARIABLES, builtInEnvironment, withHooksPath, startBuildServices, BUILT_IN_NAMES, repositoriesOf, primaryOf, RELAY_PORT, repositoryPath, CHECKOUT_DIR, lifecycleWorkdir, buildEnvironment, writeBuildMavenSettings, checkEnvironment, AGENT_CREDENTIAL_MISSING, mavenSettingsXml, namesGlobalSettings, MAVEN_NO_PROXY_NOTE, mavenArgs, MAVEN_SPACE_NOTE, writeMavenSettings, checkoutPath, JOB_MOUNT, realFdStorePort } from './chunk-SDAEXUIX.js';
26
+ import { vmAssetsDir, RUNNER_DIR_MODE, rootfsPathFor, diskTemplatesDir, RUNNER_FILE_MODE, buildsDir, buildDir, runnerDir, deliveryDir, ghConfigDir, runnerDirOfBuild, spoolDir, mirrorDir, SHIM_DIR, vsockPath, builderCacheDiskPath, builderConsolePath } from './chunk-I2GHZ2VA.js';
27
+ import { claudeCredential, parseIsolation, proxyEnvironment, withProxyWarningHidden, containerLocalAddress, destinationEnvironment, CLAUDE_CREDENTIAL_VARIABLES, builtInEnvironment, withHooksPath, startBuildServices, BUILT_IN_NAMES, repositoriesOf, primaryOf, RELAY_PORT, repositoryPath, CHECKOUT_DIR, lifecycleWorkdir, buildEnvironment, writeBuildMavenSettings, checkEnvironment, AGENT_CREDENTIAL_MISSING, mavenSettingsXml, namesGlobalSettings, MAVEN_NO_PROXY_NOTE, mavenArgs, MAVEN_SPACE_NOTE, writeMavenSettings, checkoutPath, JOB_MOUNT, realFdStorePort } from './chunk-Z7THNFUU.js';
28
28
  import { RELAY_USER, RELAY_ID, UNKNOWN_TRANSPORT_REASON, DOCKER_DESKTOP_REASON, MAX_MALFORMED_SESSIONS, MALFORMED_REASON, JOIN_WAIT_MS, MAX_OPEN_STREAMS, STREAM_RESET_RATE, STREAM_RESET_BURST, STREAM_WINDOW, SESSION_WINDOW, targetOfPath } from './chunk-MESOOLF4.js';
29
29
  import { spawn, spawnSync } from 'child_process';
30
30
  import { mkdirSync, existsSync, readFileSync, mkdtempSync, rmSync, chmodSync, truncateSync, statSync, accessSync, constants, readdirSync, writeFileSync, lstatSync, copyFileSync, renameSync, rmdirSync, unlinkSync, linkSync, openSync, closeSync, cpSync, writeSync, appendFileSync, createWriteStream, createReadStream } from 'fs';
@@ -32,7 +32,7 @@ import { randomBytes, createHash } from 'crypto';
32
32
  import { join, dirname, isAbsolute, relative, resolve, basename } from 'path';
33
33
  import { createConnection, connect, createServer as createServer$1, isIP } from 'net';
34
34
  import { availableParallelism, networkInterfaces, tmpdir } from 'os';
35
- import { Duplex, PassThrough, Transform } from 'stream';
35
+ import { Transform, Duplex, PassThrough } from 'stream';
36
36
  import { createServer, request } from 'http';
37
37
  import { lookup } from 'dns/promises';
38
38
  import http2 from 'http2';
@@ -1111,6 +1111,9 @@ var IDLE_TIMEOUT_MS = 10 * 6e4;
1111
1111
  var STALLED_RESPONSE_MS = 6e4;
1112
1112
  var MAX_BAD_GATEWAY_LINES = 10;
1113
1113
  var BAD_GATEWAY_WINDOW_MS = 1e4;
1114
+ var CONNECTION_RATE_RANGE = "connection-rate";
1115
+ var OPEN_CONNECTIONS_RANGE = "open-connections";
1116
+ var COUNTS_SAVE_MS = 500;
1114
1117
  async function systemResolve(host) {
1115
1118
  const found = await lookup(host, { all: true, verbatim: true });
1116
1119
  return found.map((a) => ({ address: a.address }));
@@ -1145,6 +1148,8 @@ async function startTunnel(socketPath, opts = {}) {
1145
1148
  const connectTimeoutMs = opts.connectTimeoutMs ?? CONNECT_TIMEOUT_MS;
1146
1149
  const idleTimeoutMs = opts.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
1147
1150
  const stalledResponseMs = opts.stalledResponseMs ?? STALLED_RESPONSE_MS;
1151
+ const limits2 = opts.egress ?? { connectionsPerSecond: 0, connectionBurst: 1, openConnections: 0, sendBytesPerSecond: 0, flagHosts: 0 };
1152
+ const clock = opts.clock ?? systemClock;
1148
1153
  let windowStartedMs = 0;
1149
1154
  let linesInWindow = 0;
1150
1155
  let suppressed = 0;
@@ -1173,6 +1178,15 @@ async function startTunnel(socketPath, opts = {}) {
1173
1178
  const extraRefusalKeys = /* @__PURE__ */ new Set();
1174
1179
  let refusalsMore = 0;
1175
1180
  const destinations = [];
1181
+ const counts = emptyEgressCounts();
1182
+ let openNow = 0;
1183
+ let secondOf = 0;
1184
+ let openedInSecond = 0;
1185
+ let tokens = limits2.connectionBurst;
1186
+ let refilledAt = clock.now();
1187
+ let nextSendFree = 0;
1188
+ let lastSendClock = 0;
1189
+ const limitLogged = /* @__PURE__ */ new Set();
1176
1190
  const routes = /* @__PURE__ */ Object.create(null);
1177
1191
  if (opts.recordPath !== void 0 && existsSync(opts.recordPath)) {
1178
1192
  try {
@@ -1183,8 +1197,12 @@ async function startTunnel(socketPath, opts = {}) {
1183
1197
  }
1184
1198
  hostsMore = saved.hostsMore ?? 0;
1185
1199
  for (const name of saved.destinations ?? []) destinations.push(name);
1186
- for (const [name, counts] of Object.entries(saved.routes ?? {})) routes[name] = { requests: counts.requests, failures: counts.failures };
1200
+ for (const [name, counts2] of Object.entries(saved.routes ?? {})) routes[name] = { requests: counts2.requests, failures: counts2.failures };
1187
1201
  refusalsMore = saved.refusalsMore ?? 0;
1202
+ if (saved.egress !== void 0) {
1203
+ const kept = saved.egress;
1204
+ Object.assign(counts, kept, { refused: { ...counts.refused, ...kept.refused } });
1205
+ }
1188
1206
  for (const refusal of saved.refusals ?? []) {
1189
1207
  refusals.push(refusal);
1190
1208
  refusalKeys.add(`${refusal.host}|${refusal.address}|${refusal.range}`);
@@ -1198,8 +1216,9 @@ async function startTunnel(socketPath, opts = {}) {
1198
1216
  refusalsMore,
1199
1217
  refusals: refusals.map((r) => ({ ...r })),
1200
1218
  destinations: [...destinations],
1219
+ egress: { ...counts, refused: { ...counts.refused } },
1201
1220
  // Absent until a route is served, so a record of a tunnel that served none is the shape an older runner wrote.
1202
- ...Object.keys(routes).length === 0 ? {} : { routes: Object.fromEntries(Object.entries(routes).map(([name, counts]) => [name, { ...counts }])) }
1221
+ ...Object.keys(routes).length === 0 ? {} : { routes: Object.fromEntries(Object.entries(routes).map(([name, counts2]) => [name, { ...counts2 }])) }
1203
1222
  });
1204
1223
  const persist = () => {
1205
1224
  if (opts.recordPath === void 0) return;
@@ -1208,6 +1227,15 @@ async function startTunnel(socketPath, opts = {}) {
1208
1227
  } catch {
1209
1228
  }
1210
1229
  };
1230
+ let saveTimer;
1231
+ const persistSoon = () => {
1232
+ if (opts.recordPath === void 0 || saveTimer !== void 0) return;
1233
+ saveTimer = setTimeout(() => {
1234
+ saveTimer = void 0;
1235
+ persist();
1236
+ }, COUNTS_SAVE_MS);
1237
+ saveTimer.unref();
1238
+ };
1211
1239
  const destinationUsed = (name) => {
1212
1240
  if (destinations.includes(name)) return;
1213
1241
  destinations.push(name);
@@ -1219,9 +1247,9 @@ async function startTunnel(socketPath, opts = {}) {
1219
1247
  persist();
1220
1248
  };
1221
1249
  const routeFinished = (name, ok) => {
1222
- const counts = routes[name] ??= { requests: 0, failures: 0 };
1223
- counts.requests++;
1224
- if (!ok) counts.failures++;
1250
+ const counts2 = routes[name] ??= { requests: 0, failures: 0 };
1251
+ counts2.requests++;
1252
+ if (!ok) counts2.failures++;
1225
1253
  persist();
1226
1254
  };
1227
1255
  const reached = (host) => {
@@ -1235,6 +1263,10 @@ async function startTunnel(socketPath, opts = {}) {
1235
1263
  hosts.push(name);
1236
1264
  seen.add(name);
1237
1265
  }
1266
+ if (limits2.flagHosts > 0 && !counts.hostsFlagged && hosts.length + hostsMore > limits2.flagHosts) {
1267
+ counts.hostsFlagged = true;
1268
+ opts.log?.(`tunnel: this build reached more than ${limits2.flagHosts} distinct remote hosts`);
1269
+ }
1238
1270
  persist();
1239
1271
  };
1240
1272
  const refused2 = (host, address, range) => {
@@ -1250,6 +1282,64 @@ async function startTunnel(socketPath, opts = {}) {
1250
1282
  }
1251
1283
  persist();
1252
1284
  };
1285
+ const limitText = (range) => range === CONNECTION_RATE_RANGE ? `${limits2.connectionsPerSecond} new connections per second, burst ${limits2.connectionBurst}` : `${limits2.openConnections} open connections`;
1286
+ const admit = () => {
1287
+ const now = clock.now();
1288
+ if (limits2.openConnections > 0 && openNow >= limits2.openConnections) return OPEN_CONNECTIONS_RANGE;
1289
+ if (limits2.connectionsPerSecond > 0) {
1290
+ tokens = Math.min(limits2.connectionBurst, tokens + Math.max(0, now - refilledAt) / 1e3 * limits2.connectionsPerSecond);
1291
+ refilledAt = now;
1292
+ if (tokens < 1) return CONNECTION_RATE_RANGE;
1293
+ tokens -= 1;
1294
+ }
1295
+ counts.connectionsOpened++;
1296
+ openNow++;
1297
+ counts.peakOpenConnections = Math.max(counts.peakOpenConnections, openNow);
1298
+ const second = Math.floor(now / 1e3);
1299
+ if (second !== secondOf) {
1300
+ secondOf = second;
1301
+ openedInSecond = 0;
1302
+ }
1303
+ openedInSecond++;
1304
+ counts.peakConnectionsPerSecond = Math.max(counts.peakConnectionsPerSecond, openedInSecond);
1305
+ persistSoon();
1306
+ return void 0;
1307
+ };
1308
+ const release = () => {
1309
+ openNow--;
1310
+ };
1311
+ const refuseOverLimit = (host, range) => {
1312
+ if (range === CONNECTION_RATE_RANGE) counts.refused.connectionRate++;
1313
+ else counts.refused.openConnections++;
1314
+ refused2(host, NOT_RESOLVED, range);
1315
+ if (!limitLogged.has(range)) {
1316
+ limitLogged.add(range);
1317
+ opts.log?.(`tunnel refused ${host}: over the ${range} limit of ${limitText(range)}. Later refusals of this kind are counted when the build ends`);
1318
+ }
1319
+ persistSoon();
1320
+ return { status: 429, body: `refused: this build is over the ${range} limit of ${limitText(range)}
1321
+ ` };
1322
+ };
1323
+ const waitToSend = async (n) => {
1324
+ const now = clock.now();
1325
+ if (now < lastSendClock) nextSendFree = Math.max(0, nextSendFree - (lastSendClock - now));
1326
+ lastSendClock = now;
1327
+ nextSendFree = Math.max(nextSendFree, now) + n * 1e3 / limits2.sendBytesPerSecond;
1328
+ await clock.sleep(nextSendFree - now);
1329
+ };
1330
+ const meter = () => new Transform({
1331
+ highWaterMark: 64 * 1024,
1332
+ transform(chunk, _encoding, done) {
1333
+ waitToSend(chunk.length).then(
1334
+ () => {
1335
+ counts.bytesSent += chunk.length;
1336
+ persistSoon();
1337
+ done(null, chunk);
1338
+ },
1339
+ (err) => done(err)
1340
+ );
1341
+ }
1342
+ });
1253
1343
  async function decide(host, port) {
1254
1344
  if (opts.allowHosts !== void 0 && !hostAllowed(host, opts.allowHosts)) {
1255
1345
  refused2(host, NOT_RESOLVED, NOT_ALLOWED_RANGE);
@@ -1294,7 +1384,7 @@ async function startTunnel(socketPath, opts = {}) {
1294
1384
  server.on("connect", (req, client, head) => {
1295
1385
  void tunnelConnect(req, client, head);
1296
1386
  });
1297
- const statusLine = (status) => `HTTP/1.1 ${status} ${status === 403 ? "Forbidden" : "Bad Gateway"}`;
1387
+ const statusLine = (status) => `HTTP/1.1 ${status} ${status === 403 ? "Forbidden" : status === 429 ? "Too Many Requests" : "Bad Gateway"}`;
1298
1388
  const reply = (client, status, body) => {
1299
1389
  client.end(`${statusLine(status)}\r
1300
1390
  Content-Type: text/plain\r
@@ -1310,6 +1400,13 @@ ${body}`);
1310
1400
  client.end("HTTP/1.1 400 Bad Request\r\nConnection: close\r\nContent-Length: 0\r\n\r\n");
1311
1401
  return;
1312
1402
  }
1403
+ const over = admit();
1404
+ if (over !== void 0) {
1405
+ const refusal = refuseOverLimit(target.host, over);
1406
+ reply(client, refusal.status, refusal.body);
1407
+ return;
1408
+ }
1409
+ client.once("close", release);
1313
1410
  const decision = await decide(target.host, target.port);
1314
1411
  if (!decision.ok) {
1315
1412
  reply(client, decision.status, decision.body);
@@ -1336,16 +1433,33 @@ ${body}`);
1336
1433
  if (!upstream.readableEnded && !client.writableEnded) client.destroy(abortedError("the tunnel closed the connection to the server before it ended"));
1337
1434
  else client.resume();
1338
1435
  });
1339
- client.once("end", () => {
1436
+ const buildEnded = () => {
1340
1437
  upstream.destroy();
1341
1438
  client.end();
1342
- });
1439
+ };
1440
+ const metered = limits2.sendBytesPerSecond > 0 ? meter() : void 0;
1441
+ if (metered === void 0) client.once("end", buildEnded);
1442
+ else metered.once("end", buildEnded);
1343
1443
  reached(target.host);
1344
1444
  client.write("HTTP/1.1 200 Connection Established\r\n\r\n");
1345
- upstream.write(head);
1445
+ if (metered !== void 0) {
1446
+ if (head.length > 0) metered.write(head);
1447
+ } else {
1448
+ counts.bytesSent += head.length;
1449
+ upstream.write(head);
1450
+ }
1346
1451
  releaseWhenStalled(client, upstream);
1347
1452
  upstream.pipe(client);
1348
- client.pipe(upstream);
1453
+ if (metered === void 0) {
1454
+ client.on("data", (chunk) => {
1455
+ counts.bytesSent += chunk.length;
1456
+ persistSoon();
1457
+ });
1458
+ client.pipe(upstream);
1459
+ } else {
1460
+ client.once("close", () => metered.destroy());
1461
+ client.pipe(metered).pipe(upstream);
1462
+ }
1349
1463
  };
1350
1464
  if (upstream.readyState === "open") established();
1351
1465
  else upstream.once("connect", established);
@@ -1395,6 +1509,14 @@ ${body}`);
1395
1509
  }
1396
1510
  const host = url.hostname.replace(/^\[|\]$/g, "");
1397
1511
  const port = url.port === "" ? 80 : Number(url.port);
1512
+ const over = admit();
1513
+ if (over !== void 0) {
1514
+ const refusal = refuseOverLimit(host, over);
1515
+ res.writeHead(refusal.status, { "Content-Type": "text/plain", Connection: "close" });
1516
+ res.end(refusal.body);
1517
+ return;
1518
+ }
1519
+ res.once("close", release);
1398
1520
  const decision = await decide(host, port);
1399
1521
  if (!decision.ok) {
1400
1522
  res.writeHead(decision.status, { "Content-Type": "text/plain", Connection: "close" });
@@ -1430,7 +1552,17 @@ ${body}`);
1430
1552
  res.destroy();
1431
1553
  }
1432
1554
  });
1433
- req.pipe(upstream);
1555
+ if (limits2.sendBytesPerSecond > 0) {
1556
+ const metered = meter();
1557
+ res.once("close", () => metered.destroy());
1558
+ req.pipe(metered).pipe(upstream);
1559
+ } else {
1560
+ req.on("data", (chunk) => {
1561
+ counts.bytesSent += chunk.length;
1562
+ persistSoon();
1563
+ });
1564
+ req.pipe(upstream);
1565
+ }
1434
1566
  }
1435
1567
  if (opts.socket !== false) {
1436
1568
  if (opts.listenOn !== void 0) {
@@ -1463,6 +1595,9 @@ ${body}`);
1463
1595
  return { port: tcp.address().port };
1464
1596
  },
1465
1597
  close: () => new Promise((resolveClose) => {
1598
+ clearTimeout(saveTimer);
1599
+ saveTimer = void 0;
1600
+ persist();
1466
1601
  for (const socket of sockets) socket.destroy();
1467
1602
  for (const tcp of tcpServers) tcp.close();
1468
1603
  server.close(() => resolveClose());
@@ -1690,6 +1825,7 @@ async function startHostServices(input) {
1690
1825
  jobDir: input.jobDir,
1691
1826
  destinations,
1692
1827
  allowHosts: config.build?.allowHosts,
1828
+ ...optionalEgress(config),
1693
1829
  serve: input.process ? "tcp" : "both",
1694
1830
  proxy: input.process,
1695
1831
  ...input.process ? { builtIns: { gatewayUrl: config.url, itemKey: input.itemKey, claudeUpstream: runtime.claudeUpstream } } : {},
@@ -2126,6 +2262,7 @@ async function buildInBuilder(opts, deps, prepared) {
2126
2262
  tunnel = await deps.startTunnel(join(dir, TUNNEL_SOCKET), {
2127
2263
  ...deps.tunnelOptions,
2128
2264
  ...opts.allowHosts === void 0 ? {} : { allowHosts: opts.allowHosts },
2265
+ ...opts.egress === void 0 ? {} : { egress: opts.egress },
2129
2266
  recordPath: join(dir, "tunnel.json")
2130
2267
  });
2131
2268
  const configPath = join(dir, "vm.json");
@@ -4658,6 +4795,7 @@ async function startServicesFor(runtime, config, buildDir2, jobDir, itemKey, bui
4658
4795
  destinations: config.build?.destinations ?? [],
4659
4796
  // A managed build's tunnel allows the factory's hosts beside the runner's own.
4660
4797
  allowHosts: withFactoryHosts(config.build?.allowHosts, managedBuildSettingsFor(settingsDir ?? jobDir)),
4798
+ ...optionalEgress(config),
4661
4799
  serve,
4662
4800
  ...lease === void 0 ? {} : { lease },
4663
4801
  ...inherit === void 0 ? {} : { inherit },