@outerlayer/cli 0.28.1 → 0.28.3

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 (103) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/{agent-setup-YVR5RO56.js → agent-setup-IDF3EXM4.js} +7 -7
  3. package/dist/{bridge-WW2V7DTB.js → bridge-JN3VJ23L.js} +3 -3
  4. package/dist/{build-5FRC3RKM.js → build-JCYOHPLL.js} +5 -5
  5. package/dist/build-info.json +1 -1
  6. package/dist/{builder-4F2XNSFC.js → builder-HCTVP2O7.js} +5 -5
  7. package/dist/{check-NDDOASVO.js → check-F2TJCQ7S.js} +34 -34
  8. package/dist/{chunk-2YSCKEL2.js → chunk-2BZTGJII.js} +49 -6
  9. package/dist/{chunk-IKXY47R5.js → chunk-4SJ57DH7.js} +135 -28
  10. package/dist/{chunk-GUXWQIEY.js → chunk-6NFXOQKZ.js} +1 -1
  11. package/dist/{chunk-F4FA3ZUT.js → chunk-AV5MJY45.js} +3 -3
  12. package/dist/{chunk-WWQVKFN6.js → chunk-DIQN5SEL.js} +1 -1
  13. package/dist/{chunk-CTYSTE5C.js → chunk-DSKOHPXN.js} +1 -1
  14. package/dist/{chunk-5K3KB4YR.js → chunk-DWVAG73B.js} +1 -1
  15. package/dist/{chunk-T57XUI6N.js → chunk-EPGMCEVP.js} +2 -2
  16. package/dist/{chunk-ATJOFXTE.js → chunk-EZ3DZXUH.js} +3 -3
  17. package/dist/{chunk-IVX3U7KV.js → chunk-HWOU2HDH.js} +1 -1
  18. package/dist/{chunk-KVDVNOUK.js → chunk-ILU6664L.js} +16 -16
  19. package/dist/{chunk-MQHTM4YJ.js → chunk-JYVBEWBC.js} +3 -3
  20. package/dist/{chunk-USJZ2LDK.js → chunk-JZJLKTZT.js} +5 -5
  21. package/dist/{chunk-7CK2TJFB.js → chunk-KJIUFOC4.js} +1 -1
  22. package/dist/{chunk-7UGFIWIW.js → chunk-LRFU6RPD.js} +21 -21
  23. package/dist/{chunk-NUHZV3A4.js → chunk-M6NNXKRM.js} +1 -1
  24. package/dist/{chunk-JGD5TWQ2.js → chunk-MESOOLF4.js} +3 -1
  25. package/dist/{chunk-VC5J7QPV.js → chunk-MFI55TNI.js} +4 -4
  26. package/dist/{chunk-HXAEQPZR.js → chunk-N5EEEKT6.js} +1 -1
  27. package/dist/{chunk-TF7G2PR6.js → chunk-NKD5BNRX.js} +2 -2
  28. package/dist/{chunk-LNIFYSNK.js → chunk-NMIYK2G2.js} +2 -2
  29. package/dist/{chunk-Z3ASAXVU.js → chunk-O47BTZSN.js} +1 -1
  30. package/dist/{chunk-N7WAEEIU.js → chunk-OO6OADZN.js} +3 -3
  31. package/dist/{chunk-DKWQMPSL.js → chunk-OOUHNKKX.js} +1 -1
  32. package/dist/{chunk-66T6XJAB.js → chunk-QBF462QH.js} +1 -1
  33. package/dist/{chunk-VU7ZJPIR.js → chunk-QFNFBQCG.js} +1 -1
  34. package/dist/{chunk-YL2VDSNF.js → chunk-R7TMTFJP.js} +1 -1
  35. package/dist/{chunk-ZTY7HHYB.js → chunk-RXFKXZJS.js} +1 -1
  36. package/dist/{chunk-W3FSGH2M.js → chunk-SVODOMYC.js} +6 -6
  37. package/dist/{chunk-R7SS5RLJ.js → chunk-T7LJ6AIC.js} +5 -5
  38. package/dist/{chunk-T2QSWFSU.js → chunk-TCBVV2JK.js} +4 -4
  39. package/dist/{chunk-4XN5FRRJ.js → chunk-TG7FAHRP.js} +2 -2
  40. package/dist/{chunk-QBQHQEUG.js → chunk-TOHKSZKI.js} +1 -1
  41. package/dist/{chunk-QJFDAKRF.js → chunk-UXLLWIA2.js} +1 -1
  42. package/dist/{chunk-TVZAC2NP.js → chunk-VM6BX2WJ.js} +2 -2
  43. package/dist/{chunk-6BWJQGTV.js → chunk-W7BH5YN6.js} +8 -8
  44. package/dist/{chunk-MHAR6S7B.js → chunk-WL3QF3QF.js} +1 -1
  45. package/dist/{chunk-X52PMPOM.js → chunk-X7SFJZIG.js} +5 -5
  46. package/dist/{chunk-QWAYRAUX.js → chunk-YTR435DO.js} +2 -2
  47. package/dist/{chunk-55XLX5PA.js → chunk-YYGXCRIW.js} +1 -1
  48. package/dist/{claude-launcher-7RGVOYCD.js → claude-launcher-LVYZ4YJI.js} +1 -1
  49. package/dist/{cli-QC6ZKHPK.js → cli-5LLFR2SX.js} +101 -101
  50. package/dist/{command-3F6GY4CK.js → command-YXOMIXOJ.js} +23 -23
  51. package/dist/{config-5QYIKYUP.js → config-TNV5HHLO.js} +3 -3
  52. package/dist/{connect-cmd-5TYAOK5M.js → connect-cmd-43IWARIV.js} +6 -6
  53. package/dist/{container-start-P7O5XGOB.js → container-start-YG45GLFE.js} +22 -22
  54. package/dist/{control-plane-launch-FZMD4MXX.js → control-plane-launch-TIK265OT.js} +6 -6
  55. package/dist/{docker-ZTC4EIU4.js → docker-2IIRBQAB.js} +5 -5
  56. package/dist/{doctor-QPQDF7FB.js → doctor-3SRHLRF5.js} +25 -25
  57. package/dist/{emit-artifact-cmd-O3IBUMUY.js → emit-artifact-cmd-RM2X3PBJ.js} +10 -10
  58. package/dist/{emit-criteria-cmd-JDO2VUG5.js → emit-criteria-cmd-ZUI7DFND.js} +7 -7
  59. package/dist/{emit-finding-cmd-VCQPCLI2.js → emit-finding-cmd-W2FU4CCF.js} +7 -7
  60. package/dist/{emit-result-cmd-BNS57DD3.js → emit-result-cmd-JINMQ7QG.js} +10 -10
  61. package/dist/{emit-step-cmd-XN44BXYU.js → emit-step-cmd-7FZWQTV3.js} +8 -8
  62. package/dist/{exec-client-VKT2XNB3.js → exec-client-6ZJJ4KVH.js} +4 -4
  63. package/dist/{fleet-readiness-G5X3MKP2.js → fleet-readiness-3A67MUAU.js} +6 -6
  64. package/dist/{governing-source-B3M2U4BC.js → governing-source-KQMKM5CI.js} +10 -10
  65. package/dist/{guest-init-QW2DPX7H.js → guest-init-A4HHI2UR.js} +5 -5
  66. package/dist/{hook-fast-EFC44SXV.js → hook-fast-UJPAWDAO.js} +1 -1
  67. package/dist/host-key-NGRCMJZ7.js +10 -0
  68. package/dist/{image-tag-SS7YKJHN.js → image-tag-TEOKZVD5.js} +4 -4
  69. package/dist/index.js +4 -4
  70. package/dist/{init-HHEAJDPN.js → init-HQW3LHIF.js} +22 -22
  71. package/dist/{init-36XMFFRQ.js → init-XP55Q4ZT.js} +22 -22
  72. package/dist/{init-cmd-K2IKTSXJ.js → init-cmd-XSOVMNNE.js} +11 -11
  73. package/dist/{init-update-RWTQSTPE.js → init-update-MZ4IRFC7.js} +9 -9
  74. package/dist/{install-35SAMY75.js → install-NPTR35MG.js} +5 -5
  75. package/dist/{install-cmd-GFY4QF72.js → install-cmd-4PXPAFQX.js} +6 -6
  76. package/dist/{logs-X2IRDP5T.js → logs-Z4L4I3OR.js} +3 -3
  77. package/dist/{loop-F5ASKFRJ.js → loop-QQBLJ7GN.js} +34 -34
  78. package/dist/{machine-6STGIRJJ.js → machine-ATDPHWL5.js} +18 -18
  79. package/dist/{mcp-serve-cmd-IITCPAAR.js → mcp-serve-cmd-NQM2WDYI.js} +5 -5
  80. package/dist/{paths-32DWGK35.js → paths-2VSGK6E2.js} +3 -3
  81. package/dist/pending-SFZ2AYSK.js +10 -0
  82. package/dist/{pidfile-CYCTH6NQ.js → pidfile-3FT5OLUE.js} +4 -4
  83. package/dist/{record-N4WPZCGK.js → record-7SSRLSI2.js} +4 -4
  84. package/dist/{relay-GFPPD6GF.js → relay-IEYNSKAZ.js} +9 -5
  85. package/dist/{relay-protocol-HELO5SNH.js → relay-protocol-5LSWUJCW.js} +1 -1
  86. package/dist/{runner-env-EIB6WFPG.js → runner-env-2Z2DVSUJ.js} +6 -6
  87. package/dist/{runner-identity-S3V6I4I3.js → runner-identity-B37HHOZR.js} +5 -5
  88. package/dist/{runner-key-Y76QXVNV.js → runner-key-SICUOQY5.js} +22 -22
  89. package/dist/{session-sender-LFYMN6TT.js → session-sender-7MSVJZ6Q.js} +11 -11
  90. package/dist/{spec-cmd-Z6MGATWC.js → spec-cmd-KAQ7MX4O.js} +8 -8
  91. package/dist/{status-OANG2EM3.js → status-AI22UPKC.js} +25 -25
  92. package/dist/{sync-cmd-TNOOUPY2.js → sync-cmd-7K3WVQKO.js} +10 -10
  93. package/dist/{watch-HBNNYATF.js → watch-NCYESLO2.js} +10 -10
  94. package/dist/{work-claim-cmd-CXALMILD.js → work-claim-cmd-IOUEHYIY.js} +11 -11
  95. package/dist/{work-cmd-COESFSHE.js → work-cmd-FOI74X5B.js} +8 -8
  96. package/dist/{work-comment-cmd-A4ZUVCSA.js → work-comment-cmd-3C44H4CG.js} +8 -8
  97. package/dist/{work-logs-cmd-CTF43MBE.js → work-logs-cmd-YGAWCX3X.js} +8 -8
  98. package/dist/{work-open-pr-cmd-EMGYJXVD.js → work-open-pr-cmd-HUG5HAVC.js} +9 -9
  99. package/dist/{work-pr-cmd-FEXMS6RH.js → work-pr-cmd-L2EDOYXH.js} +8 -8
  100. package/dist/{work-stop-cmd-NIHAN45R.js → work-stop-cmd-GGDVKC67.js} +8 -8
  101. package/package.json +1 -1
  102. package/dist/host-key-AC6LTZDS.js +0 -10
  103. package/dist/pending-CSIY4Y2I.js +0 -10
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @outerlayer/cli
2
2
 
3
+ ## 0.28.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 556dd93: A container build that drops many connections at once, as package installs and test suites do, keeps its link to the runner. The runner no longer ends the build's relay session after about a thousand dropped connections.
8
+
9
+ ## 0.28.2
10
+
11
+ ### Patch Changes
12
+
13
+ - b61b6ba: `outerlayer sync` uploads a helper agent as finished once its parent session was told it stopped, even while the parent still runs. Before, each `sync` uploaded every helper of a running session as open, so finished helpers read as running until the whole session ended.
14
+ - fc2ba91: A container build's downloads arrive whole, so package installs no longer fail with aborted requests. A burst of connections no longer drops the build's link to the runner.
15
+
3
16
  ## 0.28.1
4
17
 
5
18
  ### Patch Changes
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { keepHandWritten, runAgentSetup } from './chunk-QJFDAKRF.js';
3
+ export { keepHandWritten, runAgentSetup } from './chunk-UXLLWIA2.js';
4
4
  import './chunk-QKXF7CLR.js';
5
5
  import './chunk-KT4CN6OU.js';
6
6
  import './chunk-SATUCMAJ.js';
7
7
  import './chunk-5B7BEQPR.js';
8
8
  import './chunk-ANPNT6PM.js';
9
- import './chunk-4XN5FRRJ.js';
9
+ import './chunk-TG7FAHRP.js';
10
10
  import './chunk-P2RWZCV7.js';
11
- import './chunk-7CK2TJFB.js';
11
+ import './chunk-KJIUFOC4.js';
12
12
  import './chunk-PJDQPF5N.js';
13
- import './chunk-YL2VDSNF.js';
14
- import './chunk-5K3KB4YR.js';
15
- import './chunk-HXAEQPZR.js';
13
+ import './chunk-R7TMTFJP.js';
14
+ import './chunk-DWVAG73B.js';
15
+ import './chunk-N5EEEKT6.js';
16
16
  import './chunk-ZJSNLVCE.js';
17
17
  import './chunk-BJ3KTMDH.js';
18
18
  import './chunk-JGML2VUN.js';
@@ -27,7 +27,7 @@ import './chunk-RKOTJQVG.js';
27
27
  import './chunk-QZBXLLTV.js';
28
28
  import './chunk-VNVZDWO3.js';
29
29
  import './chunk-XD4ZCMA4.js';
30
- import './chunk-JGD5TWQ2.js';
30
+ import './chunk-MESOOLF4.js';
31
31
  import './chunk-Z5GEFMRW.js';
32
32
 
33
33
  createRequire(import.meta.url);
@@ -1,9 +1,9 @@
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-ZTY7HHYB.js';
4
- import './chunk-HXAEQPZR.js';
3
+ export { BRIDGE_ADDRESS, BRIDGE_CIDR, CONTAINER_NO_PROXY, CONTAINER_PROXY, TUNNEL_PORT, dockerClientConfig, startBridgeForward, writeDockerClientConfig } from './chunk-RXFKXZJS.js';
4
+ import './chunk-N5EEEKT6.js';
5
5
  import './chunk-XD4ZCMA4.js';
6
- import './chunk-JGD5TWQ2.js';
6
+ import './chunk-MESOOLF4.js';
7
7
  import './chunk-Z5GEFMRW.js';
8
8
 
9
9
  createRequire(import.meta.url);
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- export { buildRepositoryImage } from './chunk-T2QSWFSU.js';
4
- import './chunk-NUHZV3A4.js';
3
+ export { buildRepositoryImage } from './chunk-TCBVV2JK.js';
4
+ import './chunk-M6NNXKRM.js';
5
5
  import './chunk-JBJTC3UU.js';
6
6
  export { RecipeError } from './chunk-SJZL5F3F.js';
7
- import './chunk-5K3KB4YR.js';
8
- import './chunk-HXAEQPZR.js';
7
+ import './chunk-DWVAG73B.js';
8
+ import './chunk-N5EEEKT6.js';
9
9
  import './chunk-XD4ZCMA4.js';
10
- import './chunk-JGD5TWQ2.js';
10
+ import './chunk-MESOOLF4.js';
11
11
  import './chunk-Z5GEFMRW.js';
12
12
 
13
13
  createRequire(import.meta.url);
@@ -1 +1 @@
1
- {"id":"2026-10-17T13:49:00.892Z+55dd868","root":"/home/runner/_work/outerlayer/outerlayer","pkg":"outerlayer"}
1
+ {"id":"2026-10-17T16:34:27.736Z+686145e","root":"/home/runner/_work/outerlayer/outerlayer","pkg":"outerlayer"}
@@ -1,15 +1,15 @@
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-VC5J7QPV.js';
3
+ export { MIN_BUILDX_VERSION, builderName, builderSpec, buildxState, ensureBuilder, ensureFailureCount, isOutOfMemory, proxyEnvironment, trackImageBuild } from './chunk-MFI55TNI.js';
4
4
  import './chunk-YJLHUKYS.js';
5
5
  import './chunk-SJZL5F3F.js';
6
6
  import './chunk-UHU7H57K.js';
7
- import './chunk-YL2VDSNF.js';
8
- import './chunk-5K3KB4YR.js';
9
- import './chunk-HXAEQPZR.js';
7
+ import './chunk-R7TMTFJP.js';
8
+ import './chunk-DWVAG73B.js';
9
+ import './chunk-N5EEEKT6.js';
10
10
  import './chunk-QZBXLLTV.js';
11
11
  import './chunk-XD4ZCMA4.js';
12
- import './chunk-JGD5TWQ2.js';
12
+ import './chunk-MESOOLF4.js';
13
13
  import './chunk-Z5GEFMRW.js';
14
14
 
15
15
  createRequire(import.meta.url);
@@ -1,59 +1,59 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { probeCredentials } from './chunk-7UGFIWIW.js';
4
- import './chunk-KVDVNOUK.js';
3
+ import { probeCredentials } from './chunk-LRFU6RPD.js';
4
+ import './chunk-ILU6664L.js';
5
5
  import './chunk-3JVYMD4G.js';
6
6
  import './chunk-E7R2GIAW.js';
7
7
  import './chunk-TPKYTORP.js';
8
- import './chunk-IVX3U7KV.js';
8
+ import './chunk-HWOU2HDH.js';
9
9
  import './chunk-ZVB57WI6.js';
10
- import './chunk-66T6XJAB.js';
11
- import './chunk-N7WAEEIU.js';
12
- import './chunk-QWAYRAUX.js';
13
- import './chunk-2YSCKEL2.js';
14
- import './chunk-TVZAC2NP.js';
10
+ import './chunk-QBF462QH.js';
11
+ import './chunk-OO6OADZN.js';
12
+ import './chunk-YTR435DO.js';
13
+ import './chunk-2BZTGJII.js';
14
+ import './chunk-VM6BX2WJ.js';
15
15
  import './chunk-ESVW4MJY.js';
16
- import './chunk-ZTY7HHYB.js';
17
- import { placeholderQueues, placeholderProblem, permissionModeProblems, permissionModeProblem, needsClaudeCredential, claudeCredentialCheck, claimPermissionProblem, formerSkillQueues, formerSkillProblem } from './chunk-W3FSGH2M.js';
16
+ import './chunk-RXFKXZJS.js';
17
+ import { placeholderQueues, placeholderProblem, permissionModeProblems, permissionModeProblem, needsClaudeCredential, claudeCredentialCheck, claimPermissionProblem, formerSkillQueues, formerSkillProblem } from './chunk-SVODOMYC.js';
18
18
  import './chunk-YYYRBYWG.js';
19
- import './chunk-GUXWQIEY.js';
19
+ import './chunk-6NFXOQKZ.js';
20
20
  import './chunk-TBT347UY.js';
21
- import './chunk-R7SS5RLJ.js';
22
- import './chunk-T57XUI6N.js';
23
- import './chunk-IKXY47R5.js';
24
- import './chunk-MHAR6S7B.js';
25
- import './chunk-WWQVKFN6.js';
26
- import './chunk-USJZ2LDK.js';
27
- import './chunk-Z3ASAXVU.js';
21
+ import './chunk-T7LJ6AIC.js';
22
+ import './chunk-EPGMCEVP.js';
23
+ import './chunk-4SJ57DH7.js';
24
+ import './chunk-WL3QF3QF.js';
25
+ import './chunk-DIQN5SEL.js';
26
+ import './chunk-JZJLKTZT.js';
27
+ import './chunk-O47BTZSN.js';
28
28
  import './chunk-TQMI335S.js';
29
- import './chunk-F4FA3ZUT.js';
30
- import './chunk-MQHTM4YJ.js';
31
- import { loadRunnerConfig, RunnerConfigError, checkHooks } from './chunk-55XLX5PA.js';
29
+ import './chunk-AV5MJY45.js';
30
+ import './chunk-JYVBEWBC.js';
31
+ import { loadRunnerConfig, RunnerConfigError, checkHooks } from './chunk-YYGXCRIW.js';
32
32
  import './chunk-UXYLWVTQ.js';
33
- import './chunk-T2QSWFSU.js';
34
- import './chunk-NUHZV3A4.js';
33
+ import './chunk-TCBVV2JK.js';
34
+ import './chunk-M6NNXKRM.js';
35
35
  import './chunk-JBJTC3UU.js';
36
36
  import './chunk-OGFGZQA3.js';
37
- import './chunk-VC5J7QPV.js';
37
+ import './chunk-MFI55TNI.js';
38
38
  import './chunk-YJLHUKYS.js';
39
39
  import './chunk-SJZL5F3F.js';
40
- import './chunk-X52PMPOM.js';
41
- import './chunk-LNIFYSNK.js';
42
- import './chunk-VU7ZJPIR.js';
40
+ import './chunk-X7SFJZIG.js';
41
+ import './chunk-NMIYK2G2.js';
42
+ import './chunk-QFNFBQCG.js';
43
43
  import './chunk-BUP5N3X6.js';
44
44
  import './chunk-UHU7H57K.js';
45
45
  import './chunk-5B7BEQPR.js';
46
46
  import './chunk-HOU33DW5.js';
47
47
  import './chunk-G2JWZDFA.js';
48
48
  import './chunk-ANPNT6PM.js';
49
- import './chunk-4XN5FRRJ.js';
49
+ import './chunk-TG7FAHRP.js';
50
50
  import './chunk-P2RWZCV7.js';
51
- import './chunk-7CK2TJFB.js';
51
+ import './chunk-KJIUFOC4.js';
52
52
  import './chunk-PJDQPF5N.js';
53
- import './chunk-YL2VDSNF.js';
54
- import './chunk-5K3KB4YR.js';
55
- import { claudeEnvPath } from './chunk-HXAEQPZR.js';
56
- import './chunk-DKWQMPSL.js';
53
+ import './chunk-R7TMTFJP.js';
54
+ import './chunk-DWVAG73B.js';
55
+ import { claudeEnvPath } from './chunk-N5EEEKT6.js';
56
+ import './chunk-OOUHNKKX.js';
57
57
  import './chunk-ZJSNLVCE.js';
58
58
  import './chunk-2O5KA67H.js';
59
59
  import './chunk-BKO6JEZI.js';
@@ -74,7 +74,7 @@ import './chunk-RKOTJQVG.js';
74
74
  import './chunk-QZBXLLTV.js';
75
75
  import './chunk-VNVZDWO3.js';
76
76
  import { parseRunnerEnv } from './chunk-XD4ZCMA4.js';
77
- import './chunk-JGD5TWQ2.js';
77
+ import './chunk-MESOOLF4.js';
78
78
  import './chunk-Z5GEFMRW.js';
79
79
  import { readFileSync } from 'fs';
80
80
  import { join, dirname } from 'path';
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { uploadSpooledSteps } from './chunk-TVZAC2NP.js';
3
+ import { uploadSpooledSteps } from './chunk-VM6BX2WJ.js';
4
4
  import { LaunchFilter } from './chunk-ESVW4MJY.js';
5
5
  import { RepoFilter } from './chunk-TBT347UY.js';
6
6
  import { migrateLegacyArtifactSidecars, planArtifactUpload, artifactsStatePath, sanitizeTerminal, acquireArtifactSpoolLock, artifactBlobsDir, resolveArtifactTurnIndex, isArtifactTombstoned, ARTIFACT_RETRY_MAX_AGE_MS, writeArtifactSpoolState, reclaimUnneededArtifactBlobs, neededArtifactShas } from './chunk-BUP5N3X6.js';
7
7
  import { setCustomScrubbers, setLocalIdentity, tailTranscript, enrichSessionRepo, scanAll, setRepoRoot, resolveRepoIdentity, sessionIdFromPath, scrubDeep, SOURCE_ADAPTERS } from './chunk-UHU7H57K.js';
8
8
  import { C } from './chunk-ANPNT6PM.js';
9
- import { cliFetch, resolveGatewayCredentials, defaultFetch, unauthorizedMessage } from './chunk-7CK2TJFB.js';
9
+ import { cliFetch, resolveGatewayCredentials, defaultFetch, unauthorizedMessage } from './chunk-KJIUFOC4.js';
10
10
  import { readCloudConfig, cloudConfigPath, writeCloudConfig } from './chunk-PJDQPF5N.js';
11
- import { signerFor, signRunnerRequest } from './chunk-YL2VDSNF.js';
12
- import { writeSyncStatus, spoolDir } from './chunk-DKWQMPSL.js';
11
+ import { signerFor, signRunnerRequest } from './chunk-R7TMTFJP.js';
12
+ import { writeSyncStatus, spoolDir } from './chunk-OOUHNKKX.js';
13
13
  import { readLatestProvenanceForSession, readContextProvenance } from './chunk-ZJSNLVCE.js';
14
14
  import { hookExecSpoolPath } from './chunk-2O5KA67H.js';
15
15
  import { applyReportedCost } from './chunk-BKO6JEZI.js';
@@ -19,7 +19,7 @@ import { cliInvocation } from './chunk-CRB3POP4.js';
19
19
  import { removeJournalHooks } from './chunk-TUSYOL2O.js';
20
20
  import { CAPTURE_TIERS, inferArtifactKind, bannedPathsForTier, downconvertSession, isHumanUserTurn, turnCountBound, EVENT_TYPES } from './chunk-QZBXLLTV.js';
21
21
  import { homeFromEnv } from './chunk-VNVZDWO3.js';
22
- import { dirname, basename, join } from 'path';
22
+ import { dirname, basename, join, sep } from 'path';
23
23
  import { statSync, readFileSync, readdirSync, mkdirSync, writeFileSync, renameSync, existsSync, rmSync } from 'fs';
24
24
  import { execFileSync } from 'child_process';
25
25
  import { hostname, userInfo } from 'os';
@@ -834,6 +834,49 @@ var LiveUploader = class {
834
834
  }
835
835
  }
836
836
  };
837
+ var NOTICE = /<task-id>(?:\s|\\n)*([\w-]+)(?:\s|\\n)*<\/task-id>(?:(?!<task-notification>)[\s\S])*?<status>(?:\s|\\n)*(completed|failed|killed|stopped|cancelled|canceled|error)(?:\s|\\n)*<\/status>/gi;
838
+ var cache = /* @__PURE__ */ new Map();
839
+ function parentTranscriptOf(subagentFile) {
840
+ const segments = subagentFile.split(sep);
841
+ const at = segments.lastIndexOf("subagents");
842
+ if (at < 2) return void 0;
843
+ return join(segments.slice(0, at - 1).join(sep), `${segments[at - 1]}.jsonl`);
844
+ }
845
+ function endNotices(text) {
846
+ const endedAt = /* @__PURE__ */ new Map();
847
+ for (const raw of text.split("\n")) {
848
+ if (!raw.includes("<task-notification>")) continue;
849
+ let line;
850
+ try {
851
+ line = JSON.parse(raw);
852
+ } catch {
853
+ continue;
854
+ }
855
+ if (line.type !== "user" || typeof line.timestamp !== "string") continue;
856
+ for (const [, id] of raw.matchAll(NOTICE)) endedAt.set(id, [...endedAt.get(id) ?? [], line.timestamp]);
857
+ }
858
+ return endedAt;
859
+ }
860
+ function noticesIn(parentFile) {
861
+ try {
862
+ const { size, mtimeMs } = statSync(parentFile);
863
+ const key = `${parentFile}\0${size}\0${mtimeMs}`;
864
+ const known = cache.get(key) ?? endNotices(readFileSync(parentFile, "utf8"));
865
+ cache.set(key, known);
866
+ return known;
867
+ } catch {
868
+ return /* @__PURE__ */ new Map();
869
+ }
870
+ }
871
+ function subagentEndedInParent(subagentFile, lastActivityAt) {
872
+ const parent = parentTranscriptOf(subagentFile);
873
+ if (parent === void 0) return false;
874
+ const notices = noticesIn(parent).get(basename(subagentFile, ".jsonl").replace(/^agent-/, "")) ?? [];
875
+ return notices.some((at) => lastActivityAt === void 0 || Date.parse(at) >= Date.parse(lastActivityAt));
876
+ }
877
+ function runningForParent(entry, lastActivityAt) {
878
+ return !entry.isSubagent || !subagentEndedInParent(entry.file, lastActivityAt);
879
+ }
837
880
 
838
881
  // src/skip-verdict.ts
839
882
  var RESUME_WINDOW_MS = 14 * 24 * 60 * 60 * 1e3;
@@ -1206,7 +1249,7 @@ async function runSyncInner(opts, stats) {
1206
1249
  applyContextProvenance(session, contextSourceBySessionId.get(session.id));
1207
1250
  applyReportedCost(session, home);
1208
1251
  const gated = prepareSessionForUpload(session, tier, envVars);
1209
- const liveEntry = liveUploads[gated.id];
1252
+ const liveEntry = runningForParent(entry, gated.endedAt) ? liveUploads[gated.id] : void 0;
1210
1253
  const daemonIsStreaming = liveEntry !== void 0 && !liveEntry.ended && !liveEntry.failed;
1211
1254
  if (daemonIsStreaming && !sessionHasEnded(home, gated.subagent?.parentSessionId ?? gated.id)) {
1212
1255
  const gatedTurns = gated.turns ?? [];
@@ -1,26 +1,26 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { execCapture } from './chunk-MHAR6S7B.js';
4
- import { GUEST_CID } from './chunk-WWQVKFN6.js';
5
- import { keepStagedContext, describeCallFailure, controlPlaneTokenFailure, refusalCode, resolveGoverningSource, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, shimScript } from './chunk-USJZ2LDK.js';
6
- import { runnerImageVersion } from './chunk-Z3ASAXVU.js';
3
+ import { execCapture } from './chunk-WL3QF3QF.js';
4
+ import { GUEST_CID } from './chunk-DIQN5SEL.js';
5
+ import { keepStagedContext, describeCallFailure, controlPlaneTokenFailure, refusalCode, resolveGoverningSource, removeStagedContext, stageGovernedContext, pinnedSourceOf, commandWithShim, shimScript } from './chunk-JZJLKTZT.js';
6
+ import { runnerImageVersion } from './chunk-O47BTZSN.js';
7
7
  import { hostAllowed } from './chunk-UXYLWVTQ.js';
8
- import { readDefaultBranchHead, cloneRepository, buildRepositoryImage } from './chunk-T2QSWFSU.js';
8
+ import { readDefaultBranchHead, cloneRepository, buildRepositoryImage } from './chunk-TCBVV2JK.js';
9
9
  import { startTimeOf, isSameProcess } from './chunk-JBJTC3UU.js';
10
10
  import { currentCliBuild } from './chunk-OGFGZQA3.js';
11
- 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-VC5J7QPV.js';
11
+ 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-MFI55TNI.js';
12
12
  import { readDu } from './chunk-YJLHUKYS.js';
13
13
  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-SJZL5F3F.js';
14
- import { WorkCommandError } from './chunk-X52PMPOM.js';
14
+ import { WorkCommandError } from './chunk-X7SFJZIG.js';
15
15
  import { setCustomScrubbers, setLocalIdentity, setRepoRoot, parseTranscript, scrubDeep, scrubText } from './chunk-UHU7H57K.js';
16
- import { vmAssetsDir, RUNNER_DIR_MODE, rootfsPathFor, diskTemplatesDir, RUNNER_FILE_MODE, deliveryDir, ghConfigDir, runnerDirOfBuild, spoolDir, mirrorDir, buildDir, SHIM_DIR } from './chunk-5K3KB4YR.js';
17
- import { repositoriesOf, primaryOf, RELAY_PORT, repositoryPath, CHECKOUT_DIR, lifecycleWorkdir, claudeCredential, buildEnvironment, startBuildServices, checkEnvironment, AGENT_CREDENTIAL_MISSING, checkoutPath, JOB_MOUNT } from './chunk-HXAEQPZR.js';
16
+ import { vmAssetsDir, RUNNER_DIR_MODE, rootfsPathFor, diskTemplatesDir, RUNNER_FILE_MODE, deliveryDir, ghConfigDir, runnerDirOfBuild, spoolDir, mirrorDir, buildDir, SHIM_DIR } from './chunk-DWVAG73B.js';
17
+ import { repositoriesOf, primaryOf, RELAY_PORT, repositoryPath, CHECKOUT_DIR, lifecycleWorkdir, claudeCredential, buildEnvironment, startBuildServices, checkEnvironment, AGENT_CREDENTIAL_MISSING, checkoutPath, JOB_MOUNT } from './chunk-N5EEEKT6.js';
18
18
  import { sharedSkillNames, skillConflictMessage } from './chunk-FGF52V4V.js';
19
19
  import { versionAtLeast, MINIMUM_CLAUDE_VERSION } from './chunk-HCVLP7XA.js';
20
20
  import { orderSessions, extractFacts, sessionsToTimeline } from './chunk-RKOTJQVG.js';
21
21
  import { downconvertSession } from './chunk-QZBXLLTV.js';
22
22
  import { realFdStorePort } from './chunk-XD4ZCMA4.js';
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
+ import { RELAY_USER, RELAY_ID, UNKNOWN_TRANSPORT_REASON, DOCKER_DESKTOP_REASON, MAX_MALFORMED_SESSIONS, MALFORMED_REASON, MAX_OPEN_STREAMS, STREAM_RESET_RATE, STREAM_RESET_BURST, STREAM_WINDOW, SESSION_WINDOW, targetOfPath } from './chunk-MESOOLF4.js';
24
24
  import { readFileSync, mkdirSync, existsSync, mkdtempSync, rmSync, chmodSync, truncateSync, writeFileSync, readdirSync, lstatSync, copyFileSync, accessSync, constants, statSync, rmdirSync, renameSync, unlinkSync, openSync, closeSync, createWriteStream, createReadStream, writeSync } from 'fs';
25
25
  import { join, dirname, resolve, basename } from 'path';
26
26
  import { isIP, createConnection, connect, createServer as createServer$1 } from 'net';
@@ -1363,6 +1363,29 @@ async function resolveAgentUser(input) {
1363
1363
  var noop = () => void 0;
1364
1364
  var FRAME_HEADER_BYTES = 9;
1365
1365
  var GOAWAY_FRAME = 7;
1366
+ function describeGoawayCode(code) {
1367
+ const names = [
1368
+ "NO_ERROR",
1369
+ "PROTOCOL_ERROR",
1370
+ "INTERNAL_ERROR",
1371
+ "FLOW_CONTROL_ERROR",
1372
+ "SETTINGS_TIMEOUT",
1373
+ "STREAM_CLOSED",
1374
+ "FRAME_SIZE_ERROR",
1375
+ "REFUSED_STREAM",
1376
+ "CANCEL",
1377
+ "COMPRESSION_ERROR",
1378
+ "CONNECT_ERROR",
1379
+ "ENHANCE_YOUR_CALM",
1380
+ "INADEQUATE_SECURITY",
1381
+ "HTTP_1_1_REQUIRED"
1382
+ ];
1383
+ const name = names[code];
1384
+ return name === void 0 ? `error code ${code}` : `${name} (${code})`;
1385
+ }
1386
+ function goawayNote(label, code) {
1387
+ return code === void 0 ? "" : ` \xB7 ${label} ${describeGoawayCode(code)}`;
1388
+ }
1366
1389
  function watchSentGoaway(onError) {
1367
1390
  let head = Buffer.alloc(0);
1368
1391
  let want = FRAME_HEADER_BYTES;
@@ -1385,7 +1408,10 @@ function watchSentGoaway(onError) {
1385
1408
  want = FRAME_HEADER_BYTES + 8;
1386
1409
  continue;
1387
1410
  }
1388
- if (want > FRAME_HEADER_BYTES && head.readUInt32BE(FRAME_HEADER_BYTES + 4) !== http2.constants.NGHTTP2_NO_ERROR) onError();
1411
+ if (want > FRAME_HEADER_BYTES) {
1412
+ const code = head.readUInt32BE(FRAME_HEADER_BYTES + 4);
1413
+ if (code !== http2.constants.NGHTTP2_NO_ERROR) onError(code);
1414
+ }
1389
1415
  skip = length - (want - FRAME_HEADER_BYTES);
1390
1416
  head = Buffer.alloc(0);
1391
1417
  want = FRAME_HEADER_BYTES;
@@ -1397,9 +1423,11 @@ function serveSession(transport, services, opts = {}) {
1397
1423
  let open = 0;
1398
1424
  let served = 0;
1399
1425
  let malformed = false;
1426
+ let goawayCode;
1400
1427
  transport.on("error", noop);
1401
- const watch = watchSentGoaway(() => {
1428
+ const watch = watchSentGoaway((code) => {
1402
1429
  malformed = true;
1430
+ goawayCode ??= code;
1403
1431
  setImmediate(() => session.destroy());
1404
1432
  });
1405
1433
  const outbound = new Transform({
@@ -1412,7 +1440,11 @@ function serveSession(transport, services, opts = {}) {
1412
1440
  outbound.pipe(transport);
1413
1441
  const wire = Duplex.from({ readable: transport, writable: outbound });
1414
1442
  wire.on("error", noop);
1415
- const session = http2.performServerHandshake(wire, { settings: { initialWindowSize: STREAM_WINDOW, enablePush: false } });
1443
+ const session = http2.performServerHandshake(wire, {
1444
+ settings: { initialWindowSize: STREAM_WINDOW, enablePush: false },
1445
+ streamResetBurst: STREAM_RESET_BURST,
1446
+ streamResetRate: STREAM_RESET_RATE
1447
+ });
1416
1448
  try {
1417
1449
  session.setLocalWindowSize(SESSION_WINDOW);
1418
1450
  } catch {
@@ -1421,7 +1453,10 @@ function serveSession(transport, services, opts = {}) {
1421
1453
  session.on("error", (err) => {
1422
1454
  if (typeof err.code === "string" && err.code.startsWith("ERR_HTTP2_")) malformed = true;
1423
1455
  });
1424
- session.on("close", () => resolve2({ malformed, served }));
1456
+ session.on("goaway", (code) => {
1457
+ if (code !== http2.constants.NGHTTP2_NO_ERROR) goawayCode ??= code;
1458
+ });
1459
+ session.on("close", () => resolve2({ malformed, served, goawayCode }));
1425
1460
  });
1426
1461
  session.on("stream", (stream, headers) => {
1427
1462
  stream.on("error", noop);
@@ -1495,14 +1530,14 @@ function superviseRelay(input) {
1495
1530
  if (joined) {
1496
1531
  backoff = FIRST_BACKOFF_MS;
1497
1532
  failing = false;
1498
- if (!closed) input.log?.(`the session with ${input.container} ended \xB7 joining again`);
1533
+ if (!closed) input.log?.(`the session with ${input.container} ended \xB7 joining again${goawayNote("GOAWAY", end.goawayCode)}`);
1499
1534
  }
1500
1535
  if (!end.malformed && end.served > 0) malformedInARow = 0;
1501
1536
  if (end.malformed) {
1502
1537
  malformedInARow++;
1503
1538
  if (malformedInARow >= MAX_MALFORMED_SESSIONS) {
1504
1539
  fatal = MALFORMED_REASON;
1505
- input.log?.(`the session with ${input.container} broke HTTP/2 framing ${malformedInARow} times in a row \xB7 ending the build`);
1540
+ input.log?.(`the session with ${input.container} broke HTTP/2 framing ${malformedInARow} times in a row${goawayNote("last GOAWAY", end.goawayCode)} \xB7 ending the build`);
1506
1541
  input.onFatal?.(fatal);
1507
1542
  return;
1508
1543
  }
@@ -2279,6 +2314,9 @@ var CONNECT_TIMEOUT_MS = 3e4;
2279
2314
  var NOT_ALLOWED_RANGE = "not-allowed";
2280
2315
  var NOT_RESOLVED = "not resolved";
2281
2316
  var IDLE_TIMEOUT_MS = 10 * 6e4;
2317
+ var STALLED_RESPONSE_MS = 6e4;
2318
+ var MAX_BAD_GATEWAY_LINES = 10;
2319
+ var BAD_GATEWAY_WINDOW_MS = 1e4;
2282
2320
  async function systemResolve(host) {
2283
2321
  const found = await lookup(host, { all: true, verbatim: true });
2284
2322
  return found.map((a) => ({ address: a.address }));
@@ -2286,6 +2324,13 @@ async function systemResolve(host) {
2286
2324
  function systemHostAddresses() {
2287
2325
  return Object.values(networkInterfaces()).flatMap((list) => (list ?? []).map((i) => i.address));
2288
2326
  }
2327
+ function errorCode(err) {
2328
+ const code = err?.code;
2329
+ return typeof code === "string" ? code : "unknown";
2330
+ }
2331
+ function abortedError(message) {
2332
+ return Object.assign(new Error(message), { code: "ECONNABORTED" });
2333
+ }
2289
2334
  function normalize(address) {
2290
2335
  const zone = address.indexOf("%");
2291
2336
  return (zone === -1 ? address : address.slice(0, zone)).toLowerCase();
@@ -2305,6 +2350,26 @@ async function startTunnel(socketPath, opts = {}) {
2305
2350
  const ownAddresses = opts.hostAddresses ?? systemHostAddresses;
2306
2351
  const connectTimeoutMs = opts.connectTimeoutMs ?? CONNECT_TIMEOUT_MS;
2307
2352
  const idleTimeoutMs = opts.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
2353
+ const stalledResponseMs = opts.stalledResponseMs ?? STALLED_RESPONSE_MS;
2354
+ let windowStartedMs = 0;
2355
+ let linesInWindow = 0;
2356
+ let suppressed = 0;
2357
+ const logBadGateway = (what) => {
2358
+ if (opts.log === void 0) return;
2359
+ const now = Date.now();
2360
+ if (now - windowStartedMs >= BAD_GATEWAY_WINDOW_MS) {
2361
+ windowStartedMs = now;
2362
+ linesInWindow = 0;
2363
+ }
2364
+ if (linesInWindow >= MAX_BAD_GATEWAY_LINES) {
2365
+ suppressed++;
2366
+ return;
2367
+ }
2368
+ linesInWindow++;
2369
+ const more = suppressed === 0 ? "" : ` (${suppressed} more 502 lines were not written)`;
2370
+ suppressed = 0;
2371
+ opts.log(`tunnel answered 502: ${what}${more}`);
2372
+ };
2308
2373
  const hosts = [];
2309
2374
  const seen = /* @__PURE__ */ new Set();
2310
2375
  const extraHosts = /* @__PURE__ */ new Set();
@@ -2376,7 +2441,7 @@ async function startTunnel(socketPath, opts = {}) {
2376
2441
  }
2377
2442
  persist();
2378
2443
  };
2379
- async function decide(host) {
2444
+ async function decide(host, port) {
2380
2445
  if (opts.allowHosts !== void 0 && !hostAllowed(host, opts.allowHosts)) {
2381
2446
  refused2(host, NOT_RESOLVED, NOT_ALLOWED_RANGE);
2382
2447
  return { ok: false, status: 403, body: `refused: ${host} is not in runner.build.allowHosts
@@ -2385,12 +2450,16 @@ async function startTunnel(socketPath, opts = {}) {
2385
2450
  let addresses;
2386
2451
  try {
2387
2452
  addresses = await resolve2(host);
2388
- } catch {
2453
+ } catch (err) {
2454
+ logBadGateway(`could not resolve ${host}:${port}, ${errorCode(err)}`);
2389
2455
  return { ok: false, status: 502, body: `could not resolve ${host}
2390
2456
  ` };
2391
2457
  }
2392
- if (addresses.length === 0) return { ok: false, status: 502, body: `${host} has no address
2458
+ if (addresses.length === 0) {
2459
+ logBadGateway(`${host}:${port} resolved to no address`);
2460
+ return { ok: false, status: 502, body: `${host} has no address
2393
2461
  ` };
2462
+ }
2394
2463
  const own = new Set(ownAddresses().map(normalize));
2395
2464
  let firstRefusal;
2396
2465
  for (const { address: address2 } of addresses) {
@@ -2432,36 +2501,70 @@ ${body}`);
2432
2501
  client.end("HTTP/1.1 400 Bad Request\r\nConnection: close\r\nContent-Length: 0\r\n\r\n");
2433
2502
  return;
2434
2503
  }
2435
- const decision = await decide(target.host);
2504
+ const decision = await decide(target.host, target.port);
2436
2505
  if (!decision.ok) {
2437
2506
  reply(client, decision.status, decision.body);
2438
2507
  return;
2439
2508
  }
2440
2509
  const upstream = openConnection({ address: decision.address, port: target.port });
2441
2510
  upstream.setTimeout(connectTimeoutMs);
2442
- const failed = () => {
2511
+ const failed = (err) => {
2443
2512
  upstream.destroy();
2513
+ logBadGateway(`could not connect to ${target.host}:${target.port}, ${err === void 0 ? "ETIMEDOUT" : errorCode(err)}`);
2444
2514
  reply(client, 502, `could not connect to ${target.host}
2445
2515
  `);
2446
2516
  };
2517
+ const timedOut = () => failed();
2447
2518
  upstream.once("error", failed);
2448
- upstream.once("timeout", failed);
2519
+ upstream.once("timeout", timedOut);
2449
2520
  client.on("close", () => upstream.destroy());
2450
2521
  const established = () => {
2451
2522
  upstream.removeListener("error", failed);
2452
- upstream.removeListener("timeout", failed);
2523
+ upstream.removeListener("timeout", timedOut);
2453
2524
  upstream.setTimeout(idleTimeoutMs, () => upstream.destroy());
2454
- upstream.on("error", () => void 0);
2455
- upstream.on("close", () => client.destroy());
2525
+ upstream.on("error", (err) => client.destroy(err));
2526
+ upstream.on("close", () => {
2527
+ if (!upstream.readableEnded && !client.writableEnded) client.destroy(abortedError("the tunnel closed the connection to the server before it ended"));
2528
+ });
2529
+ client.once("end", () => {
2530
+ upstream.destroy();
2531
+ client.end();
2532
+ });
2456
2533
  reached(target.host);
2457
2534
  client.write("HTTP/1.1 200 Connection Established\r\n\r\n");
2458
2535
  upstream.write(head);
2536
+ releaseWhenStalled(client, upstream);
2459
2537
  upstream.pipe(client);
2460
2538
  client.pipe(upstream);
2461
2539
  };
2462
2540
  if (upstream.readyState === "open") established();
2463
2541
  else upstream.once("connect", established);
2464
2542
  }
2543
+ function releaseWhenStalled(client, upstream) {
2544
+ let delivered = 0;
2545
+ upstream.on("data", (chunk) => delivered += chunk.length);
2546
+ let read = delivered;
2547
+ let timer;
2548
+ const blocked = () => upstream.isPaused() || upstream.readableEnded;
2549
+ const check = () => {
2550
+ timer = void 0;
2551
+ if (client.writableFinished || !blocked()) return;
2552
+ if (delivered > read) {
2553
+ read = delivered;
2554
+ timer = setTimeout(check, stalledResponseMs);
2555
+ return;
2556
+ }
2557
+ client.destroy(abortedError("the build stopped reading the response"));
2558
+ };
2559
+ const watch = () => {
2560
+ if (timer !== void 0) return;
2561
+ read = delivered;
2562
+ timer = setTimeout(check, stalledResponseMs);
2563
+ };
2564
+ upstream.on("pause", watch);
2565
+ upstream.on("end", watch);
2566
+ client.once("close", () => clearTimeout(timer));
2567
+ }
2465
2568
  async function proxyPlain(req, res) {
2466
2569
  if (opts.gitRemote !== void 0 && (req.url ?? "").startsWith("/")) {
2467
2570
  await opts.gitRemote(req, res);
@@ -2482,7 +2585,7 @@ ${body}`);
2482
2585
  }
2483
2586
  const host = url.hostname.replace(/^\[|\]$/g, "");
2484
2587
  const port = url.port === "" ? 80 : Number(url.port);
2485
- const decision = await decide(host);
2588
+ const decision = await decide(host, port);
2486
2589
  if (!decision.ok) {
2487
2590
  res.writeHead(decision.status, { "Content-Type": "text/plain", Connection: "close" });
2488
2591
  res.end(decision.body);
@@ -2507,8 +2610,9 @@ ${body}`);
2507
2610
  );
2508
2611
  upstream.setTimeout(connectTimeoutMs, () => upstream.destroy());
2509
2612
  res.on("close", () => upstream.destroy());
2510
- upstream.on("error", () => {
2613
+ upstream.on("error", (err) => {
2511
2614
  if (!res.headersSent) {
2615
+ logBadGateway(`could not reach ${host}:${port}, ${errorCode(err)}`);
2512
2616
  res.writeHead(502, { "Content-Type": "text/plain", Connection: "close" });
2513
2617
  res.end(`could not reach ${host}
2514
2618
  `);
@@ -2561,6 +2665,9 @@ var RELAY_WAIT_MS = 500;
2561
2665
  var BUSY_IMAGE_WAIT_MS = 5e3;
2562
2666
  var VOLUME_REMOVE_ATTEMPTS = 4;
2563
2667
  var WORKFLOW_PERMISSION_REASON = "workflow_permission_required";
2668
+ function withTunnelLog(opts, log) {
2669
+ return { ...opts, tunnelOptions: { log, ...opts?.tunnelOptions } };
2670
+ }
2564
2671
  function createContainerRuntime(opts = {}) {
2565
2672
  const { cli, remoteFor } = opts;
2566
2673
  return {
@@ -3421,4 +3528,4 @@ async function startCheckContainer(input) {
3421
3528
  };
3422
3529
  }
3423
3530
 
3424
- export { ADDED_USER, AgentUserError, AssetError, DeliveryFailure, EVAL_INPUT_NAME, GH_CONFIG_YML, HelperRefusal, LEASE_SECONDS, MIN_ENGINE_MAJOR, cleanupContainer, containerCommandExec, containerJudgeEnvironment, containerSenderCommand, copyJudgeTree, copyTranscripts, copyTranscriptsFromContainer, createBuildDisk, createContainerRuntime, createLeaseChannel, deleteBuildDisk, deliverContainerHooks, ensureFirecrackerAndJailer, ensureRootfs, ensureTunnel, filesAreCopied, ghHostsYml, gitRemoteFor, helperFirecrackerNote, helperSocketPath, isLiteralAddress, keepGhConfigCurrent, leaseExpiresAtMs, leaseTimeLeftMs, lifecycleFailureReason, lifecycleSteps, machineConfig, measureDisk, obtainImage, outOfMemoryReason, parseCpuList, prepareBranch, probeHelper, provisionContainer, resolveAgentUser, runBuildSteps, senderAliveScript, senderSignalScript, setUpRunnerCgroup, shellQuote, signalInContainer, startCheckContainer, startServicesFor, stopContainer, syncInContainer, writeEvalInput };
3531
+ export { ADDED_USER, AgentUserError, AssetError, DeliveryFailure, EVAL_INPUT_NAME, GH_CONFIG_YML, HelperRefusal, LEASE_SECONDS, MIN_ENGINE_MAJOR, cleanupContainer, containerCommandExec, containerJudgeEnvironment, containerSenderCommand, copyJudgeTree, copyTranscripts, copyTranscriptsFromContainer, createBuildDisk, createContainerRuntime, createLeaseChannel, deleteBuildDisk, deliverContainerHooks, ensureFirecrackerAndJailer, ensureRootfs, ensureTunnel, filesAreCopied, ghHostsYml, gitRemoteFor, helperFirecrackerNote, helperSocketPath, isLiteralAddress, keepGhConfigCurrent, leaseExpiresAtMs, leaseTimeLeftMs, lifecycleFailureReason, lifecycleSteps, machineConfig, measureDisk, obtainImage, outOfMemoryReason, parseCpuList, prepareBranch, probeHelper, provisionContainer, resolveAgentUser, runBuildSteps, senderAliveScript, senderSignalScript, setUpRunnerCgroup, shellQuote, signalInContainer, startCheckContainer, startServicesFor, stopContainer, syncInContainer, withTunnelLog, writeEvalInput };
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-5K3KB4YR.js';
3
+ import { runnerDir, RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-DWVAG73B.js';
4
4
  import { readlinkSync, realpathSync, mkdirSync, unlinkSync, symlinkSync, renameSync, readFileSync, writeFileSync, rmSync, existsSync, readdirSync } from 'fs';
5
5
  import { join, basename, sep, resolve } from 'path';
6
6
 
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { DEFAULT_UNIT_NAME } from './chunk-MQHTM4YJ.js';
4
- import { RUNNER_FILE_MODE } from './chunk-5K3KB4YR.js';
5
- import { claudeEnvPath, withoutCredentialLines } from './chunk-HXAEQPZR.js';
3
+ import { DEFAULT_UNIT_NAME } from './chunk-JYVBEWBC.js';
4
+ import { RUNNER_FILE_MODE } from './chunk-DWVAG73B.js';
5
+ import { claudeEnvPath, withoutCredentialLines } from './chunk-N5EEEKT6.js';
6
6
  import { parseRunnerEnv } from './chunk-XD4ZCMA4.js';
7
7
  import { existsSync, readFileSync, writeFileSync, renameSync, rmSync } from 'fs';
8
8
  import { join, dirname } from 'path';