0sec-cli 0.21.4 → 0.22.1

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 (251) hide show
  1. package/0.js +56 -56
  2. package/README.md +48 -63
  3. package/chunks/{adapt-loop-IGBRQAXO.js → adapt-loop-J6QCZZTB.js} +4 -4
  4. package/chunks/{artifact-scraper-LNQJUORS.js → artifact-scraper-MFKT6OI4.js} +2 -2
  5. package/chunks/{assumption-mining-4MJTP6H5.js → assumption-mining-646LYSJY.js} +16 -16
  6. package/chunks/{chunk-Z3IKZX3X.js → chunk-23DG5YKS.js} +1 -1
  7. package/chunks/{chunk-2WSXFFJZ.js → chunk-3E2KALZ5.js} +2 -2
  8. package/chunks/{chunk-TF46UWFU.js → chunk-4G7OVYJX.js} +1 -1
  9. package/chunks/{chunk-E2UOY5PJ.js → chunk-5BTJMINS.js} +12 -70
  10. package/chunks/{chunk-QZVG3BG4.js → chunk-5IBCBQEH.js} +1 -2
  11. package/chunks/{chunk-YA4PUM4H.js → chunk-7XCKYNLO.js} +1 -1
  12. package/chunks/{chunk-BACXRTQ4.js → chunk-AV2LG2L7.js} +87 -767
  13. package/chunks/{chunk-IMGWPNQM.js → chunk-BCSRRQG5.js} +76 -593
  14. package/chunks/{chunk-NOPBXZUV.js → chunk-BOUGKEKA.js} +1 -1
  15. package/chunks/{chunk-RF5QGKLR.js → chunk-CPWA6RWE.js} +3 -3
  16. package/chunks/{chunk-P6YG6TEZ.js → chunk-DKSCN2AB.js} +1 -1
  17. package/chunks/{chunk-YPOA3W4O.js → chunk-GOEA3NW6.js} +877 -110
  18. package/chunks/{chunk-ANDKY54G.js → chunk-HHPWRY2M.js} +4019 -7299
  19. package/chunks/{chunk-NDJU5ZZ7.js → chunk-IFME676H.js} +3 -3
  20. package/chunks/{chunk-HBKCGJAV.js → chunk-IVQV574Y.js} +1 -1
  21. package/chunks/{chunk-W4JOXE4N.js → chunk-IXT64DV5.js} +709 -1929
  22. package/chunks/{chunk-PC6RCKQV.js → chunk-KAU6NLGP.js} +59 -26
  23. package/chunks/{chunk-FAH6V4QM.js → chunk-LGCASF2C.js} +1117 -2291
  24. package/chunks/{chunk-CAJJRUTV.js → chunk-NLH4LMWH.js} +1 -1
  25. package/chunks/chunk-OHHCGDJ2.js +5523 -0
  26. package/chunks/{chunk-YHWWF4QY.js → chunk-OSBPGWTE.js} +3 -3
  27. package/chunks/{chunk-G34QP2XW.js → chunk-TM74SSHC.js} +1 -1
  28. package/chunks/{chunk-VOAXLO4A.js → chunk-TO35Y326.js} +5 -721
  29. package/chunks/{chunk-FWAYJ2IV.js → chunk-TV27OWIW.js} +8 -8
  30. package/chunks/chunk-UELXHK2Y.js +1950 -0
  31. package/chunks/{chunk-CL5KAUM6.js → chunk-V6GHX34G.js} +274 -8
  32. package/chunks/{chunk-WZISK5VC.js → chunk-VWITLWXB.js} +53 -7
  33. package/chunks/{chunk-ER3SUMYJ.js → chunk-W6UWZFKL.js} +0 -195
  34. package/chunks/chunk-WSDDGFA6.js +114 -0
  35. package/chunks/{chunk-5T6D5BVY.js → chunk-WZRVS7SB.js} +1 -1
  36. package/chunks/chunk-X7LAEEUW.js +2143 -0
  37. package/chunks/chunk-XA2O4WXA.js +1228 -0
  38. package/chunks/{chunk-Y5H6E24H.js → chunk-XCISCI4T.js} +1 -1
  39. package/chunks/{chunk-WPQLBN4S.js → chunk-XDKB2P5X.js} +1 -1
  40. package/chunks/{chunk-SBMB4OL3.js → chunk-YL6YAGLL.js} +62 -8
  41. package/chunks/{chunk-O6SD4A36.js → chunk-ZKQ2I3S2.js} +1 -1
  42. package/chunks/{codex-models-TYYV4JNN.js → codex-models-NHQW45SO.js} +5 -3
  43. package/chunks/{commands-WF5RG4I2.js → commands-N6GN5SBF.js} +2152 -3643
  44. package/chunks/{db-U3WQZVAO.js → db-5IWEJUYV.js} +3 -3
  45. package/chunks/{disclose-67GZCDBO.js → disclose-LDNKAVRH.js} +10 -8
  46. package/chunks/{dist-ACC3DZUZ.js → dist-BS4CY4RG.js} +3 -1
  47. package/chunks/{dist-EVTN3UTT.js → dist-FSS7MBDF.js} +2 -2
  48. package/chunks/{dist-F6X62TQK.js → dist-L3XJWWZ6.js} +225 -192
  49. package/chunks/{eval-runner-SA6OUGHZ.js → eval-runner-EMEGF24P.js} +11 -11
  50. package/chunks/{exploit-agent-36Q7XQFP.js → exploit-agent-KW4EB7BE.js} +1 -1
  51. package/chunks/{exploit-autoclimb-J4OTSTZ6.js → exploit-autoclimb-CXJ2ERRO.js} +1 -1
  52. package/chunks/{exploit-climb-PYEJDIC4.js → exploit-climb-TJWLY4XC.js} +2 -2
  53. package/chunks/fix-UUKPXCFB.js +26 -0
  54. package/chunks/{harness-GDUMKGSE.js → harness-C5HOKIEV.js} +3 -3
  55. package/chunks/{hunt-scan-UDJSCISU.js → hunt-scan-KZZ444V2.js} +14 -14
  56. package/chunks/{identity-JTIVJSV7.js → identity-62SVRW4H.js} +1 -1
  57. package/chunks/{kernel-primitive-F2IXUFAX.js → kernel-primitive-Z77IR7YS.js} +2 -2
  58. package/chunks/{kernel-vm-runner-276LHIOV.js → kernel-vm-runner-JW77P276.js} +2 -2
  59. package/chunks/{memsafety-scan-NHUOGTEX.js → memsafety-scan-FCPAXIZE.js} +2 -2
  60. package/chunks/{native-loop-3BSYVDUI.js → native-loop-P6P5GYVJ.js} +10 -10
  61. package/chunks/{npm-detectors-VIYJXKFQ.js → npm-detectors-Z2ZIQCN4.js} +2 -2
  62. package/chunks/orchestrate-DWWUT5RC.js +58 -0
  63. package/chunks/{process-PNMC36JI.js → process-N245QIQG.js} +1 -4
  64. package/chunks/{run-CBGE6DRQ.js → run-GAFKBCTN.js} +14935 -17598
  65. package/chunks/{runtime-PXO5G6UV.js → runtime-H7YBR5IZ.js} +4 -5
  66. package/chunks/{scope-NJHIDDTN.js → scope-QWY4VQZ7.js} +4 -1
  67. package/chunks/{session-store-46WBZM22.js → session-store-XIDFGG7K.js} +2 -2
  68. package/chunks/{variant-candidates-UH2WC2HA.js → variant-candidates-7D4F5E4H.js} +3 -3
  69. package/chunks/{web-recon-prepass-SFXU44SS.js → web-recon-prepass-VXXBPDAV.js} +3 -3
  70. package/cli-path-traversal-fixture.js +352 -0
  71. package/dashboard/assets/bot-Bg1Tp9_d.js +1 -0
  72. package/dashboard/assets/dist-B_dDCPbu.js +1 -0
  73. package/dashboard/assets/findings-page-mayGhNx6.js +5 -0
  74. package/dashboard/assets/format--susmHX7.js +1 -0
  75. package/dashboard/assets/input-TuVPR3Zl.js +1 -0
  76. package/dashboard/assets/jsx-runtime-MGseXjj5.js +3 -0
  77. package/dashboard/assets/live-page-HWWHX99U.js +1 -0
  78. package/dashboard/assets/meta-tile-ckHo-w7k.js +1 -0
  79. package/dashboard/assets/operations-BxZ0OoXO.js +10 -0
  80. package/dashboard/assets/operations-app-D3d35rgo.js +46 -0
  81. package/dashboard/assets/overview-page-W_4IteEr.js +1 -0
  82. package/dashboard/assets/page-header-Bw9AJgBV.js +1 -0
  83. package/dashboard/assets/scans-page-CgzVXHnn.js +1 -0
  84. package/dashboard/assets/siren-KQj8QAnJ.js +1 -0
  85. package/dashboard/assets/table-8EDklulN.js +1 -0
  86. package/dashboard/assets/tabs-CFHPOwg8.js +1 -0
  87. package/dashboard/index.html +2 -3
  88. package/node_modules/node-addon-api/LICENSE.md +9 -0
  89. package/node_modules/node-addon-api/README.md +95 -0
  90. package/node_modules/node-addon-api/common.gypi +21 -0
  91. package/node_modules/node-addon-api/except.gypi +25 -0
  92. package/node_modules/node-addon-api/index.js +14 -0
  93. package/node_modules/node-addon-api/napi-inl.deprecated.h +186 -0
  94. package/node_modules/node-addon-api/napi-inl.h +7250 -0
  95. package/node_modules/node-addon-api/napi.h +3463 -0
  96. package/node_modules/node-addon-api/node_addon_api.gyp +42 -0
  97. package/node_modules/node-addon-api/node_api.gyp +9 -0
  98. package/node_modules/node-addon-api/noexcept.gypi +26 -0
  99. package/node_modules/node-addon-api/nothing.c +0 -0
  100. package/node_modules/node-addon-api/package-support.json +21 -0
  101. package/node_modules/node-addon-api/package.json +481 -0
  102. package/node_modules/node-addon-api/tools/README.md +73 -0
  103. package/node_modules/node-addon-api/tools/check-napi.js +99 -0
  104. package/node_modules/node-addon-api/tools/clang-format.js +71 -0
  105. package/node_modules/node-addon-api/tools/conversion.js +301 -0
  106. package/node_modules/node-gyp-build/LICENSE +21 -0
  107. package/node_modules/node-gyp-build/README.md +58 -0
  108. package/node_modules/node-gyp-build/SECURITY.md +5 -0
  109. package/node_modules/node-gyp-build/bin.js +84 -0
  110. package/node_modules/node-gyp-build/build-test.js +19 -0
  111. package/node_modules/node-gyp-build/index.js +6 -0
  112. package/node_modules/node-gyp-build/node-gyp-build.js +207 -0
  113. package/node_modules/node-gyp-build/optional.js +7 -0
  114. package/node_modules/node-gyp-build/package.json +43 -0
  115. package/node_modules/tree-sitter/LICENSE +21 -0
  116. package/node_modules/tree-sitter/README.md +90 -0
  117. package/node_modules/tree-sitter/binding.gyp +76 -0
  118. package/node_modules/tree-sitter/index.js +895 -0
  119. package/node_modules/tree-sitter/package.json +62 -0
  120. package/node_modules/tree-sitter/prebuilds/darwin-arm64/tree-sitter.node +0 -0
  121. package/node_modules/tree-sitter/prebuilds/darwin-x64/tree-sitter.node +0 -0
  122. package/node_modules/tree-sitter/prebuilds/linux-x64/tree-sitter.node +0 -0
  123. package/node_modules/tree-sitter/prebuilds/win32-x64/tree-sitter.node +0 -0
  124. package/node_modules/tree-sitter/src/addon_data.h +47 -0
  125. package/node_modules/tree-sitter/src/binding.cc +35 -0
  126. package/node_modules/tree-sitter/src/conversions.cc +140 -0
  127. package/node_modules/tree-sitter/src/conversions.h +22 -0
  128. package/node_modules/tree-sitter/src/language.cc +106 -0
  129. package/node_modules/tree-sitter/src/language.h +17 -0
  130. package/node_modules/tree-sitter/src/logger.cc +70 -0
  131. package/node_modules/tree-sitter/src/logger.h +19 -0
  132. package/node_modules/tree-sitter/src/lookaheaditerator.cc +122 -0
  133. package/node_modules/tree-sitter/src/lookaheaditerator.h +33 -0
  134. package/node_modules/tree-sitter/src/node.cc +1056 -0
  135. package/node_modules/tree-sitter/src/node.h +30 -0
  136. package/node_modules/tree-sitter/src/parser.cc +298 -0
  137. package/node_modules/tree-sitter/src/parser.h +35 -0
  138. package/node_modules/tree-sitter/src/query.cc +383 -0
  139. package/node_modules/tree-sitter/src/query.h +39 -0
  140. package/node_modules/tree-sitter/src/tree.cc +307 -0
  141. package/node_modules/tree-sitter/src/tree.h +45 -0
  142. package/node_modules/tree-sitter/src/tree_cursor.cc +213 -0
  143. package/node_modules/tree-sitter/src/tree_cursor.h +52 -0
  144. package/node_modules/tree-sitter/tree-sitter.d.ts +211 -0
  145. package/node_modules/tree-sitter/vendor/tree-sitter/LICENSE +21 -0
  146. package/node_modules/tree-sitter/vendor/tree-sitter/README.md +21 -0
  147. package/node_modules/tree-sitter/vendor/tree-sitter/lib/README.md +6 -0
  148. package/node_modules/tree-sitter/vendor/tree-sitter/lib/include/tree_sitter/api.h +1266 -0
  149. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.c +48 -0
  150. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.h +41 -0
  151. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/array.h +290 -0
  152. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/atomic.h +68 -0
  153. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/clock.h +146 -0
  154. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/error_costs.h +11 -0
  155. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.c +501 -0
  156. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.h +36 -0
  157. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/host.h +21 -0
  158. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.c +221 -0
  159. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.h +299 -0
  160. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/length.h +52 -0
  161. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.c +419 -0
  162. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.h +49 -0
  163. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lib.c +14 -0
  164. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/node.c +774 -0
  165. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.c +2151 -0
  166. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.h +230 -0
  167. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/point.h +62 -0
  168. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/query.c +4134 -0
  169. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reduce_action.h +34 -0
  170. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reusable_node.h +95 -0
  171. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.c +899 -0
  172. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.h +133 -0
  173. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.c +1060 -0
  174. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.h +382 -0
  175. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.c +165 -0
  176. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.h +31 -0
  177. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.c +714 -0
  178. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.h +48 -0
  179. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ICU_SHA +1 -0
  180. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/LICENSE +414 -0
  181. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/README.md +29 -0
  182. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ptypes.h +1 -0
  183. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/umachine.h +448 -0
  184. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/urename.h +1 -0
  185. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf.h +1 -0
  186. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf16.h +733 -0
  187. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf8.h +881 -0
  188. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode.h +50 -0
  189. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib-symbols.txt +23 -0
  190. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib.c +109 -0
  191. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/wasm-stdlib.h +1294 -0
  192. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.c +1823 -0
  193. package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.h +31 -0
  194. package/node_modules/tree-sitter/vendor/tree-sitter/test/fixtures/grammars/.gitkeep +0 -0
  195. package/node_modules/tree-sitter-c/LICENSE +21 -0
  196. package/node_modules/tree-sitter-c/README.md +18 -0
  197. package/node_modules/tree-sitter-c/binding.gyp +20 -0
  198. package/node_modules/tree-sitter-c/bindings/node/binding.cc +20 -0
  199. package/node_modules/tree-sitter-c/bindings/node/index.d.ts +28 -0
  200. package/node_modules/tree-sitter-c/bindings/node/index.js +7 -0
  201. package/node_modules/tree-sitter-c/grammar.js +1463 -0
  202. package/node_modules/tree-sitter-c/package.json +108 -0
  203. package/node_modules/tree-sitter-c/prebuilds/darwin-arm64/tree-sitter-c.node +0 -0
  204. package/node_modules/tree-sitter-c/prebuilds/darwin-x64/tree-sitter-c.node +0 -0
  205. package/node_modules/tree-sitter-c/prebuilds/linux-x64/tree-sitter-c.node +0 -0
  206. package/node_modules/tree-sitter-c/prebuilds/win32-x64/tree-sitter-c.node +0 -0
  207. package/node_modules/tree-sitter-c/queries/highlights.scm +81 -0
  208. package/node_modules/tree-sitter-c/queries/tags.scm +9 -0
  209. package/node_modules/tree-sitter-c/src/grammar.json +9682 -0
  210. package/node_modules/tree-sitter-c/src/node-types.json +4556 -0
  211. package/node_modules/tree-sitter-c/src/parser.c +113852 -0
  212. package/node_modules/tree-sitter-c/src/tree_sitter/alloc.h +54 -0
  213. package/node_modules/tree-sitter-c/src/tree_sitter/array.h +290 -0
  214. package/node_modules/tree-sitter-c/src/tree_sitter/parser.h +265 -0
  215. package/package.json +10 -3
  216. package/vendor/tree-sitter-0.21.1-node24.json +16 -0
  217. package/vendor/tree-sitter-0.21.1-node24.tgz +0 -0
  218. package/chunks/chunk-CGHCEN7W.js +0 -169
  219. package/chunks/chunk-CXKDWFNO.js +0 -102
  220. package/chunks/chunk-GIQKESMN.js +0 -687
  221. package/chunks/chunk-HPQZHOIU.js +0 -67
  222. package/chunks/chunk-PD2BBBKT.js +0 -245
  223. package/chunks/chunk-WF5W75WY.js +0 -1070
  224. package/chunks/fix-J2KBRJDV.js +0 -12
  225. package/chunks/orchestrate-DHBFRTSI.js +0 -59
  226. package/chunks/replay-runner-LK2XFIVG.js +0 -39
  227. package/dashboard/assets/bot-yILPnRgD.js +0 -1
  228. package/dashboard/assets/chevron-down-BeDJ-Vka.js +0 -1
  229. package/dashboard/assets/circle-alert-BEnMBMT-.js +0 -1
  230. package/dashboard/assets/client-DRYsuOGl.js +0 -9
  231. package/dashboard/assets/copy-Bi5vzoF9.js +0 -1
  232. package/dashboard/assets/desktop-BT7RkC4q.js +0 -32
  233. package/dashboard/assets/desktop-OaBI0E0e.css +0 -1
  234. package/dashboard/assets/dist-CmX-h7a4.js +0 -1
  235. package/dashboard/assets/dist-DAwYQmf_.js +0 -45
  236. package/dashboard/assets/findings-page-B4rwF6fZ.js +0 -5
  237. package/dashboard/assets/format-LNQSSpn6.js +0 -1
  238. package/dashboard/assets/jsx-runtime-C7oxC63R.js +0 -1
  239. package/dashboard/assets/live-page-DoNwpPAO.js +0 -1
  240. package/dashboard/assets/meta-tile-BMtBC-Qq.js +0 -1
  241. package/dashboard/assets/operations-app-ER0gg7GN.js +0 -2
  242. package/dashboard/assets/operations-e2CGYKB1.js +0 -4
  243. package/dashboard/assets/overview-page-CmeWH17A.js +0 -1
  244. package/dashboard/assets/page-header-CIJyycfz.js +0 -1
  245. package/dashboard/assets/play-Dwo-9xt6.js +0 -1
  246. package/dashboard/assets/scans-page-CuhzWhHx.js +0 -1
  247. package/dashboard/assets/search-CiooTLck.js +0 -1
  248. package/dashboard/assets/siren-CCBwTSuk.js +0 -1
  249. package/dashboard/assets/table-BgsSBdke.js +0 -1
  250. package/dashboard/assets/tabs-vn6v7Bk6.js +0 -1
  251. package/dashboard/desktop.html +0 -21
@@ -2,9 +2,8 @@
2
2
  import { createRequire as __0CreateRequire } from "node:module";
3
3
  const require = __0CreateRequire(import.meta.url);
4
4
  import {
5
- VERSION,
6
- cloudStateDir
7
- } from "./chunk-PC6RCKQV.js";
5
+ VERSION
6
+ } from "./chunk-KAU6NLGP.js";
8
7
 
9
8
  // packages/core/dist/agent/feature-presets.js
10
9
  var FP_MOAT_FLAGS = [
@@ -309,18 +308,6 @@ var features = {
309
308
  get cloudSurface() {
310
309
  return env("ZERO_FEATURE_CLOUD_SURFACE", false);
311
310
  },
312
- /**
313
- * #978 (ADR-060) — agent fan-out. When ON, the agent gets the `start_scan`
314
- * tool: it can dispatch CHILD scans (via the same POST /scans the UI uses)
315
- * that run independently and report up the scan tree — the recursive
316
- * sub-agent orchestration. Default OFF: fan-out multiplies scans/cost, so it
317
- * stays opt-in even though the orchestrator enforces budget + a tree-level
318
- * cap (max children/depth). Enable with ZERO_FEATURE_AGENT_FANOUT=1.
319
- * Getter so the CLI `--features` flag is honored at dispatch time.
320
- */
321
- get agentFanout() {
322
- return env("ZERO_FEATURE_AGENT_FANOUT", false);
323
- },
324
311
  // ── Phase-2 offensive-engine feature flags (dev-live-engine-recovery) ──
325
312
  // Each gates a tool that RUNS/BUILDS untrusted code or WEAPONIZES. They are
326
313
  // deny-by-default and mirror `cloudSurface` exactly: the env flag is only one
@@ -448,20 +435,6 @@ var features = {
448
435
  get dynamicTriageRouting() {
449
436
  return env("ZERO_FEATURE_DYNAMIC_TRIAGE", false);
450
437
  },
451
- /**
452
- * Opt-in cloud-sink webhook integration (`packages/core/src/cloud-sink.ts`).
453
- * When enabled AND the user has set ZERO_CLOUD_SINK + ZERO_CLOUD_SCAN_ID,
454
- * every finding and the final scan report are POSTed to the configured
455
- * remote endpoint in real time.
456
- *
457
- * Default ON so the env-var trio is sufficient to enable streaming, but the
458
- * flag exists so operators can force-disable the integration in environments
459
- * where outbound HTTP from the scanner is not desired (e.g. air-gapped CI).
460
- * Disable via ZERO_FEATURE_CLOUD_SINK=0.
461
- */
462
- get cloudSink() {
463
- return env("ZERO_FEATURE_CLOUD_SINK", true);
464
- },
465
438
  /**
466
439
  * Pre-recon CVE check (`packages/core/src/pre-recon-cve.ts`).
467
440
  * In white-box mode (`--repo` set), runs `npm audit` / `pip-audit`
@@ -1050,514 +1023,11 @@ function _resetDiagnosticsForTests() {
1050
1023
  diag.resetForTests();
1051
1024
  }
1052
1025
 
1053
- // packages/core/dist/cloud/credentials.js
1054
- import { readFileSync, statSync } from "node:fs";
1055
- import { join } from "node:path";
1056
- var DEFAULT_CLOUD_HOST = "https://cloud.0.security";
1057
- var CloudAuthMissingError = class extends Error {
1058
- constructor(message) {
1059
- super(message);
1060
- this.name = "CloudAuthMissingError";
1061
- }
1062
- };
1063
- var CloudAuthError = class extends Error {
1064
- status;
1065
- constructor(message, status) {
1066
- super(message);
1067
- this.status = status;
1068
- this.name = "CloudAuthError";
1069
- }
1070
- };
1071
- function loadCloudCredentials(opts = {}) {
1072
- const env2 = opts.env ?? process.env;
1073
- const warn = opts.warn ?? ((m) => process.stderr.write(`${m}
1074
- `));
1075
- const envTok = env2["ZERO_CLOUD_TOKEN"]?.trim() || env2["0SEC_CLOUD_TOKEN"]?.trim();
1076
- if (envTok) {
1077
- const envHost = normaliseHost(env2["ZERO_CLOUD_HOST"]?.trim() ?? env2["0SEC_CLOUD_HOST"]?.trim() ?? DEFAULT_CLOUD_HOST);
1078
- if (!env2["ZERO_CLOUD_TOKEN"]?.trim()) {
1079
- warn("[0 cloud] using legacy 0SEC_CLOUD_* credentials; re-run `0 auth login` to migrate to ZERO_CLOUD_*.");
1080
- }
1081
- return { host: envHost, token: envTok, source: "env" };
1082
- }
1083
- const path = join(cloudStateDir(opts.homeDir, env2), "cloud.env");
1084
- let raw;
1085
- try {
1086
- raw = readFileSync(path, "utf-8");
1087
- } catch (err) {
1088
- const code = err.code;
1089
- if (code === "ENOENT") {
1090
- throw new CloudAuthMissingError(`0-cloud credentials not found. Run \`${env2["ZERO_DEV_SOURCE_ROOT"]?.trim() ? "0dev" : "0"} auth login\`.`);
1091
- }
1092
- throw err;
1093
- }
1094
- try {
1095
- const st = statSync(path);
1096
- const mode = st.mode & 511;
1097
- if (mode !== 384) {
1098
- warn(`[0 cloud] WARNING: ${path} mode is ${mode.toString(8).padStart(3, "0")} (expected 600). Run: chmod 600 ${path}`);
1099
- }
1100
- } catch {
1101
- }
1102
- const parsed = parseEnvFile(raw);
1103
- const fileTok = parsed["ZERO_CLOUD_TOKEN"]?.trim() || parsed["0SEC_CLOUD_TOKEN"]?.trim();
1104
- if (!fileTok) {
1105
- throw new CloudAuthMissingError(`0-cloud credentials in ${path} are incomplete: ZERO_CLOUD_TOKEN is required.`);
1106
- }
1107
- if (!parsed["ZERO_CLOUD_TOKEN"]?.trim()) {
1108
- warn("[0 cloud] using legacy 0SEC_CLOUD_* credentials; re-run `0 auth login` to migrate to ZERO_CLOUD_*.");
1109
- }
1110
- const fileHost = normaliseHost(parsed["ZERO_CLOUD_HOST"]?.trim() ?? parsed["0SEC_CLOUD_HOST"]?.trim() ?? env2["ZERO_CLOUD_HOST"]?.trim() ?? env2["0SEC_CLOUD_HOST"]?.trim() ?? DEFAULT_CLOUD_HOST);
1111
- return { host: fileHost, token: fileTok, source: "file" };
1112
- }
1113
- function normaliseHost(host) {
1114
- let h = host;
1115
- if (!/^https?:\/\//.test(h)) {
1116
- throw new CloudAuthMissingError(`ZERO_CLOUD_HOST must be an http(s) URL (got ${JSON.stringify(host)}).`);
1117
- }
1118
- while (h.endsWith("/"))
1119
- h = h.slice(0, -1);
1120
- return h;
1121
- }
1122
- function parseEnvFile(raw) {
1123
- const out = {};
1124
- const lines = raw.split(/\r?\n/);
1125
- for (let i = 0; i < lines.length; i++) {
1126
- const line = lines[i];
1127
- const trimmed = line.trim();
1128
- if (trimmed.length === 0)
1129
- continue;
1130
- if (trimmed.startsWith("#"))
1131
- continue;
1132
- const eq = trimmed.indexOf("=");
1133
- if (eq <= 0) {
1134
- throw new CloudAuthMissingError(`Malformed cloud.env at line ${i + 1}: expected KEY=VALUE, got ${JSON.stringify(line)}`);
1135
- }
1136
- const key = trimmed.slice(0, eq).trim();
1137
- const value = trimmed.slice(eq + 1).trim();
1138
- if (!/^[A-Z0-9_]+$/.test(key)) {
1139
- throw new CloudAuthMissingError(`Malformed cloud.env at line ${i + 1}: invalid key ${JSON.stringify(key)}`);
1140
- }
1141
- out[key] = value;
1142
- }
1143
- return out;
1144
- }
1145
-
1146
- // packages/core/dist/cloud/client.js
1147
- var CloudError = class extends Error {
1148
- status;
1149
- path;
1150
- code;
1151
- constructor(message, status, path, code) {
1152
- super(message);
1153
- this.status = status;
1154
- this.path = path;
1155
- this.code = code;
1156
- this.name = "CloudError";
1157
- }
1158
- };
1159
- var CloudUnauthorizedError = class extends CloudError {
1160
- constructor(path) {
1161
- super(`0-cloud auth rejected (HTTP 401) on ${path}. Run \`0 auth login\` to refresh.`, 401, path);
1162
- this.name = "CloudUnauthorizedError";
1163
- }
1164
- };
1165
- var CloudForbiddenError = class extends CloudError {
1166
- constructor(path) {
1167
- super(`0-cloud forbidden (HTTP 403) on ${path}. Token lacks scope for this resource.`, 403, path);
1168
- this.name = "CloudForbiddenError";
1169
- }
1170
- };
1171
- var CloudNetworkError = class extends CloudError {
1172
- constructor(message, path) {
1173
- super(`0-cloud network error on ${path}: ${message}`, void 0, path);
1174
- this.name = "CloudNetworkError";
1175
- }
1176
- };
1177
- function isUsageAccount(raw) {
1178
- if (!raw || typeof raw !== "object")
1179
- return false;
1180
- const obj = raw;
1181
- if (obj.schemaVersion !== "usage-v2")
1182
- return false;
1183
- if (!isUtcDate(obj.snapshotAt))
1184
- return false;
1185
- if (!obj.scope || typeof obj.scope !== "object")
1186
- return false;
1187
- if (typeof obj.scope.orgId !== "string")
1188
- return false;
1189
- if (typeof obj.state !== "string")
1190
- return false;
1191
- if (!["ready", "disabled", "unavailable", "restricted"].includes(obj.state))
1192
- return false;
1193
- if (obj.reason !== null && typeof obj.reason !== "string")
1194
- return false;
1195
- const plan = obj.plan;
1196
- if (!plan || typeof plan !== "object")
1197
- return false;
1198
- if (typeof plan.id !== "string" && plan.id !== null)
1199
- return false;
1200
- if (plan.id !== null && !["pro", "gold", "enterprise"].includes(plan.id))
1201
- return false;
1202
- if (typeof plan.name !== "string" && plan.name !== null)
1203
- return false;
1204
- if (!isUsd(plan.monthlyPriceUsd))
1205
- return false;
1206
- const included = obj.included;
1207
- if (!included || typeof included !== "object")
1208
- return false;
1209
- if (typeof included.state !== "string")
1210
- return false;
1211
- if (!["active", "exhausted", "none", "unavailable"].includes(included.state))
1212
- return false;
1213
- if (included.usedPercent !== null && typeof included.usedPercent !== "number")
1214
- return false;
1215
- if (included.usedPercent !== null && (!Number.isFinite(included.usedPercent) || included.usedPercent < 0 || included.usedPercent > 100))
1216
- return false;
1217
- if (included.resetsAt !== null && !isUtcDate(included.resetsAt))
1218
- return false;
1219
- const prepaid = obj.prepaid;
1220
- if (!prepaid || typeof prepaid !== "object")
1221
- return false;
1222
- if (!isUsd(prepaid.balanceUsd))
1223
- return false;
1224
- if (typeof prepaid.fallbackEnabled !== "boolean")
1225
- return false;
1226
- if (typeof obj.canManageBilling !== "boolean")
1227
- return false;
1228
- const admission = obj.admission;
1229
- if (!admission || typeof admission !== "object")
1230
- return false;
1231
- if (typeof admission.eligible !== "boolean")
1232
- return false;
1233
- if (admission.reason !== null && typeof admission.reason !== "string")
1234
- return false;
1235
- return true;
1236
- }
1237
- function isUsd(value) {
1238
- return value === null || typeof value === "string" && /^\d+(?:\.\d{1,9})?$/.test(value);
1239
- }
1240
- function isUtcDate(value) {
1241
- return typeof value === "string" && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/.test(value) && Number.isFinite(Date.parse(value));
1242
- }
1243
- function healthPath(host) {
1244
- try {
1245
- const hostname = new URL(host).hostname.toLowerCase();
1246
- if (hostname === "cloud.0.ai" || hostname === "cloud.0.security") {
1247
- return "/api/health";
1248
- }
1249
- } catch {
1250
- }
1251
- return "/health";
1252
- }
1253
- var CloudClient = class {
1254
- host;
1255
- token;
1256
- fetchImpl;
1257
- constructor(opts) {
1258
- this.host = opts.host;
1259
- this.token = opts.token;
1260
- this.fetchImpl = opts.fetchImpl ?? fetch;
1261
- }
1262
- /**
1263
- * Verify cloud reachability through its health route. The hosted dashboard
1264
- * uses `/api/health`; a self-hosted receiver uses `/health`.
1265
- */
1266
- async pingHealth() {
1267
- return this.getJson(healthPath(this.host));
1268
- }
1269
- /**
1270
- * Fetch the hosted inference model catalog — available models, pricing,
1271
- * wire API protocol, and context limits. Used at runtime for model
1272
- * selection and by the hosted provider to determine per-model capabilities.
1273
- * Returns the raw list response; the caller caches/filters as needed.
1274
- */
1275
- async getInferenceModels() {
1276
- return this.getJson("/api/inference/v1/models");
1277
- }
1278
- /**
1279
- * Fetch the organization's credit account — usage-v2 shape including
1280
- * plan, included allowance, prepaid balance, and admission status.
1281
- *
1282
- * Returns `null` when the response is a recognised HTTP 200 (customer is
1283
- * authenticated) but the payload is missing, legacy, or structurally
1284
- * unrecognised — not an auth failure. HTTP 401/403 still throw the
1285
- * existing typed errors so the caller can distinguish a credential
1286
- * problem from unsupported credit data.
1287
- *
1288
- * Monetary amounts are decimal strings (no Number coercion); the
1289
- * caller preserves them for exact display.
1290
- */
1291
- async getInferenceAccount() {
1292
- const raw = await this.getJson("/api/inference/account");
1293
- if (!isUsageAccount(raw))
1294
- return null;
1295
- const { plan, included, prepaid, admission } = raw;
1296
- return {
1297
- schemaVersion: raw.schemaVersion,
1298
- snapshotAt: raw.snapshotAt,
1299
- scope: { orgId: raw.scope.orgId },
1300
- state: raw.state,
1301
- reason: raw.reason,
1302
- plan: {
1303
- id: plan.id,
1304
- name: plan.name,
1305
- monthlyPriceUsd: plan.monthlyPriceUsd
1306
- },
1307
- included: {
1308
- state: included.state,
1309
- usedPercent: included.usedPercent,
1310
- resetsAt: included.resetsAt
1311
- },
1312
- prepaid: {
1313
- balanceUsd: prepaid.balanceUsd,
1314
- fallbackEnabled: prepaid.fallbackEnabled
1315
- },
1316
- canManageBilling: raw.canManageBilling,
1317
- admission: { eligible: admission.eligible, reason: admission.reason }
1318
- };
1319
- }
1320
- /**
1321
- * Fetch request-level usage metadata for the operator's hosted
1322
- * inference sessions. Returns lightweight metadata records (model,
1323
- * tokens, provider, timestamp) — no prompt/response payload.
1324
- */
1325
- async getInferenceUsage() {
1326
- return this.getJson("/api/inference/usage");
1327
- }
1328
- // ── Audit-skills helpers (#audit-skills) ──
1329
- /** List all audit skills for the authenticated organization. */
1330
- async listAuditSkills() {
1331
- return this.getJson("/api/audit-skills");
1332
- }
1333
- /**
1334
- * Get a single audit skill with its revision history and project
1335
- * assignments.
1336
- */
1337
- async getAuditSkill(id) {
1338
- return this.getJson(`/api/audit-skills/${encodeURIComponent(id)}`);
1339
- }
1340
- /** Create a new markdown-based audit skill. */
1341
- async createAuditSkill(input) {
1342
- return this.postJson("/api/audit-skills", input);
1343
- }
1344
- /** Import an audit skill from a GitHub repository. */
1345
- async importAuditSkillFromGithub(input) {
1346
- return this.postJson("/api/audit-skills/import", input);
1347
- }
1348
- /** Create a new revision of an audit skill (CAS — 409 on stale expectedRevision). */
1349
- async createAuditSkillRevision(id, input) {
1350
- return this.postJson(`/api/audit-skills/${encodeURIComponent(id)}/revisions`, input);
1351
- }
1352
- /** Re-fetch the skill from its original GitHub source. */
1353
- async syncAuditSkill(id, expectedRevision) {
1354
- return this.postJson(`/api/audit-skills/${encodeURIComponent(id)}/sync`, { expectedRevision });
1355
- }
1356
- /** Pin an audit skill revision to a project for future scans. */
1357
- async assignAuditSkill(id, projectId, revisionId) {
1358
- return this.postJson(`/api/audit-skills/${encodeURIComponent(id)}/projects/${encodeURIComponent(projectId)}`, { revisionId });
1359
- }
1360
- /** Unpin an audit skill from a project (future scans no longer use it). */
1361
- async unassignAuditSkill(id, projectId) {
1362
- return this.deleteJson(`/api/audit-skills/${encodeURIComponent(id)}/projects/${encodeURIComponent(projectId)}`);
1363
- }
1364
- /** Archive an audit skill (disables future bindings, preserves history). */
1365
- async archiveAuditSkill(id) {
1366
- await this.deleteJson(`/api/audit-skills/${encodeURIComponent(id)}`);
1367
- }
1368
- /**
1369
- * List audit skills available to a specific project, along with current
1370
- * assignments for that project. The project must belong to the caller's org.
1371
- */
1372
- async listAuditSkillsByProject(projectId) {
1373
- return this.getJson(`/api/audit-skills/by-project/${encodeURIComponent(projectId)}`);
1374
- }
1375
- /**
1376
- * Generic JSON DELETE helper with the same error mapping as getJson/postJson.
1377
- * Used by `0 service disconnect` to remove scan schedules.
1378
- */
1379
- async deleteJson(path) {
1380
- const url = `${this.host}${path}`;
1381
- let res;
1382
- try {
1383
- res = await this.fetchImpl(url, {
1384
- method: "DELETE",
1385
- headers: { ...this.headers(), "Content-Type": "application/json" }
1386
- });
1387
- } catch (err) {
1388
- const msg = err instanceof Error ? err.message : String(err);
1389
- throw new CloudNetworkError(this.scrub(msg), path);
1390
- }
1391
- if (!res.ok) {
1392
- let code;
1393
- try {
1394
- const parsed = await res.json();
1395
- const raw = typeof parsed?.error === "object" ? parsed.error?.code : void 0;
1396
- if (typeof raw === "string" && raw.length > 0)
1397
- code = raw;
1398
- } catch {
1399
- }
1400
- this.throwForStatus(res.status, path, code);
1401
- }
1402
- if (res.status === 204)
1403
- return void 0;
1404
- return await res.json();
1405
- }
1406
- /**
1407
- * Generic JSON POST helper with the same error mapping as getJson.
1408
- * Used by `0 connect` to enqueue scans and schedules.
1409
- */
1410
- async postJson(path, body) {
1411
- const url = `${this.host}${path}`;
1412
- let res;
1413
- try {
1414
- res = await this.fetchImpl(url, {
1415
- method: "POST",
1416
- headers: { ...this.headers(), "Content-Type": "application/json" },
1417
- body: JSON.stringify(body)
1418
- });
1419
- } catch (err) {
1420
- const msg = err instanceof Error ? err.message : String(err);
1421
- throw new CloudNetworkError(this.scrub(msg), path);
1422
- }
1423
- if (!res.ok) {
1424
- let code;
1425
- try {
1426
- const parsed = await res.json();
1427
- const raw = typeof parsed?.error === "object" ? parsed.error?.code : void 0;
1428
- if (typeof raw === "string" && raw.length > 0)
1429
- code = raw;
1430
- } catch {
1431
- }
1432
- this.throwForStatus(res.status, path, code);
1433
- }
1434
- return await res.json();
1435
- }
1436
- /**
1437
- * Generic JSON GET helper. Public so future modules (scans, findings)
1438
- * can reuse the same error mapping without duplicating it. Not exported
1439
- * past the package boundary — see ./index.ts.
1440
- */
1441
- async getJson(path) {
1442
- const url = `${this.host}${path}`;
1443
- let res;
1444
- try {
1445
- res = await this.fetchImpl(url, {
1446
- method: "GET",
1447
- headers: this.headers()
1448
- });
1449
- } catch (err) {
1450
- const msg = err instanceof Error ? err.message : String(err);
1451
- throw new CloudNetworkError(this.scrub(msg), path);
1452
- }
1453
- if (!res.ok) {
1454
- let code;
1455
- try {
1456
- const body = await res.json();
1457
- const raw = body?.error?.code;
1458
- if (typeof raw === "string" && raw.length > 0)
1459
- code = raw;
1460
- } catch {
1461
- }
1462
- this.throwForStatus(res.status, path, code);
1463
- }
1464
- return await res.json();
1465
- }
1466
- /** Throw a typed error for a non-2xx status, carrying the gateway's body `code`. */
1467
- throwForStatus(status, path, code) {
1468
- if (status === 401)
1469
- throw new CloudUnauthorizedError(path);
1470
- if (status === 403)
1471
- throw new CloudForbiddenError(path);
1472
- throw new CloudError(`0-cloud request failed (HTTP ${status}${code ? ` ${code}` : ""}) on ${path}.`, status, path, code);
1473
- }
1474
- /**
1475
- * Throw a typed error for non-2xx responses. Public so direct callers
1476
- * (e.g. an integration test driving raw fetch) can reuse the mapping.
1477
- */
1478
- assertOk(res, path) {
1479
- if (res.ok)
1480
- return;
1481
- if (res.status === 401)
1482
- throw new CloudUnauthorizedError(path);
1483
- if (res.status === 403)
1484
- throw new CloudForbiddenError(path);
1485
- throw new CloudError(`0-cloud request failed (HTTP ${res.status}) on ${path}.`, res.status, path);
1486
- }
1487
- // ── internals ──
1488
- headers() {
1489
- return {
1490
- Authorization: `Bearer ${this.token}`,
1491
- Accept: "application/json",
1492
- "User-Agent": `@0/cli/${VERSION}`
1493
- };
1494
- }
1495
- /**
1496
- * Strip anything that looks like our own token from a string. The
1497
- * cloud token may be interpolated into a TLS-layer error message in
1498
- * exotic failure modes — we redact it to keep the no-leak invariant
1499
- * local to this module.
1500
- */
1501
- scrub(s) {
1502
- if (!this.token)
1503
- return s;
1504
- return s.split(this.token).join("[REDACTED]");
1505
- }
1506
- };
1507
-
1508
1026
  // packages/core/dist/runtime/llm-api.js
1509
- import { randomUUID } from "node:crypto";
1510
- import { appendFileSync, existsSync, readFileSync as readFileSync2, renameSync, writeFileSync } from "node:fs";
1027
+ import { createHash, randomUUID } from "node:crypto";
1028
+ import { appendFileSync, existsSync, readFileSync, renameSync, writeFileSync } from "node:fs";
1511
1029
  import { homedir } from "node:os";
1512
- import { join as join2 } from "node:path";
1513
-
1514
- // packages/core/dist/runtime/hosted-request-queue.js
1515
- var MAX_IN_FLIGHT = 4;
1516
- var endpoints = /* @__PURE__ */ new Map();
1517
- function acquireHostedRequestSlot(endpoint, token, signal) {
1518
- signal?.throwIfAborted();
1519
- let accounts = endpoints.get(endpoint);
1520
- if (!accounts)
1521
- endpoints.set(endpoint, accounts = /* @__PURE__ */ new Map());
1522
- let queue = accounts.get(token);
1523
- if (!queue)
1524
- accounts.set(token, queue = { active: 0, waiting: [] });
1525
- const accountQueues = accounts;
1526
- const current = queue;
1527
- return new Promise((resolve, reject) => {
1528
- const abort = () => {
1529
- const index = current.waiting.indexOf(waiter);
1530
- if (index !== -1)
1531
- current.waiting.splice(index, 1);
1532
- reject(signal.reason);
1533
- };
1534
- const waiter = { grant: () => {
1535
- signal?.removeEventListener("abort", abort);
1536
- current.active++;
1537
- let released = false;
1538
- resolve(() => {
1539
- if (released)
1540
- return;
1541
- released = true;
1542
- current.active--;
1543
- const next = current.waiting.shift();
1544
- if (next)
1545
- next.grant();
1546
- else if (current.active === 0) {
1547
- accountQueues.delete(token);
1548
- if (accountQueues.size === 0)
1549
- endpoints.delete(endpoint);
1550
- }
1551
- });
1552
- } };
1553
- if (current.active < MAX_IN_FLIGHT)
1554
- waiter.grant();
1555
- else {
1556
- current.waiting.push(waiter);
1557
- signal?.addEventListener("abort", abort, { once: true });
1558
- }
1559
- });
1560
- }
1030
+ import { join } from "node:path";
1561
1031
 
1562
1032
  // packages/core/dist/runtime/prompt-cache.js
1563
1033
  var MAX_CACHE_BREAKPOINTS = 4;
@@ -2085,8 +1555,7 @@ function parseLlmFallbackChain(env2 = process.env) {
2085
1555
  xai: true,
2086
1556
  opencode: true,
2087
1557
  copilot: true,
2088
- google: true,
2089
- hosted: true
1558
+ google: true
2090
1559
  };
2091
1560
  for (const part of raw.split(",")) {
2092
1561
  const trimmed = part.trim();
@@ -2192,24 +1661,6 @@ function resolveFailoverProvider(provider, model, env2 = process.env, apiKey) {
2192
1661
  return void 0;
2193
1662
  return { apiKey: "", baseUrl: CODE_ASSIST_ENDPOINT, wireApi: "google_generate_content" };
2194
1663
  }
2195
- case "hosted": {
2196
- try {
2197
- const creds = loadCloudCredentials({
2198
- env: env2,
2199
- warn: () => {
2200
- }
2201
- });
2202
- return {
2203
- apiKey: creds.token,
2204
- baseUrl: `${creds.host}/api/inference/v1`,
2205
- wireApi: "chat_completions"
2206
- };
2207
- } catch (err) {
2208
- if (err instanceof CloudAuthMissingError)
2209
- return void 0;
2210
- throw err;
2211
- }
2212
- }
2213
1664
  }
2214
1665
  }
2215
1666
  var fallbackChainCache;
@@ -2235,6 +1686,12 @@ var KIMI_DEFAULT_MODEL = "k3";
2235
1686
  var QWEN_DEFAULT_BASE_URL = "https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1";
2236
1687
  var QWEN_DEFAULT_MODEL = "qwen3.8-max";
2237
1688
  var CODEX_API_ENDPOINT = "https://chatgpt.com/backend-api/codex/responses";
1689
+ var CODEX_CLIENT_VERSION = "0.153.0";
1690
+ var CODEX_PROTOCOL_HEADERS = {
1691
+ "OpenAI-Beta": "responses=experimental",
1692
+ originator: "0",
1693
+ version: CODEX_CLIENT_VERSION
1694
+ };
2238
1695
  var CODEX_OAUTH_ISSUER = "https://auth.openai.com";
2239
1696
  var CODEX_OAUTH_CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
2240
1697
  var CODEX_DEFAULT_MODEL = "gpt-5.5";
@@ -2258,13 +1715,13 @@ function readChatGptCodexEnv(env2 = process.env) {
2258
1715
  };
2259
1716
  }
2260
1717
  function resolveChatGptCodexAuthPath(env2 = process.env) {
2261
- return env2["ZERO_CHATGPT_AUTH_FILE"] ?? join2(env2.HOME ?? homedir(), ".codex", "auth.json");
1718
+ return env2["ZERO_CHATGPT_AUTH_FILE"] ?? join(env2.HOME ?? homedir(), ".codex", "auth.json");
2262
1719
  }
2263
1720
  function persistChatGptCodexAuthFile(authPath, tokens, usedRefreshToken) {
2264
1721
  try {
2265
1722
  let existing = {};
2266
1723
  try {
2267
- existing = JSON.parse(readFileSync2(authPath, "utf8"));
1724
+ existing = JSON.parse(readFileSync(authPath, "utf8"));
2268
1725
  } catch {
2269
1726
  existing = {};
2270
1727
  }
@@ -2296,7 +1753,7 @@ function readChatGptCodexAuthFile(env2 = process.env) {
2296
1753
  if (!existsSync(authPath))
2297
1754
  return void 0;
2298
1755
  try {
2299
- const auth = JSON.parse(readFileSync2(authPath, "utf8"));
1756
+ const auth = JSON.parse(readFileSync(authPath, "utf8"));
2300
1757
  const tokens = auth.tokens;
2301
1758
  if (!tokens)
2302
1759
  return void 0;
@@ -2642,7 +2099,7 @@ function parseCodexAzureConfig(env2 = process.env) {
2642
2099
  if (!existsSync(configPath))
2643
2100
  return {};
2644
2101
  try {
2645
- const content = readFileSync2(configPath, "utf8");
2102
+ const content = readFileSync(configPath, "utf8");
2646
2103
  const azureSectionMatch = content.match(/\[model_providers\.azure\]([\s\S]*?)(?:\n\[|$)/);
2647
2104
  const activeProviderMatch = content.match(/^\s*model_provider\s*=\s*"([^"]+)"/m);
2648
2105
  const baseUrlMatch = azureSectionMatch?.[1]?.match(/base_url\s*=\s*"([^"]+)"/);
@@ -2698,7 +2155,7 @@ function providerForModel(model, env2) {
2698
2155
  return env2["ZERO_GEMINI_ACCESS_TOKEN"] || env2["ZERO_GEMINI_OAUTH_REFRESH_TOKEN"] ? "google" : void 0;
2699
2156
  }
2700
2157
  if (/^gpt-|^o[1-4](?:[-_]|$)/.test(m)) {
2701
- if (env2["ZERO_CHATGPT_ACCESS_TOKEN"] || env2["ZERO_CHATGPT_OAUTH_REFRESH_TOKEN"])
2158
+ if (readChatGptCodexEnv(env2) || readChatGptCodexAuthFile(env2))
2702
2159
  return "chatgpt-codex";
2703
2160
  if (env2.OPENAI_API_KEY)
2704
2161
  return "openai";
@@ -2726,8 +2183,7 @@ var DEFAULT_PROVIDER_MODELS = {
2726
2183
  xai: XAI_DEFAULT_MODEL,
2727
2184
  opencode: OPENCODE_DEFAULT_MODEL,
2728
2185
  copilot: COPILOT_DEFAULT_MODEL,
2729
- google: GEMINI_DEFAULT_MODEL,
2730
- hosted: ""
2186
+ google: GEMINI_DEFAULT_MODEL
2731
2187
  };
2732
2188
  var AUTO_MODEL_SENTINEL = "auto";
2733
2189
  function detectProvider(configApiKey, preferredModel, env2, configProvider) {
@@ -2748,11 +2204,11 @@ function detectProvider(configApiKey, preferredModel, env2, configProvider) {
2748
2204
  throw new Error(`${source} is unsupported: ${pinnedProviderRaw}`);
2749
2205
  }
2750
2206
  const provider = pinnedProviderRaw;
2751
- const model = preferredModel ?? env2["ZERO_MODEL"] ?? (configProvider !== void 0 || provider === "hosted" ? DEFAULT_PROVIDER_MODELS[provider] : void 0);
2752
- if (model === void 0 || model === "" && provider !== "hosted") {
2207
+ const model = preferredModel ?? env2["ZERO_MODEL"] ?? (configProvider !== void 0 ? DEFAULT_PROVIDER_MODELS[provider] : void 0);
2208
+ if (model === void 0 || model === "") {
2753
2209
  throw new Error(`${source} requires an explicit model`);
2754
2210
  }
2755
- if (configApiKey && (provider === "hosted" || provider === "chatgpt-codex")) {
2211
+ if (configApiKey && provider === "chatgpt-codex") {
2756
2212
  throw new Error(`${source}=${provider} requires its own authentication, not RuntimeConfig.apiKey`);
2757
2213
  }
2758
2214
  const resolved = resolveFailoverProvider(provider, model, env2, configApiKey);
@@ -2906,21 +2362,6 @@ function detectProvider(configApiKey, preferredModel, env2, configProvider) {
2906
2362
  default:
2907
2363
  break;
2908
2364
  }
2909
- try {
2910
- const hostedCreds = loadCloudCredentials({
2911
- env: env2,
2912
- warn: () => {
2913
- }
2914
- });
2915
- return {
2916
- provider: "hosted",
2917
- apiKey: hostedCreds.token,
2918
- baseUrl: `${hostedCreds.host}/api/inference/v1`,
2919
- defaultModel: "",
2920
- wireApi: "chat_completions"
2921
- };
2922
- } catch {
2923
- }
2924
2365
  const chatGptAccess = env2["ZERO_CHATGPT_ACCESS_TOKEN"];
2925
2366
  const chatGptRefresh = env2["ZERO_CHATGPT_OAUTH_REFRESH_TOKEN"];
2926
2367
  const chatGptAuthFile = !chatGptAccess && !chatGptRefresh ? readChatGptCodexAuthFile(env2) : void 0;
@@ -3084,6 +2525,9 @@ var LlmApiRuntime = class _LlmApiRuntime {
3084
2525
  apiKey;
3085
2526
  baseUrl;
3086
2527
  model;
2528
+ pricingModelSource = "";
2529
+ pricingProviderSource;
2530
+ pricingModelKey = "";
3087
2531
  wireApi;
3088
2532
  reasoningEffort;
3089
2533
  azureConfig;
@@ -3092,19 +2536,12 @@ var LlmApiRuntime = class _LlmApiRuntime {
3092
2536
  fallbackChain;
3093
2537
  /** Index into fallbackChain — which entry to try next. */
3094
2538
  fallbackIndex;
3095
- /** Resolve and validate the hosted model and wire protocol once per runtime. */
3096
- hostedCatalogPromise = null;
3097
- /** Catalog ceiling, resolved before hosted inference is submitted. */
3098
- hostedMaxOutputTokens;
3099
2539
  constructor(config, inherited) {
3100
2540
  if (inherited) {
3101
2541
  const timeout = config.timeout ?? inherited.config.timeout ?? 12e4;
3102
2542
  if (!Number.isFinite(timeout) || timeout <= 0) {
3103
2543
  throw new Error("Subagent timeout must be a positive finite number");
3104
2544
  }
3105
- if (inherited.provider === "hosted" && inherited.hostedMaxOutputTokens === void 0) {
3106
- throw new Error("Hosted model catalog must resolve before creating a subagent");
3107
- }
3108
2545
  const model = config.model ?? inherited.model;
3109
2546
  const modelChanged = model !== inherited.model;
3110
2547
  this.config = {
@@ -3138,10 +2575,6 @@ var LlmApiRuntime = class _LlmApiRuntime {
3138
2575
  this.geminiAuthState = inherited.geminiAuthState;
3139
2576
  this.fallbackChain = [];
3140
2577
  this.fallbackIndex = 0;
3141
- if (!modelChanged) {
3142
- this.hostedMaxOutputTokens = inherited.hostedMaxOutputTokens;
3143
- this.hostedCatalogPromise = inherited.hostedCatalogPromise;
3144
- }
3145
2578
  return;
3146
2579
  }
3147
2580
  this.applyConfiguration(config);
@@ -3201,66 +2634,59 @@ var LlmApiRuntime = class _LlmApiRuntime {
3201
2634
  });
3202
2635
  }
3203
2636
  }
2637
+ /** Non-secret identity for preferences scoped to the captured connection. */
2638
+ connectionIdentity() {
2639
+ let identity;
2640
+ if (this.provider === "chatgpt-codex") {
2641
+ const state = this.codexAuthState;
2642
+ if (!state)
2643
+ return void 0;
2644
+ if (state.accountId) {
2645
+ identity = [this.provider, "account", state.accountId];
2646
+ } else {
2647
+ const credential = state.refreshToken || state.accessToken;
2648
+ if (!credential)
2649
+ return void 0;
2650
+ identity = [this.provider, "credential", credential];
2651
+ }
2652
+ } else if (this.provider === "google") {
2653
+ const credential = this.geminiAuthState?.refreshToken || this.geminiAuthState?.accessToken;
2654
+ if (!credential)
2655
+ return void 0;
2656
+ identity = [this.provider, this.baseUrl, credential, firstNonEmptyEnv(this.env, "GOOGLE_CLOUD_PROJECT", "ZERO_GEMINI_PROJECT") ?? ""];
2657
+ } else {
2658
+ if (!this.apiKey)
2659
+ return void 0;
2660
+ identity = [this.provider, this.baseUrl, this.apiKey];
2661
+ }
2662
+ return createHash("sha256").update(JSON.stringify(identity)).digest("hex");
2663
+ }
3204
2664
  /** Discover models using this runtime's captured account, including after a separate login changes. */
3205
2665
  async codexModelCatalog(signal) {
3206
2666
  const state = this.codexAuthState;
3207
2667
  if (this.provider !== "chatgpt-codex" || !state)
3208
2668
  throw new Error("No active Codex subscription");
3209
- const { loadCodexModelCatalog } = await import("./codex-models-TYYV4JNN.js");
2669
+ const { loadCodexModelCatalog } = await import("./codex-models-NHQW45SO.js");
3210
2670
  return loadCodexModelCatalog({ signal, resolveCredentials: () => refreshChatGptCodexAuthState(state) });
3211
2671
  }
3212
- /** Check account admission and resolve the service model without inference.
3213
- * Each explicit check refreshes admission; failed discovery is never cached.
3214
- */
3215
- async prepare() {
3216
- while (this.provider === "hosted") {
3217
- const config = this.config;
3218
- const client = new CloudClient({
3219
- host: this.baseUrl.replace(/\/api\/inference\/v1$/, ""),
3220
- token: this.apiKey
3221
- });
3222
- try {
3223
- const account = await client.getInferenceAccount();
3224
- if (this.config !== config)
3225
- continue;
3226
- if (!account) {
3227
- throw new CloudError("0cloud account availability could not be read. Check again or review your account in /connect.", void 0, "/api/inference/account", "unsupported_account_data");
3228
- }
3229
- if (!account.admission.eligible) {
3230
- const reason = account.admission.reason ?? account.reason ?? "account_restricted";
3231
- throw new CloudError(account.state === "unavailable" ? `0cloud account availability could not be checked (${reason}). Check again or review your account in /connect.` : `0cloud account access is restricted (${reason}). Review your account in /connect or contact your organization owner.`, void 0, "/api/inference/account", reason);
3232
- }
3233
- await this.ensureHostedModel();
3234
- if (this.config === config)
3235
- return;
3236
- } catch (error) {
3237
- if (this.config !== config)
3238
- continue;
3239
- throw error;
3240
- }
3241
- }
3242
- }
3243
2672
  /**
3244
2673
  * Mutate the live selection in place so the NEXT turn (the engine reads
3245
2674
  * `config.runtime` per turn) and the NEXT `forkForSubagent` pick up the new
3246
- * model / provider / role map with zero session teardown. No-op-safe:
3247
- * undefined fields leave the corresponding state unchanged.
2675
+ * model / provider / role map with zero session teardown. Undefined fields
2676
+ * preserve the current state, except a provider change resets an omitted model.
3248
2677
  */
3249
2678
  reconfigure(sel) {
3250
2679
  const providerChanged = sel.provider !== void 0 && sel.provider !== this.provider;
3251
- if (providerChanged || this.provider === "hosted" && (sel.env !== void 0 || sel.provider === "hosted")) {
2680
+ if (providerChanged) {
3252
2681
  const merged = {
3253
2682
  ...this.config,
3254
- ...providerChanged && sel.provider === "hosted" && sel.model === void 0 ? { model: "" } : {},
3255
2683
  apiKey: void 0,
3256
2684
  provider: sel.provider ?? this.provider,
3257
- ...sel.model !== void 0 ? { model: sel.model } : {},
2685
+ model: sel.model,
3258
2686
  ...sel.agentModels !== void 0 ? { agentModels: sel.agentModels } : {},
3259
2687
  ...sel.singleModel !== void 0 ? { singleModel: sel.singleModel } : {},
3260
2688
  ...sel.env !== void 0 ? { env: sel.env } : {}
3261
2689
  };
3262
- this.hostedCatalogPromise = null;
3263
- this.hostedMaxOutputTokens = void 0;
3264
2690
  this.applyConfiguration(merged);
3265
2691
  return;
3266
2692
  }
@@ -3283,15 +2709,13 @@ var LlmApiRuntime = class _LlmApiRuntime {
3283
2709
  this.wireApi = openAICompatibleWireApi(this.env, "AZURE_OPENAI_WIRE_API", this.azureConfig.wireApi);
3284
2710
  this.applyModelWireApi();
3285
2711
  this.reasoningEffort = void 0;
3286
- this.hostedCatalogPromise = null;
3287
- this.hostedMaxOutputTokens = void 0;
3288
2712
  }
3289
2713
  }
3290
2714
  }
3291
- /** Exact deployments requiring Responses for tools, shared by roots and forks. */
2715
+ /** Modern OpenAI tool calls use Responses, shared by roots and forks. */
3292
2716
  applyModelWireApi() {
3293
2717
  const normalizedModel = this.model.toLowerCase();
3294
- if (this.wireApi === "chat_completions" && (this.provider === "azure" && normalizedModel === "gpt-5.6-sol" || this.provider === "openai" && normalizedModel === "gpt-5.6-luna")) {
2718
+ if (this.wireApi === "chat_completions" && (this.provider === "azure" && normalizedModel === "gpt-5.6-sol" || this.provider === "openai" && (normalizedModel === "gpt-5.6-luna" || /^gpt-(?:[6-9]|\d{2,})(?:[-.]|$)/.test(normalizedModel)))) {
3295
2719
  this.wireApi = "responses";
3296
2720
  }
3297
2721
  }
@@ -3300,18 +2724,14 @@ var LlmApiRuntime = class _LlmApiRuntime {
3300
2724
  * Providers whose credentials are present in THIS runtime's environment
3301
2725
  * (`this.env`, never process-global). A provider counts as accessible iff
3302
2726
  * `resolveFailoverProvider` — the same auth-presence check the cross-provider
3303
- * failover chain uses — can build a connection for it, so auth-only providers
3304
- * (chatgpt-codex OAuth) and cloud-hosted are covered by the identical rule.
2727
+ * failover chain uses — including auth-only providers (chatgpt-codex OAuth).
3305
2728
  */
3306
2729
  accessibleProviders() {
3307
2730
  const out = [];
3308
2731
  for (const provider of Object.keys(DEFAULT_PROVIDER_MODELS)) {
3309
2732
  const probeModel = DEFAULT_PROVIDER_MODELS[provider] || "probe";
3310
- try {
3311
- if (resolveFailoverProvider(provider, probeModel, this.env))
3312
- out.push(provider);
3313
- } catch {
3314
- }
2733
+ if (resolveFailoverProvider(provider, probeModel, this.env))
2734
+ out.push(provider);
3315
2735
  }
3316
2736
  return out;
3317
2737
  }
@@ -3348,7 +2768,6 @@ var LlmApiRuntime = class _LlmApiRuntime {
3348
2768
  if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
3349
2769
  throw new Error("Subagent timeout must be a positive finite number");
3350
2770
  }
3351
- await this.ensureHostedModel();
3352
2771
  const roleModel = selection?.role !== void 0 && this.config.agentModels && Object.hasOwn(this.config.agentModels, selection.role) ? this.config.agentModels[selection.role] : void 0;
3353
2772
  const autoInEffect = roleModel === AUTO_MODEL_SENTINEL || this.config.autoRoute === true && roleModel === void 0;
3354
2773
  const configuredModel = roleModel === AUTO_MODEL_SENTINEL ? void 0 : roleModel;
@@ -3364,70 +2783,15 @@ var LlmApiRuntime = class _LlmApiRuntime {
3364
2783
  throw new Error(autoInEffect ? `Subagent model "${selectedModel}" is not reachable: its provider has no configured credentials.` : `Subagent model "${selectedModel}" is not operator-approved. Configure agentModels before selecting it.`);
3365
2784
  }
3366
2785
  const child = new _LlmApiRuntime({ type: "api", timeout: timeoutMs, model }, this);
3367
- await child.ensureHostedModel();
3368
2786
  return child;
3369
2787
  }
3370
- /** The server catalog is authoritative even when a model was selected explicitly. */
3371
- async ensureHostedModel() {
3372
- while (this.provider === "hosted") {
3373
- let pending = this.hostedCatalogPromise;
3374
- if (!pending) {
3375
- const requestedModel = this.model;
3376
- const client = new CloudClient({
3377
- host: this.baseUrl.replace(/\/api\/inference\/v1$/, ""),
3378
- token: this.apiKey
3379
- });
3380
- const request = client.getInferenceModels().then((catalog) => {
3381
- if (this.hostedCatalogPromise !== request)
3382
- return;
3383
- const selected = requestedModel ? catalog.data.find((model) => model.id === requestedModel) : catalog.data[0];
3384
- if (!selected) {
3385
- throw new Error(requestedModel ? `Hosted model "${requestedModel}" is unavailable. Run \`0 models\` for available models.` : "No hosted models are available. Run `0 models` to check service availability.");
3386
- }
3387
- this.model = selected.id;
3388
- this.wireApi = selected.wire_api;
3389
- this.hostedMaxOutputTokens = selected.max_output_tokens;
3390
- });
3391
- this.hostedCatalogPromise = pending = request;
3392
- }
3393
- try {
3394
- await pending;
3395
- } catch (error) {
3396
- if (this.hostedCatalogPromise !== pending)
3397
- continue;
3398
- this.hostedCatalogPromise = null;
3399
- throw error;
3400
- }
3401
- if (this.hostedCatalogPromise === pending)
3402
- return;
3403
- }
3404
- }
3405
- /** All audits and nested workers on this hosted credential share admission. */
3406
- async acquireHostedSlot(signal) {
3407
- while (this.provider === "hosted") {
3408
- const config = this.config;
3409
- const release = await acquireHostedRequestSlot(this.baseUrl, this.apiKey, signal);
3410
- if (this.config === config)
3411
- return release;
3412
- release();
3413
- await this.ensureHostedModel();
3414
- }
3415
- return void 0;
3416
- }
3417
2788
  /**
3418
2789
  * A hard dollar ceiling needs a provider-enforced bound on the next response.
3419
2790
  * ChatGPT Codex OAuth rejects `max_output_tokens`, so it cannot support that
3420
2791
  * contract; callers must fail closed before making a metered comparison call.
3421
2792
  */
3422
2793
  get outputTokenLimit() {
3423
- return this.provider === "chatgpt-codex" ? void 0 : this.effectiveOutputTokens;
3424
- }
3425
- /** Hosted requests honor both the catalog ceiling and the local hard cap. */
3426
- get effectiveOutputTokens() {
3427
- if (this.provider === "hosted" && this.hostedMaxOutputTokens !== void 0) {
3428
- return Math.min(NATIVE_COMPLETION_TOKEN_LIMIT, this.hostedMaxOutputTokens);
3429
- }
3430
- return NATIVE_COMPLETION_TOKEN_LIMIT;
2794
+ return this.provider === "chatgpt-codex" ? void 0 : NATIVE_COMPLETION_TOKEN_LIMIT;
3431
2795
  }
3432
2796
  /**
3433
2797
  * Whether this provider uses OpenAI-compatible chat/completions format.
@@ -3439,7 +2803,7 @@ var LlmApiRuntime = class _LlmApiRuntime {
3439
2803
  * inert default — it is intentionally unused for these two providers.
3440
2804
  */
3441
2805
  get isOpenAICompat() {
3442
- return this.provider === "openrouter" || this.provider === "openai" || this.provider === "azure" || this.provider === "deepseek" || this.provider === "qwen" || this.provider === "xai" || this.provider === "copilot" || this.provider === "hosted" || this.provider === "opencode" && (this.wireApi === "chat_completions" || this.wireApi === "responses") || // chatgpt-codex always speaks Responses API; treat it as
2806
+ return this.provider === "openrouter" || this.provider === "openai" || this.provider === "azure" || this.provider === "deepseek" || this.provider === "qwen" || this.provider === "xai" || this.provider === "copilot" || this.provider === "opencode" && (this.wireApi === "chat_completions" || this.wireApi === "responses") || // chatgpt-codex always speaks Responses API; treat it as
3443
2807
  // OpenAI-compat for body-shape branching purposes (the Responses
3444
2808
  // wire-API code paths below already key on `wireApi === "responses"`
3445
2809
  // and produce a body codex's backend accepts as-is).
@@ -3485,12 +2849,24 @@ var LlmApiRuntime = class _LlmApiRuntime {
3485
2849
  resolvedModel() {
3486
2850
  return this.model;
3487
2851
  }
2852
+ /** Price discovered IDs on their actual route without changing the wire model. */
2853
+ resolvedPricingModel() {
2854
+ if (this.provider === "chatgpt-codex" || this.provider === "copilot" || this.provider === "google")
2855
+ return this.model;
2856
+ if (this.pricingModelSource !== this.model || this.pricingProviderSource !== this.provider) {
2857
+ this.pricingModelSource = this.model;
2858
+ this.pricingProviderSource = this.provider;
2859
+ this.pricingModelKey = `${this.provider}/${this.model}`;
2860
+ }
2861
+ return this.pricingModelKey;
2862
+ }
3488
2863
  /** Build the appropriate headers for the configured provider. */
3489
2864
  buildHeaders() {
3490
2865
  if (this.provider === "chatgpt-codex") {
3491
2866
  return {
3492
2867
  "Content-Type": "application/json",
3493
- originator: "0",
2868
+ ...CODEX_PROTOCOL_HEADERS,
2869
+ "x-codex-routing-hint": `model=${this.model}`,
3494
2870
  "User-Agent": `0/${VERSION}`
3495
2871
  };
3496
2872
  }
@@ -3753,12 +3129,10 @@ var LlmApiRuntime = class _LlmApiRuntime {
3753
3129
  return "GitHub Copilot";
3754
3130
  case "google":
3755
3131
  return "Google Gemini (Code Assist)";
3756
- case "hosted":
3757
- return "0.security Cloud";
3758
3132
  }
3759
3133
  }
3760
3134
  noKeyError() {
3761
- return "No provider credential found. Set one of:\n env ZERO_CHATGPT_OAUTH_REFRESH_TOKEN=... 0 <command> (ChatGPT Codex subscription auth)\n export OPENROUTER_API_KEY=sk-or-... (OpenRouter \u2014 many models, one key)\n export DEEPSEEK_API_KEY=... (DeepSeek \u2014 direct Flash 0731 inference)\n export ANTHROPIC_API_KEY=sk-ant-... (Anthropic \u2014 direct Claude access)\n export AZURE_OPENAI_API_KEY=... (Azure OpenAI \u2014 reuse your Codex Azure provider)\n export OPENAI_API_KEY=sk-... (OpenAI \u2014 direct GPT access)\n export Z_AI_API_KEY=... (Z.ai GLM \u2014 flat-rate Coding Plan, Anthropic-compatible)\n export KIMI_API_KEY=... (Moonshot Kimi K3 \u2014 flat-rate coding, Anthropic-compatible)\n export QWEN_API_KEY=... (Alibaba Qwen \u2014 Token Plan sub, OpenAI-compatible)\n export XAI_API_KEY=... (xAI Grok \u2014 OpenAI-compatible)\n export OPENCODE_API_KEY=... (OpenCode Zen \u2014 multi-wire gateway)\n export ZERO_COPILOT_GITHUB_TOKEN=... (GitHub Copilot \u2014 device-code OAuth token)\n Run `0 login` (0 hosted inference)";
3135
+ return "No provider credential found. Set one of:\n env ZERO_CHATGPT_OAUTH_REFRESH_TOKEN=... 0 <command> (ChatGPT Codex subscription auth)\n export OPENROUTER_API_KEY=sk-or-... (OpenRouter \u2014 many models, one key)\n export DEEPSEEK_API_KEY=... (DeepSeek \u2014 direct Flash 0731 inference)\n export ANTHROPIC_API_KEY=sk-ant-... (Anthropic \u2014 direct Claude access)\n export AZURE_OPENAI_API_KEY=... (Azure OpenAI \u2014 reuse your Codex Azure provider)\n export OPENAI_API_KEY=sk-... (OpenAI \u2014 direct GPT access)\n export Z_AI_API_KEY=... (Z.ai GLM \u2014 flat-rate Coding Plan, Anthropic-compatible)\n export KIMI_API_KEY=... (Moonshot Kimi K3 \u2014 flat-rate coding, Anthropic-compatible)\n export QWEN_API_KEY=... (Alibaba Qwen \u2014 Token Plan sub, OpenAI-compatible)\n export XAI_API_KEY=... (xAI Grok \u2014 OpenAI-compatible)\n export OPENCODE_API_KEY=... (OpenCode Zen \u2014 multi-wire gateway)\n export ZERO_COPILOT_GITHUB_TOKEN=... (GitHub Copilot \u2014 device-code OAuth token)";
3762
3136
  }
3763
3137
  getConfigurationDiagnostics() {
3764
3138
  if (!this.apiKey && this.provider !== "chatgpt-codex") {
@@ -3851,7 +3225,6 @@ Missing: ${missing.join("; ")}
3851
3225
  this.apiKey = cfg.apiKey;
3852
3226
  this.baseUrl = cfg.baseUrl;
3853
3227
  this.wireApi = cfg.wireApi;
3854
- this.hostedCatalogPromise = null;
3855
3228
  diag.warn("failover_engaged", `${reason} \u2014 failover to ${entry.provider} (${entry.model})`, { reason, provider: entry.provider, model: entry.model });
3856
3229
  return true;
3857
3230
  }
@@ -3865,9 +3238,8 @@ Missing: ${missing.join("; ")}
3865
3238
  * hammering the limit in lockstep).
3866
3239
  *
3867
3240
  * The body factory is valid only for the current provider and wire protocol.
3868
- * A null result signals failover: the caller resolves the hosted catalog and
3869
- * rebuilds the complete request under its existing timeout/cancellation signal.
3870
- *
3241
+ * A null result signals failover so the caller rebuilds the complete request
3242
+ * under its existing timeout/cancellation signal.
3871
3243
  * Retry + failover caps documented on `retryBackoffMs` / `llm429MaxRetries`.
3872
3244
  *
3873
3245
  * Headers are re-resolved per attempt (via ensureFreshHeaders → OAuth
@@ -3888,9 +3260,6 @@ Missing: ${missing.join("; ")}
3888
3260
  });
3889
3261
  } catch (error) {
3890
3262
  abort?.throwIfCancelled();
3891
- if (this.provider === "hosted") {
3892
- throw new Error("0 hosted request outcome is unknown. Automatic replay is disabled; check your inference usage before retrying.", { cause: error });
3893
- }
3894
3263
  const cause = error instanceof Error ? error.cause : void 0;
3895
3264
  const causeCode = cause && typeof cause === "object" && "code" in cause && typeof cause.code === "string" ? cause.code : "unknown";
3896
3265
  const causeHost = cause && typeof cause === "object" && "hostname" in cause && typeof cause.hostname === "string" ? `@${cause.hostname}` : "";
@@ -3917,13 +3286,6 @@ Missing: ${missing.join("; ")}
3917
3286
  if (res.ok || !isRetryableHttpStatus(res.status)) {
3918
3287
  return res;
3919
3288
  }
3920
- if (this.provider === "hosted" && res.status === 429 && res.headers.get("x-0-retry-safe") !== "1") {
3921
- return res;
3922
- }
3923
- if (this.provider === "hosted" && res.status >= 500) {
3924
- await res.body?.cancel();
3925
- throw new Error(`0 hosted request returned HTTP ${res.status}; its outcome may be unknown. Automatic replay is disabled; check your inference usage before retrying.`);
3926
- }
3927
3289
  abort?.throwIfCancelled();
3928
3290
  const is429 = res.status === 429;
3929
3291
  let bodyText;
@@ -4014,7 +3376,6 @@ Missing: ${missing.join("; ")}
4014
3376
  }
4015
3377
  // ── Legacy Runtime interface (single-prompt) ──
4016
3378
  async execute(prompt, context) {
4017
- await this.ensureHostedModel();
4018
3379
  const start = Date.now();
4019
3380
  if (!this.apiKey && this.provider !== "chatgpt-codex" && this.provider !== "google") {
4020
3381
  return {
@@ -4026,15 +3387,11 @@ Missing: ${missing.join("; ")}
4026
3387
  };
4027
3388
  }
4028
3389
  const systemPrompt = context?.systemPrompt ?? "";
4029
- let releaseHostedSlot = this.provider === "hosted" ? await this.acquireHostedSlot() : void 0;
4030
3390
  const controller = new AbortController();
4031
3391
  const timer = setTimeout(() => controller.abort(), this.config.timeout || 12e4);
4032
3392
  try {
4033
3393
  let res;
4034
3394
  do {
4035
- if (this.provider === "hosted" && !releaseHostedSlot) {
4036
- releaseHostedSlot = await this.acquireHostedSlot(controller.signal);
4037
- }
4038
3395
  if (this.isOpenAICompat && this.wireApi === "chat_completions") {
4039
3396
  const messages = [];
4040
3397
  if (systemPrompt) {
@@ -4043,7 +3400,7 @@ Missing: ${missing.join("; ")}
4043
3400
  messages.push({ role: "user", content: prompt });
4044
3401
  res = await this.postWithRetry(() => JSON.stringify({
4045
3402
  model: this.model,
4046
- [this.maxTokensParamKey]: this.effectiveOutputTokens,
3403
+ [this.maxTokensParamKey]: NATIVE_COMPLETION_TOKEN_LIMIT,
4047
3404
  messages,
4048
3405
  // See executeNative: explicit reasoning_effort passthrough only.
4049
3406
  ...this.reasoningEffort ? { reasoning_effort: this.reasoningEffort } : {}
@@ -4064,7 +3421,7 @@ Missing: ${missing.join("; ")}
4064
3421
  res = await this.postWithRetry(() => JSON.stringify({
4065
3422
  model: this.model,
4066
3423
  input,
4067
- ...isCodex ? { store: false } : { max_output_tokens: this.effectiveOutputTokens }
3424
+ ...isCodex ? { store: false } : { max_output_tokens: NATIVE_COMPLETION_TOKEN_LIMIT }
4068
3425
  }), controller.signal);
4069
3426
  } else if (this.isGeminiCodeAssist) {
4070
3427
  const request = {
@@ -4091,8 +3448,6 @@ Missing: ${missing.join("; ")}
4091
3448
  } else {
4092
3449
  throw new Error(`execute: provider ${this.provider} is not mapped to a wire`);
4093
3450
  }
4094
- if (!res)
4095
- await this.ensureHostedModel();
4096
3451
  } while (!res);
4097
3452
  clearTimeout(timer);
4098
3453
  const body = await res.text();
@@ -4162,8 +3517,6 @@ Missing: ${missing.join("; ")}
4162
3517
  durationMs: Date.now() - start,
4163
3518
  error: timedOut ? `${this.providerLabel} API request timed out` : `${this.providerLabel} API error: ${msg}`
4164
3519
  };
4165
- } finally {
4166
- releaseHostedSlot?.();
4167
3520
  }
4168
3521
  }
4169
3522
  // ── Native Runtime interface (structured messages + tool_use) ──
@@ -4177,14 +3530,7 @@ Missing: ${missing.join("; ")}
4177
3530
  error: `${this.providerLabel} request cancelled by operator`
4178
3531
  };
4179
3532
  }
4180
- /**
4181
- * Public entry point. Runs {@link executeNativeAttempt} and, ONLY for a
4182
- * transient empty stream (see {@link shouldRetryNativeStream}), re-issues the
4183
- * whole request up to {@link llmStreamMaxAttempts} times with a short backoff.
4184
- * Every other outcome — success, a real API error, a timeout, an operator
4185
- * cancellation — is returned from the first attempt untouched, preserving the
4186
- * existing behaviour exactly.
4187
- */
3533
+ /** Public entry point. Retries a transient empty stream with bounded backoff. */
4188
3534
  async executeNative(system, messages, tools, callbacks, signal) {
4189
3535
  const maxAttempts = llmStreamMaxAttempts();
4190
3536
  let result;
@@ -4205,7 +3551,6 @@ Missing: ${missing.join("; ")}
4205
3551
  return result;
4206
3552
  }
4207
3553
  async executeNativeAttempt(system, messages, tools, callbacks, signal) {
4208
- await this.ensureHostedModel();
4209
3554
  const start = Date.now();
4210
3555
  if (!this.apiKey && this.provider !== "chatgpt-codex" && this.provider !== "google") {
4211
3556
  return {
@@ -4217,25 +3562,12 @@ Missing: ${missing.join("; ")}
4217
3562
  }
4218
3563
  if (signal?.aborted)
4219
3564
  return this.cancelledResult(start);
4220
- let releaseHostedSlot;
4221
- if (this.provider === "hosted") {
4222
- try {
4223
- releaseHostedSlot = await this.acquireHostedSlot(signal);
4224
- } catch (error) {
4225
- if (signal?.aborted)
4226
- return this.cancelledResult(start);
4227
- throw error;
4228
- }
4229
- }
4230
3565
  const controller = new AbortController();
4231
3566
  const timer = setTimeout(() => controller.abort(), this.config.timeout || 12e4);
4232
3567
  const call = composeCallAbort(controller.signal, signal);
4233
3568
  try {
4234
3569
  let res;
4235
3570
  do {
4236
- if (this.provider === "hosted" && !releaseHostedSlot) {
4237
- releaseHostedSlot = await this.acquireHostedSlot(call.signal);
4238
- }
4239
3571
  if (this.isOpenAICompat && this.wireApi === "chat_completions") {
4240
3572
  const chatMessages = [];
4241
3573
  chatMessages.push({ role: "system", content: system });
@@ -4283,7 +3615,7 @@ Missing: ${missing.join("; ")}
4283
3615
  }
4284
3616
  const body = {
4285
3617
  model: this.model,
4286
- [this.maxTokensParamKey]: this.effectiveOutputTokens,
3618
+ [this.maxTokensParamKey]: NATIVE_COMPLETION_TOKEN_LIMIT,
4287
3619
  messages: chatMessages
4288
3620
  };
4289
3621
  if (this.reasoningEffort) {
@@ -4351,7 +3683,7 @@ Missing: ${missing.join("; ")}
4351
3683
  const body = {
4352
3684
  model: this.model,
4353
3685
  input,
4354
- ...isCodex ? { store: false, instructions: system } : { max_output_tokens: this.effectiveOutputTokens },
3686
+ ...isCodex ? { store: false, instructions: system } : { max_output_tokens: NATIVE_COMPLETION_TOKEN_LIMIT },
4355
3687
  ...reasoningEffort ? {
4356
3688
  reasoning: {
4357
3689
  effort: reasoningEffort,
@@ -4410,10 +3742,8 @@ Missing: ${missing.join("; ")}
4410
3742
  }
4411
3743
  }
4412
3744
  res = await this.postWithRetry(() => JSON.stringify({ ...body, stream: true, model: this.model }), call.signal, call);
4413
- if (!res) {
4414
- await this.ensureHostedModel();
3745
+ if (!res)
4415
3746
  continue;
4416
- }
4417
3747
  if (!res.ok) {
4418
3748
  const responseText2 = await res.text();
4419
3749
  clearTimeout(timer);
@@ -4522,8 +3852,6 @@ Missing: ${missing.join("; ")}
4522
3852
  } else {
4523
3853
  throw new Error(`executeNative: provider ${this.provider} is not mapped to a wire`);
4524
3854
  }
4525
- if (!res)
4526
- await this.ensureHostedModel();
4527
3855
  } while (!res);
4528
3856
  const responseText = await res.text();
4529
3857
  clearTimeout(timer);
@@ -4734,7 +4062,6 @@ Missing: ${missing.join("; ")}
4734
4062
  error: timedOut ? `${this.providerLabel} API request timed out` : `${this.providerLabel} API error: ${msg}`
4735
4063
  };
4736
4064
  } finally {
4737
- releaseHostedSlot?.();
4738
4065
  call.dispose();
4739
4066
  }
4740
4067
  }
@@ -5083,18 +4410,11 @@ export {
5083
4410
  isDiagnosticsClaimed,
5084
4411
  recentDiagnostics,
5085
4412
  _resetDiagnosticsForTests,
5086
- DEFAULT_CLOUD_HOST,
5087
- CloudAuthMissingError,
5088
- CloudAuthError,
5089
- loadCloudCredentials,
5090
- CloudError,
5091
- CloudUnauthorizedError,
5092
- CloudForbiddenError,
5093
- CloudNetworkError,
5094
- CloudClient,
5095
4413
  QuotaExhaustedError,
5096
4414
  OperatorAbortError,
5097
4415
  parseUsageLimitReached,
4416
+ CODEX_CLIENT_VERSION,
4417
+ CODEX_PROTOCOL_HEADERS,
5098
4418
  LOOP_SERVER_COMPACTION_TOKENS,
5099
4419
  getChatGptCodexAccessToken,
5100
4420
  LlmApiRuntime